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>
189 ImplementationDefined
child(Node&& node, Indices... indices)
217 template<
typename Node, std::size_t... Indices>
224 return child(std::forward<Node>(node),index_constant<Indices>{}...);
227 template<
typename Node, std::size_t... Indices>
234 static_assert(
sizeof...(Indices) > 0,
"childStorage() cannot be called with an empty TreePath");
262 template<
typename Node,
typename... Indices>
269 return impl::child(std::forward<Node>(node),tp,std::index_sequence_for<Indices...>{});
272 template<
typename Node,
typename... Indices>
274 ImplementationDefined
child(Node&& node, HybridTreePath<Indices...> treePath)
276 auto childStorage(Node&& node, HybridTreePath<Indices...> tp)
279 static_assert(
sizeof...(Indices) > 0,
"childStorage() cannot be called with an empty TreePath");
288 template<
typename Node, std::size_t... indices>
291 using type = std::decay_t<decltype(child(std::declval<Node>(),index_constant<indices>{}...))>;
306 template<
typename Node, std::size_t... indices>
307 using Child =
typename impl::_Child<Node,indices...>::type;
314 template<
typename Node,
typename TreePath>
315 struct _ChildForTreePath
317 using type =
typename std::decay<decltype(child(std::declval<Node>(),std::declval<TreePath>()))>::type;
333 template<
typename Node,
typename TreePath>
343 struct _is_flat_index
345 using type = std::is_integral<T>;
349 template<std::
size_t i>
350 struct _is_flat_index<index_constant<i>>
352 using type = std::true_type;
374 template<
typename Node>
375 struct _lazy_member_child_decltype
377 template<
typename... Indices>
388 constexpr
typename std::enable_if<
392 _non_empty_tree_path(T)
398 constexpr
typename std::enable_if<
402 _non_empty_tree_path(T t)
416 #endif // DUNE_TYPETREE_CHILDEXTRACTION_HH