DUNE PDELab (2.7)

pairtraversal.hh
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
7#include <dune/common/std/type_traits.hh>
8
9#include <dune/typetree/nodeinterface.hh>
10#include <dune/typetree/nodetags.hh>
11#include <dune/typetree/treepath.hh>
12#include <dune/typetree/visitor.hh>
13#include <dune/typetree/traversal.hh>
14
15namespace Dune {
16 namespace TypeTree {
17
23 namespace Detail {
24
25 /* The signature is the same as for the public applyToTreePair
26 * function in Dune::Typtree, despite the additionally passed
27 * treePath argument. The path passed here is associated to
28 * the tree and the relative paths of the children (wrt. to tree)
29 * are appended to this. Hence the behavior of the public function
30 * is resembled by passing an empty treePath.
31 */
32
33 /*
34 * This is the overload for leaf traversal
35 */
36 template<class T1, class T2, class TreePath, class V,
37 std::enable_if_t<(std::decay_t<T1>::isLeaf or std::decay_t<T2>::isLeaf), int> = 0>
38 void applyToTreePair(T1&& tree1, T2&& tree2, TreePath treePath, V&& visitor)
39 {
40 visitor.leaf(tree1, tree2, treePath);
41 }
42
43 /*
44 * This is the general overload doing static child traversal.
45 */
46 template<class T1, class T2, class TreePath, class V,
47 std::enable_if_t<not(std::decay_t<T1>::isLeaf or std::decay_t<T2>::isLeaf), int> = 0>
48 void applyToTreePair(T1&& tree1, T2&& tree2, TreePath treePath, V&& visitor)
49 {
50 // Do we really want to take care for const-ness of the Tree
51 // when instanciating VisitChild below? I'd rather expect this:
52 // using Tree1 = std::decay_t<T1>;
53 // using Tree2 = std::decay_t<T2>;
54 // using Visitor = std::decay_t<V>;
55 using Tree1 = std::remove_reference_t<T1>;
56 using Tree2 = std::remove_reference_t<T2>;
57 using Visitor = std::remove_reference_t<V>;
58 visitor.pre(tree1, tree2, treePath);
59
60 // Use statically encoded degree unless both trees
61 // are power nodes and dynamic traversal is requested.
62 constexpr auto useDynamicTraversal = (Tree1::isPower and Tree2::isPower and Visitor::treePathType==TreePathType::dynamic);
63 auto degree = conditionalValue<useDynamicTraversal>(Tree1::degree(), Dune::index_constant<Tree1::degree()>{});
64
65 auto indices = Dune::range(degree);
66 Dune::Hybrid::forEach(indices, [&](auto i) {
67 auto childTreePath = Dune::TypeTree::push_back(treePath, i);
68 auto&& child1 = tree1.child(i);
69 auto&& child2 = tree2.child(i);
70 using Child1 = std::decay_t<decltype(child1)>;
71 using Child2 = std::decay_t<decltype(child2)>;
72
73 visitor.beforeChild(tree1, child1, tree2, child2, treePath, i);
74
75 // This requires that visiotor.in(...) can always be instantiated,
76 // even if there's a single child only.
77 if (i>0)
78 visitor.in(tree1, tree2, treePath);
79 static const auto visitChild = Visitor::template VisitChild<Tree1,Child1,Tree2,Child2,TreePath>::value;
81 applyToTreePair(child1, child2, childTreePath, visitor);
82 });
83
84 visitor.afterChild(tree1, child1, tree2, child2, treePath, i);
85 });
86 visitor.post(tree1, tree2, treePath);
87 }
88
89 } // namespace Detail
90
92
106 template<typename Tree1, typename Tree2, typename Visitor>
107 void applyToTreePair(Tree1&& tree1, Tree2&& tree2, Visitor&& visitor)
108 {
109 Detail::applyToTreePair(tree1, tree2, hybridTreePath(), visitor);
110 }
111
113
114 } // namespace TypeTree
115} //namespace Dune
116
117#endif // DUNE_TYPETREE_PAIRTRAVERSAL_HH
std::integral_constant< std::size_t, i > index_constant
An index constant with value i.
Definition: indices.hh:28
std::integral_constant< bool, value > bool_constant
A template alias for std::integral_constant<bool, value>
Definition: type_traits.hh:118
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:267
decltype(auto) ifElse(const Condition &condition, IfFunc &&ifFunc, ElseFunc &&elseFunc)
A conditional expression.
Definition: hybridutilities.hh:355
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:71
constexpr HybridTreePath< T..., std::size_t > push_back(const HybridTreePath< T... > &tp, std::size_t i)
Appends a run time index to a HybridTreePath.
Definition: treepath.hh:278
constexpr HybridTreePath< T... > hybridTreePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:177
constexpr HybridTreePath< T... > treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:188
void applyToTreePair(Tree1 &&tree1, Tree2 &&tree2, Visitor &&visitor)
Apply visitor to a pair of TypeTrees.
Definition: pairtraversal.hh:107
Dune namespace.
Definition: alignedallocator.hh:14
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)