26 template<
typename result_type>
29 template<result_type r1, result_type r2>
32 static const result_type
result = r1 || r2;
37 template<
typename result_type>
40 template<result_type r1, result_type r2>
43 static const result_type
result = r1 && r2;
48 template<
typename result_type>
51 template<result_type r1, result_type r2>
54 static const result_type
result = r1 + r2;
59 template<
typename result_type>
62 template<result_type r1, result_type r2>
65 static const result_type
result = r1 - r2;
70 template<
typename result_type>
73 template<result_type r1, result_type r2>
76 static const result_type
result = r1 * r2;
81 template<
typename result_type>
84 template<result_type r1, result_type r2>
87 static const result_type
result = r1 < r2 ? r1 : r2;
92 template<
typename result_type>
95 template<result_type r1, result_type r2>
98 static const result_type
result = r1 > r2 ? r1 : r2;
108 template<
typename Node,
typename Functor,
typename Reduction,
typename Functor::result_type current_value,
typename TreePath,
bool doVisit>
109 struct accumulate_node_helper
112 typedef typename Functor::result_type result_type;
114 static const result_type result = current_value;
119 template<
typename Node,
typename Functor,
typename Reduction,
typename Functor::result_type current_value,
typename TreePath>
120 struct accumulate_node_helper<Node,Functor,Reduction,current_value,TreePath,true>
123 typedef typename Functor::result_type result_type;
125 static const result_type result = Reduction::template reduce<current_value,Functor::template visit<Node,TreePath>::result>::result;
130 template<
typename Tree,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath,
typename Tag>
131 struct accumulate_value;
134 template<
typename LeafNode,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath>
135 struct accumulate_value<LeafNode,Functor,Reduction,ParentChildReduction,current_value,TreePath,LeafNodeTag>
138 typedef typename Functor::result_type result_type;
140 static const result_type result =
142 accumulate_node_helper<LeafNode,Functor,Reduction,current_value,TreePath,Functor::template doVisit<LeafNode,TreePath>::value>::result;
147 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>
148 struct accumulate_over_children
151 typedef typename Functor::result_type result_type;
153 typedef decltype(push_back(TreePath{},index_constant<i>{})) child_tree_path;
155 typedef typename Node::template Child<i>::Type child;
157 static const result_type child_result = accumulate_value<child,Functor,Reduction,ParentChildReduction,current_value,child_tree_path,
NodeTag<child>>::result;
159 static const result_type result = accumulate_over_children<Node,Functor,Reduction,ParentChildReduction,child_result,TreePath,i+1,n>::result;
164 template<typename Node, typename Functor, typename Reduction, typename ParentChildReduction, typename Functor::result_type current_value, typename TreePath, std::
size_t n>
165 struct accumulate_over_children<Node,Functor,Reduction,ParentChildReduction,current_value,TreePath,n,n>
168 typedef typename Functor::result_type result_type;
170 static const result_type result = current_value;
176 template<
typename Node,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath>
177 struct accumulate_value_generic_composite_node
180 typedef typename Functor::result_type result_type;
182 static const result_type child_result = accumulate_over_children<Node,Functor,Reduction,ParentChildReduction,current_value,TreePath,0,StaticDegree<Node>::value>::result;
184 static const result_type result =
185 accumulate_node_helper<Node,Functor,ParentChildReduction,child_result,TreePath,Functor::template doVisit<Node,TreePath>::value>::result;
191 template<
typename PowerNode,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath>
192 struct accumulate_value<PowerNode,Functor,Reduction,ParentChildReduction,current_value,TreePath,PowerNodeTag>
193 :
public accumulate_value_generic_composite_node<PowerNode,Functor,Reduction,ParentChildReduction,current_value,TreePath>
197 template<
typename CompositeNode,
typename Functor,
typename Reduction,
typename ParentChildReduction,
typename Functor::result_type current_value,
typename TreePath>
198 struct accumulate_value<CompositeNode,Functor,Reduction,ParentChildReduction,current_value,TreePath,CompositeNodeTag>
199 :
public accumulate_value_generic_composite_node<CompositeNode,Functor,Reduction,ParentChildReduction,current_value,TreePath>
261 template<
typename Tree,
typename Functor,
typename Reduction,
typename Functor::result_type startValue,
typename ParentChildReduction = Reduction>
275 struct flattened_reduction;
279 struct bottom_up_reduction;
287 template<
typename Node,
typename Functor,
typename Reduction,
typename current_type,
typename TreePath,
bool doVisit>
288 struct accumulate_type_node_helper
291 typedef current_type type;
296 template<
typename Node,
typename Functor,
typename Reduction,
typename current_type,
typename TreePath>
297 struct accumulate_type_node_helper<Node,Functor,Reduction,current_type,TreePath,true>
300 typedef typename Reduction::template reduce<
302 typename Functor::template visit<
311 template<
typename Tree,
typename Policy,
typename current_type,
typename TreePath,
typename Tag>
312 struct accumulate_type;
315 template<
typename LeafNode,
typename Policy,
typename current_type,
typename TreePath>
316 struct accumulate_type<LeafNode,Policy,current_type,TreePath,LeafNodeTag>
319 typedef typename accumulate_type_node_helper<
321 typename Policy::functor,
322 typename Policy::sibling_reduction,
325 Policy::functor::template doVisit<
335 template<
typename current_type,
typename tree_path,
typename start_type,
typename reduction_strategy>
336 struct propagate_type_down_tree;
339 template<
typename current_type,
typename tree_path,
typename start_type>
340 struct propagate_type_down_tree<
347 typedef current_type type;
351 template<
typename current_type,
typename tree_path,
typename start_type>
352 struct propagate_type_down_tree<
359 typedef typename std::conditional<
360 tree_path().back() == 0,
368 template<
typename Node,
typename Policy,
typename current_type,
typename TreePath, std::
size_t i, std::
size_t n>
369 struct accumulate_type_over_children
372 typedef decltype(push_back(TreePath{},index_constant<i>{})) child_tree_path;
374 typedef typename Node::template Child<i>::Type child;
376 typedef typename accumulate_type<
380 typename propagate_type_down_tree<
383 typename Policy::start_type,
384 typename Policy::reduction_strategy
388 >::type child_result_type;
390 typedef typename accumulate_type_over_children<
402 template<typename Node, typename Policy, typename current_type, typename TreePath, std::
size_t n>
403 struct accumulate_type_over_children<Node,Policy,current_type,TreePath,n,n>
406 typedef current_type type;
413 template<
typename Node,
typename Policy,
typename current_type,
typename TreePath>
414 struct accumulate_type_generic_composite_node
417 typedef typename accumulate_type_over_children<
423 StaticDegree<Node>::value
424 >::type children_result_type;
426 typedef typename accumulate_type_node_helper<
428 typename Policy::functor,
429 typename Policy::parent_child_reduction,
430 children_result_type,
432 Policy::functor::template doVisit<
441 template<
typename PowerNode,
typename Policy,
typename current_type,
typename TreePath>
442 struct accumulate_type<PowerNode,Policy,current_type,TreePath,PowerNodeTag>
443 :
public accumulate_type_generic_composite_node<PowerNode,Policy,current_type,TreePath>
447 template<
typename CompositeNode,
typename Policy,
typename current_type,
typename TreePath>
448 struct accumulate_type<CompositeNode,Policy,current_type,TreePath,CompositeNodeTag>
449 :
public accumulate_type_generic_composite_node<CompositeNode,Policy,current_type,TreePath>
466 typename ParentChildReduction = Reduction,
467 typename ReductionAlgorithm = flattened_reduction
555 template<
typename Tree,
typename Policy>
560 typedef typename accumulate_type<
563 typename Policy::start_type,
580 template<
class T,
class TreePath,
class V,
class U,
581 std::enable_if_t<std::decay_t<T>::isLeaf,
int> = 0>
582 auto hybridApplyToTree(T&& tree, TreePath treePath, V&& visitor, U&& current_val)
584 return visitor.leaf(tree, treePath, std::forward<U>(current_val));
588 template<
class T,
class TreePath,
class V,
class U,
589 std::enable_if_t<not std::decay_t<T>::isLeaf,
int> = 0>
590 auto hybridApplyToTree(T&& tree, TreePath treePath, V&& visitor, U&& current_val)
592 using Tree = std::remove_reference_t<T>;
593 using Visitor = std::remove_reference_t<V>;
594 auto pre_val = visitor.pre(tree, treePath, std::forward<U>(current_val));
597 using allowDynamicTraversal = Dune::Std::is_detected<Detail::DynamicTraversalConcept,Tree>;
598 using allowStaticTraversal = Dune::Std::is_detected<Detail::StaticTraversalConcept,Tree>;
601 static_assert(allowDynamicTraversal::value || allowStaticTraversal::value);
604 using preferDynamicTraversal = std::bool_constant<Visitor::treePathType == TreePathType::dynamic>;
607 auto apply_i = [&](
auto&& value,
const auto& i){
608 auto&& child = tree.child(i);
609 using Child = std::decay_t<
decltype(child)>;
611 auto val_before = visitor.beforeChild(tree, child, treePath, i, std::move(value));
614 auto val_in = Hybrid::ifElse(
615 Hybrid::equal_to(i,Indices::_0),
616 [&](
auto id){
return std::move(val_before);},
617 [&](
auto id){
return visitor.in(tree, treePath, std::move(val_before));}
620 constexpr bool visitChild = Visitor::template VisitChild<Tree,Child,TreePath>::value;
621 auto val_visit = [&](){
622 if constexpr (visitChild) {
623 auto childTreePath = Dune::TypeTree::push_back(treePath, i);
627 return std::move(val_in);
630 return visitor.afterChild(tree, child, treePath, i, std::move(val_visit));
635 if constexpr (allowStaticTraversal::value && not preferDynamicTraversal::value) {
637 auto indices = std::make_index_sequence<Tree::degree()>{};
640 return unpackIntegerSequence([&](
auto... i) {
660 return left_fold(std::move(apply_i),std::move(pre_val), i...);
665 auto i_val = apply_i(std::move(pre_val),std::size_t{0});
667 for(std::size_t i = 1; i < tree.degree(); i++)
668 i_val = apply_i(i_val,i);
673 return visitor.post(tree, treePath, in_val);
701 template<
typename Tree,
typename Visitor,
typename Init>
704 return Impl::hybridApplyToTree(tree,
hybridTreePath(), visitor, init);