Dune TypeTree (unstable)

childextraction.hh
1// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=8 sw=2 sts=2:
3// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-GPL-2.0-only-with-PDELab-exception
5
6#ifndef DUNE_TYPETREE_CHILDEXTRACTION_HH
7#define DUNE_TYPETREE_CHILDEXTRACTION_HH
8
9#include <type_traits>
10#include <utility>
11#include <tuple>
12
13#include <dune/common/documentation.hh>
14#include <dune/common/indices.hh>
15#include <dune/common/typetraits.hh>
16#include <dune/common/shared_ptr.hh>
17
18#include <dune/common/typetree/childaccess.hh>
19
20#include <dune/typetree/treepath.hh>
21
22
23namespace Dune {
24 namespace TypeTree {
25
26#ifndef DOXYGEN
27
28 namespace Impl {
29
30 // check at run time whether index is a valid child index
31 template <class Node, class Index>
32 std::true_type checkChildIndex (Node const& node, Index i)
33 {
34 assert(std::size_t(i) < node.degree() && "Child index out of range");
35 return {};
36 }
37
38 // check at compile time whether index is a valid index
39 template <class Node, std::size_t i>
40 std::bool_constant<(i < Node::degree())> checkChildIndex (Node const& node, index_constant<i>)
41 {
42 static_assert(i < Node::degree(), "Child index out of range");
43 return {};
44 }
45
46 template<class NodePtr>
47 auto childStorageImpl (NodePtr&& nodePtr)
48 {
49 return std::forward<NodePtr>(nodePtr);
50 }
51
52 // recursively call `node.childStorage(...)` with the given indices
53 template<class NodePtr, class I0, class... I>
54 decltype(auto) childStorageImpl (NodePtr&& nodePtr, I0 i0, [[maybe_unused]] I... i)
55 {
56 auto valid = checkChildIndex(*nodePtr,i0);
57 if constexpr (valid)
58 return childStorageImpl(nodePtr->childStorage(i0),i...);
59 else
60 return;
61 }
62
63 // forward to the impl methods by extracting the indices from the treepath
64 template<class NodePtr, class... Indices, std::size_t... i>
65 decltype(auto) childStorage (NodePtr&& nodePtr, [[maybe_unused]] HybridTreePath<Indices...> tp, std::index_sequence<i...>)
66 {
67 return childStorageImpl(std::forward<NodePtr>(nodePtr),treePathEntry<i>(tp)...);
68 }
69
70 } // end namespace Impl
71
72#endif // DOXYGEN
73
74 template<typename Node, typename... Indices>
75 auto childStorage (Node&& node, Indices... indices)
76 {
77 static_assert(sizeof...(Indices) > 0, "childStorage() cannot be called with an empty list of child indices");
78 return Impl::childStorageImpl(&node,indices...);
79 }
80
81 template<typename Node, typename... Indices>
82 auto childStorage (Node&& node, HybridTreePath<Indices...> treePath)
83 {
84 static_assert(sizeof...(Indices) > 0, "childStorage() cannot be called with an empty TreePath");
85 return Impl::childStorage(&node, treePath, std::index_sequence_for<Indices...>{});
86 }
87
88#ifndef DOXYGEN
89
90 namespace impl {
91
92 // By default, types are flat indices if they are integral
93 template<typename T>
94 struct _is_flat_index
95 {
96 using type = std::is_integral<T>;
97 };
98
99 // And so is any index_constant
100 template<std::size_t i>
101 struct _is_flat_index<index_constant<i>>
102 {
103 using type = std::true_type;
104 };
105
106 }
107
108#endif // DOXYGEN
109
111 /*
112 * This type trait can be used to check whether T is a flat index (i.e. either `std::size_t`
113 * or `index_constant`). The type trait normalizes T before doing the check, so it will also
114 * work correctly for references and cv-qualified types.
115 */
116 template<typename T>
117 using is_flat_index = typename impl::_is_flat_index<std::decay_t<T>>::type;
118
119#ifndef DOXYGEN
120
121 namespace impl {
122
123 // helper function for check in member child() functions that tolerates being passed something that
124 // isn't a TreePath. It will just return 0 in that case
125
126 template<typename T>
127 constexpr typename std::enable_if<
128 Dune::TypeTree::is_flat_index<T>::value,
129 bool
130 >::type
131 _non_empty_tree_path (T)
132 {
133 return false;
134 }
135
136 template<typename T>
137 constexpr typename std::enable_if<
138 !Dune::TypeTree::is_flat_index<T>::value,
139 bool
140 >::type
141 _non_empty_tree_path (T t)
142 {
143 return treePathSize(t) > 0;
144 }
145
146 }
147
148#endif // DOXYGEN
149
151
152 } // namespace TypeTree
153} //namespace Dune
154
155#endif // DUNE_TYPETREE_CHILDEXTRACTION_HH
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:79
constexpr std::size_t treePathSize(const HybridTreePath< T... > &)
Returns the size (number of components) of the given HybridTreePath.
Definition: treepath.hh:191
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Jan 10, 23:35, 2026)