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
17namespace 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
217 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 {
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
tuple_index_pack_builder< tuple >::type tuple_indices(const tuple &t)
Generate an index_pack for the tuple t.
Definition utility.hh:241
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
void discard(Args &&... args)
No-op function to make calling a function on a variadic template argument pack legal C++.
Definition utility.hh:265
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
Definition accumulate_static.hh:13
no_pass_index default_policy
Default policy.
Definition utility.hh:278
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
Simple holder class for a template argument pack of indices.
Definition utility.hh:207
TMP to build an index_pack containing the sequence 0,...,n-1.
Definition utility.hh:213
index_pack< 0, 1,..., n-1 > type
Result.
Definition utility.hh:217
TMP to build an index_pack for all elements in the tuple.
Definition utility.hh:237
Do not pass the index of the current tuple to the functor.
Definition utility.hh:272
Pass the index of the current tuple to the functor as its first argument in a std::integral_constant.
Definition utility.hh:275