Dune Core Modules (unstable)

traversal.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
5
6#ifndef DUNE_COMMON_TYPETREE_TRAVERSAL_HH
7#define DUNE_COMMON_TYPETREE_TRAVERSAL_HH
8
9#include <utility>
10
11#include <dune/common/hybridutilities.hh>
12#include <dune/common/indices.hh>
13#include <dune/common/std/type_traits.hh>
14
15#include <dune/common/typetree/nodeconcepts.hh>
16#include <dune/common/typetree/childaccess.hh>
17#include <dune/common/typetree/treepath.hh>
18
19namespace Dune::TypeTree {
20
21 namespace Impl {
22
23 template<class Callable, class Arg0, class Arg1>
24 constexpr void invokeWithTwoOrOneArg(Callable&& callable, Arg0&& arg0, Arg1&& arg1) {
25 static_assert(std::invocable<Callable&&, Arg0&&, Arg1&&> || std::invocable<Callable&&, Arg0&&>);
26 if constexpr (std::invocable<Callable&&, Arg0&&, Arg1&&>)
27 callable(arg0, arg1);
28 else if constexpr (std::invocable<Callable&&, Arg0&&>)
29 callable(arg0);
30 };
31
32 } // namespace Impl
33
39#ifndef DOXYGEN
41 struct NoOp
42 {
43 template<class... T>
44 constexpr void operator()(T&&...) const { /* do nothing */ }
45 };
46#endif
47
66 template<Concept::InnerTreeNode Tree, class Callable>
67 constexpr void forEachChild(Tree&& container, Callable&& at_value)
68 {
70 for (std::size_t i = 0; i != container.degree(); ++i)
71 Impl::invokeWithTwoOrOneArg(at_value, std::forward<Tree>(container).child(i), i);
72 else
74 [&](auto... i) { (Impl::invokeWithTwoOrOneArg(at_value, std::forward<Tree>(container).child(i), i), ...); },
75 std::make_index_sequence<std::remove_cvref_t<Tree>::degree()>{});
76 }
77
78 namespace Impl {
79
80 /* Traverse tree and visit each node. The signature is the same
81 * as for the public forEachNode function in Dune::Typtree,
82 * despite the additionally passed treePath argument. The path
83 * passed here is associated to the tree and the relative
84 * paths of the children (wrt. to tree) are appended to this.
85 * Hence the behavior of the public function is resembled
86 * by passing an empty treePath.
87 */
88 template<Concept::TreeNode Tree, class TreePath, class PreFunc, class LeafFunc, class PostFunc>
89 void forEachNode(Tree&& tree, TreePath treePath, PreFunc&& preFunc, LeafFunc&& leafFunc, PostFunc&& postFunc)
90 {
91 if constexpr(Concept::LeafTreeNode<std::decay_t<Tree>>) {
92 Impl::invokeWithTwoOrOneArg(leafFunc, tree, treePath);
93 } else {
94 Impl::invokeWithTwoOrOneArg(preFunc, tree, treePath);
96 tree,
97 [&]<class Child>(Child&& child, auto i) {
99 std::forward<Child>(child),
101 preFunc,
102 leafFunc,
103 postFunc
104 );
105 });
106 Impl::invokeWithTwoOrOneArg(postFunc, tree, treePath);
107 }
108 }
109
110 } // namespace Impl
111
112
113 // ********************************************************************************
114 // Public Interface
115 // ********************************************************************************
116
132 template<class Tree, class PreNodeFunc, class LeafNodeFunc, class PostNodeFunc>
133 void forEachNode(Tree&& tree, PreNodeFunc&& preNodeFunc, LeafNodeFunc&& leafNodeFunc, PostNodeFunc&& postNodeFunc)
134 {
135 Impl::forEachNode(tree, treePath(), preNodeFunc, leafNodeFunc, postNodeFunc);
136 }
137
147 template<Concept::TreeNode Tree, class NodeFunc>
148 void forEachNode(Tree&& tree, NodeFunc&& nodeFunc)
149 {
150 forEachNode(tree, nodeFunc, nodeFunc, NoOp{});
151 }
152
162 template<Concept::TreeNode Tree, class LeafFunc>
163 void forEachLeafNode(Tree&& tree, LeafFunc&& leafFunc)
164 {
165 forEachNode(tree, NoOp{}, leafFunc, NoOp{});
166 }
167
169
170} //namespace Dune::TypeTree
171
172#endif // DUNE_COMMON_TYPETREE_TRAVERSAL_HH
Model of an inner node of a typetree with uniform nodes accessible via runtime index.
Definition: nodeconcepts.hh:52
decltype(auto) constexpr unpackIntegerSequence(F &&f, std::integer_sequence< I, i... > sequence)
Unpack an std::integer_sequence<I,i...> to std::integral_constant<I,i>...
Definition: indices.hh:124
Dune::HybridMultiIndex< T... > TreePath
A type for representing tree paths that supports both compile time and run time indices.
Definition: treepath.hh:43
constexpr auto treePath(const T &... t)
Constructs a new TreePath from the given indices.
Definition: treepath.hh:55
void forEachNode(Tree &&tree, NodeFunc &&nodeFunc)
Traverse tree and visit each node.
Definition: traversal.hh:148
constexpr void forEachChild(Tree &&container, Callable &&at_value)
Traverse each child of a tree and apply a callable function.
Definition: traversal.hh:67
void forEachLeafNode(Tree &&tree, LeafFunc &&leafFunc)
Traverse tree and visit each leaf node.
Definition: traversal.hh:163
decltype(auto) child(Node &&node, TreePath< Indices... > treePath)
Extracts the child of a node given by a TreePath object.
Definition: childaccess.hh:55
typename Impl::ChildTraits< Node, indices... >::type Child
Template alias for the type of a child node given by a list of child indices.
Definition: childaccess.hh:129
constexpr HybridMultiIndex< T..., std::size_t > push_back(const HybridMultiIndex< T... > &tp, std::size_t i)
Appends a run time index to a HybridMultiIndex.
Definition: hybridmultiindex.hh:249
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Jan 9, 23:34, 2026)