4#ifndef DUNE_TYPETREE_TRAVERSAL_HH
5#define DUNE_TYPETREE_TRAVERSAL_HH
9#include <dune/common/hybridutilities.hh>
10#include <dune/common/std/type_traits.hh>
30 constexpr void operator()(T&&...)
const { }
39 std::declval<Tree>().degree(),
40 std::declval<Tree>().child(0u)
51 std::enable_if_t<Tree::isLeaf, int> = 0>
54 return std::make_tuple(prefix);
58 std::enable_if_t<not Tree::isLeaf, int> = 0>
61 template<
class Tree,
TreePathType::Type pathType,
class Prefix, std::size_t... indices,
62 std::enable_if_t<(Tree::isComposite or (Tree::isPower and (pathType!=
TreePathType::dynamic))),
int> = 0>
68 template<
class Tree,
TreePathType::Type pathType,
class Prefix, std::size_t... indices,
76 std::enable_if_t<not Tree::isLeaf, int>>
79 return Detail::leafTreePathTuple<Tree, pathType>(prefix, std::make_index_sequence<
Tree::degree()>{});
93 template<
class T,
class TreePath,
class V,
94 std::enable_if_t<std::decay_t<T>::isLeaf,
int> = 0>
103 template<
class T,
class TreePath,
class V,
104 std::enable_if_t<not std::decay_t<T>::isLeaf,
int> = 0>
107 using Tree = std::remove_reference_t<T>;
108 using Visitor = std::remove_reference_t<V>;
112 using allowDynamicTraversal = Dune::Std::is_detected<DynamicTraversalConcept,Tree>;
113 using allowStaticTraversal = Dune::Std::is_detected<StaticTraversalConcept,Tree>;
116 static_assert(allowDynamicTraversal::value || allowStaticTraversal::value);
119 using preferDynamicTraversal = std::bool_constant<Visitor::treePathType == TreePathType::dynamic>;
123 if constexpr(preferDynamicTraversal::value && allowDynamicTraversal::value)
124 return Dune::range(std::size_t(tree.degree()));
126 return Dune::range(tree.degree());
129 if constexpr(allowDynamicTraversal::value || allowStaticTraversal::value) {
130 Hybrid::forEach(indices, [&](
auto i) {
131 auto&&
child = tree.child(i);
141 constexpr bool visitChild = Visitor::template VisitChild<Tree,Child,TreePath>::value;
142 if constexpr(visitChild) {
161 template<
class T,
class TreePath,
class PreFunc,
class LeafFunc,
class PostFunc>
164 using Tree = std::decay_t<T>;
165 if constexpr(Tree::isLeaf) {
171 using allowDynamicTraversal = Dune::Std::is_detected<DynamicTraversalConcept,Tree>;
172 using allowStaticTraversal = Dune::Std::is_detected<StaticTraversalConcept,Tree>;
175 static_assert(allowDynamicTraversal::value || allowStaticTraversal::value);
177 if constexpr(allowDynamicTraversal::value) {
179 for (std::size_t i = 0; i < tree.degree(); ++i) {
181 forEachNode(tree.child(i), childTreePath, preFunc, leafFunc, postFunc);
183 }
else if constexpr(allowStaticTraversal::value) {
185 auto indices = std::make_index_sequence<
Tree::degree()>{};
186 Hybrid::forEach(indices, [&](
auto i) {
188 forEachNode(tree.child(i), childTreePath, preFunc, leafFunc, postFunc);
215 template<
class Tree, TreePathType::Type pathType=TreePathType::dynamic>
218 return Detail::leafTreePathTuple<std::decay_t<Tree>, pathType>(
hybridTreePath());
236 template<
typename Tree,
typename Visitor>
255 template<
class Tree,
class PreFunc,
class LeafFunc,
class PostFunc>
256 [[deprecated]]
void forEachNode(Tree&& tree, PreFunc&& preFunc, LeafFunc&& leafFunc, PostFunc&& postFunc)
273 template<
class Tree,
class InnerFunc,
class LeafFunc>
274 [[deprecated]]
void forEachNode(Tree&& tree, InnerFunc&& innerFunc, LeafFunc&& leafFunc)
288 template<
class Tree,
class NodeFunc>
303 template<
class Tree,
class LeafFunc>
void forEachNode(Tree &&tree, PreFunc &&preFunc, LeafFunc &&leafFunc, PostFunc &&postFunc)
Traverse tree and visit each node.
Definition: traversal.hh:256
constexpr auto leafTreePathTuple()
Create tuple of tree paths to leafs.
Definition: traversal.hh:216
void forEachLeafNode(Tree &&tree, LeafFunc &&leafFunc)
Traverse tree and visit each leaf node.
Definition: traversal.hh:304
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition: traversal.hh:237
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:223
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:126
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:76
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
HybridTreePath< Dune::index_constant< i >... > TreePath
Definition: treepath.hh:433
Definition: accumulate_static.hh:13
void forEachNode(T &&tree, TreePath treePath, PreFunc &&preFunc, LeafFunc &&leafFunc, PostFunc &&postFunc)
Definition: traversal.hh:162
decltype((std::declval< Tree >().degree(), std::declval< Tree >().child(0u))) DynamicTraversalConcept
Definition: traversal.hh:41
decltype((std::integral_constant< std::size_t, Tree::degree()>{})) StaticTraversalConcept
Definition: traversal.hh:47
void applyToTree(T &&tree, TreePath treePath, V &&visitor)
Definition: traversal.hh:95
constexpr auto leafTreePathTuple(Prefix prefix)
Definition: traversal.hh:52
Type
Definition: treepath.hh:30
@ dynamic
Definition: treepath.hh:30
A hybrid version of TreePath that supports both compile time and run time indices.
Definition: treepath.hh:79