dune-typetree  2.7.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 <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 
187  using Dune::index_constant;
188  namespace Indices = Dune::Indices;
189 
191  template<typename... Args>
192  void discard(Args&&... args)
193  {}
194 
196  namespace apply_to_tuple_policy {
197 
199  struct no_pass_index {};
200 
202  struct pass_index {};
203 
206 
207  }
208 
209  namespace {
210 
211  // version that does not pass index
212  template<typename T, typename F, std::size_t... i>
213  void _apply_to_tuple(T&& t, F&& f, std::index_sequence<i...>,apply_to_tuple_policy::no_pass_index)
214  {
215  discard((f(std::get<i>(std::forward<T>(t))),0)...);
216  }
217 
218  // version that passes index
219  template<typename T, typename F, std::size_t... i>
220  void _apply_to_tuple(T&& t, F&& f, std::index_sequence<i...>,apply_to_tuple_policy::pass_index)
221  {
222  discard((f(index_constant<i>{},std::get<i>(std::forward<T>(t))),0)...);
223  }
224 
225  }
226 
228  /*
229  * This function applies the functor f to each element of the std::tuple t.
230  * It works for arbitrary combinations of const- and non const lvalues and rvalues.
231  * The function accepts an optional policy argument that can currently be used to make
232  * it pass the index of the current tuple argument to the functor as a compile time constant
233  * in addition to the tuple element itself.
234  */
235  template<typename T, typename F, typename Policy>
237  {
238  const std::size_t size = std::tuple_size<typename std::decay<T>::type>::value;
239  _apply_to_tuple(
240  std::forward<T>(t),
241  std::forward<F>(f),
242  std::make_index_sequence<size>{},
243  Policy()
244  );
245  }
246 
248 
249  } // namespace TypeTree
250 } //namespace Dune
251 
252 #endif // DUNE_TYPETREE_UTILITY_HH
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:236
void discard(Args &&... args)
No-op function to make calling a function on a variadic template argument pack legal C++.
Definition: utility.hh:192
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:276
Definition: accumulate_static.hh:13
Type
Definition: treepath.hh:30
no_pass_index default_policy
Default policy.
Definition: utility.hh:205
Tag designating a leaf node.
Definition: nodetags.hh:16
Struct for obtaining some basic structural information about a TypeTree.
Definition: utility.hh:66
static const std::size_t leafCount
The number of leaf nodes in the TypeTree.
Definition: utility.hh:81
static const std::size_t depth
The depth of the TypeTree.
Definition: utility.hh:75
static const std::size_t nodeCount
The total number of nodes in the TypeTree.
Definition: utility.hh:78
Do not pass the index of the current tuple to the functor.
Definition: utility.hh:199
Pass the index of the current tuple to the functor as its first argument in a std::integral_constant.
Definition: utility.hh:202