4 #ifndef DUNE_TYPETREE_ACCUMULATE_STATIC_HH
5 #define DUNE_TYPETREE_ACCUMULATE_STATIC_HH
7 #include <dune/common/typetraits.hh>
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;
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;
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
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>
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>
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) {
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>
decltype(push_back(TreePath{}, index_constant< i >{})) typedef child_tree_path
Definition: accumulate_static.hh:149
static const result_type child_result
Definition: accumulate_static.hh:153
static const result_type result
Definition: accumulate_static.hh:110
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:223
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:126
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:85
typename std::decay_t< Node >::NodeTag NodeTag
Returns the node tag of the given Node.
Definition: nodeinterface.hh:76
constexpr HybridTreePath< T... > treePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:191
constexpr HybridTreePath< T... > hybridTreePath(const T &... t)
Constructs a new HybridTreePath from the given indices.
Definition: treepath.hh:180
constexpr HybridTreePath< T..., std::size_t > push_back(const HybridTreePath< T... > &tp, std::size_t i)
Appends a run time index to a HybridTreePath.
Definition: treepath.hh:281
HybridTreePath< Dune::index_constant< i >... > TreePath
Definition: treepath.hh:521
Definition: accumulate_static.hh:13
auto hybridApplyToTree(Tree &&tree, Visitor &&visitor, Init &&init)
Apply hybrid visitor to TypeTree.
Definition: accumulate_static.hh:698
Type
Definition: treepath.hh:30
Statically combine two values of type result_type using ||.
Definition: accumulate_static.hh:24
Definition: accumulate_static.hh:27
static const result_type result
Definition: accumulate_static.hh:28
Statically combine two values of type result_type using &&.
Definition: accumulate_static.hh:35
Definition: accumulate_static.hh:38
static const result_type result
Definition: accumulate_static.hh:39
Statically combine two values of type result_type using +.
Definition: accumulate_static.hh:46
Definition: accumulate_static.hh:49
static const result_type result
Definition: accumulate_static.hh:50
Statically combine two values of type result_type using -.
Definition: accumulate_static.hh:57
Definition: accumulate_static.hh:60
static const result_type result
Definition: accumulate_static.hh:61
Statically combine two values of type result_type using *.
Definition: accumulate_static.hh:68
Definition: accumulate_static.hh:71
static const result_type result
Definition: accumulate_static.hh:72
Statically combine two values of type result_type by returning their minimum.
Definition: accumulate_static.hh:79
Definition: accumulate_static.hh:82
static const result_type result
Definition: accumulate_static.hh:83
Statically combine two values of type result_type by returning their maximum.
Definition: accumulate_static.hh:90
Definition: accumulate_static.hh:93
static const result_type result
Definition: accumulate_static.hh:94
Statically accumulate a value over the nodes of a TypeTree.
Definition: accumulate_static.hh:259
Functor::result_type result_type
The result type of the computation.
Definition: accumulate_static.hh:262
static const result_type result
The accumulated result of the computation.
Definition: accumulate_static.hh:265
Definition: accumulate_static.hh:466
ParentChildReduction parent_child_reduction
Definition: accumulate_static.hh:524
Functor functor
Definition: accumulate_static.hh:495
StartType start_type
Definition: accumulate_static.hh:532
ReductionAlgorithm reduction_strategy
Definition: accumulate_static.hh:538
Reduction sibling_reduction
Definition: accumulate_static.hh:516
Statically accumulate a type over the nodes of a TypeTree.
Definition: accumulate_static.hh:553
accumulate_type< Tree, Policy, typename Policy::start_type, HybridTreePath<>, NodeTag< Tree > >::type type
The accumulated result of the computation.
Definition: accumulate_static.hh:562
A hybrid version of TreePath that supports both compile time and run time indices.
Definition: treepath.hh:79