dune-typetree 3.0-dev
pairtraversal.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_PAIRTRAVERSAL_HH
5#define DUNE_TYPETREE_PAIRTRAVERSAL_HH
6
12
13namespace Dune {
14 namespace TypeTree {
15
21#ifndef DOXYGEN // these are all internals and not public API. Only access is using applyToTree().
22
23 template<TreePathType::Type tpType>
24 struct ApplyToTreePair<tpType,StartTag,StartTag,true>
25 {
26
27 template<typename Node1, typename Node2, typename Visitor>
28 static void apply(Node1&& node1, Node2&& node2, Visitor&& visitor)
29 {
30 ApplyToTreePair<tpType,
31 NodeTag<Node1>,
32 NodeTag<Node2>
33 >::apply(std::forward<Node1>(node1),
34 std::forward<Node2>(node2),
35 std::forward<Visitor>(visitor),
36 TreePathFactory<tpType>::create(node1).mutablePath());
37 }
38
39 };
40
41
42 // Do not visit nodes the visitor is not interested in
43 template<TreePathType::Type tpType, typename Tag1, typename Tag2>
44 struct ApplyToTreePair<tpType,Tag1,Tag2,false>
45 {
46 template<typename Node1, typename Node2, typename Visitor, typename TreePath>
47 static void apply(const Node1& node1, const Node2& node2, const Visitor& visitor, TreePath treePath)
48 {}
49 };
50
51
52 /*
53
54 // LeafNode - again, this is easy: just do all three visits
55 template<TreePathType::Type tpType>
56 struct ApplyToTree<tpType,LeafNodeTag,LeafNodeTag,true>
57 {
58
59 #if HAVE_RVALUE_REFERENCES
60
61 template<typename N1, typename N2, typename V, typename TreePath>
62 static void apply(N1&& n1, N2&& n2, V&& v, TreePath tp)
63 {
64 v.leaf(std::forward<N1>(n1),std::forward<N2>(n2),tp.view());
65 }
66
67 #else
68
69 template<typename N1, typename N2, typename V, typename TreePath>
70 static void apply(N1& n1, N2& n2, V& v, TreePath tp)
71 {
72 v.leaf(n1,n2,tp.view());
73 }
74
75 template<typename N1, typename N2, typename V, typename TreePath>
76 static void apply(const N1& n1, const N2& n2, V& v, TreePath tp)
77 {
78 v.leaf(n1,n2,tp.view());
79 }
80
81 template<typename N1, typename N2, typename V, typename TreePath>
82 static void apply(N1& n1, N2& n2, const V& v, TreePath tp)
83 {
84 v.leaf(n1,n2,tp.view());
85 }
86
87 template<typename N1, typename N2, typename V, typename TreePath>
88 static void apply(const N1& n1, const N2& n2, const V& v, TreePath tp)
89 {
90 v.leaf(n1,n2,tp.view());
91 }
92
93 #endif // HAVE_RVALUE_REFERENCES
94
95 };
96 */
97
98
99 // Automatically pick the correct traversal algorithm for the two nodes
100 template<TreePathType::Type treePathType,typename FirstTag, typename SecondTag>
101 struct ApplyToTreePair<treePathType,FirstTag,SecondTag,true>
102 : public ApplyToGenericCompositeNodePair<treePathType>
103 {
104 };
105
106
107
108 // ********************************************************************************
109 // Specialization for dynamic traversal and two PowerNodes -> use runtime iteration
110 // ********************************************************************************
111
112 template<>
113 struct ApplyToTreePair<TreePathType::dynamic,PowerNodeTag,PowerNodeTag,true>
114 {
115
116 template<typename N1, typename N2, typename V, typename TreePath>
117 static void apply(N1&& n1, N2&& n2, V&& v, TreePath tp)
118 {
119 v.pre(std::forward<N1>(n1),std::forward<N2>(n2),tp.view());
120 typedef typename std::remove_reference<N1>::type Node1;
121 typedef typename std::remove_reference<N2>::type Node2;
122 typedef typename Node1::template Child<0>::Type C1;
123 typedef typename Node2::template Child<0>::Type C2;
124 static_assert(StaticDegree<Node1>::value == StaticDegree<Node2>::value,
125 "non-leaf nodes with different numbers of children " \
126 "are not allowed during simultaneous grid traversal");
127 const bool visit = std::remove_reference<V>::type
128 ::template VisitChild<Node1,C1,Node2,C2,typename TreePath::ViewType>::value;
129 for (std::size_t k = 0; k < degree(n1); ++k)
130 {
131 v.beforeChild(std::forward<N1>(n1),n1.child(k),std::forward<N2>(n2),n2.child(k),tp.view(),k);
132 tp.push_back(k);
133 ApplyToTreePair<TreePathType::dynamic, // we know that due to the specialization
134 NodeTag<C1>,
135 NodeTag<C2>,
136 visit>::apply(n1.child(k),
137 n2.child(k),
138 std::forward<V>(v),
139 tp);
140 tp.pop_back();
141 v.afterChild(std::forward<N1>(n1),n1.child(k),std::forward<N2>(n2),n2.child(k),tp.view(),k);
142 if (k < degree(n1) - 1)
143 v.in(std::forward<N1>(n1),std::forward<N2>(n2),tp.view());
144 }
145 v.post(std::forward<N1>(n1),std::forward<N2>(n2),tp.view());
146 }
147
148 };
149
150#endif // DOXYGEN
151
153
167 template<typename Tree1, typename Tree2, typename Visitor>
168 void applyToTreePair(Tree1&& tree1, Tree2&& tree2, Visitor&& visitor)
169 {
170 ApplyToTreePair<std::remove_reference<Visitor>::type::treePathType>::apply(std::forward<Tree1>(tree1),
171 std::forward<Tree2>(tree2),
172 std::forward<Visitor>(visitor));
173 }
174
176
177 } // namespace TypeTree
178} //namespace Dune
179
180#endif // DUNE_TYPETREE_PAIRTRAVERSAL_HH
static const TreePathType::Type treePathType
Definition traversalutilities.hh:30
void applyToTreePair(Tree1 &&tree1, Tree2 &&tree2, Visitor &&visitor)
Apply visitor to a pair of TypeTrees.
Definition pairtraversal.hh:168
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition nodeinterface.hh:71
Definition accumulate_static.hh:13
@ dynamic
Definition treepath.hh:26