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