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 
10 #include <dune/typetree/visitor.hh>
12 
13 namespace 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  {
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
nodetags.hh
visitor.hh
treepath.hh
Dune::TypeTree::TreePathType::dynamic
Definition: treepath.hh:26
Dune::TypeTree::applyToTreePair
void applyToTreePair(Tree1 &&tree1, Tree2 &&tree2, Visitor &&visitor)
Apply visitor to a pair of TypeTrees.
Definition: pairtraversal.hh:168
Dune::TypeTree::TreePathType::Type
Type
Definition: treepath.hh:26
Dune
Definition: accumulate_static.hh:13
treePathType
static const TreePathType::Type treePathType
Definition: traversalutilities.hh:30
applytochildrentreepair.hh
Dune::TypeTree::degree
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:71
nodeinterface.hh