dune-typetree  2.4.0-rc1
utility.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_TYPETREE_UTILITY_HH
5 #define DUNE_TYPETREE_UTILITY_HH
6 
7 #include <memory>
8 #include <tuple>
9 #include <type_traits>
10 
11 #include <dune/common/shared_ptr.hh>
12 #include <dune/common/std/utility.hh>
14 
15 namespace Dune {
16  namespace TypeTree {
17 
22 #ifndef DOXYGEN
23 
24  template<typename T>
25  std::shared_ptr<T> convert_arg(const T& t)
26  {
27  return std::make_shared<T>(t);
28  }
29 
30  template<typename T>
31  std::shared_ptr<T> convert_arg(T& t)
32  {
33  return stackobject_to_shared_ptr(t);
34  }
35 
36  template<typename BaseType, typename T>
37  T& assertGridViewType(T& t)
38  {
39  static_assert((std::is_same<typename BaseType::Traits::GridViewType,
40  typename T::Traits::GridViewType>::value),
41  "GridViewType must be equal in all components of composite type");
42  return t;
43  }
44 
45  // only bind to real rvalues
46  template<typename T>
47  typename std::enable_if<!std::is_lvalue_reference<T>::value,std::shared_ptr<T> >::type convert_arg(T&& t)
48  {
49  return std::make_shared<T>(std::forward<T>(t));
50  }
51 
52 #endif // DOXYGEN
53 
55 
62  template<typename Tree, typename Tag = StartTag>
63  struct TreeInfo
64  {
65 
66  private:
67  // Start the tree traversal
69 
70  public:
71 
73  static const std::size_t depth = NodeInfo::depth;
74 
76  static const std::size_t nodeCount = NodeInfo::nodeCount;
77 
79  static const std::size_t leafCount = NodeInfo::leafCount;
80 
81  };
82 
83 
84 #ifndef DOXYGEN
85 
86  // ********************************************************************************
87  // TreeInfo specializations for the different node types
88  // ********************************************************************************
89 
90 
91  // leaf node
92  template<typename Node>
93  struct TreeInfo<Node,LeafNodeTag>
94  {
95 
96  static const std::size_t depth = 1;
97 
98  static const std::size_t nodeCount = 1;
99 
100  static const std::size_t leafCount = 1;
101 
102  };
103 
104 
105  // power node - exploit the fact that all children are identical
106  template<typename Node>
107  struct TreeInfo<Node,PowerNodeTag>
108  {
109 
110  typedef TreeInfo<typename Node::ChildType,typename Node::ChildType::NodeTag> ChildInfo;
111 
112  static const std::size_t depth = 1 + ChildInfo::depth;
113 
114  static const std::size_t nodeCount = 1 + Node::CHILDREN * ChildInfo::nodeCount;
115 
116  static const std::size_t leafCount = Node::CHILDREN * ChildInfo::leafCount;
117 
118  };
119 
120 
121  namespace {
122 
123  // TMP for iterating over the children of a composite node
124  // identical for both composite node implementations
125  template<typename Node, std::size_t k, std::size_t n>
126  struct generic_compositenode_children_info
127  {
128 
129  typedef generic_compositenode_children_info<Node,k+1,n> NextChild;
130 
131  // extract child info
132  typedef typename Node::template Child<k>::Type Child;
133  typedef typename Child::NodeTag ChildTag;
134  typedef TreeInfo<Child,ChildTag> ChildInfo;
135 
136  // combine information of current child with info about following children
137  static const std::size_t maxDepth = ChildInfo::depth > NextChild::maxDepth ? ChildInfo::depth : NextChild::maxDepth;
138 
139  static const std::size_t nodeCount = ChildInfo::nodeCount + NextChild::nodeCount;
140 
141  static const std::size_t leafCount = ChildInfo::leafCount + NextChild::leafCount;
142 
143  };
144 
145  // End of recursion
146  template<typename Node, std::size_t n>
147  struct generic_compositenode_children_info<Node,n,n>
148  {
149  static const std::size_t maxDepth = 0;
150 
151  static const std::size_t nodeCount = 0;
152 
153  static const std::size_t leafCount = 0;
154  };
155 
156  } // anonymous namespace
157 
158 
159  // Struct for building information about composite node
160  template<typename Node>
161  struct GenericCompositeNodeInfo
162  {
163 
164  typedef generic_compositenode_children_info<Node,0,Node::CHILDREN> Children;
165 
166  static const std::size_t depth = 1 + Children::maxDepth;
167 
168  static const std::size_t nodeCount = 1 + Children::nodeCount;
169 
170  static const std::size_t leafCount = Children::leafCount;
171 
172  };
173 
174 
175  // CompositeNode: delegate to GenericCompositeNodeInfo
176  template<typename Node>
177  struct TreeInfo<Node,CompositeNodeTag>
178  : public GenericCompositeNodeInfo<Node>
179  {};
180 
181 
182 #endif // DOXYGEN
183 
184 
186 
204  template<std::size_t... i>
205  struct index_pack {};
206 
208  template<std::size_t n, std::size_t... i>
210  : public index_pack_builder<n-1,n-1,i...>
211  {
212 
213 #ifdef DOXYGEN
214  typedef index_pack<0,1,...,n-1> type;
216 #endif // DOXYGEN
217 
218  };
219 
220 #ifndef DOXYGEN
221 
222  // end of recursion
223  template<std::size_t... i>
224  struct index_pack_builder<0,i...>
225  {
226  typedef index_pack<i...> type;
227  };
228 
229 #endif // DOXYGEN
230 
232  template<typename tuple>
234  : public index_pack_builder<std::tuple_size<tuple>::value>
235  {};
236 
238  template<typename tuple>
240  {
241  return typename tuple_index_pack_builder<tuple>::type();
242  }
243 
245 
249  template<std::size_t n>
250  typename index_pack_builder<n>::type index_range(std::integral_constant<std::size_t,n> = {})
251  {
252  return typename index_pack_builder<n>::type();
253  }
254 
255  namespace Std {
256 
258 
263  using Dune::Std::integer_sequence;
264 
266  template<std::size_t... indices>
267  using index_sequence = integer_sequence<std::size_t,indices...>;
268 
270  template<typename T, T n>
271  using make_integer_sequence = decltype(Dune::Std::make_integer_sequence<T,n>());
272 
274  template<std::size_t n>
276 
277 #ifndef DOXYGEN
278 
279  namespace impl {
280 
281  // This is a workaround for clang bug 14858 (https://llvm.org/bugs/show_bug.cgi?id=14858)
282  // in a template alias declaration, clang always deduces sizeof...(T) as 1, if the template
283  // alias is evaluated with an unpacked template parameter pack (instead of one that is explicitly
284  // constructed as a list of types at the call site. This is slightly braindead (and has been around
285  // since at least clang 3.0).
286  // As a workaround, we lift the computation into a struct definition.
287  template<typename... T>
288  struct _get_pack_length
289  : public std::integral_constant<std::size_t,sizeof...(T)>
290  {};
291 
292  }
293 
294 #endif
295 
297  template<typename... T>
298  using index_sequence_for = make_index_sequence<impl::_get_pack_length<T...>{}>;
299 
300  }
301 
302 
304 
311  template<std::size_t i>
312  using index_constant = std::integral_constant<std::size_t, i>;
313 
314 
315 
317 
332  namespace Indices {
333 
335  constexpr index_constant< 0> _0 = {};
336 
338  constexpr index_constant< 1> _1 = {};
339 
341  constexpr index_constant< 2> _2 = {};
342 
344  constexpr index_constant< 3> _3 = {};
345 
347  constexpr index_constant< 4> _4 = {};
348 
350  constexpr index_constant< 5> _5 = {};
351 
353  constexpr index_constant< 6> _6 = {};
354 
356  constexpr index_constant< 7> _7 = {};
357 
359  constexpr index_constant< 8> _8 = {};
360 
362  constexpr index_constant< 9> _9 = {};
363 
365  constexpr index_constant<10> _10 = {};
366 
368  constexpr index_constant<11> _11 = {};
369 
371  constexpr index_constant<12> _12 = {};
372 
374  constexpr index_constant<13> _13 = {};
375 
377  constexpr index_constant<14> _14 = {};
378 
380  constexpr index_constant<15> _15 = {};
381 
383  constexpr index_constant<16> _16 = {};
384 
386  constexpr index_constant<17> _17 = {};
387 
389  constexpr index_constant<18> _18 = {};
390 
392  constexpr index_constant<19> _19 = {};
393 
394  }
395 
396 
397 
399 
402  template<typename... Args>
403  void discard(Args&&... args)
404  {}
405 
407  namespace apply_to_tuple_policy {
408 
410  struct no_pass_index {};
411 
413  struct pass_index {};
414 
417 
418  }
419 
420  namespace {
421 
422  // version that does not pass index
423  template<typename T, typename F, std::size_t... i>
424  void _apply_to_tuple(T&& t, F&& f, Std::index_sequence<i...>,apply_to_tuple_policy::no_pass_index)
425  {
426  discard((f(std::get<i>(std::forward<T>(t))),0)...);
427  }
428 
429  // version that passes index
430  template<typename T, typename F, std::size_t... i>
431  void _apply_to_tuple(T&& t, F&& f, Std::index_sequence<i...>,apply_to_tuple_policy::pass_index)
432  {
433  discard((f(index_constant<i>{},std::get<i>(std::forward<T>(t))),0)...);
434  }
435 
436  }
437 
439  /*
440  * This function applies the functor f to each element of the std::tuple t.
441  * It works for arbitrary combinations of const- and non const lvalues and rvalues.
442  * The function accepts an optional policy argument that can currently be used to make
443  * it pass the index of the current tuple argument to the functor as a compile time constant
444  * in addition to the tuple element itself.
445  */
446  template<typename T, typename F, typename Policy>
448  {
449  const std::size_t size = std::tuple_size<typename std::decay<T>::type>::value;
450  _apply_to_tuple(
451  std::forward<T>(t),
452  std::forward<F>(f),
454  Policy()
455  );
456  }
457 
459 
460  } // namespace TypeTree
461 } //namespace Dune
462 
463 #endif // DUNE_TYPETREE_UTILITY_HH
constexpr index_constant< 7 > _7
Compile time index with value 7.
Definition: utility.hh:356
constexpr index_constant< 4 > _4
Compile time index with value 4.
Definition: utility.hh:347
index_pack_builder< n >::type index_range(std::integral_constant< std::size_t, n >={})
Generate an index_pack with the values {0, 1, ..., n-1}.
Definition: utility.hh:250
TMP to build an index_pack for all elements in the tuple.
Definition: utility.hh:233
void apply_to_tuple(T &&t, F &&f, Policy=apply_to_tuple_policy::default_policy())
Apply a functor to each element of a std::tuple.
Definition: utility.hh:447
static const std::size_t leafCount
The number of leaf nodes in the TypeTree.
Definition: utility.hh:79
constexpr index_constant< 10 > _10
Compile time index with value 10.
Definition: utility.hh:365
tuple_index_pack_builder< tuple >::type tuple_indices(const tuple &t)
Generate an index_pack for the tuple t.
Definition: utility.hh:239
constexpr index_constant< 1 > _1
Compile time index with value 1.
Definition: utility.hh:338
decltype(Dune::Std::make_integer_sequence< T, n >()) make_integer_sequence
Create an integer_sequence [0,n-1] with entries of type T.
Definition: utility.hh:271
Definition: accumulate_static.hh:12
constexpr index_constant< 13 > _13
Compile time index with value 13.
Definition: utility.hh:374
constexpr index_constant< 6 > _6
Compile time index with value 6.
Definition: utility.hh:353
Do not pass the index of the current tuple to the functor.
Definition: utility.hh:410
Tag designating a leaf node.
Definition: nodetags.hh:16
constexpr index_constant< 5 > _5
Compile time index with value 5.
Definition: utility.hh:350
Pass the index of the current tuple to the functor as its first argument in a std::integral_constant...
Definition: utility.hh:413
make_index_sequence< impl::_get_pack_length< T...>{}> index_sequence_for
Create an index_sequence for the pack T..., i.e. [0,sizeof...(T)].
Definition: utility.hh:298
static const std::size_t nodeCount
The total number of nodes in the TypeTree.
Definition: utility.hh:76
std::integral_constant< std::size_t, i > index_constant
An index constant with value i.
Definition: utility.hh:312
constexpr index_constant< 15 > _15
Compile time index with value 15.
Definition: utility.hh:380
constexpr index_constant< 17 > _17
Compile time index with value 17.
Definition: utility.hh:386
constexpr index_constant< 18 > _18
Compile time index with value 18.
Definition: utility.hh:389
constexpr index_constant< 12 > _12
Compile time index with value 12.
Definition: utility.hh:371
constexpr index_constant< 3 > _3
Compile time index with value 3.
Definition: utility.hh:344
constexpr index_constant< 19 > _19
Compile time index with value 19.
Definition: utility.hh:392
integer_sequence< std::size_t, indices...> index_sequence
A sequence of indices, with each entry a std::size_t.
Definition: utility.hh:267
TMP to build an index_pack containing the sequence 0,...,n-1.
Definition: utility.hh:209
void discard(Args &&...args)
No-op function to make calling a function on a variadic template argument pack legal C++...
Definition: utility.hh:403
constexpr index_constant< 8 > _8
Compile time index with value 8.
Definition: utility.hh:359
constexpr index_constant< 9 > _9
Compile time index with value 9.
Definition: utility.hh:362
constexpr index_constant< 0 > _0
Compile time index with value 0.
Definition: utility.hh:335
constexpr index_constant< 14 > _14
Compile time index with value 14.
Definition: utility.hh:377
constexpr index_constant< 2 > _2
Compile time index with value 2.
Definition: utility.hh:341
Type
Definition: treepath.hh:26
no_pass_index default_policy
Default policy.
Definition: utility.hh:416
typename impl::_Child< Node, indices...>::type Child
Template alias for the type of a child node given by a list of child indices.
Definition: childextraction.hh:568
constexpr index_constant< 16 > _16
Compile time index with value 16.
Definition: utility.hh:383
static const std::size_t depth
The depth of the TypeTree.
Definition: utility.hh:73
index_pack< 0, 1,..., n-1 > type
Result.
Definition: utility.hh:215
make_integer_sequence< std::size_t, n > make_index_sequence
Create an index_sequence [0,n-1].
Definition: utility.hh:275
Struct for obtaining some basic structural information about a TypeTree.
Definition: utility.hh:63
Simple holder class for a template argument pack of indices.
Definition: utility.hh:205
constexpr index_constant< 11 > _11
Compile time index with value 11.
Definition: utility.hh:368