Dune Core Modules (unstable)

childaccess.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: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
5
6#ifndef DUNE_COMMON_TYPETREE_CHILDACCESS_HH
7#define DUNE_COMMON_TYPETREE_CHILDACCESS_HH
8
9#include <cstddef>
10#include <type_traits>
11#include <utility>
12#include <tuple>
13
14#include <dune/common/indices.hh>
15#include <dune/common/typelist.hh>
17
18#include <dune/common/hybridmultiindex.hh>
19#include <dune/common/typetree/nodeconcepts.hh>
20#include <dune/common/typetree/treepath.hh>
21
22
23namespace Dune::TypeTree {
24
29
31
54 template<typename Node, typename... Indices>
55 decltype(auto) child (Node&& node, TreePath<Indices...> treePath)
56 {
57 if constexpr (sizeof...(Indices) == 0)
58 return std::forward<Node>(node);
59 else
60 {
61 using I0 = std::tuple_element_t<0, TreePath<Indices...>>;
63 static_assert(I0::value < std::decay_t<Node>::degree(), "Child index out of range");
64 else
65 assert(std::size_t(treePath.front()) < node.degree() && "Child index out of range");
66 if constexpr (sizeof...(Indices) == 1)
67 return node.child(treePath.front());
68 else
69 return child(node.child(treePath.front()), pop_front(treePath));
70 }
71 }
72
74
96 template<typename Node, typename... Indices>
97 decltype(auto) child (Node&& node, Indices... indices)
98 {
99 return child(node, Dune::HybridMultiIndex{indices...});
100 }
101
102 namespace Impl {
103
104 // We could directly implement Child as
105 //
106 // using Child = std::decay_t<decltype(child(std::declval<Node>(), Dune::index_constant<indices>()...))>;
107 //
108 // but this triggers an internal compiler error in
109 // gcc 11, 12, and 13 while it does work with gcc 10
110 // and 14 and clang. This can be avoided by extracting
111 // this into a traits class.
112 template<typename Node, std::size_t... indices>
113 struct ChildTraits
114 {
115 using type = std::decay_t<decltype(child(std::declval<Node>(), Dune::index_constant<indices>()...))>;
116 };
117
118 }
119
121
128 template<typename Node, std::size_t... indices>
129 using Child = typename Impl::ChildTraits<Node, indices...>::type;
130
132
139 template<typename Node, typename TreePath>
140 using ChildForTreePath = std::decay_t<decltype(child(std::declval<Node>(), std::declval<TreePath>()))>;
141
142
143
144 namespace Impl {
145
146 template<class N>
147 static constexpr auto childTypes()
148 {
150 {
151 return Dune::unpackIntegerSequence([&](auto... i) {
153 }, std::make_index_sequence<N::degree()>{});
154 }
155 else
156 return Dune::MetaType<void>{};
157 }
158
160
170 template<class N>
171 using Children = typename decltype(Impl::childTypes<N>())::type;
172
173 }
174
176
177} //namespace Dune::TypeTree
178
179#endif // DUNE_COMMON_TYPETREE_CHILDACCESS_HH
A hybrid multi-index class that supports both compile time and run time indices.
Definition: hybridmultiindex.hh:81
Model of an inner node of a typetree with compile time known degree and child access via index_consta...
Definition: nodeconcepts.hh:41
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
std::integral_constant< std::size_t, i > index_constant
An index constant with value i.
Definition: indices.hh:29
constexpr auto treePath(const T &... t)
Constructs a new TreePath from the given indices.
Definition: treepath.hh:55
decltype(auto) child(Node &&node, Indices... indices)
Extracts the child of a node given by a sequence of compile-time and run-time indices.
Definition: childaccess.hh:97
std::decay_t< decltype(child(std::declval< Node >(), std::declval< TreePath >()))> ChildForTreePath
Template alias for the type of a child node given by a TreePath type.
Definition: childaccess.hh:140
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 auto pop_front(const HybridMultiIndex< T... > &tp)
Removes first index on a HybridMultiIndex.
Definition: hybridmultiindex.hh:374
Check if T is an std::integral_constant<I, i>
Definition: typetraits.hh:384
A type that refers to another type.
Definition: typelist.hh:33
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Jan 9, 23:34, 2026)