6#ifndef DUNE_TYPETREE_TRAVERSAL_HH
7#define DUNE_TYPETREE_TRAVERSAL_HH
11#include <dune/common/hybridutilities.hh>
12#include <dune/common/std/type_traits.hh>
32 constexpr void operator()(T&&...)
const { }
41 std::declval<Tree>().degree(),
42 std::declval<Tree>().child(0u)
48 std::integral_constant<std::size_t, Tree::degree()>{}
53 std::enable_if_t<Tree::isLeaf, int> = 0>
56 return std::make_tuple(prefix);
60 std::enable_if_t<not Tree::isLeaf, int> = 0>
63 template<
class Tree,
TreePathType::Type pathType,
class Prefix, std::size_t... indices,
64 std::enable_if_t<(Tree::isComposite or (Tree::isPower and (pathType!=
TreePathType::dynamic))),
int> = 0>
70 template<
class Tree,
TreePathType::Type pathType,
class Prefix, std::size_t... indices,
78 std::enable_if_t<not Tree::isLeaf, int>>
81 return Detail::leafTreePathTuple<Tree, pathType>(prefix, std::make_index_sequence<Tree::degree()>{});
95 template<
class T,
class TreePath,
class V,
96 std::enable_if_t<std::decay_t<T>::isLeaf,
int> = 0>
105 template<
class T,
class TreePath,
class V,
106 std::enable_if_t<not std::decay_t<T>::isLeaf,
int> = 0>
109 using Tree = std::remove_reference_t<T>;
110 using Visitor = std::remove_reference_t<V>;
114 using allowDynamicTraversal = Dune::Std::is_detected<DynamicTraversalConcept,Tree>;
115 using allowStaticTraversal = Dune::Std::is_detected<StaticTraversalConcept,Tree>;
118 static_assert(allowDynamicTraversal::value || allowStaticTraversal::value);
121 using preferDynamicTraversal = std::bool_constant<Visitor::treePathType == TreePathType::dynamic>;
125 if constexpr(preferDynamicTraversal::value && allowDynamicTraversal::value)
126 return Dune::range(std::size_t(tree.degree()));
128 return Dune::range(tree.degree());
131 if constexpr(allowDynamicTraversal::value || allowStaticTraversal::value) {
132 Hybrid::forEach(indices, [&](
auto i) {
133 auto&&
child = tree.child(i);
143 constexpr bool visitChild = Visitor::template VisitChild<Tree,Child,TreePath>::value;
144 if constexpr(visitChild) {
163 template<
class T,
class TreePath,
class PreFunc,
class LeafFunc,
class PostFunc>
164 void forEachNode(T&& tree, TreePath
treePath, PreFunc&& preFunc, LeafFunc&& leafFunc, PostFunc&& postFunc)
166 using Tree = std::decay_t<T>;
167 if constexpr(Tree::isLeaf) {
173 using allowDynamicTraversal = Dune::Std::is_detected<DynamicTraversalConcept,Tree>;
174 using allowStaticTraversal = Dune::Std::is_detected<StaticTraversalConcept,Tree>;
177 static_assert(allowDynamicTraversal::value || allowStaticTraversal::value);
179 if constexpr(allowDynamicTraversal::value) {
181 for (std::size_t i = 0; i < tree.degree(); ++i) {
183 forEachNode(tree.child(i), childTreePath, preFunc, leafFunc, postFunc);
185 }
else if constexpr(allowStaticTraversal::value) {
187 auto indices = std::make_index_sequence<Tree::degree()>{};
188 Hybrid::forEach(indices, [&](
auto i) {
190 forEachNode(tree.child(i), childTreePath, preFunc, leafFunc, postFunc);
217 template<
class Tree, TreePathType::Type pathType=TreePathType::dynamic>
220 return Detail::leafTreePathTuple<std::decay_t<Tree>, pathType>(
hybridTreePath());
238 template<
typename Tree,
typename Visitor>
253 template<
class Tree,
class NodeFunc>
268 template<
class Tree,
class LeafFunc>
void forEachNode(Tree &&tree, NodeFunc &&nodeFunc)
Traverse tree and visit each node.
Definition traversal.hh:254
constexpr auto leafTreePathTuple()
Create tuple of tree paths to leafs.
Definition traversal.hh:218
void forEachLeafNode(Tree &&tree, LeafFunc &&leafFunc)
Traverse tree and visit each leaf node.
Definition traversal.hh:269
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition traversal.hh:239
typename impl::_Child< Node, indices... >::type Child
Template alias for the type of a child node given by a list of child indices.
Definition childextraction.hh:225
ImplementationDefined child(Node &&node, Indices... indices)
Extracts the child of a node given by a sequence of compile-time and run-time indices.
Definition childextraction.hh:128
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:416
constexpr auto hybridTreePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition treepath.hh:312
constexpr auto treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition treepath.hh:326
Definition accumulate_static.hh:16
void forEachNode(T &&tree, TreePath treePath, PreFunc &&preFunc, LeafFunc &&leafFunc, PostFunc &&postFunc)
Definition traversal.hh:164
decltype((std::declval< Tree >().degree(), std::declval< Tree >().child(0u))) DynamicTraversalConcept
Definition traversal.hh:43
decltype((std::integral_constant< std::size_t, Tree::degree()>{})) StaticTraversalConcept
Definition traversal.hh:49
void applyToTree(T &&tree, TreePath treePath, V &&visitor)
Definition traversal.hh:97
constexpr auto leafTreePathTuple(Prefix prefix)
Definition traversal.hh:54
Type
Definition treepath.hh:106
@ dynamic
Definition treepath.hh:106