22 template<
typename result_type>
25 template<result_type r1, result_type r2>
28 static const result_type
result = r1 || r2;
33 template<
typename result_type>
36 template<result_type r1, result_type r2>
39 static const result_type
result = r1 && r2;
44 template<
typename result_type>
47 template<result_type r1, result_type r2>
50 static const result_type
result = r1 + r2;
55 template<
typename result_type>
58 template<result_type r1, result_type r2>
61 static const result_type
result = r1 - r2;
66 template<
typename result_type>
69 template<result_type r1, result_type r2>
72 static const result_type
result = r1 * r2;
77 template<
typename result_type>
80 template<result_type r1, result_type r2>
83 static const result_type
result = r1 < r2 ? r1 : r2;
88 template<
typename result_type>
91 template<result_type r1, result_type r2>
94 static const result_type
result = r1 > r2 ? r1 : r2;
104 template<
typename Node,
typename Functor,
typename Reduction,
typename Functor::result_type current_value,
typename TreePath,
bool doVisit>
105 struct accumulate_node_helper
108 typedef typename Functor::result_type result_type;
110 static const result_type
result = current_value;
115 template<
typename Node,
typename Functor,
typename Reduction,
typename Functor::result_type current_value,
typename TreePath>
116 struct accumulate_node_helper<Node,Functor,Reduction,current_value,
TreePath,true>
119 typedef typename Functor::result_type result_type;
121 static const result_type
result = Reduction::template reduce<current_value,Functor::template visit<Node,TreePath>::result>::result;
126 template<
typename Tree,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath,
typename Tag>
127 struct accumulate_value;
130 template<
typename LeafNode,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath>
131 struct accumulate_value<LeafNode,Functor,Reduction,ParentChildReduction,current_value,
TreePath,LeafNodeTag>
134 typedef typename Functor::result_type result_type;
136 static const result_type
result =
138 accumulate_node_helper<LeafNode,Functor,Reduction,current_value,TreePath,Functor::template doVisit<LeafNode,TreePath>::value>
::result;
143 template<
typename Node,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath, std::
size_t i, std::
size_t n>
144 struct accumulate_over_children
147 typedef typename Functor::result_type result_type;
151 typedef typename Node::template
Child<i>::Type child;
153 static const result_type child_result = accumulate_value<child,Functor,Reduction,ParentChildReduction,current_value,child_tree_path,
NodeTag<child>>::result;
155 static const result_type result = accumulate_over_children<Node,Functor,Reduction,ParentChildReduction,child_result,
TreePath,i+1,n>::result;
160 template<typename Node, typename Functor, typename Reduction, typename ParentChildReduction, typename Functor::result_type current_value, typename
TreePath, std::
size_t n>
161 struct accumulate_over_children<Node,Functor,Reduction,ParentChildReduction,current_value,
TreePath,n,n>
164 typedef typename Functor::result_type result_type;
166 static const result_type
result = current_value;
172 template<
typename Node,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath>
173 struct accumulate_value_generic_composite_node
176 typedef typename Functor::result_type result_type;
178 static const result_type
child_result = accumulate_over_children<Node,Functor,Reduction,ParentChildReduction,current_value,TreePath,0,StaticDegree<Node>::value>
::result;
180 static const result_type
result =
181 accumulate_node_helper<Node,Functor,ParentChildReduction,child_result,TreePath,Functor::template doVisit<Node,TreePath>::value>
::result;
187 template<
typename PowerNode,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath>
188 struct accumulate_value<PowerNode,Functor,Reduction,ParentChildReduction,current_value,
TreePath,PowerNodeTag>
189 :
public accumulate_value_generic_composite_node<PowerNode,Functor,Reduction,ParentChildReduction,current_value,TreePath>
193 template<
typename CompositeNode,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath>
194 struct accumulate_value<CompositeNode,Functor,Reduction,ParentChildReduction,current_value,
TreePath,CompositeNodeTag>
195 :
public accumulate_value_generic_composite_node<CompositeNode,Functor,Reduction,ParentChildReduction,current_value,TreePath>
257 template<
typename Tree,
typename Functor,
typename Reduction,
typename Functor::result_type startValue,
typename ParentChildReduction = Reduction>
271 struct flattened_reduction;
275 struct bottom_up_reduction;
283 template<
typename Node,
typename Functor,
typename Reduction,
typename current_type,
typename TreePath,
bool doVisit>
284 struct accumulate_type_node_helper
287 typedef current_type type;
292 template<
typename Node,
typename Functor,
typename Reduction,
typename current_type,
typename TreePath>
293 struct accumulate_type_node_helper<Node,Functor,Reduction,current_type,TreePath,true>
296 typedef typename Reduction::template reduce<
298 typename Functor::template visit<
307 template<
typename Tree,
typename Policy,
typename current_type,
typename TreePath,
typename Tag>
308 struct accumulate_type;
311 template<
typename LeafNode,
typename Policy,
typename current_type,
typename TreePath>
312 struct accumulate_type<LeafNode,Policy,current_type,TreePath,LeafNodeTag>
315 typedef typename accumulate_type_node_helper<
317 typename Policy::functor,
318 typename Policy::sibling_reduction,
321 Policy::functor::template doVisit<
331 template<
typename current_type,
typename tree_path,
typename start_type,
typename reduction_strategy>
332 struct propagate_type_down_tree;
335 template<
typename current_type,
typename tree_path,
typename start_type>
336 struct propagate_type_down_tree<
343 typedef current_type type;
347 template<
typename current_type,
typename tree_path,
typename start_type>
348 struct propagate_type_down_tree<
355 typedef typename std::conditional<
356 TreePathBack<tree_path>::value == 0,
364 template<
typename Node,
typename Policy,
typename current_type,
typename TreePath, std::
size_t i, std::
size_t n>
365 struct accumulate_type_over_children
368 typedef decltype(
push_back(TreePath{},index_constant<i>{})) child_tree_path;
370 typedef typename Node::template Child<i>::Type child;
372 typedef typename accumulate_type<
376 typename propagate_type_down_tree<
379 typename Policy::start_type,
380 typename Policy::reduction_strategy
384 >::type child_result_type;
386 typedef typename accumulate_type_over_children<
398 template<typename Node, typename Policy, typename current_type, typename TreePath, std::
size_t n>
399 struct accumulate_type_over_children<Node,Policy,current_type,TreePath,n,n>
402 typedef current_type type;
409 template<
typename Node,
typename Policy,
typename current_type,
typename TreePath>
410 struct accumulate_type_generic_composite_node
413 typedef typename accumulate_type_over_children<
419 StaticDegree<Node>::value
420 >::type children_result_type;
422 typedef typename accumulate_type_node_helper<
424 typename Policy::functor,
425 typename Policy::parent_child_reduction,
426 children_result_type,
428 Policy::functor::template doVisit<
437 template<
typename PowerNode,
typename Policy,
typename current_type,
typename TreePath>
438 struct accumulate_type<PowerNode,Policy,current_type,
TreePath,PowerNodeTag>
439 :
public accumulate_type_generic_composite_node<PowerNode,Policy,current_type,TreePath>
443 template<
typename CompositeNode,
typename Policy,
typename current_type,
typename TreePath>
444 struct accumulate_type<CompositeNode,Policy,current_type,
TreePath,CompositeNodeTag>
445 :
public accumulate_type_generic_composite_node<CompositeNode,Policy,current_type,TreePath>
462 typename ParentChildReduction = Reduction,
463 typename ReductionAlgorithm = flattened_reduction
551 template<
typename Tree,
typename Policy>
556 typedef typename accumulate_type<
559 typename Policy::start_type,
572 namespace Experimental {
576 template<
class T,
class TreePath,
class V,
class U,
577 std::enable_if_t<std::decay_t<T>::isLeaf,
int> = 0>
578 auto hybridApplyToTree(T&& tree,
TreePath treePath, V&& visitor, U&& current_val)
580 return visitor.leaf(tree,
treePath, std::forward<U>(current_val));
584 template<
class T,
class TreePath,
class V,
class U,
585 std::enable_if_t<not std::decay_t<T>::isLeaf,
int> = 0>
586 auto hybridApplyToTree(T&& tree,
TreePath treePath, V&& visitor, U&& current_val)
588 using Tree = std::remove_reference_t<T>;
589 using Visitor = std::remove_reference_t<V>;
590 auto pre_val = visitor.pre(tree,
treePath, std::forward<U>(current_val));
593 using allowDynamicTraversal = Dune::Std::is_detected<Detail::DynamicTraversalConcept,Tree>;
594 using allowStaticTraversal = Dune::Std::is_detected<Detail::StaticTraversalConcept,Tree>;
597 static_assert(allowDynamicTraversal::value || allowStaticTraversal::value);
600 using preferDynamicTraversal = std::bool_constant<Visitor::treePathType == TreePathType::dynamic>;
603 auto apply_i = [&](
auto&& value,
const auto& i){
604 auto&&
child = tree.child(i);
607 auto val_before = visitor.beforeChild(tree,
child,
treePath, i, std::move(value));
610 auto val_in = Hybrid::ifElse(
611 Hybrid::equals(i,Indices::_0),
612 [&](
auto id){
return std::move(val_before);},
613 [&](
auto id){
return visitor.in(tree,
treePath, std::move(val_before));}
616 constexpr bool visitChild = Visitor::template VisitChild<Tree,Child,TreePath>::value;
617 auto val_visit = [&](){
618 if constexpr (visitChild) {
620 return hybridApplyToTree(
child, childTreePath, visitor, std::move(val_in));
623 return std::move(val_in);
626 return visitor.afterChild(tree,
child,
treePath, i, std::move(val_visit));
631 if constexpr (allowStaticTraversal::value && not preferDynamicTraversal::value) {
633 auto indices = std::make_index_sequence<Tree::degree()>{};
636 return unpackIntegerSequence([&](
auto... i) {
656 return left_fold(std::move(apply_i),std::move(pre_val), i...);
661 auto i_val = apply_i(std::move(pre_val),std::size_t{0});
663 for(std::size_t i = 1; i < tree.degree(); i++)
664 i_val = apply_i(i_val,i);
669 return visitor.post(tree,
treePath, in_val);
697 template<
typename Tree,
typename Visitor,
typename Init>
698 auto hybridApplyToTree(Tree&& tree, Visitor&& visitor, Init&& init)
700 return Impl::hybridApplyToTree(tree,
hybridTreePath(), visitor, init);