6#ifndef DUNE_TYPETREE_TRAVERSAL_HH
7#define DUNE_TYPETREE_TRAVERSAL_HH
11#include <dune/common/hybridutilities.hh>
12#include <dune/common/indices.hh>
13#include <dune/common/std/type_traits.hh>
15#include <dune/common/typetree/childaccess.hh>
16#include <dune/common/typetree/nodeconcepts.hh>
17#include <dune/common/typetree/traversal.hh>
19#include <dune/typetree/treepath.hh>
20#include <dune/typetree/visitor.hh>
34 using DynamicTraversalConcept =
decltype((
35 std::declval<Tree>().degree(),
36 std::declval<Tree>().child(0u)
41 using StaticTraversalConcept =
decltype((
46 template<
class Tree, TreePathType::Type pathType,
class Prefix,
47 std::enable_if_t<Tree::isLeaf, int> = 0>
50 return std::make_tuple(prefix);
53 template<
class Tree, TreePathType::Type pathType,
class Prefix,
54 std::enable_if_t<not Tree::isLeaf, int> = 0>
57 template<
class Tree, TreePathType::Type pathType,
class Prefix, std::size_t... indices,
58 std::enable_if_t<(Tree::isComposite or (Tree::isPower and (pathType!=TreePathType::dynamic))),
int> = 0>
61 return std::tuple_cat(
Detail::leafTreePathTuple<TypeTree::Child<Tree,indices>, pathType>(Dune::TypeTree::push_back(prefix, Dune::index_constant<indices>{}))...);
64 template<
class Tree, TreePathType::Type pathType,
class Prefix, std::size_t... indices,
65 std::enable_if_t<(Tree::isPower and (pathType==TreePathType::dynamic)),
int> = 0>
68 return std::tuple_cat(
Detail::leafTreePathTuple<TypeTree::Child<Tree,indices>, pathType>(Dune::TypeTree::push_back(prefix, indices))...);
71 template<
class Tree, TreePathType::Type pathType,
class Prefix,
72 std::enable_if_t<not Tree::isLeaf, int>>
75 return Detail::leafTreePathTuple<Tree, pathType>(prefix, std::make_index_sequence<
Tree::degree()>{});
89 template<
class T,
class TreePath,
class V,
90 std::enable_if_t<std::decay_t<T>::isLeaf,
int> = 0>
91 void applyToTree(T&& tree, TreePath treePath, V&& visitor)
93 visitor.leaf(tree, treePath);
99 template<
class T,
class TreePath,
class V,
100 std::enable_if_t<not std::decay_t<T>::isLeaf,
int> = 0>
101 void applyToTree(T&& tree, TreePath treePath, V&& visitor)
103 using Tree = std::remove_reference_t<T>;
104 using Visitor = std::remove_reference_t<V>;
105 visitor.pre(tree, treePath);
108 using preferDynamicTraversal = std::bool_constant<Visitor::treePathType == TreePathType::dynamic>;
112 if constexpr(preferDynamicTraversal::value && Concept::UniformInnerTreeNode<Tree>)
113 return Dune::range(std::size_t(tree.degree()));
115 return Dune::range(tree.degree());
118 if constexpr(Concept::InnerTreeNode<Tree>) {
119 Hybrid::forEach(indices, [&](
auto i) {
120 auto&& child = tree.child(i);
121 using Child = std::decay_t<
decltype(child)>;
123 visitor.beforeChild(tree, child, treePath, i);
128 visitor.in(tree, treePath);
130 constexpr bool visitChild = Visitor::template VisitChild<Tree,Child,TreePath>::value;
131 if constexpr(visitChild) {
132 auto childTreePath = Dune::TypeTree::push_back(treePath, i);
136 visitor.afterChild(tree, child, treePath, i);
139 visitor.post(tree, treePath);
162 template<
class Tree, TreePathType::Type pathType=TreePathType::dynamic>
165 return Detail::leafTreePathTuple<std::decay_t<Tree>, pathType>(
hybridTreePath());
183 template<Concept::TreeNode Tree,
typename Visitor>
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:79
constexpr auto hybridTreePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:102
constexpr auto leafTreePathTuple()
Create tuple of tree paths to leafs.
Definition: traversal.hh:163
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition: traversal.hh:184