dune-typetree  2.3.1
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/static_assert.hh>
9 #include <dune/common/tuples.hh>
11 
12 namespace Dune {
13  namespace TypeTree {
14 
19 #ifndef DOXYGEN
20 
21  template<typename T>
22  shared_ptr<T> convert_arg(const T& t)
23  {
24  return make_shared<T>(t);
25  }
26 
27  template<typename T>
28  shared_ptr<T> convert_arg(T& t)
29  {
30  return stackobject_to_shared_ptr(t);
31  }
32 
33  template<typename BaseType, typename T>
34  T& assertGridViewType(T& t)
35  {
36  dune_static_assert((is_same<typename BaseType::Traits::GridViewType,
37  typename T::Traits::GridViewType>::value),
38  "GridViewType must be equal in all components of composite type");
39  return t;
40  }
41 
42  // this partial specialization is required for the non-variadic case
43  template<typename BaseType>
44  TypeTree::EmptyNode assertGridViewType(TypeTree::EmptyNode e)
45  {
46  return e;
47  }
48 
49 #if HAVE_RVALUE_REFERENCES
50 
51  // only bind to real rvalues
52  template<typename T>
53  typename enable_if<!std::is_lvalue_reference<T>::value,shared_ptr<T> >::type convert_arg(T&& t)
54  {
55  return make_shared<T>(std::forward<T>(t));
56  }
57 
58 #endif
59 
60 #endif // DOXYGEN
61 
63  const shared_ptr<EmptyNode>& emptyNodePtr();
64 
66 
73  template<typename Tree, typename Tag = StartTag>
74  struct TreeInfo
75  {
76 
77  private:
78  // Start the tree traversal
80 
81  public:
82 
84  static const std::size_t depth = NodeInfo::depth;
85 
87  static const std::size_t nodeCount = NodeInfo::nodeCount;
88 
90  static const std::size_t leafCount = NodeInfo::leafCount;
91 
92  };
93 
94 
95 #ifndef DOXYGEN
96 
97  // ********************************************************************************
98  // TreeInfo specializations for the different node types
99  // ********************************************************************************
100 
101 
102  // leaf node
103  template<typename Node>
104  struct TreeInfo<Node,LeafNodeTag>
105  {
106 
107  static const std::size_t depth = 1;
108 
109  static const std::size_t nodeCount = 1;
110 
111  static const std::size_t leafCount = 1;
112 
113  };
114 
115 
116  // power node - exploit the fact that all children are identical
117  template<typename Node>
118  struct TreeInfo<Node,PowerNodeTag>
119  {
120 
121  typedef TreeInfo<typename Node::ChildType,typename Node::ChildType::NodeTag> ChildInfo;
122 
123  static const std::size_t depth = 1 + ChildInfo::depth;
124 
125  static const std::size_t nodeCount = 1 + Node::CHILDREN * ChildInfo::nodeCount;
126 
127  static const std::size_t leafCount = Node::CHILDREN * ChildInfo::leafCount;
128 
129  };
130 
131 
132  namespace {
133 
134  // TMP for iterating over the children of a composite node
135  // identical for both composite node implementations
136  template<typename Node, std::size_t k, std::size_t n>
137  struct generic_compositenode_children_info
138  {
139 
140  typedef generic_compositenode_children_info<Node,k+1,n> NextChild;
141 
142  // extract child info
143  typedef typename Node::template Child<k>::Type Child;
144  typedef typename Child::NodeTag ChildTag;
145  typedef TreeInfo<Child,ChildTag> ChildInfo;
146 
147  // combine information of current child with info about following children
148  static const std::size_t maxDepth = ChildInfo::depth > NextChild::maxDepth ? ChildInfo::depth : NextChild::maxDepth;
149 
150  static const std::size_t nodeCount = ChildInfo::nodeCount + NextChild::nodeCount;
151 
152  static const std::size_t leafCount = ChildInfo::leafCount + NextChild::leafCount;
153 
154  };
155 
156  // End of recursion
157  template<typename Node, std::size_t n>
158  struct generic_compositenode_children_info<Node,n,n>
159  {
160  static const std::size_t maxDepth = 0;
161 
162  static const std::size_t nodeCount = 0;
163 
164  static const std::size_t leafCount = 0;
165  };
166 
167  } // anonymous namespace
168 
169 
170  // Struct for building information about composite node
171  template<typename Node>
172  struct GenericCompositeNodeInfo
173  {
174 
175  typedef generic_compositenode_children_info<Node,0,Node::CHILDREN> Children;
176 
177  static const std::size_t depth = 1 + Children::maxDepth;
178 
179  static const std::size_t nodeCount = 1 + Children::nodeCount;
180 
181  static const std::size_t leafCount = Children::leafCount;
182 
183  };
184 
185 
186  // CompositeNode: delegate to GenericCompositeNodeInfo
187  template<typename Node>
188  struct TreeInfo<Node,CompositeNodeTag>
189  : public GenericCompositeNodeInfo<Node>
190  {};
191 
192 
193  // VariadicCompositeNode: delegate to GenericCompositeNodeInfo
194  template<typename Node>
195  struct TreeInfo<Node,VariadicCompositeNodeTag>
196  : public GenericCompositeNodeInfo<Node>
197  {};
198 
199 #endif // DOXYGEN
200 
201 
202 #if HAVE_VARIADIC_TEMPLATES
203 
205 
223  template<std::size_t... i>
224  struct index_pack {};
225 
227  template<std::size_t n, std::size_t... i>
228  struct index_pack_builder
229  : public index_pack_builder<n-1,n-1,i...>
230  {
231 
232 #ifdef DOXYGEN
233  typedef index_pack<0,1,...,n-1> type;
235 #endif // DOXYGEN
236 
237  };
238 
239 #ifndef DOXYGEN
240 
241  // end of recursion
242  template<std::size_t... i>
243  struct index_pack_builder<0,i...>
244  {
245  typedef index_pack<i...> type;
246  };
247 
248 #endif // DOXYGEN
249 
251  template<typename tuple>
252  struct tuple_index_pack_builder
253  : public index_pack_builder<tuple_size<tuple>::value>
254  {};
255 
257  template<typename tuple>
258  typename tuple_index_pack_builder<tuple>::type tuple_indices(const tuple& t)
259  {
260  return typename tuple_index_pack_builder<tuple>::type();
261  }
262 
264 
268  template<std::size_t n>
269  typename index_pack_builder<n>::type index_range()
270  {
271  return typename index_pack_builder<n>::type();
272  }
273 
275 
278  template<typename... Args>
279  void discard(Args&&... args)
280  {}
281 
282 #endif // HAVE_VARIADIC_TEMPLATES
283 
285 
286  } // namespace TypeTree
287 } //namespace Dune
288 
289 #endif // DUNE_TYPETREE_UTILITY_HH
const shared_ptr< EmptyNode > & emptyNodePtr()
Reference to a pointer to an empty node that is used for all empty slots.
Definition: utility.cc:12
static const std::size_t nodeCount
The total number of nodes in the TypeTree.
Definition: utility.hh:87
static const std::size_t leafCount
The number of leaf nodes in the TypeTree.
Definition: utility.hh:90
Struct for obtaining some basic structural information about a TypeTree.
Definition: utility.hh:74
static const std::size_t value
Definition: compositenode.hh:38
static const std::size_t depth
The depth of the TypeTree.
Definition: utility.hh:84
Type
Definition: treepath.hh:26
Tag designating a leaf node.
Definition: nodetags.hh:16