1#ifndef __DUNE_ACFEM_EXPRESSIONS_EXAMINE_HH__
2#define __DUNE_ACFEM_EXPRESSIONS_EXAMINE_HH__
4#include "../mpl/typetuple.hh"
8namespace Dune::ACFem::Expressions {
10 namespace ExamineImpl {
14 template<
class E,
template<
class... Arg>
class F, class ArgIndex, class SFINAE =
void>
15 struct TraverseHelper;
18 struct MakeAritySequence
20 using Type = MakeIndexSequence<Arity<T>::value>;
23 template<
class T,
class... Rest>
24 struct MakeAritySequence<MPL::TypeTuple<T, Rest...> >
26 using Type = MakeIndexSequence<Arity<T>::value>;
30 using AritySequence =
typename MakeAritySequence<T>::Type;
33 template<
class E,
template<
class... Arg>
class F,
std::size_t... ArgIndex>
34 struct TraverseHelper<
35 E, F, IndexSequence<ArgIndex...>,
36 std::enable_if_t<!MPL::IsTypeTupleV<E> && !IsSelfExpression<E>::value && IsExpression<E>::value> >
40 typename TraverseHelper<Operand<ArgIndex, E>, F,
41 AritySequence<Operand<ArgIndex, E> > >::Type...>::Type;
45 template<
class E,
template<
class... Arg>
class F,
std::size_t... ArgIndex>
46 struct TraverseHelper<
47 E, F, IndexSequence<ArgIndex...>,
48 std::enable_if_t<!MPL::IsTypeTupleV<E> && (IsSelfExpression<E>::value || !IsExpression<E>::value)> >
50 using Type =
typename F<E>::Type;
54 template<
class E, std::size_t... TreePos,
template<
class... Arg>
class F,
std::size_t... ArgIndex>
55 struct TraverseHelper<
56 MPL::TypeTuple<E, IndexSequence<TreePos...> >, F, IndexSequence<ArgIndex...>,
57 std::enable_if_t<!IsSelfExpression<E>::value && IsExpression<E>::value> >
61 typename TraverseHelper<MPL::TypeTuple<Operand<ArgIndex, E>,
IndexSequence<TreePos..., ArgIndex> >, F,
62 AritySequence<Operand<ArgIndex, E> > >::Type...>::Type;
66 template<
class E, std::size_t... TreePos,
template<
class... Arg>
class F,
std::size_t... ArgIndex>
67 struct TraverseHelper<
68 MPL::TypeTuple<E, IndexSequence<TreePos...> >, F, IndexSequence<ArgIndex...>,
69 std::enable_if_t<IsSelfExpression<E>::value || !IsExpression<E>::value> >
71 using Type =
typename F<MPL::TypeTuple<E,
IndexSequence<TreePos...> > >::Type;
75 template<
class E,
class Parent,
template<
class... Arg>
class F,
std::size_t... ArgIndex>
76 struct TraverseHelper<
77 MPL::TypeTuple<E, Parent>, F, IndexSequence<ArgIndex...>,
78 std::enable_if_t<!IsSequence<Parent>::value && !IsSelfExpression<E>::value && IsExpression<E>::value> >
81 typename F<MPL::TypeTuple<E, Parent>,
82 typename TraverseHelper<
83 MPL::TypeTuple<Operand<ArgIndex, E>, E>,
85 AritySequence<Operand<ArgIndex, E> >
91 template<
class E,
class Parent,
template<
class... Arg>
class F,
std::size_t... ArgIndex>
92 struct TraverseHelper<
93 MPL::TypeTuple<E, Parent>, F, IndexSequence<ArgIndex...>,
94 std::enable_if_t<!IsSequence<Parent>::value && (IsSelfExpression<E>::value || !IsExpression<E>::value)> >
96 using Type =
typename F<MPL::TypeTuple<E, Parent> >::Type;
100 template<
class E, std::size_t... TreePos,
class Parent,
template<
class... Arg>
class F,
std::size_t... ArgIndex>
101 struct TraverseHelper<
102 MPL::TypeTuple<E, IndexSequence<TreePos...>, Parent>, F, IndexSequence<ArgIndex...>,
103 std::enable_if_t<!IsSelfExpression<E>::value && IsExpression<E>::value> >
106 typename F<MPL::TypeTuple<E,
IndexSequence<TreePos...>, Parent>,
107 typename TraverseHelper<
108 MPL::TypeTuple<Operand<ArgIndex, E>,
IndexSequence<TreePos..., ArgIndex>, E>,
110 AritySequence<Operand<ArgIndex, E> >
116 template<
class E,
class TreePos,
class Parent,
template<
class... Arg>
class F,
std::size_t... ArgIndex>
117 struct TraverseHelper<
118 MPL::TypeTuple<E, TreePos, Parent>, F, IndexSequence<ArgIndex...>,
119 std::enable_if_t<IsSelfExpression<E>::value || !IsExpression<E>::value> >
121 using Type =
typename F<MPL::TypeTuple<E, TreePos, Parent> >::Type;
142 template<
class E,
template<
class... Arg>
class F>
143 using Traverse =
typename TraverseHelper<E, F, AritySequence<E> >::Type;
159 template<
class T,
template<
class ...>
class AccuFunctor,
template<
class... Arg>
class ExprPredicate, class... Rest>
165 template<
class E,
class... Args>
168 using Type = AccuFunctor<
Sequence<T, ExprPredicate<E, Rest...>::value, Args::value...> >;
172 template<
class E,
class... Args>
175 using Type = ExprPredicate<E, AccuFunctor<
Sequence<T, Args::value...> >, Rest...>;
182 template<
class E,
class T,
template<
class...>
class AccuFunctor,
template<
class...>
class ExprPredicate,
class... Rest>
183 using ExamineRecurse = Traverse<E,
FunctorFactory<T, AccuFunctor, ExprPredicate, Rest...>::template Recurse>;
186 template<
class E,
class T,
template<
class...>
class AccuFunctor,
template<
class... Arg>
class ExprPredicate, class... Rest>
187 using Examine = Traverse<E,
FunctorFactory<T, AccuFunctor, ExprPredicate, Rest...>::template Accumulate>;
191 using ExamineImpl::Examine;
192 using ExamineImpl::ExamineRecurse;
205 template<
class E,
template<
class... Arg>
class ExprPredicate, class... Rest>
206 using ExamineOr =
BoolConstant<Examine<E, bool, LogicalOr, ExprPredicate, Rest...>::value>;
209 template<
class E,
template<
class... Arg>
class F, class... Rest>
210 using ExamineAnd =
BoolConstant<Examine<E, bool, LogicalAnd, F, Rest...>::value>;
215 template<
class E,
template<
class... Arg>
class F, class... Rest>
216 using ExamineAdd =
IndexConstant<Examine<E, std::size_t, Sum, F, Rest...>::value>;
218 template<
class E,
class TreePos,
class Parent,
template<
class...>
class F,
class... Rest>
220 : ExamineOr<MPL::TypeTuple<E, TreePos, Parent>, F, Rest...>
223 template<
class E,
class TreePos,
template<
class...>
class F,
class... Rest>
224 struct ExamineTreeOr<E, TreePos,
FalseType, F, Rest...>
225 : ExamineOr<MPL::TypeTuple<E, TreePos>, F, Rest...>
228 template<
class E,
class Parent,
template<
class...>
class F,
class... Rest>
229 struct ExamineTreeOr<E,
FalseType, Parent, F, Rest...>
230 : ExamineOr<MPL::TypeTuple<E, Parent>, F, Rest...>
233 template<
class E,
template<
class...>
class F,
class... Rest>
235 : ExamineOr<E, F, Rest...>
238 template<
class E,
class TreePos,
class Parent,
template<
class...>
class F,
class... Rest>
239 struct ExamineTreeAnd
240 : ExamineAnd<MPL::TypeTuple<E, TreePos, Parent>, F, Rest...>
243 template<
class E,
class TreePos,
template<
class...>
class F,
class... Rest>
244 struct ExamineTreeAnd<E, TreePos,
FalseType, F, Rest...>
245 : ExamineAnd<MPL::TypeTuple<E, TreePos>, F, Rest...>
248 template<
class E,
class Parent,
template<
class...>
class F,
class... Rest>
249 struct ExamineTreeAnd<E,
FalseType, Parent, F, Rest...>
250 : ExamineAnd<MPL::TypeTuple<E, Parent>, F, Rest...>
253 template<
class E,
template<
class...>
class F,
class... Rest>
255 : ExamineAnd<E, F, Rest...>
Sequence< std::size_t, V... > IndexSequence
Sequence of std::size_t values.
Definition: types.hh:64
Constant< bool, V > BoolConstant
Short-cut for integral constant of type bool.
Definition: types.hh:48
std::integer_sequence< T, V... > Sequence
Sequence of any type of integer values.
Definition: types.hh:56
Constant< std::size_t, V > IndexConstant
Short-cut for integral constant of type std::size_t.
Definition: types.hh:44
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110
Just accumulate all values, F must accept the expression as first template parameter.
Definition: examine.hh:167
Feed the accumulated values for the operands back into F.
Definition: examine.hh:174
Definition: examine.hh:161