25 template<
typename result_type>
28 template<result_type r1, result_type r2>
31 static const result_type
result = r1 || r2;
36 template<
typename result_type>
39 template<result_type r1, result_type r2>
42 static const result_type
result = r1 && r2;
47 template<
typename result_type>
50 template<result_type r1, result_type r2>
53 static const result_type
result = r1 + r2;
58 template<
typename result_type>
61 template<result_type r1, result_type r2>
64 static const result_type
result = r1 - r2;
69 template<
typename result_type>
72 template<result_type r1, result_type r2>
75 static const result_type
result = r1 * r2;
80 template<
typename result_type>
83 template<result_type r1, result_type r2>
86 static const result_type
result = r1 < r2 ? r1 : r2;
91 template<
typename result_type>
94 template<result_type r1, result_type r2>
97 static const result_type
result = r1 > r2 ? r1 : r2;
107 template<
typename Node,
typename Functor,
typename Reduction,
typename Functor::result_type current_value,
typename TreePath,
bool doVisit>
108 struct accumulate_node_helper
111 typedef typename Functor::result_type result_type;
113 static const result_type
result = current_value;
118 template<
typename Node,
typename Functor,
typename Reduction,
typename Functor::result_type current_value,
typename TreePath>
119 struct accumulate_node_helper<Node,Functor,Reduction,current_value,TreePath,true>
122 typedef typename Functor::result_type result_type;
124 static const result_type
result = Reduction::template reduce<current_value,Functor::template visit<Node,TreePath>::result>::result;
129 template<
typename Tree,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath,
typename Tag>
130 struct accumulate_value;
133 template<
typename LeafNode,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath>
134 struct accumulate_value<LeafNode,Functor,Reduction,ParentChildReduction,current_value,TreePath,LeafNodeTag>
137 typedef typename Functor::result_type result_type;
139 static const result_type
result =
141 accumulate_node_helper<LeafNode,Functor,Reduction,current_value,TreePath,Functor::template doVisit<LeafNode,TreePath>::value>
::result;
146 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>
147 struct accumulate_over_children
150 typedef typename Functor::result_type result_type;
152 typedef decltype(
push_back(TreePath{},index_constant<i>{})) child_tree_path;
154 typedef typename Node::template
Child<i>::Type child;
156 static const result_type child_result = accumulate_value<child,Functor,Reduction,ParentChildReduction,current_value,child_tree_path,
NodeTag<child>>::result;
158 static const result_type result = accumulate_over_children<Node,Functor,Reduction,ParentChildReduction,child_result,TreePath,i+1,n>::result;
163 template<typename Node, typename Functor, typename Reduction, typename ParentChildReduction, typename Functor::result_type current_value, typename TreePath, std::
size_t n>
164 struct accumulate_over_children<Node,Functor,Reduction,ParentChildReduction,current_value,TreePath,n,n>
167 typedef typename Functor::result_type result_type;
169 static const result_type
result = current_value;
175 template<
typename Node,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath>
176 struct accumulate_value_generic_composite_node
179 typedef typename Functor::result_type result_type;
181 static const result_type
child_result = accumulate_over_children<Node,Functor,Reduction,ParentChildReduction,current_value,TreePath,0,StaticDegree<Node>::value>
::result;
183 static const result_type
result =
184 accumulate_node_helper<Node,Functor,ParentChildReduction,child_result,TreePath,Functor::template doVisit<Node,TreePath>::value>
::result;
190 template<
typename PowerNode,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath>
191 struct accumulate_value<PowerNode,Functor,Reduction,ParentChildReduction,current_value,TreePath,PowerNodeTag>
192 :
public accumulate_value_generic_composite_node<PowerNode,Functor,Reduction,ParentChildReduction,current_value,TreePath>
196 template<
typename CompositeNode,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath>
197 struct accumulate_value<CompositeNode,Functor,Reduction,ParentChildReduction,current_value,TreePath,CompositeNodeTag>
198 :
public accumulate_value_generic_composite_node<CompositeNode,Functor,Reduction,ParentChildReduction,current_value,TreePath>
260 template<
typename Tree,
typename Functor,
typename Reduction,
typename Functor::result_type startValue,
typename ParentChildReduction = Reduction>
274 struct flattened_reduction;
278 struct bottom_up_reduction;
286 template<
typename Node,
typename Functor,
typename Reduction,
typename current_type,
typename TreePath,
bool doVisit>
287 struct accumulate_type_node_helper
290 typedef current_type type;
295 template<
typename Node,
typename Functor,
typename Reduction,
typename current_type,
typename TreePath>
296 struct accumulate_type_node_helper<Node,Functor,Reduction,current_type,TreePath,true>
299 typedef typename Reduction::template reduce<
301 typename Functor::template visit<
310 template<
typename Tree,
typename Policy,
typename current_type,
typename TreePath,
typename Tag>
311 struct accumulate_type;
314 template<
typename LeafNode,
typename Policy,
typename current_type,
typename TreePath>
315 struct accumulate_type<LeafNode,Policy,current_type,TreePath,LeafNodeTag>
318 typedef typename accumulate_type_node_helper<
320 typename Policy::functor,
321 typename Policy::sibling_reduction,
324 Policy::functor::template doVisit<
334 template<
typename current_type,
typename tree_path,
typename start_type,
typename reduction_strategy>
335 struct propagate_type_down_tree;
338 template<
typename current_type,
typename tree_path,
typename start_type>
339 struct propagate_type_down_tree<
346 typedef current_type type;
350 template<
typename current_type,
typename tree_path,
typename start_type>
351 struct propagate_type_down_tree<
358 typedef typename std::conditional<
359 TreePathBack<tree_path>::value == 0,
367 template<
typename Node,
typename Policy,
typename current_type,
typename TreePath, std::
size_t i, std::
size_t n>
368 struct accumulate_type_over_children
371 typedef decltype(
push_back(TreePath{},index_constant<i>{})) child_tree_path;
373 typedef typename Node::template Child<i>::Type child;
375 typedef typename accumulate_type<
379 typename propagate_type_down_tree<
382 typename Policy::start_type,
383 typename Policy::reduction_strategy
387 >::type child_result_type;
389 typedef typename accumulate_type_over_children<
401 template<typename Node, typename Policy, typename current_type, typename TreePath, std::
size_t n>
402 struct accumulate_type_over_children<Node,Policy,current_type,TreePath,n,n>
405 typedef current_type type;
412 template<
typename Node,
typename Policy,
typename current_type,
typename TreePath>
413 struct accumulate_type_generic_composite_node
416 typedef typename accumulate_type_over_children<
422 StaticDegree<Node>::value
423 >::type children_result_type;
425 typedef typename accumulate_type_node_helper<
427 typename Policy::functor,
428 typename Policy::parent_child_reduction,
429 children_result_type,
431 Policy::functor::template doVisit<
440 template<
typename PowerNode,
typename Policy,
typename current_type,
typename TreePath>
441 struct accumulate_type<PowerNode,Policy,current_type,TreePath,PowerNodeTag>
442 :
public accumulate_type_generic_composite_node<PowerNode,Policy,current_type,TreePath>
446 template<
typename CompositeNode,
typename Policy,
typename current_type,
typename TreePath>
447 struct accumulate_type<CompositeNode,Policy,current_type,TreePath,CompositeNodeTag>
448 :
public accumulate_type_generic_composite_node<CompositeNode,Policy,current_type,TreePath>
465 typename ParentChildReduction = Reduction,
466 typename ReductionAlgorithm = flattened_reduction
554 template<
typename Tree,
typename Policy>
559 typedef typename accumulate_type<
562 typename Policy::start_type,
575 namespace Experimental {
579 template<
class T,
class TreePath,
class V,
class U,
580 std::enable_if_t<std::decay_t<T>::isLeaf,
int> = 0>
581 auto hybridApplyToTree(T&& tree, TreePath
treePath, V&& visitor, U&& current_val)
583 return visitor.leaf(tree,
treePath, std::forward<U>(current_val));
587 template<
class T,
class TreePath,
class V,
class U,
588 std::enable_if_t<not std::decay_t<T>::isLeaf,
int> = 0>
589 auto hybridApplyToTree(T&& tree, TreePath
treePath, V&& visitor, U&& current_val)
591 using Tree = std::remove_reference_t<T>;
592 using Visitor = std::remove_reference_t<V>;
593 auto pre_val = visitor.pre(tree,
treePath, std::forward<U>(current_val));
596 using allowDynamicTraversal = Dune::Std::is_detected<Detail::DynamicTraversalConcept,Tree>;
597 using allowStaticTraversal = Dune::Std::is_detected<Detail::StaticTraversalConcept,Tree>;
600 static_assert(allowDynamicTraversal::value || allowStaticTraversal::value);
603 using preferDynamicTraversal = std::bool_constant<Visitor::treePathType == TreePathType::dynamic>;
606 auto apply_i = [&](
auto&& value,
const auto& i){
607 auto&&
child = tree.child(i);
610 auto val_before = visitor.beforeChild(tree,
child,
treePath, i, std::move(value));
613 auto val_in = Hybrid::ifElse(
614 Hybrid::equal_to(i,Indices::_0),
615 [&](
auto id){
return std::move(val_before);},
616 [&](
auto id){
return visitor.in(tree,
treePath, std::move(val_before));}
619 constexpr bool visitChild = Visitor::template VisitChild<Tree,Child,TreePath>::value;
620 auto val_visit = [&](){
621 if constexpr (visitChild) {
623 return hybridApplyToTree(
child, childTreePath, visitor, std::move(val_in));
626 return std::move(val_in);
629 return visitor.afterChild(tree,
child,
treePath, i, std::move(val_visit));
634 if constexpr (allowStaticTraversal::value && not preferDynamicTraversal::value) {
636 auto indices = std::make_index_sequence<Tree::degree()>{};
639 return unpackIntegerSequence([&](
auto... i) {
659 return left_fold(std::move(apply_i),std::move(pre_val), i...);
664 auto i_val = apply_i(std::move(pre_val),std::size_t{0});
666 for(std::size_t i = 1; i < tree.degree(); i++)
667 i_val = apply_i(i_val,i);
672 return visitor.post(tree,
treePath, in_val);
700 template<
typename Tree,
typename Visitor,
typename Init>
701 auto hybridApplyToTree(Tree&& tree, Visitor&& visitor, Init&& init)
703 return Impl::hybridApplyToTree(tree,
hybridTreePath(), visitor, init);