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