Dune Core Modules (2.5.2)

tupleutility.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 
4 #ifndef DUNE_TUPLE_UTILITY_HH
5 #define DUNE_TUPLE_UTILITY_HH
6 
7 #include <cstddef>
8 #include <tuple>
9 #include <type_traits>
10 
11 #include <dune/common/hybridutilities.hh>
12 #include <dune/common/std/type_traits.hh>
13 #include <dune/common/std/utility.hh>
14 
15 namespace Dune {
16 
27  template<class T>
28  struct TupleAccessTraits
29  {
30  typedef typename std::add_const<T>::type& ConstType;
31  typedef T& NonConstType;
32  typedef const typename std::remove_const<T>::type& ParameterType;
33  };
34 
35  template<class T>
36  struct TupleAccessTraits<T*>
37  {
38  typedef typename std::add_const<T>::type* ConstType;
39  typedef T* NonConstType;
40  typedef T* ParameterType;
41  };
42 
43  template<class T>
44  struct TupleAccessTraits<T&>
45  {
46  typedef T& ConstType;
47  typedef T& NonConstType;
48  typedef T& ParameterType;
49  };
50 
58  template<class T>
60 
61  template<class... Args>
62  struct NullPointerInitialiser<std::tuple<Args...> >
63  {
64  typedef std::tuple<Args...> ResultType;
65  static ResultType apply()
66  {
67  return ResultType(static_cast<Args>(nullptr)...);
68  }
69  };
70 
95  template<template <class> class TE, class T>
96  struct ForEachType;
97 
98  template<template <class> class TE, class... Args>
99  struct ForEachType<TE, std::tuple<Args...> >
100  {
101  typedef std::tuple<typename TE<Args>::Type...> Type;
102  };
103 
104 #ifndef DOXYGEN
105  template<class Tuple, class Functor, std::size_t... I>
106  inline auto genericTransformTupleBackendImpl(Tuple& t, Functor& f, const Std::index_sequence<I...>& )
107  -> std::tuple<decltype(f(std::get<I>(t)))...>
108  {
109  return std::tuple<decltype(f(std::get<I>(t)))...>(f(std::get<I>(t))...);
110  }
111 
112  template<class... Args, class Functor>
113  auto genericTransformTupleBackend(std::tuple<Args...>& t, Functor& f) ->
114  decltype(genericTransformTupleBackendImpl(t, f,Std::index_sequence_for<Args...>{}))
115  {
116  return genericTransformTupleBackendImpl(t, f,Std::index_sequence_for<Args...>{});
117  }
118 
119  template<class... Args, class Functor>
120  auto genericTransformTupleBackend(const std::tuple<Args...>& t, Functor& f) ->
121  decltype(genericTransformTupleBackendImpl(t, f, Std::index_sequence_for<Args...>{}))
122  {
123  return genericTransformTupleBackendImpl(t, f, Std::index_sequence_for<Args...>{});
124  }
125 #endif
126 
165  template<class Tuple, class Functor>
166  auto genericTransformTuple(Tuple&& t, Functor&& f) ->
167  decltype(genericTransformTupleBackend(t, f))
168  {
169  return genericTransformTupleBackend(t, f);
170  }
171 
204  template<template<class> class TE, class... Args>
206  {
207  mutable std::tuple<Args&...> tup;
208 
209  template<class T, std::size_t... I>
210  inline auto apply(T&& t, const Std::index_sequence<I...>& ) ->
211  decltype(TE<T>::apply(t,std::get<I>(tup)...)) const
212  {
213  return TE<T>::apply(t,std::get<I>(tup)...);
214  }
215 
216  public:
217  template<class T>
218  struct TypeEvaluator : public TE<T>
219  {};
220 
221  TransformTupleFunctor(Args&&... args)
222  : tup(args...)
223  { }
224 
225  template<class T>
226  inline auto operator()(T&& t) ->
227  decltype(this->apply(t,Std::index_sequence_for<Args...>{})) const
228  {
229  return apply(t,Std::index_sequence_for<Args...>{});
230  }
231  };
232 
233  template<template<class> class TE, class... Args>
234  TransformTupleFunctor<TE, Args...> makeTransformTupleFunctor(Args&&... args)
235  {
236  return TransformTupleFunctor<TE, Args...>(args...);
237  }
238 
271  template<template<class> class TypeEvaluator, class Tuple, class... Args>
272  auto transformTuple(Tuple&& orig, Args&&... args) ->
273  decltype(genericTransformTuple(orig, makeTransformTupleFunctor<TypeEvaluator>(args...)))
274  {
275  return genericTransformTuple(orig, makeTransformTupleFunctor<TypeEvaluator>(args...));
276  }
277 
279 
283  template<class T>
285  {
286  typedef T& Type;
287  static Type apply(T& t)
288  {
289  return t;
290  }
291  };
292 
294 
298  template<class T>
300  {
301  typedef typename std::remove_reference<T>::type* Type;
302  static Type apply(T& t)
303  {
304  return &t;
305  }
306  };
307 
308  // Specialization, in case the type is already a reference
309  template<class T>
310  struct AddPtrTypeEvaluator<T&>
311  {
312  typedef typename std::remove_reference<T>::type* Type;
313  static Type apply(T& t)
314  {
315  return &t;
316  }
317  };
318 
362  template<class Tuple>
364  {
365  public:
368  ForEachValue(Tuple& t) :
369  t_(t)
370  {}
371 
374  template<class Functor>
375  void apply(Functor& f) const
376  {
377  Hybrid::forEach(Std::make_index_sequence<std::tuple_size<Tuple>::value>{},
378  [&](auto i){f.visit(std::get<i>(t_));});
379  }
380  private:
381  Tuple& t_;
382  };
383 
397  template<class Tuple1, class Tuple2>
399  {
400  public:
404  ForEachValuePair(Tuple1& t1, Tuple2& t2) :
405  t1_(t1),
406  t2_(t2)
407  {}
408 
411  template<class Functor>
412  void apply(Functor& f)
413  {
414  Hybrid::forEach(Std::make_index_sequence<std::tuple_size<Tuple1>::value>{},
415  [&](auto i){f.visit(std::get<i>(t1_), std::get<i>(t2_));});
416  }
417  private:
418  Tuple1& t1_;
419  Tuple2& t2_;
420  };
421 
427  template<int N, class Tuple>
428  struct AtType
429  {
430  typedef typename std::tuple_element<std::tuple_size<Tuple>::value - N - 1, Tuple>::type Type;
431  };
432 
440  template<int N>
441  struct At
442  {
443  template<typename Tuple>
444  static typename TupleAccessTraits<typename AtType<N, Tuple>::Type>::NonConstType
445  get(Tuple& t)
446  {
447  return std::get<std::tuple_size<Tuple>::value - N - 1>(t);
448  }
449 
450  template<typename Tuple>
451  static typename TupleAccessTraits<typename AtType<N, Tuple>::Type>::ConstType
452  get(const Tuple& t)
453  {
454  return std::get<std::tuple_size<Tuple>::value - N - 1>(t);
455  }
456  };
457 
461  template<class Tuple>
463  {
464  template<typename... Ts>
465  static void apply(std::tuple<Ts...>& t)
466  {
467  Hybrid::forEach(t,[&](auto&& ti){delete ti; ti=nullptr;});
468  }
469  };
470 
494  template<class Tuple, template<class> class Predicate, std::size_t start = 0,
495  std::size_t size = std::tuple_size<Tuple>::value>
497  public std::conditional<Predicate<typename std::tuple_element<start,
498  Tuple>::type>::value,
499  std::integral_constant<std::size_t, start>,
500  FirstPredicateIndex<Tuple, Predicate, start+1> >::type
501  {
502  static_assert(std::tuple_size<Tuple>::value == size, "The \"size\" "
503  "template parameter of FirstPredicateIndex is an "
504  "implementation detail and should never be set "
505  "explicitly!");
506  };
507 
508 #ifndef DOXYGEN
509  template<class Tuple, template<class> class Predicate, std::size_t size>
510  class FirstPredicateIndex<Tuple, Predicate, size, size>
511  {
512  static_assert(Std::to_false_type<Tuple>::value, "None of the std::tuple element "
513  "types matches the predicate!");
514  };
515 #endif // !DOXYGEN
516 
526  template<class T>
527  struct IsType
528  {
530  template<class U>
531  struct Predicate : public std::is_same<T, U> {};
532  };
533 
547  template<class Tuple, class T, std::size_t start = 0>
548  struct FirstTypeIndex :
549  public FirstPredicateIndex<Tuple, IsType<T>::template Predicate, start>
550  { };
551 
558  template<class Tuple, class T>
560 
561  template<class... Args, class T>
562  struct PushBackTuple<typename std::tuple<Args...>, T>
563  {
564  typedef typename std::tuple<Args..., T> type;
565  };
566 
573  template<class Tuple, class T>
575 
576  template<class... Args, class T>
577  struct PushFrontTuple<typename std::tuple<Args...>, T>
578  {
579  typedef typename std::tuple<T, Args...> type;
580  };
581 
594  template<
595  template <class, class> class F,
596  class Tuple,
597  class Seed=std::tuple<>,
598  int N=std::tuple_size<Tuple>::value>
599  struct ReduceTuple
600  {
601  typedef typename ReduceTuple<F, Tuple, Seed, N-1>::type Accumulated;
602  typedef typename std::tuple_element<N-1, Tuple>::type Value;
603 
605  typedef typename F<Accumulated, Value>::type type;
606  };
607 
618  template<
619  template <class, class> class F,
620  class Tuple,
621  class Seed>
622  struct ReduceTuple<F, Tuple, Seed, 0>
623  {
625  typedef Seed type;
626  };
627 
637  template<class Head, class Tail>
638  struct JoinTuples
639  {
642  };
643 
652  template<class Tuple>
654  {
657  };
658 
660 }
661 
662 #endif
Finding the index of a certain type in a std::tuple.
Definition: tupleutility.hh:501
Extension of ForEachValue to two std::tuple's.
Definition: tupleutility.hh:399
Helper template which implements iteration over all storage elements in a std::tuple.
Definition: tupleutility.hh:364
Definition: tupleutility.hh:206
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:314
ForEachValuePair(Tuple1 &t1, Tuple2 &t2)
Definition: tupleutility.hh:404
auto transformTuple(Tuple &&orig, Args &&... args) -> decltype(genericTransformTuple(orig, makeTransformTupleFunctor< TypeEvaluator >(args...)))
Definition: tupleutility.hh:272
Seed type
Result of the reduce operation.
Definition: tupleutility.hh:625
ReduceTuple< PushBackTuple, Tail, Head >::type type
Result of the join operation.
Definition: tupleutility.hh:641
F< Accumulated, Value >::type type
Result of the reduce operation.
Definition: tupleutility.hh:605
void apply(Functor &f)
Definition: tupleutility.hh:412
ReduceTuple< JoinTuples, Tuple >::type type
Result of the flatten operation.
Definition: tupleutility.hh:656
ForEachValue(Tuple &t)
Constructor.
Definition: tupleutility.hh:368
void apply(Functor &f) const
Applies a function object to each storage element of the std::tuple.
Definition: tupleutility.hh:375
auto genericTransformTuple(Tuple &&t, Functor &&f) -> decltype(genericTransformTupleBackend(t, f))
Definition: tupleutility.hh:166
Dune namespace.
Definition: alignment.hh:11
TypeEvaluator to turn a type T into a pointer to T
Definition: tupleutility.hh:300
TypeEvaluator to turn a type T into a reference to T
Definition: tupleutility.hh:285
Type for reverse element access.
Definition: tupleutility.hh:429
Reverse element access.
Definition: tupleutility.hh:442
Find the first occurrence of a type in a std::tuple.
Definition: tupleutility.hh:550
Flatten a std::tuple of std::tuple's.
Definition: tupleutility.hh:654
Helper template to clone the type definition of a std::tuple with the storage types replaced by a use...
Definition: tupleutility.hh:96
The actual predicate.
Definition: tupleutility.hh:531
Generator for predicates accepting one particular type.
Definition: tupleutility.hh:528
Join two std::tuple's.
Definition: tupleutility.hh:639
A helper template that initializes a std::tuple consisting of pointers to nullptr.
Definition: tupleutility.hh:59
Deletes all objects pointed to in a std::tuple of pointers.
Definition: tupleutility.hh:463
Helper template to append a type to a std::tuple.
Definition: tupleutility.hh:559
Helper template to prepend a type to a std::tuple.
Definition: tupleutility.hh:574
Apply reduce with meta binary function to template.
Definition: tupleutility.hh:600
template mapping a type to std::false_type
Definition: type_traits.hh:63
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 13, 22:30, 2024)