Dune Core Modules (2.6.0)

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 
12 #include <dune/common/hybridutilities.hh>
13 #include <dune/common/std/type_traits.hh>
14 #include <dune/common/std/utility.hh>
15 
16 namespace Dune {
17 
28  template<class T>
29  struct TupleAccessTraits
30  {
31  typedef typename std::add_const<T>::type& ConstType;
32  typedef T& NonConstType;
33  typedef const typename std::remove_const<T>::type& ParameterType;
34  };
35 
36  template<class T>
37  struct TupleAccessTraits<T*>
38  {
39  typedef typename std::add_const<T>::type* ConstType;
40  typedef T* NonConstType;
41  typedef T* ParameterType;
42  };
43 
44  template<class T>
45  struct TupleAccessTraits<T&>
46  {
47  typedef T& ConstType;
48  typedef T& NonConstType;
49  typedef T& ParameterType;
50  };
51 
59  template<class T>
61 
62  template<class... Args>
63  struct NullPointerInitialiser<std::tuple<Args...> >
64  {
65  typedef std::tuple<Args...> ResultType;
66  static ResultType apply()
67  {
68  return ResultType(static_cast<Args>(nullptr)...);
69  }
70  };
71 
96  template<template <class> class TE, class T>
97  struct ForEachType;
98 
99  template<template <class> class TE, class... Args>
100  struct ForEachType<TE, std::tuple<Args...> >
101  {
102  typedef std::tuple<typename TE<Args>::Type...> Type;
103  };
104 
105 #ifndef DOXYGEN
106  template<class Tuple, class Functor, std::size_t... I>
107  inline auto genericTransformTupleBackendImpl(Tuple& t, Functor& f, const Std::index_sequence<I...>& )
108  -> std::tuple<decltype(f(std::get<I>(t)))...>
109  {
110  return std::tuple<decltype(f(std::get<I>(t)))...>(f(std::get<I>(t))...);
111  }
112 
113  template<class... Args, class Functor>
114  auto genericTransformTupleBackend(std::tuple<Args...>& t, Functor& f) ->
115  decltype(genericTransformTupleBackendImpl(t, f,Std::index_sequence_for<Args...>{}))
116  {
117  return genericTransformTupleBackendImpl(t, f,Std::index_sequence_for<Args...>{});
118  }
119 
120  template<class... Args, class Functor>
121  auto genericTransformTupleBackend(const std::tuple<Args...>& t, Functor& f) ->
122  decltype(genericTransformTupleBackendImpl(t, f, Std::index_sequence_for<Args...>{}))
123  {
124  return genericTransformTupleBackendImpl(t, f, Std::index_sequence_for<Args...>{});
125  }
126 #endif
127 
166  template<class Tuple, class Functor>
167  auto genericTransformTuple(Tuple&& t, Functor&& f) ->
168  decltype(genericTransformTupleBackend(t, f))
169  {
170  return genericTransformTupleBackend(t, f);
171  }
172 
205  template<template<class> class TE, class... Args>
207  {
208  mutable std::tuple<Args&...> tup;
209 
210  template<class T, std::size_t... I>
211  inline auto apply(T&& t, const Std::index_sequence<I...>& ) ->
212  decltype(TE<T>::apply(t,std::get<I>(tup)...)) const
213  {
214  return TE<T>::apply(t,std::get<I>(tup)...);
215  }
216 
217  public:
218  template<class T>
219  struct TypeEvaluator : public TE<T>
220  {};
221 
222  TransformTupleFunctor(Args&&... args)
223  : tup(args...)
224  { }
225 
226  template<class T>
227  inline auto operator()(T&& t) ->
228  decltype(this->apply(t,Std::index_sequence_for<Args...>{})) const
229  {
230  return apply(t,Std::index_sequence_for<Args...>{});
231  }
232  };
233 
234  template<template<class> class TE, class... Args>
235  TransformTupleFunctor<TE, Args...> makeTransformTupleFunctor(Args&&... args)
236  {
237  return TransformTupleFunctor<TE, Args...>(args...);
238  }
239 
272  template<template<class> class TypeEvaluator, class Tuple, class... Args>
273  auto transformTuple(Tuple&& orig, Args&&... args) ->
274  decltype(genericTransformTuple(orig, makeTransformTupleFunctor<TypeEvaluator>(args...)))
275  {
276  return genericTransformTuple(orig, makeTransformTupleFunctor<TypeEvaluator>(args...));
277  }
278 
280 
284  template<class T>
286  {
287  typedef T& Type;
288  static Type apply(T& t)
289  {
290  return t;
291  }
292  };
293 
295 
299  template<class T>
301  {
302  typedef typename std::remove_reference<T>::type* Type;
303  static Type apply(T& t)
304  {
305  return &t;
306  }
307  };
308 
309  // Specialization, in case the type is already a reference
310  template<class T>
311  struct AddPtrTypeEvaluator<T&>
312  {
313  typedef typename std::remove_reference<T>::type* Type;
314  static Type apply(T& t)
315  {
316  return &t;
317  }
318  };
319 
320  template<class Tuple>
321  struct DUNE_DEPRECATED_MSG("Use Hybrid::forEach instead!") ForEachValue
322  {
323  ForEachValue(Tuple& t) :
324  t_(t)
325  {}
326 
327  template<class Functor>
328  void apply(Functor& f) const
329  {
330  Hybrid::forEach(Std::make_index_sequence<std::tuple_size<Tuple>::value>{},
331  [&](auto i){f.visit(std::get<i>(t_));});
332  }
333 
334  Tuple& t_;
335  };
336 
337  template<class Tuple1, class Tuple2>
338  struct DUNE_DEPRECATED_MSG("Use Hybrid::forEach instead!") ForEachValuePair
339  {
340  ForEachValuePair(Tuple1& t1, Tuple2& t2) :
341  t1_(t1),
342  t2_(t2)
343  {}
344 
345  template<class Functor>
346  void apply(Functor& f)
347  {
348  Hybrid::forEach(Std::make_index_sequence<std::tuple_size<Tuple1>::value>{},
349  [&](auto i){f.visit(std::get<i>(t1_), std::get<i>(t2_));});
350  }
351 
352  Tuple1& t1_;
353  Tuple2& t2_;
354  };
355 
361  template<int N, class Tuple>
362  struct AtType
363  {
364  typedef typename std::tuple_element<std::tuple_size<Tuple>::value - N - 1, Tuple>::type Type;
365  };
366 
374  template<int N>
375  struct At
376  {
377  template<typename Tuple>
378  static typename TupleAccessTraits<typename AtType<N, Tuple>::Type>::NonConstType
379  get(Tuple& t)
380  {
381  return std::get<std::tuple_size<Tuple>::value - N - 1>(t);
382  }
383 
384  template<typename Tuple>
385  static typename TupleAccessTraits<typename AtType<N, Tuple>::Type>::ConstType
386  get(const Tuple& t)
387  {
388  return std::get<std::tuple_size<Tuple>::value - N - 1>(t);
389  }
390  };
391 
395  template<class Tuple>
397  {
398  template<typename... Ts>
399  static void apply(std::tuple<Ts...>& t)
400  {
401  Hybrid::forEach(t,[&](auto&& ti){delete ti; ti=nullptr;});
402  }
403  };
404 
428  template<class Tuple, template<class> class Predicate, std::size_t start = 0,
429  std::size_t size = std::tuple_size<Tuple>::value>
431  public std::conditional<Predicate<typename std::tuple_element<start,
432  Tuple>::type>::value,
433  std::integral_constant<std::size_t, start>,
434  FirstPredicateIndex<Tuple, Predicate, start+1> >::type
435  {
436  static_assert(std::tuple_size<Tuple>::value == size, "The \"size\" "
437  "template parameter of FirstPredicateIndex is an "
438  "implementation detail and should never be set "
439  "explicitly!");
440  };
441 
442 #ifndef DOXYGEN
443  template<class Tuple, template<class> class Predicate, std::size_t size>
444  class FirstPredicateIndex<Tuple, Predicate, size, size>
445  {
446  static_assert(Std::to_false_type<Tuple>::value, "None of the std::tuple element "
447  "types matches the predicate!");
448  };
449 #endif // !DOXYGEN
450 
460  template<class T>
461  struct IsType
462  {
464  template<class U>
465  struct Predicate : public std::is_same<T, U> {};
466  };
467 
481  template<class Tuple, class T, std::size_t start = 0>
482  struct FirstTypeIndex :
483  public FirstPredicateIndex<Tuple, IsType<T>::template Predicate, start>
484  { };
485 
492  template<class Tuple, class T>
494 
495  template<class... Args, class T>
496  struct PushBackTuple<typename std::tuple<Args...>, T>
497  {
498  typedef typename std::tuple<Args..., T> type;
499  };
500 
507  template<class Tuple, class T>
509 
510  template<class... Args, class T>
511  struct PushFrontTuple<typename std::tuple<Args...>, T>
512  {
513  typedef typename std::tuple<T, Args...> type;
514  };
515 
528  template<
529  template <class, class> class F,
530  class Tuple,
531  class Seed=std::tuple<>,
532  int N=std::tuple_size<Tuple>::value>
533  struct ReduceTuple
534  {
535  typedef typename ReduceTuple<F, Tuple, Seed, N-1>::type Accumulated;
536  typedef typename std::tuple_element<N-1, Tuple>::type Value;
537 
539  typedef typename F<Accumulated, Value>::type type;
540  };
541 
552  template<
553  template <class, class> class F,
554  class Tuple,
555  class Seed>
556  struct ReduceTuple<F, Tuple, Seed, 0>
557  {
559  typedef Seed type;
560  };
561 
571  template<class Head, class Tail>
572  struct JoinTuples
573  {
576  };
577 
586  template<class Tuple>
588  {
591  };
592 
594 }
595 
596 #endif
Finding the index of a certain type in a std::tuple.
Definition: tupleutility.hh:435
Definition: tupleutility.hh:207
Definition of the DUNE_DEPRECATED macro for the case that config.h is not available.
decltype(auto) apply(F &&f, ArgTuple &&args)
Apply function with arguments given as tuple.
Definition: apply.hh:58
#define DUNE_DEPRECATED_MSG(text)
Mark some entity as deprecated.
Definition: deprecated.hh:169
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:308
auto transformTuple(Tuple &&orig, Args &&... args) -> decltype(genericTransformTuple(orig, makeTransformTupleFunctor< TypeEvaluator >(args...)))
Definition: tupleutility.hh:273
Seed type
Result of the reduce operation.
Definition: tupleutility.hh:559
ReduceTuple< PushBackTuple, Tail, Head >::type type
Result of the join operation.
Definition: tupleutility.hh:575
F< Accumulated, Value >::type type
Result of the reduce operation.
Definition: tupleutility.hh:539
ReduceTuple< JoinTuples, Tuple >::type type
Result of the flatten operation.
Definition: tupleutility.hh:590
auto genericTransformTuple(Tuple &&t, Functor &&f) -> decltype(genericTransformTupleBackend(t, f))
Definition: tupleutility.hh:167
make_index_sequence< typename Dune::SizeOf< T... >{}> index_sequence_for
Create index_sequence from 0 to sizeof...(T)-1.
Definition: utility.hh:38
Dune namespace.
Definition: alignedallocator.hh:10
TypeEvaluator to turn a type T into a pointer to T
Definition: tupleutility.hh:301
TypeEvaluator to turn a type T into a reference to T
Definition: tupleutility.hh:286
Type for reverse element access.
Definition: tupleutility.hh:363
Reverse element access.
Definition: tupleutility.hh:376
Find the first occurrence of a type in a std::tuple.
Definition: tupleutility.hh:484
Flatten a std::tuple of std::tuple's.
Definition: tupleutility.hh:588
Helper template to clone the type definition of a std::tuple with the storage types replaced by a use...
Definition: tupleutility.hh:97
The actual predicate.
Definition: tupleutility.hh:465
Generator for predicates accepting one particular type.
Definition: tupleutility.hh:462
Join two std::tuple's.
Definition: tupleutility.hh:573
A helper template that initializes a std::tuple consisting of pointers to nullptr.
Definition: tupleutility.hh:60
Deletes all objects pointed to in a std::tuple of pointers.
Definition: tupleutility.hh:397
Helper template to append a type to a std::tuple.
Definition: tupleutility.hh:493
Helper template to prepend a type to a std::tuple.
Definition: tupleutility.hh:508
Apply reduce with meta binary function to template.
Definition: tupleutility.hh:534
template mapping a type to std::false_type
Definition: type_traits.hh:79
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 27, 22:29, 2024)