dune-typetree  2.3.1
applytochildrentreepair.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_APPLYTOCHILDRENTREEPAIR_HH
5 #define DUNE_TYPETREE_APPLYTOCHILDRENTREEPAIR_HH
6 
7 #include <dune/common/typetraits.hh>
8 
11 #include <dune/typetree/visitor.hh>
12 
13 #if HAVE_RVALUE_REFERENCES
14 #include <utility>
15 #endif
16 
17 namespace Dune {
18  namespace TypeTree {
19 
25 #ifndef DOXYGEN // these are all internals and not public API. Only access is using applyToTree().
26 
27  // forward declaration of main engine struct
28  template<TreePathType::Type tpType, typename tag1 = StartTag, typename tag2 = StartTag, bool doApply = true>
29  struct ApplyToTreePair;
30 
31  namespace {
32 
33  // TMP for traversing the children of non-leaf nodes with a static TreePath.
34  // Due to the static TreePath, we have to use this TMP for both CompositeNode
35  // and PowerNode.
36  template<std::size_t inverse_k, std::size_t count>
37  struct apply_to_children_pair_fully_static
38  {
39 
40 #if HAVE_RVALUE_REFERENCES
41 
42  template<typename N1, typename N2, typename V, typename TreePath>
43  static void apply(N1&& n1, N2&& n2, V&& v, TreePath tp)
44  {
45  typedef typename remove_reference<N1>::type::template Child<count-inverse_k>::Type C1;
46  typedef typename remove_reference<N2>::type::template Child<count-inverse_k>::Type C2;
47  typedef typename TreePathPushBack<TreePath,count-inverse_k>::type ChildTreePath;
48  const bool visit = std::remove_reference<V>::type
49  ::template VisitChild<typename remove_reference<N1>::type,
50  C1,
51  typename remove_reference<N2>::type,
52  C2,
53  ChildTreePath>::value;
54  v.beforeChild(std::forward<N1>(n1),n1.template child<count-inverse_k>(),
55  std::forward<N2>(n2),n2.template child<count-inverse_k>(),
56  tp,integral_constant<std::size_t,count-inverse_k>());
58  typename C1::NodeTag,
59  typename C2::NodeTag,
60  visit>::apply(n1.template child<count-inverse_k>(),
61  n2.template child<count-inverse_k>(),
62  std::forward<V>(v),
63  ChildTreePath());
64  v.afterChild(std::forward<N1>(n1),n1.template child<count-inverse_k>(),
65  std::forward<N2>(n2),n2.template child<count-inverse_k>(),
66  tp,integral_constant<std::size_t,count-inverse_k>());
67  v.in(std::forward<N1>(n1),std::forward<N2>(n2),tp);
68  apply_to_children_pair_fully_static<inverse_k-1,count>::apply(std::forward<N1>(n1),
69  std::forward<N2>(n2),
70  std::forward<V>(v),
71  tp);
72  }
73 
74 #else
75 
76  template<typename N1, typename N2, typename V, typename TreePath>
77  static void apply(N1& n1, N2& n2, V& v, TreePath tp)
78  {
79  typedef typename N1::template Child<count-inverse_k>::Type C1;
80  typedef typename N2::template Child<count-inverse_k>::Type C2;
81  typedef typename TreePathPushBack<TreePath,count-inverse_k>::type ChildTreePath;
82  const bool visit = V::template VisitChild<N1,C1,N2,C2,ChildTreePath>::value;
83  v.beforeChild(n1,n1.template child<count-inverse_k>(),
84  n2,n2.template child<count-inverse_k>(),
85  tp,
86  integral_constant<std::size_t,count-inverse_k>());
87  ApplyToTreePair<V::treePathType,
88  typename C1::NodeTag,
89  typename C2::NodeTag,
90  visit>::apply(n1.template child<count-inverse_k>(),
91  n2.template child<count-inverse_k>(),
92  v,
93  ChildTreePath());
94  v.afterChild(n1,n1.template child<count-inverse_k>(),
95  n2,n2.template child<count-inverse_k>(),
96  tp,
97  integral_constant<std::size_t,count-inverse_k>());
98  v.in(n1,n2,tp);
99  apply_to_children_pair_fully_static<inverse_k-1,count>::apply(n1,n2,v,tp);
100  }
101 
102  template<typename N1, typename N2, typename V, typename TreePath>
103  static void apply(const N1& n1, const N2& n2, V& v, TreePath tp)
104  {
105  typedef typename N1::template Child<count-inverse_k>::Type C1;
106  typedef typename N2::template Child<count-inverse_k>::Type C2;
107  typedef typename TreePathPushBack<TreePath,count-inverse_k>::type ChildTreePath;
108  const bool visit = V::template VisitChild<N1,C1,N2,C2,ChildTreePath>::value;
109  v.beforeChild(n1,n1.template child<count-inverse_k>(),
110  n2,n2.template child<count-inverse_k>(),
111  tp,
112  integral_constant<std::size_t,count-inverse_k>());
113  ApplyToTreePair<V::treePathType,
114  typename C1::NodeTag,
115  typename C2::NodeTag,
116  visit>::apply(n1.template child<count-inverse_k>(),
117  n2.template child<count-inverse_k>(),
118  v,
119  ChildTreePath());
120  v.afterChild(n1,n1.template child<count-inverse_k>(),
121  n2,n2.template child<count-inverse_k>(),
122  tp,
123  integral_constant<std::size_t,count-inverse_k>());
124  v.in(n1,n2,tp);
125  apply_to_children_pair_fully_static<inverse_k-1,count>::apply(n1,n2,v,tp);
126  }
127 
128  template<typename N1, typename N2, typename V, typename TreePath>
129  static void apply(N1& n1, N2& n2, const V& v, TreePath tp)
130  {
131  typedef typename N1::template Child<count-inverse_k>::Type C1;
132  typedef typename N2::template Child<count-inverse_k>::Type C2;
133  typedef typename TreePathPushBack<TreePath,count-inverse_k>::type ChildTreePath;
134  const bool visit = V::template VisitChild<N1,C1,N2,C2,ChildTreePath>::value;
135  v.beforeChild(n1,n1.template child<count-inverse_k>(),
136  n2,n2.template child<count-inverse_k>(),
137  tp,
138  integral_constant<std::size_t,count-inverse_k>());
139  ApplyToTreePair<V::treePathType,
140  typename C1::NodeTag,
141  typename C2::NodeTag,
142  visit>::apply(n1.template child<count-inverse_k>(),
143  n2.template child<count-inverse_k>(),
144  v,
145  ChildTreePath());
146  v.afterChild(n1,n1.template child<count-inverse_k>(),
147  n2,n2.template child<count-inverse_k>(),
148  tp,
149  integral_constant<std::size_t,count-inverse_k>());
150  v.in(n1,n2,tp);
151  apply_to_children_pair_fully_static<inverse_k-1,count>::apply(n1,n2,v,tp);
152  }
153 
154  template<typename N1, typename N2, typename V, typename TreePath>
155  static void apply(const N1& n1, const N2& n2, const V& v, TreePath tp)
156  {
157  typedef typename N1::template Child<count-inverse_k>::Type C1;
158  typedef typename N2::template Child<count-inverse_k>::Type C2;
159  typedef typename TreePathPushBack<TreePath,count-inverse_k>::type ChildTreePath;
160  const bool visit = V::template VisitChild<N1,C1,N2,C2,ChildTreePath>::value;
161  v.beforeChild(n1,n1.template child<count-inverse_k>(),
162  n2,n2.template child<count-inverse_k>(),
163  tp,
164  integral_constant<std::size_t,count-inverse_k>());
165  ApplyToTreePair<V::treePathType,
166  typename C1::NodeTag,
167  typename C2::NodeTag,
168  visit>::apply(n1.template child<count-inverse_k>(),
169  n2.template child<count-inverse_k>(),
170  v,
171  ChildTreePath());
172  v.afterChild(n1,n1.template child<count-inverse_k>(),
173  n2,n2.template child<count-inverse_k>(),
174  tp,
175  integral_constant<std::size_t,count-inverse_k>());
176  v.in(n1,n2,tp);
177  apply_to_children_pair_fully_static<inverse_k-1,count>::apply(n1,n2,v,tp);
178  }
179 
180 #endif // HAVE_RVALUE_REFERENCES
181 
182  };
183 
184  // Specialization for last child. This specialization stops the recursion and
185  // does not call the infix visitor.
186  template<std::size_t count>
187  struct apply_to_children_pair_fully_static<1,count>
188  {
189 
190 #if HAVE_RVALUE_REFERENCES
191 
192  template<typename N1, typename N2, typename V, typename TreePath>
193  static void apply(N1&& n1, N2&& n2, V&& v, TreePath tp)
194  {
195  typedef typename remove_reference<N1>::type::template Child<count-1>::Type C1;
196  typedef typename remove_reference<N2>::type::template Child<count-1>::Type C2;
197  typedef typename TreePathPushBack<TreePath,count-1>::type ChildTreePath;
198  const bool visit = std::remove_reference<V>::type
199  ::template VisitChild<typename remove_reference<N1>::type,
200  C1,
201  typename remove_reference<N2>::type,
202  C2,
203  ChildTreePath>::value;
204  v.beforeChild(std::forward<N1>(n1),n1.template child<count-1>(),
205  std::forward<N2>(n2),n2.template child<count-1>(),
206  tp,integral_constant<std::size_t,count-1>());
208  typename C1::NodeTag,
209  typename C2::NodeTag,
210  visit>::apply(n1.template child<count-1>(),
211  n2.template child<count-1>(),
212  std::forward<V>(v),
213  ChildTreePath());
214  v.afterChild(std::forward<N1>(n1),n1.template child<count-1>(),
215  std::forward<N2>(n2),n2.template child<count-1>(),
216  tp,integral_constant<std::size_t,count-1>());
217  }
218 
219 #else
220 
221  template<typename N1, typename N2, typename V, typename TreePath>
222  static void apply(N1& n1, N2& n2, V& v, TreePath tp)
223  {
224  typedef typename N1::template Child<count-1>::Type C1;
225  typedef typename N2::template Child<count-1>::Type C2;
226  typedef typename TreePathPushBack<TreePath,count-1>::type ChildTreePath;
227  const bool visit = V::template VisitChild<N1,C1,N2,C2,ChildTreePath>::value;
228  v.beforeChild(n1,n1.template child<count-1>(),
229  n2,n2.template child<count-1>(),
230  tp,
231  integral_constant<std::size_t,count-1>());
232  ApplyToTreePair<V::treePathType,
233  typename C1::NodeTag,
234  typename C2::NodeTag,
235  visit>::apply(n1.template child<count-1>(),
236  n2.template child<count-1>(),
237  v,
238  ChildTreePath());
239  v.afterChild(n1,n1.template child<count-1>(),
240  n2,n2.template child<count-1>(),
241  tp,
242  integral_constant<std::size_t,count-1>());
243  }
244 
245  template<typename N1, typename N2, typename V, typename TreePath>
246  static void apply(const N1& n1, const N2& n2, V& v, TreePath tp)
247  {
248  typedef typename N1::template Child<count-1>::Type C1;
249  typedef typename N2::template Child<count-1>::Type C2;
250  typedef typename TreePathPushBack<TreePath,count-1>::type ChildTreePath;
251  const bool visit = V::template VisitChild<N1,C1,N2,C2,ChildTreePath>::value;
252  v.beforeChild(n1,n1.template child<count-1>(),
253  n2,n2.template child<count-1>(),
254  tp,
255  integral_constant<std::size_t,count-1>());
256  ApplyToTreePair<V::treePathType,
257  typename C1::NodeTag,
258  typename C2::NodeTag,
259  visit>::apply(n1.template child<count-1>(),
260  n2.template child<count-1>(),
261  v,
262  ChildTreePath());
263  v.afterChild(n1,n1.template child<count-1>(),
264  n2,n2.template child<count-1>(),
265  tp,
266  integral_constant<std::size_t,count-1>());
267  }
268 
269  template<typename N1, typename N2, typename V, typename TreePath>
270  static void apply(N1& n1, N2& n2, const V& v, TreePath tp)
271  {
272  typedef typename N1::template Child<count-1>::Type C1;
273  typedef typename N2::template Child<count-1>::Type C2;
274  typedef typename TreePathPushBack<TreePath,count-1>::type ChildTreePath;
275  const bool visit = V::template VisitChild<N1,C1,N2,C2,ChildTreePath>::value;
276  v.beforeChild(n1,n1.template child<count-1>(),
277  n2,n2.template child<count-1>(),
278  tp,
279  integral_constant<std::size_t,count-1>());
280  ApplyToTreePair<V::treePathType,
281  typename C1::NodeTag,
282  typename C2::NodeTag,
283  visit>::apply(n1.template child<count-1>(),
284  n2.template child<count-1>(),
285  v,
286  ChildTreePath());
287  v.afterChild(n1,n1.template child<count-1>(),
288  n2,n2.template child<count-1>(),
289  tp,
290  integral_constant<std::size_t,count-1>());
291  }
292 
293  template<typename N1, typename N2, typename V, typename TreePath>
294  static void apply(const N1& n1, const N2& n2, const V& v, TreePath tp)
295  {
296  typedef typename N1::template Child<count-1>::Type C1;
297  typedef typename N2::template Child<count-1>::Type C2;
298  typedef typename TreePathPushBack<TreePath,count-1>::type ChildTreePath;
299  const bool visit = V::template VisitChild<N1,C1,N2,C2,ChildTreePath>::value;
300  v.beforeChild(n1,n1.template child<count-1>(),
301  n2,n2.template child<count-1>(),
302  tp,
303  integral_constant<std::size_t,count-1>());
304  ApplyToTreePair<V::treePathType,
305  typename C1::NodeTag,
306  typename C2::NodeTag,
307  visit>::apply(n1.template child<count-1>(),
308  n2.template child<count-1>(),
309  v,
310  ChildTreePath());
311  v.afterChild(n1,n1.template child<count-1>(),
312  n2,n2.template child<count-1>(),
313  tp,
314  integral_constant<std::size_t,count-1>());
315  }
316 
317 #endif // HAVE_RVALUE_REFERENCES
318 
319  };
320 
321  // Specialization for CompositeNode without any children.
322  template<>
323  struct apply_to_children_pair_fully_static<0,0>
324  {
325 
326 #if HAVE_RVALUE_REFERENCES
327 
328  template<typename N1, typename N2, typename V, typename TreePath>
329  static void apply(N1&& n1, N2&& n2, V&& v, TreePath tp) {}
330 
331 #else
332 
333  template<typename N1, typename N2, typename V, typename TreePath>
334  static void apply(N1& n1, N2& n2, V& v, TreePath tp) {}
335 
336  template<typename N1, typename N2, typename V, typename TreePath>
337  static void apply(const N1& n1, const N2& n2, V& v, TreePath tp) {}
338 
339  template<typename N1, typename N2, typename V, typename TreePath>
340  static void apply(N1& n1, N2& n2, const V& v, TreePath tp) {}
341 
342  template<typename N1, typename N2, typename V, typename TreePath>
343  static void apply(const N1& n1, const N2& n2, const V& v, TreePath tp) {}
344 
345 #endif // HAVE_RVALUE_REFERENCES
346 
347  };
348 
349 
350  // TMP for traversing the children of non-leaf nodes with a dynamic TreePath.
351  // This is used if at least one of the nodes is a CompositeNode.
352  // If both nodes are PowerNodes, this will not be instantiated and we simply
353  // use a runtime loop to iterate over the children.
354  template<std::size_t inverse_k, std::size_t count>
355  struct apply_to_children_pair_dynamic
356  {
357 
358 #if HAVE_RVALUE_REFERENCES
359 
360  template<typename N1, typename N2, typename V, typename TreePath>
361  static void apply(N1&& n1, N2&& n2, V&& v, TreePath tp)
362  {
363  typedef typename remove_reference<N1>::type::template Child<count-inverse_k>::Type C1;
364  typedef typename remove_reference<N2>::type::template Child<count-inverse_k>::Type C2;
365  const bool visit = std::remove_reference<V>::type
366  ::template VisitChild<typename remove_reference<N1>::type,
367  C1,
368  typename remove_reference<N2>::type,
369  C2,
370  typename TreePath::ViewType>::value;
371  v.beforeChild(std::forward<N1>(n1),n1.template child<count-inverse_k>(),
372  std::forward<N2>(n2),n2.template child<count-inverse_k>(),
373  tp.view(),count-inverse_k);
374  tp.push_back(count-inverse_k);
376  typename C1::NodeTag,
377  typename C2::NodeTag,
378  visit>::apply(n1.template child<count-inverse_k>(),
379  n2.template child<count-inverse_k>(),
380  std::forward<V>(v),
381  tp);
382  tp.pop_back();
383  v.afterChild(std::forward<N1>(n1),n1.template child<count-inverse_k>(),
384  std::forward<N2>(n2),n2.template child<count-inverse_k>(),
385  tp.view(),count-inverse_k);
386  v.in(std::forward<N1>(n1),std::forward<N2>(n2),tp.view());
387  apply_to_children_pair_dynamic<inverse_k-1,count>::apply(std::forward<N1>(n1),
388  std::forward<N2>(n2),
389  std::forward<V>(v),
390  tp);
391  }
392 
393 #else
394 
395  template<typename N1, typename N2, typename V, typename TreePath>
396  static void apply(N1& n1, N2& n2, V& v, TreePath tp)
397  {
398  typedef typename N1::template Child<count-inverse_k>::Type C1;
399  typedef typename N2::template Child<count-inverse_k>::Type C2;
400  const bool visit = V::template VisitChild<N1,C1,N2,C2,typename TreePath::ViewType>::value;
401  v.beforeChild(n1,n1.template child<count-inverse_k>(),
402  n2,n2.template child<count-inverse_k>(),
403  tp.view(),count-inverse_k);
404  tp.push_back(count-inverse_k);
405  ApplyToTreePair<V::treePathType,
406  typename C1::NodeTag,
407  typename C2::NodeTag,
408  visit>::apply(n1.template child<count-inverse_k>(),
409  n2.template child<count-inverse_k>(),
410  v,
411  tp);
412  tp.pop_back();
413  v.afterChild(n1,n1.template child<count-inverse_k>(),
414  n2,n2.template child<count-inverse_k>(),
415  tp.view(),count-inverse_k);
416  v.in(n1,n2,tp.view());
417  apply_to_children_pair_dynamic<inverse_k-1,count>::apply(n1,n2,v,tp);
418  }
419 
420  template<typename N1, typename N2, typename V, typename TreePath>
421  static void apply(const N1& n1, const N2& n2, V& v, TreePath tp) {
422  typedef typename N1::template Child<count-inverse_k>::Type C1;
423  typedef typename N2::template Child<count-inverse_k>::Type C2;
424  const bool visit = V::template VisitChild<N1,C1,N2,C2,typename TreePath::ViewType>::value;
425  v.beforeChild(n1,n1.template child<count-inverse_k>(),
426  n2,n2.template child<count-inverse_k>(),
427  tp.view(),count-inverse_k);
428  tp.push_back(count-inverse_k);
429  ApplyToTreePair<V::treePathType,
430  typename C1::NodeTag,
431  typename C2::NodeTag,
432  visit>::apply(n1.template child<count-inverse_k>(),
433  n2.template child<count-inverse_k>(),
434  v,
435  tp);
436  tp.pop_back();
437  v.afterChild(n1,n1.template child<count-inverse_k>(),
438  n2,n2.template child<count-inverse_k>(),
439  tp.view(),count-inverse_k);
440  v.in(n1,n2,tp.view());
441  apply_to_children_pair_dynamic<inverse_k-1,count>::apply(n1,n2,v,tp);
442  }
443 
444  template<typename N1, typename N2, typename V, typename TreePath>
445  static void apply(N1& n1, N2& n2, const V& v, TreePath tp)
446  {
447  typedef typename N1::template Child<count-inverse_k>::Type C1;
448  typedef typename N2::template Child<count-inverse_k>::Type C2;
449  const bool visit = V::template VisitChild<N1,C1,N2,C2,typename TreePath::ViewType>::value;
450  v.beforeChild(n1,n1.template child<count-inverse_k>(),
451  n2,n2.template child<count-inverse_k>(),
452  tp.view(),count-inverse_k);
453  tp.push_back(count-inverse_k);
454  ApplyToTreePair<V::treePathType,
455  typename C1::NodeTag,
456  typename C2::NodeTag,
457  visit>::apply(n1.template child<count-inverse_k>(),
458  n2.template child<count-inverse_k>(),
459  v,
460  tp);
461  tp.pop_back();
462  v.afterChild(n1,n1.template child<count-inverse_k>(),
463  n2,n2.template child<count-inverse_k>(),
464  tp.view(),count-inverse_k);
465  v.in(n1,n2,tp.view());
466  apply_to_children_pair_dynamic<inverse_k-1,count>::apply(n1,n2,v,tp);
467  }
468 
469  template<typename N1, typename N2, typename V, typename TreePath>
470  static void apply(const N1& n1, const N2& n2, const V& v, TreePath tp)
471  {
472  typedef typename N1::template Child<count-inverse_k>::Type C1;
473  typedef typename N2::template Child<count-inverse_k>::Type C2;
474  const bool visit = V::template VisitChild<N1,C1,N2,C2,typename TreePath::ViewType>::value;
475  v.beforeChild(n1,n1.template child<count-inverse_k>(),
476  n2,n2.template child<count-inverse_k>(),
477  tp.view(),count-inverse_k);
478  tp.push_back(count-inverse_k);
479  ApplyToTreePair<V::treePathType,
480  typename C1::NodeTag,
481  typename C2::NodeTag,
482  visit>::apply(n1.template child<count-inverse_k>(),
483  n2.template child<count-inverse_k>(),
484  v,
485  tp);
486  tp.pop_back();
487  v.afterChild(n1,n1.template child<count-inverse_k>(),
488  n2,n2.template child<count-inverse_k>(),
489  tp.view(),count-inverse_k);
490  v.in(n1,n2,tp.view());
491  apply_to_children_pair_dynamic<inverse_k-1,count>::apply(n1,n2,v,tp);
492  }
493 
494 #endif // HAVE_RVALUE_REFERENCES
495 
496  };
497 
498  // Specialization for last child. This specialization stops the recursion and
499  // does not call the infix visitor on the CompositeNode.
500  template<std::size_t count>
501  struct apply_to_children_pair_dynamic<1,count>
502  {
503 
504 #if HAVE_RVALUE_REFERENCES
505 
506  template<typename N1, typename N2, typename V, typename TreePath>
507  static void apply(N1&& n1, N2&& n2, V&& v, TreePath tp)
508  {
509  typedef typename remove_reference<N1>::type::template Child<count-1>::Type C1;
510  typedef typename remove_reference<N2>::type::template Child<count-1>::Type C2;
511  const bool visit = std::remove_reference<V>::type
512  ::template VisitChild<typename remove_reference<N1>::type,
513  C1,
514  typename remove_reference<N2>::type,
515  C2,
516  typename TreePath::ViewType>::value;
517  v.beforeChild(std::forward<N1>(n1),n1.template child<count-1>(),
518  std::forward<N2>(n2),n2.template child<count-1>(),
519  tp.view(),count-1);
520  tp.push_back(count-1);
522  typename C1::NodeTag,
523  typename C2::NodeTag,
524  visit>::apply(n1.template child<count-1>(),
525  n2.template child<count-1>(),
526  std::forward<V>(v),
527  tp);
528  tp.pop_back();
529  v.afterChild(std::forward<N1>(n1),n1.template child<count-1>(),
530  std::forward<N2>(n2),n2.template child<count-1>(),
531  tp.view(),count-1);
532  }
533 
534 #else
535 
536  template<typename N1, typename N2, typename V, typename TreePath>
537  static void apply(N1& n1, N2& n2, V& v, TreePath tp)
538  {
539  typedef typename N1::template Child<count-1>::Type C1;
540  typedef typename N2::template Child<count-1>::Type C2;
541  const bool visit = V::template VisitChild<N1,C1,N2,C2,typename TreePath::ViewType>::value;
542  v.beforeChild(n1,n1.template child<count-1>(),
543  n2,n2.template child<count-1>(),
544  tp.view(),count-1);
545  tp.push_back(count-1);
546  ApplyToTreePair<V::treePathType,
547  typename C1::NodeTag,
548  typename C2::NodeTag,
549  visit>::apply(n1.template child<count-1>(),
550  n2.template child<count-1>(),
551  v,
552  tp);
553  tp.pop_back();
554  v.afterChild(n1,n1.template child<count-1>(),
555  n2,n2.template child<count-1>(),
556  tp.view(),count-1);
557  }
558 
559  template<typename N1, typename N2, typename V, typename TreePath>
560  static void apply(const N1& n1, const N2& n2, V& v, TreePath tp)
561  {
562  typedef typename N1::template Child<count-1>::Type C1;
563  typedef typename N2::template Child<count-1>::Type C2;
564  const bool visit = V::template VisitChild<N1,C1,N2,C2,typename TreePath::ViewType>::value;
565  v.beforeChild(n1,n1.template child<count-1>(),
566  n2,n2.template child<count-1>(),
567  tp.view(),count-1);
568  tp.push_back(count-1);
569  ApplyToTreePair<V::treePathType,
570  typename C1::NodeTag,
571  typename C2::NodeTag,
572  visit>::apply(n1.template child<count-1>(),
573  n2.template child<count-1>(),
574  v,
575  tp);
576  tp.pop_back();
577  v.afterChild(n1,n1.template child<count-1>(),
578  n2,n2.template child<count-1>(),
579  tp.view(),count-1);
580  }
581 
582  template<typename N1, typename N2, typename V, typename TreePath>
583  static void apply(N1& n1, N2& n2, const V& v, TreePath tp)
584  {
585  typedef typename N1::template Child<count-1>::Type C1;
586  typedef typename N2::template Child<count-1>::Type C2;
587  const bool visit = V::template VisitChild<N1,C1,N2,C2,typename TreePath::ViewType>::value;
588  v.beforeChild(n1,n1.template child<count-1>(),
589  n2,n2.template child<count-1>(),
590  tp.view(),count-1);
591  tp.push_back(count-1);
592  ApplyToTreePair<V::treePathType,
593  typename C1::NodeTag,
594  typename C2::NodeTag,
595  visit>::apply(n1.template child<count-1>(),
596  n2.template child<count-1>(),
597  v,
598  tp);
599  tp.pop_back();
600  v.afterChild(n1,n1.template child<count-1>(),
601  n2,n2.template child<count-1>(),
602  tp.view(),count-1);
603  }
604 
605  template<typename N1, typename N2, typename V, typename TreePath>
606  static void apply(const N1& n1, const N2& n2, const V& v, TreePath tp)
607  {
608  typedef typename N1::template Child<count-1>::Type C1;
609  typedef typename N2::template Child<count-1>::Type C2;
610  const bool visit = V::template VisitChild<N1,C1,N2,C2,typename TreePath::ViewType>::value;
611  v.beforeChild(n1,n1.template child<count-1>(),
612  n2,n2.template child<count-1>(),
613  tp.view(),count-1);
614  tp.push_back(count-1);
615  ApplyToTreePair<V::treePathType,
616  typename C1::NodeTag,
617  typename C2::NodeTag,
618  visit>::apply(n1.template child<count-1>(),
619  n2.template child<count-1>(),
620  v,
621  tp);
622  tp.pop_back();
623  v.afterChild(n1,n1.template child<count-1>(),
624  n2,n2.template child<count-1>(),
625  tp.view(),count-1);
626  }
627 
628 #endif // HAVE_RVALUE_REFERENCES
629 
630  };
631 
632  // Specialization for CompositeNode without any children.
633  template<>
634  struct apply_to_children_pair_dynamic<0,0>
635  {
636 
637 #if HAVE_RVALUE_REFERENCES
638 
639  template<typename N1, typename N2, typename V, typename TreePath>
640  static void apply(N1&& n1, N2&& n2, V&& v, TreePath tp) {}
641 
642 #else
643 
644  template<typename N1, typename N2, typename V, typename TreePath>
645  static void apply(N1& n1, N2& n2, V& v, TreePath tp) {}
646 
647  template<typename N1, typename N2, typename V, typename TreePath>
648  static void apply(const N1& n1, const N2& n2, V& v, TreePath tp) {}
649 
650  template<typename N1, typename N2, typename V, typename TreePath>
651  static void apply(N1& n1, N2& n2, const V& v, TreePath tp) {}
652 
653  template<typename N1, typename N2, typename V, typename TreePath>
654  static void apply(const N1& n1, const N2& n2, const V& v, TreePath tp) {}
655 
656 #endif // HAVE_RVALUE_REFERENCES
657 
658  };
659 
660  // helper struct for automatically picking the correct child
661  // traversal algorithm variant
662  template<TreePathType::Type treePathType, std::size_t CHILDREN>
663  struct apply_to_children_pair;
664 
665  template<std::size_t CHILDREN>
666  struct apply_to_children_pair<TreePathType::fullyStatic,CHILDREN>
667  : public apply_to_children_pair_fully_static<CHILDREN,CHILDREN>
668  {};
669 
670  template<std::size_t CHILDREN>
671  struct apply_to_children_pair<TreePathType::dynamic,CHILDREN>
672  : public apply_to_children_pair_dynamic<CHILDREN,CHILDREN>
673  {};
674 
675 
676  } // anonymous namespace
677 
678 
679  // Base class for composite node traversal
680  template<TreePathType::Type treePathType>
681  struct ApplyToGenericCompositeNodePair
682  {
683 
684 #if HAVE_RVALUE_REFERENCES
685 
686  // one node is a leaf -> treat node pair as a leaf
687  template<typename N1, typename N2, typename V, typename TreePath>
688  static typename enable_if<(remove_reference<N1>::type::isLeaf || remove_reference<N2>::type::isLeaf)>::type
689  apply(N1&& n1, N2&& n2, V&& v, TreePath tp)
690  {
691  v.leaf(std::forward<N1>(n1),std::forward<N2>(n2),tp.view());
692  }
693 
694  // both nodes contain children -> iterate over them
695  template<typename N1, typename N2, typename V, typename TreePath>
696  static typename enable_if<!(remove_reference<N1>::type::isLeaf || remove_reference<N2>::type::isLeaf)>::type
697  apply(N1&& n1, N2&& n2, V&& v, TreePath tp)
698  {
699  v.pre(std::forward<N1>(n1),std::forward<N2>(n2),tp.view());
700  typedef typename remove_reference<N1>::type Node1;
701  typedef typename remove_reference<N2>::type Node2;
702  // make sure both nodes have the same number of children - otherwise, it
703  // would be difficult to match the children to each other.
704  dune_static_assert(Node1::CHILDREN == Node2::CHILDREN,
705  "non-leaf nodes with different numbers of children " \
706  "are not allowed during simultaneous grid traversal");
707  apply_to_children_pair<treePathType,Node1::CHILDREN>::apply(std::forward<N1>(n1),
708  std::forward<N2>(n2),
709  std::forward<V>(v),
710  tp);
711  v.post(std::forward<N1>(n1),std::forward<N2>(n2),tp.view());
712  }
713 
714 #else
715 
716  template<typename N1, typename N2, typename V, typename TreePath>
717  static typename enable_if<N1::isLeaf || N2::isLeaf>::type
718  apply(N1& n1, N2& n2, V& v, TreePath tp)
719  {
720  v.leaf(n1,n2,tp.view());
721  }
722 
723  template<typename N1, typename N2, typename V, typename TreePath>
724  static typename enable_if<N1::isLeaf || N2::isLeaf>::type
725  apply(const N1& n1, const N2& n2, V& v, TreePath tp)
726  {
727  v.leaf(n1,n2,tp.view());
728  }
729 
730  template<typename N1, typename N2, typename V, typename TreePath>
731  static typename enable_if<N1::isLeaf || N2::isLeaf>::type
732  apply(N1& n1, N2& n2, const V& v, TreePath tp)
733  {
734  v.leaf(n1,n2,tp.view());
735  }
736 
737  template<typename N1, typename N2, typename V, typename TreePath>
738  static typename enable_if<N1::isLeaf || N2::isLeaf>::type
739  apply(const N1& n1, const N2& n2, const V& v, TreePath tp)
740  {
741  v.leaf(n1,n2,tp.view());
742  }
743 
744 
745  template<typename N1, typename N2, typename V, typename TreePath>
746  static typename enable_if<!(N1::isLeaf || N2::isLeaf)>::type
747  apply(N1& n1, N2& n2, V& v, TreePath tp)
748  {
749  v.pre(n1,n2,tp.view());
750  dune_static_assert(N1::CHILDREN == N2::CHILDREN,
751  "non-leaf nodes with different numbers of children " \
752  "are not allowed during simultaneous grid traversal");
753  apply_to_children_pair<treePathType,N1::CHILDREN>::apply(n1,n2,v,tp);
754  v.post(n1,n2,tp.view());
755  }
756 
757  template<typename N1, typename N2, typename V, typename TreePath>
758  static typename enable_if<!(N1::isLeaf || N2::isLeaf)>::type
759  apply(const N1& n1, const N2& n2, V& v, TreePath tp)
760  {
761  v.pre(n1,n2,tp.view());
762  dune_static_assert(N1::CHILDREN == N2::CHILDREN,
763  "non-leaf nodes with different numbers of children " \
764  "are not allowed during simultaneous grid traversal");
765  apply_to_children_pair<treePathType,N1::CHILDREN>::apply(n1,n2,v,tp);
766  v.post(n1,n2,tp.view());
767  }
768 
769  template<typename N1, typename N2, typename V, typename TreePath>
770  static typename enable_if<!(N1::isLeaf || N2::isLeaf)>::type
771  apply(N1& n1, N2& n2, const V& v, TreePath tp)
772  {
773  v.pre(n1,n2,tp.view());
774  dune_static_assert(N1::CHILDREN == N2::CHILDREN,
775  "non-leaf nodes with different numbers of children " \
776  "are not allowed during simultaneous grid traversal");
777  apply_to_children_pair<treePathType,N1::CHILDREN>::apply(n1,n2,v,tp);
778  v.post(n1,n2,tp.view());
779  }
780 
781  template<typename N1, typename N2, typename V, typename TreePath>
782  static typename enable_if<!(N1::isLeaf || N2::isLeaf)>::type
783  apply(const N1& n1, const N2& n2, const V& v, TreePath tp)
784  {
785  v.pre(n1,n2,tp.view());
786  dune_static_assert(N1::CHILDREN == N2::CHILDREN,
787  "non-leaf nodes with different numbers of children " \
788  "are not allowed during simultaneous grid traversal");
789  apply_to_children_pair<treePathType,N1::CHILDREN>::apply(n1,n2,v,tp);
790  v.post(n1,n2,tp.view());
791  }
792 
793 #endif // HAVE_RVALUE_REFERENCES
794 
795  };
796 
797 
798 #endif // DOXYGEN
799 
801 
802  } // namespace TypeTree
803 } //namespace Dune
804 
805 #endif // DUNE_TYPETREE_APPLYTOCHILDRENTREEPAIR_HH
Definition: treepath.hh:26
static const TreePathType::Type treePathType
Definition: traversalutilities.hh:30
static const std::size_t value
Definition: compositenode.hh:38
Type
Definition: treepath.hh:26
TreePath ViewType
Definition: treepath.hh:33