dune-typetree  2.4-dev
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 <dune/common/shared_ptr.hh>
8 #include <dune/common/tuples.hh>
10 
11 namespace Dune {
12  namespace TypeTree {
13 
18 #ifndef DOXYGEN
19 
20  template<typename T>
21  shared_ptr<T> convert_arg(const T& t)
22  {
23  return make_shared<T>(t);
24  }
25 
26  template<typename T>
27  shared_ptr<T> convert_arg(T& t)
28  {
29  return stackobject_to_shared_ptr(t);
30  }
31 
32  template<typename BaseType, typename T>
33  T& assertGridViewType(T& t)
34  {
35  static_assert((is_same<typename BaseType::Traits::GridViewType,
36  typename T::Traits::GridViewType>::value),
37  "GridViewType must be equal in all components of composite type");
38  return t;
39  }
40 
41  // only bind to real rvalues
42  template<typename T>
43  typename enable_if<!std::is_lvalue_reference<T>::value,shared_ptr<T> >::type convert_arg(T&& t)
44  {
45  return make_shared<T>(std::forward<T>(t));
46  }
47 
48 #endif // DOXYGEN
49 
51 
58  template<typename Tree, typename Tag = StartTag>
59  struct TreeInfo
60  {
61 
62  private:
63  // Start the tree traversal
65 
66  public:
67 
69  static const std::size_t depth = NodeInfo::depth;
70 
72  static const std::size_t nodeCount = NodeInfo::nodeCount;
73 
75  static const std::size_t leafCount = NodeInfo::leafCount;
76 
77  };
78 
79 
80 #ifndef DOXYGEN
81 
82  // ********************************************************************************
83  // TreeInfo specializations for the different node types
84  // ********************************************************************************
85 
86 
87  // leaf node
88  template<typename Node>
89  struct TreeInfo<Node,LeafNodeTag>
90  {
91 
92  static const std::size_t depth = 1;
93 
94  static const std::size_t nodeCount = 1;
95 
96  static const std::size_t leafCount = 1;
97 
98  };
99 
100 
101  // power node - exploit the fact that all children are identical
102  template<typename Node>
103  struct TreeInfo<Node,PowerNodeTag>
104  {
105 
106  typedef TreeInfo<typename Node::ChildType,typename Node::ChildType::NodeTag> ChildInfo;
107 
108  static const std::size_t depth = 1 + ChildInfo::depth;
109 
110  static const std::size_t nodeCount = 1 + Node::CHILDREN * ChildInfo::nodeCount;
111 
112  static const std::size_t leafCount = Node::CHILDREN * ChildInfo::leafCount;
113 
114  };
115 
116 
117  namespace {
118 
119  // TMP for iterating over the children of a composite node
120  // identical for both composite node implementations
121  template<typename Node, std::size_t k, std::size_t n>
122  struct generic_compositenode_children_info
123  {
124 
125  typedef generic_compositenode_children_info<Node,k+1,n> NextChild;
126 
127  // extract child info
128  typedef typename Node::template Child<k>::Type Child;
129  typedef typename Child::NodeTag ChildTag;
130  typedef TreeInfo<Child,ChildTag> ChildInfo;
131 
132  // combine information of current child with info about following children
133  static const std::size_t maxDepth = ChildInfo::depth > NextChild::maxDepth ? ChildInfo::depth : NextChild::maxDepth;
134 
135  static const std::size_t nodeCount = ChildInfo::nodeCount + NextChild::nodeCount;
136 
137  static const std::size_t leafCount = ChildInfo::leafCount + NextChild::leafCount;
138 
139  };
140 
141  // End of recursion
142  template<typename Node, std::size_t n>
143  struct generic_compositenode_children_info<Node,n,n>
144  {
145  static const std::size_t maxDepth = 0;
146 
147  static const std::size_t nodeCount = 0;
148 
149  static const std::size_t leafCount = 0;
150  };
151 
152  } // anonymous namespace
153 
154 
155  // Struct for building information about composite node
156  template<typename Node>
157  struct GenericCompositeNodeInfo
158  {
159 
160  typedef generic_compositenode_children_info<Node,0,Node::CHILDREN> Children;
161 
162  static const std::size_t depth = 1 + Children::maxDepth;
163 
164  static const std::size_t nodeCount = 1 + Children::nodeCount;
165 
166  static const std::size_t leafCount = Children::leafCount;
167 
168  };
169 
170 
171  // CompositeNode: delegate to GenericCompositeNodeInfo
172  template<typename Node>
173  struct TreeInfo<Node,CompositeNodeTag>
174  : public GenericCompositeNodeInfo<Node>
175  {};
176 
177 
178 #endif // DOXYGEN
179 
180 
182 
200  template<std::size_t... i>
201  struct index_pack {};
202 
204  template<std::size_t n, std::size_t... i>
206  : public index_pack_builder<n-1,n-1,i...>
207  {
208 
209 #ifdef DOXYGEN
210  typedef index_pack<0,1,...,n-1> type;
212 #endif // DOXYGEN
213 
214  };
215 
216 #ifndef DOXYGEN
217 
218  // end of recursion
219  template<std::size_t... i>
220  struct index_pack_builder<0,i...>
221  {
222  typedef index_pack<i...> type;
223  };
224 
225 #endif // DOXYGEN
226 
228  template<typename tuple>
230  : public index_pack_builder<tuple_size<tuple>::value>
231  {};
232 
234  template<typename tuple>
236  {
237  return typename tuple_index_pack_builder<tuple>::type();
238  }
239 
241 
245  template<std::size_t n>
247  {
248  return typename index_pack_builder<n>::type();
249  }
250 
252 
255  template<typename... Args>
256  void discard(Args&&... args)
257  {}
258 
260  namespace apply_to_tuple_policy {
261 
263  struct no_pass_index {};
264 
266  struct pass_index {};
267 
270 
271  }
272 
273  namespace {
274 
275  // version that does not pass index
276  template<typename T, typename F, std::size_t... i>
277  void _apply_to_tuple(T&& t, F&& f, index_pack<i...> indices,apply_to_tuple_policy::no_pass_index)
278  {
279  discard((f(std::get<i>(std::forward<T>(t))),0)...);
280  }
281 
282  // version that passes index
283  template<typename T, typename F, std::size_t... i>
284  void _apply_to_tuple(T&& t, F&& f, index_pack<i...> indices,apply_to_tuple_policy::pass_index)
285  {
286  discard((f(std::integral_constant<std::size_t,i>(),std::get<i>(std::forward<T>(t))),0)...);
287  }
288 
289  }
290 
292  /*
293  * This function applies the functor f to each element of the std::tuple t.
294  * It works for arbitrary combinations of const- and non const lvalues and rvalues.
295  * The function accepts an optional policy argument that can currently be used to make
296  * it pass the index of the current tuple argument to the functor as a compile time constant
297  * in addition to the tuple element itself.
298  */
299  template<typename T, typename F, typename Policy>
301  {
302  _apply_to_tuple(
303  std::forward<T>(t),
304  std::forward<F>(f),
305  tuple_indices(t),
306  Policy()
307  );
308  }
309 
311 
312  } // namespace TypeTree
313 } //namespace Dune
314 
315 #endif // DUNE_TYPETREE_UTILITY_HH
TMP to build an index_pack for all elements in the tuple.
Definition: utility.hh:229
Pass the index of the current tuple to the functor as its first argument in a std::integral_constant...
Definition: utility.hh:266
tuple_index_pack_builder< tuple >::type tuple_indices(const tuple &t)
Generate an index_pack for the tuple t.
Definition: utility.hh:235
index_pack< 0, 1,..., n-1 > type
Result.
Definition: utility.hh:211
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:300
Simple holder class for a template argument pack of indices.
Definition: utility.hh:201
Definition: accumulate_static.hh:12
static const std::size_t leafCount
The number of leaf nodes in the TypeTree.
Definition: utility.hh:75
void discard(Args &&...args)
No-op function to make calling a function on a variadic template argument pack legal C++...
Definition: utility.hh:256
Struct for obtaining some basic structural information about a TypeTree.
Definition: utility.hh:59
static const std::size_t nodeCount
The total number of nodes in the TypeTree.
Definition: utility.hh:72
Type
Definition: treepath.hh:25
static const std::size_t depth
The depth of the TypeTree.
Definition: utility.hh:69
index_pack_builder< n >::type index_range()
Generate an index_pack with the values {0, 1, ..., n-1}.
Definition: utility.hh:246
no_pass_index default_policy
Default policy.
Definition: utility.hh:269
Do not pass the index of the current tuple to the functor.
Definition: utility.hh:263
Tag designating a leaf node.
Definition: nodetags.hh:16
TMP to build an index_pack containing the sequence 0,...,n-1.
Definition: utility.hh:205