dune-typetree 3.0-dev
applytochildrensingletree.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_APPLYTOCHILDRENSINGLETREE_HH
5#define DUNE_TYPETREE_APPLYTOCHILDRENSINGLETREE_HH
6
7#include <dune/common/typetraits.hh>
8
13
14namespace Dune {
15 namespace TypeTree {
16
22#ifndef DOXYGEN // these are all internals and not public API.
23
24 // forward declaration of main engine struct
25 template<TreePathType::Type tpType, typename tag = StartTag, bool doApply = true>
26 struct ApplyToTree;
27
28 namespace {
29
30 // For the CompositeNode, we do need a TMP for iterating over the
31 // children. Note that we use an index that counts down instead of up.
32 // This allows us to specialize the TMP for the last child, where we
33 // do not want to invoke the infix visitor on the CompositeNode.
34
35 // There are two versions of this TMP, one for iteration with a static TreePath, and one
36 // for iteration with a dynamic TreePath.
37
38
39
40
41 // ********************************************************************************
42 // Static Version
43 // ********************************************************************************
44
45 template<std::size_t inverse_k, std::size_t count>
46 struct apply_to_children_fully_static
47 {
48
49 template<typename N, typename V, typename TreePath>
50 static void apply(N&& n, V&& v, TreePath tp)
51 {
52 // make sure we do not try to work with references to the actual types
53 typedef typename std::remove_reference<N>::type Node;
54 typedef typename std::remove_reference<V>::type Visitor;
55
56 // get child type
57 typedef typename Node::template Child<count-inverse_k>::Type C;
58
59 // extend TreePath by child index
60 typedef typename TreePathPushBack<TreePath,count-inverse_k>::type ChildTreePath;
61
62 // is the visitor interested in this child?
63 const bool visit = Visitor::template VisitChild<Node,C,ChildTreePath>::value;
64
65 // beforeChild() gets called regardless of the value of visit
66 v.beforeChild(std::forward<N>(n),n.template child<count-inverse_k>(),tp,std::integral_constant<std::size_t,count-inverse_k>());
67
68 // traverse to child
69 ApplyToTree<Visitor::treePathType,NodeTag<C>,visit>::apply(n.template child<count-inverse_k>(),
70 std::forward<V>(v),
71 ChildTreePath());
72
73 // afterChild() gets called regardless of the value of visit
74 v.afterChild(std::forward<N>(n),n.template child<count-inverse_k>(),tp,std::integral_constant<std::size_t,count-inverse_k>());
75
76 // we are not at the last child (that is specialized), so call infix visitor callback
77 v.in(std::forward<N>(n),tp);
78
79 // continue with next child
80 apply_to_children_fully_static<inverse_k-1,count>::apply(std::forward<N>(n),
81 std::forward<V>(v),
82 tp);
83 }
84
85 };
86
87 // Specialization for last child. This specialization stops the recursion and
88 // does not call the infix visitor on the CompositeNode.
89 template<std::size_t count>
90 struct apply_to_children_fully_static<1,count>
91 {
92
93 template<typename N, typename V, typename TreePath>
94 static void apply(N&& n, V&& v, TreePath tp)
95 {
96 typedef typename std::remove_reference<N>::type Node;
97 typedef typename std::remove_reference<V>::type Visitor;
98 typedef typename Node::template Child<count-1>::Type C;
99 typedef typename TreePathPushBack<TreePath,count-1>::type ChildTreePath;
100 const bool visit = Visitor::template VisitChild<Node,C,ChildTreePath>::value;
101 v.beforeChild(std::forward<N>(n),n.template child<count-1>(),tp,std::integral_constant<std::size_t,count-1>());
102 ApplyToTree<Visitor::treePathType,NodeTag<C>,visit>::apply(n.template child<count-1>(),
103 std::forward<V>(v),
104 ChildTreePath());
105 v.afterChild(std::forward<N>(n),n.template child<count-1>(),tp,std::integral_constant<std::size_t,count-1>());
106 }
107
108 };
109
110 // Specialization for CompositeNode without any children.
111 template<>
112 struct apply_to_children_fully_static<0,0>
113 {
114
115 template<typename N, typename V, typename TreePath>
116 static void apply(N&& n, V&& v, TreePath tp) {}
117
118 };
119
120
121
122
123 // ********************************************************************************
124 // Dynamic Version
125 // ********************************************************************************
126
127 template<std::size_t inverse_k, std::size_t count>
128 struct apply_to_children_dynamic
129 {
130
131 template<typename N, typename V, typename TreePath>
132 static void apply(N&& n, V&& v, TreePath tp)
133 {
134 typedef typename std::remove_reference<N>::type Node;
135 typedef typename std::remove_reference<V>::type Visitor;
136 typedef typename Node::template Child<count-inverse_k>::Type C;
137 const bool visit = Visitor::template VisitChild<Node,C,typename TreePath::ViewType>::value;
138 v.beforeChild(std::forward<N>(n),n.template child<count-inverse_k>(),tp.view(),count-inverse_k);
139 tp.push_back(count-inverse_k);
140 ApplyToTree<Visitor::treePathType,NodeTag<C>,visit>::apply(n.template child<count-inverse_k>(),
141 std::forward<V>(v),
142 tp);
143 tp.pop_back();
144 v.afterChild(std::forward<N>(n),n.template child<count-inverse_k>(),tp.view(),count-inverse_k);
145 v.in(std::forward<N>(n),tp.view());
146 apply_to_children_dynamic<inverse_k-1,count>::apply(std::forward<N>(n),
147 std::forward<V>(v),
148 tp);
149 }
150
151 };
152
153 // Specialization for last child. This specialization stops the recursion and
154 // does not call the infix visitor on the CompositeNode.
155 template<std::size_t count>
156 struct apply_to_children_dynamic<1,count>
157 {
158
159 template<typename N, typename V, typename TreePath>
160 static void apply(N&& n, V&& v, TreePath tp)
161 {
162 typedef typename std::remove_reference<N>::type Node;
163 typedef typename std::remove_reference<V>::type Visitor;
164 typedef typename Node::template Child<count-1>::Type C;
165 const bool visit = Visitor::template VisitChild<Node,C,typename TreePath::ViewType>::value;
166 v.beforeChild(std::forward<N>(n),n.template child<count-1>(),tp.view(),count-1);
167 tp.push_back(count-1);
168 ApplyToTree<Visitor::treePathType,NodeTag<C>,visit>::apply(n.template child<count-1>(),
169 std::forward<V>(v),
170 tp);
171 tp.pop_back();
172 v.afterChild(std::forward<N>(n),n.template child<count-1>(),tp.view(),count-1);
173 }
174
175 };
176
177 // Specialization for CompositeNode without any children.
178 template<>
179 struct apply_to_children_dynamic<0,0>
180 {
181
182 template<typename N, typename V, typename TreePath>
183 static void apply(N&& n, V&& v, TreePath tp) {}
184
185 };
186
187
188 // helper struct for automatically picking the right traversal
189 // algorithm variant
190 template<TreePathType::Type treePathType, std::size_t CHILDREN>
191 struct apply_to_children;
192
193 template<std::size_t CHILDREN>
194 struct apply_to_children<TreePathType::fullyStatic,CHILDREN>
195 : public apply_to_children_fully_static<CHILDREN,CHILDREN>
196 {};
197
198 template<std::size_t CHILDREN>
199 struct apply_to_children<TreePathType::dynamic,CHILDREN>
200 : public apply_to_children_dynamic<CHILDREN,CHILDREN>
201 {};
202
203
204 } // anonymous namespace
205
206
207
208 // Base class for composite node traversal
209
210 // The traversal algorithm is identical for CompositeNode
211 // and PowerNode in the case of static traversal,
212 // so the implementation can be bundled
213 // in a single base class.
214 struct ApplyToGenericCompositeNode
215 {
216
217 template<typename N, typename V, typename TreePath>
218 static void apply(N&& n, V&& v, TreePath tp)
219 {
220 v.pre(std::forward<N>(n),tp);
221 typedef typename std::remove_reference<N>::type Node;
222 typedef typename std::remove_reference<V>::type Visitor;
223 apply_to_children<Visitor::treePathType,StaticDegree<Node>::value>::apply(std::forward<N>(n),
224 std::forward<V>(v),
225 tp);
226 v.post(std::forward<N>(n),tp);
227 }
228
229 };
230
231#endif // DOXYGEN
232
234
235 } // namespace TypeTree
236} //namespace Dune
237
238#endif // DUNE_TYPETREE_APPLYTOCHILDRENSINGLETREE_HH
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
Definition accumulate_static.hh:13
@ fullyStatic
Definition treepath.hh:26
@ dynamic
Definition treepath.hh:26