6#ifndef DUNE_TYPETREE_PAIRTRAVERSAL_HH 
    7#define DUNE_TYPETREE_PAIRTRAVERSAL_HH 
    9#include <dune/common/std/type_traits.hh> 
   11#include <dune/typetree/nodeinterface.hh> 
   12#include <dune/typetree/nodetags.hh> 
   13#include <dune/typetree/treepath.hh> 
   14#include <dune/typetree/visitor.hh> 
   15#include <dune/typetree/traversal.hh> 
   38      template<
class T1, 
class T2, 
class TreePath, 
class V,
 
   39        std::enable_if_t<(std::decay_t<T1>::isLeaf or std::decay_t<T2>::isLeaf), 
int> = 0>
 
   42        visitor.leaf(tree1, tree2, 
treePath);
 
   48      template<
class T1, 
class T2, 
class TreePath, 
class V,
 
   49        std::enable_if_t<not(std::decay_t<T1>::isLeaf or std::decay_t<T2>::isLeaf), 
int> = 0>
 
   57        using Tree1 = std::remove_reference_t<T1>;
 
   58        using Tree2 = std::remove_reference_t<T2>;
 
   59        using Visitor = std::remove_reference_t<V>;
 
   63        using allowDynamicTraversal = std::conjunction<
 
   64          Dune::Std::is_detected<DynamicTraversalConcept,Tree1>,
 
   65          Dune::Std::is_detected<DynamicTraversalConcept,Tree2>>;
 
   66        using allowStaticTraversal = std::conjunction<
 
   67          Dune::Std::is_detected<StaticTraversalConcept,Tree1>,
 
   68          Dune::Std::is_detected<StaticTraversalConcept,Tree2>>;
 
   71        static_assert(allowDynamicTraversal::value || allowStaticTraversal::value);
 
   74        using preferDynamicTraversal = std::bool_constant<Visitor::treePathType == TreePathType::dynamic>;
 
   78          if constexpr(preferDynamicTraversal::value && allowDynamicTraversal::value)
 
   79            return Dune::range(std::size_t(tree1.degree()));
 
   81            return Dune::range(tree1.degree());
 
   84        if constexpr(allowDynamicTraversal::value || allowStaticTraversal::value) {
 
   85          Dune::Hybrid::forEach(indices, [&](
auto i) {
 
   86            auto&& child1 = tree1.child(i);
 
   87            auto&& child2 = tree2.child(i);
 
   88            using Child1 = std::decay_t<
decltype(child1)>;
 
   89            using Child2 = std::decay_t<
decltype(child2)>;
 
   91            visitor.beforeChild(tree1, child1, tree2, child2, 
treePath, i);
 
   98            constexpr bool visitChild = Visitor::template VisitChild<Tree1,Child1,Tree2,Child2,TreePath>::value;
 
   99            if constexpr(visitChild) {
 
  100              auto childTreePath = Dune::TypeTree::push_back(
treePath, i);
 
  104            visitor.afterChild(tree1, child1, tree2, child2, 
treePath, i);
 
  107        visitor.post(tree1, tree2, 
treePath);
 
  127    template<
typename Tree1, 
typename Tree2, 
typename Visitor>
 
constexpr auto hybridTreePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:184
 
constexpr auto treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:199
 
void applyToTreePair(Tree1 &&tree1, Tree2 &&tree2, Visitor &&visitor)
Apply visitor to a pair of TypeTrees.
Definition: pairtraversal.hh:128