dune-common  2.11
childaccess.hh
Go to the documentation of this file.
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 
21 
22 
23 namespace 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...>>;
62  if constexpr (Dune::IsIntegralConstant<I0>::value and Concept::StaticDegreeInnerTreeNode<Node>)
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  {
149  if constexpr (Dune::TypeTree::Concept::StaticDegreeInnerTreeNode<N>)
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
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
decltype(auto) constexpr unpackIntegerSequence(F &&f, [[maybe_unused]] 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
I i
Definition: hybridmultiindex.hh:328
Definition: childaccess.hh:23
decltype(auto) child(Node &&node, TreePath< Indices... > treePath)
Extracts the child of a node given by a TreePath object.
Definition: childaccess.hh:55
Check if T is an std::integral_constant<I, i>
Definition: typetraits.hh:383
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
A hybrid multi-index class that supports both compile time and run time indices.
Definition: hybridmultiindex.hh:80
Traits for type conversions and type information.
A type that refers to another type.
Definition: typelist.hh:33