4#ifndef DUNE_TYPETREE_PAIRTRAVERSAL_HH
5#define DUNE_TYPETREE_PAIRTRAVERSAL_HH
7#include <dune/common/std/type_traits.hh>
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>
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>
40 visitor.leaf(tree1, tree2,
treePath);
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>
55 using Tree1 = std::remove_reference_t<T1>;
56 using Tree2 = std::remove_reference_t<T2>;
57 using Visitor = std::remove_reference_t<V>;
61 using allowDynamicTraversal = std::conjunction<
62 Dune::Std::is_detected<DynamicTraversalConcept,Tree1>,
63 Dune::Std::is_detected<DynamicTraversalConcept,Tree2>>;
64 using allowStaticTraversal = std::conjunction<
65 Dune::Std::is_detected<StaticTraversalConcept,Tree1>,
66 Dune::Std::is_detected<StaticTraversalConcept,Tree2>>;
69 static_assert(allowDynamicTraversal::value || allowStaticTraversal::value);
72 using preferDynamicTraversal = std::bool_constant<Visitor::treePathType == TreePathType::dynamic>;
76 if constexpr(preferDynamicTraversal::value && allowDynamicTraversal::value)
77 return Dune::range(std::size_t(tree1.degree()));
79 return Dune::range(tree1.degree());
82 if constexpr(allowDynamicTraversal::value || allowStaticTraversal::value) {
83 Dune::Hybrid::forEach(indices, [&](
auto i) {
84 auto&& child1 = tree1.child(i);
85 auto&& child2 = tree2.child(i);
86 using Child1 = std::decay_t<
decltype(child1)>;
87 using Child2 = std::decay_t<
decltype(child2)>;
89 visitor.beforeChild(tree1, child1, tree2, child2,
treePath, i);
96 constexpr bool visitChild = Visitor::template VisitChild<Tree1,Child1,Tree2,Child2,TreePath>::value;
97 if constexpr(visitChild) {
102 visitor.afterChild(tree1, child1, tree2, child2,
treePath, i);
105 visitor.post(tree1, tree2,
treePath);
125 template<
typename Tree1,
typename Tree2,
typename Visitor>
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:126