4 #ifndef DUNE_TYPETREE_CHILDEXTRACTION_HH
5 #define DUNE_TYPETREE_CHILDEXTRACTION_HH
9 #include <dune/common/concept.hh>
10 #include <dune/common/documentation.hh>
11 #include <dune/common/typetraits.hh>
12 #include <dune/common/shared_ptr.hh>
34 struct IsPointerLike {
36 auto require(
const Node& node) -> decltype(*node);
39 template<
typename Node>
40 auto child(Node&& node) -> decltype(std::forward<Node>(node))
42 return std::forward<Node>(node);
47 template<typename Node, typename std::enable_if_t<Dune::models<IsPointerLike,Node>(),
int> = 0>
50 return std::forward<Node>(node);
59 struct HasTemplateChildMethod {
61 auto require(
const Node& node) -> decltype(node.template child<0>());
68 template<
typename Node, std::size_t i,
typename... J,
69 typename std::enable_if<
70 Dune::models<HasTemplateChildMethod, Node>() &&
71 (i < StaticDegree<Node>::value),
int>::type = 0>
72 decltype(
auto)
child(Node&& node, index_constant<i>, J... j)
74 return child(std::forward<Node>(node).
template child<i>(),j...);
77 template<
typename Node, std::size_t i,
typename... J,
78 typename std::enable_if<
79 Dune::models<HasTemplateChildMethod, decltype(*std::declval<std::decay_t<Node>>())>() &&
80 (i <
StaticDegree<decltype(*std::declval<Node>())>::value),
int>::type = 0>
81 decltype(
auto)
childStorage(Node&& node, index_constant<i>, J... j)
83 return childStorage(std::forward<Node>(node)->
template childStorage<i>(),j...);
89 template<
typename Node, std::size_t i,
typename... J,
90 typename std::enable_if<
91 (!Dune::models<HasTemplateChildMethod, Node>()) ||
92 (i >= StaticDegree<Node>::value),
int>::type = 0>
93 void child(Node&& node, index_constant<i>, J... j)
95 static_assert(Dune::models<HasTemplateChildMethod, Node>(),
"Node does not have a template method child()");
96 static_assert(i < StaticDegree<Node>::value,
"Child index out of range");
106 template<
typename Node,
typename... J>
119 return child(std::forward<Node>(node).
child(i),j...);
122 template<
typename Node,
typename... J>
128 NodeTag<decltype(*std::declval<Node>())>,
138 template<
typename Node,
typename... Indices, std::size_t... i>
139 decltype(
auto)
child(Node&& node, HybridTreePath<Indices...> tp, std::index_sequence<i...>)
141 return child(std::forward<Node>(node),treePathEntry<i>(tp)...);
144 template<
typename Node,
typename... Indices, std::size_t... i>
145 decltype(
auto)
childStorage(Node&& node, HybridTreePath<Indices...> tp, std::index_sequence<i...>)
147 return childStorage(std::forward<Node>(node),treePathEntry<i>(tp)...);
177 template<
typename Node,
typename... Indices>
179 ImplementationDefined
child(Node&& node, Indices... indices)
181 decltype(
auto)
child(Node&& node, Indices... indices)
184 return impl::child(std::forward<Node>(node),indices...);
187 template<
typename Node,
typename... Indices>
222 template<
typename Node,
typename... Indices>
229 return impl::child(std::forward<Node>(node),tp,std::index_sequence_for<Indices...>{});
232 template<
typename Node,
typename... Indices>
234 ImplementationDefined
child(Node&& node, HybridTreePath<Indices...>
treePath)
236 auto childStorage(Node&& node, HybridTreePath<Indices...> tp)
239 static_assert(
sizeof...(Indices) > 0,
"childStorage() cannot be called with an empty TreePath");
255 struct filter_void<void>
258 template<
typename Node, std::size_t... indices>
260 :
public filter_void<std::decay_t<decltype(child(std::declval<Node>(),index_constant<indices>{}...))>>
275 template<
typename Node, std::size_t... indices>
276 using Child =
typename impl::_Child<Node,indices...>::type;
283 template<
typename Node,
typename TreePath>
284 struct _ChildForTreePath
286 using type =
typename std::decay<decltype(child(std::declval<Node>(),std::declval<TreePath>()))>::type;
302 template<
typename Node,
typename TreePath>
312 struct _is_flat_index
314 using type = std::is_integral<T>;
318 template<std::
size_t i>
319 struct _is_flat_index<index_constant<i>>
321 using type = std::true_type;
345 constexpr
typename std::enable_if<
349 _non_empty_tree_path(T)
355 constexpr
typename std::enable_if<
359 _non_empty_tree_path(T t)
typename impl::_is_flat_index< std::decay_t< T > >::type is_flat_index
Type trait that determines whether T is a flat index in the context of child extraction.
Definition: childextraction.hh:335
ImplementationDefined childStorage(Node &&node, Indices... indices)
Definition: childextraction.hh:189
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:276
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:179
typename impl::_ChildForTreePath< Node, TreePath >::type ChildForTreePath
Template alias for the type of a child node given by a TreePath or a HybridTreePath type.
Definition: childextraction.hh:303
ImplementationDefined child(Node &&node, HybridTreePath< Indices... > treePath)
Extracts the child of a node given by a HybridTreePath object.
Definition: childextraction.hh:224
typename std::decay_t< Node >::NodeTag NodeTag
Returns the node tag of the given Node.
Definition: nodeinterface.hh:62
std::integral_constant< std::size_t, degree(static_cast< std::decay_t< Node > * >(nullptr), NodeTag< std::decay_t< Node > >()) > StaticDegree
Returns the statically known degree of the given Node type as a std::integral_constant.
Definition: nodeinterface.hh:105
constexpr std::size_t treePathSize(const HybridTreePath< T... > &)
Returns the size (number of components) of the given HybridTreePath.
Definition: treepath.hh:196
constexpr HybridTreePath< T... > treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:188
Definition: accumulate_static.hh:13
A hybrid version of TreePath that supports both compile time and run time indices.
Definition: treepath.hh:79