1#ifndef __DUNE_ACFEM_EXPRESSIONS_OPERATIONPAIR_HH__
2#define __DUNE_ACFEM_EXPRESSIONS_OPERATIONPAIR_HH__
4#include "treeoperand.hh"
5#include "complexity.hh"
7namespace Dune::ACFem::Expressions {
12 template<
class S,
class E,
class Pos>
23 template<
class S,
class F,
class TreeData0,
class TreeData1,
class OptimizeTag = OptimizeTop>
27 using FunctorType = F;
28 using TreeNode0 = TreeData0;
29 using TreeNode1 = TreeData1;
33 template<
class T,
class SFINAE =
void>
34 constexpr inline bool IsTreeDataV =
false;
36 template<
class Sign,
class E,
class Pos>
37 constexpr inline bool IsTreeDataV<TreeData<Sign, E, Pos> > =
true;
42 template<
class S,
class F,
class... TreeData0,
class TreeData1,
class OptimizeTag>
46 using FunctorType = F;
47 using TreeNode0 = MPL::TypeTuple<TreeData0...>;
48 using TreeNode1 = TreeData1;
55 template<
class S,
class F,
class TreeData0,
class... TreeData1,
class OptimizeTag>
59 using FunctorType = F;
60 using TreeNode0 = TreeData0;
61 using TreeNode1 = MPL::TypeTuple<TreeData1...>;
65 template<
class T,
class SFINAE =
void>
66 constexpr inline bool IsOperationPairV =
false;
68 template<
class Sign,
class InnerF,
class TreeData0,
class TreeData1,
class OptimizeTag>
69 constexpr inline bool IsOperationPairV<OperationPair<Sign, InnerF, TreeData0, TreeData1, OptimizeTag> > =
true;
71 template<
class F,
class Node>
72 struct MergeTreeNodeSignHelper;
74 template<
class OuterSign,
class Sign,
class E,
class Pos>
75 struct MergeTreeNodeSignHelper<OuterSign,
TreeData<Sign, E, Pos> >
80 template<
class OuterSign,
class Sign,
class F,
class TreeData0,
class TreeData1,
class OptimizeTag>
81 struct MergeTreeNodeSignHelper<OuterSign, OperationPair<Sign, F, TreeData0, TreeData1, OptimizeTag> >
83 using Type = OperationPair<NestedSumFunctor<OuterSign, Sign>, F, TreeData0, TreeData1, OptimizeTag>;
86 template<
class Sign,
class... Node>
87 struct MergeTreeNodeSignHelper<Sign, MPL::TypeTuple<Node...> >
89 using Type = MPL::TypeTuple<typename MergeTreeNodeSignHelper<Sign, Node>::Type...>;
96 template<
class Sign,
class Node>
97 using MergeTreeNodeSign =
typename MergeTreeNodeSignHelper<Sign, Node>::Type;
99 template<
class F,
class Node>
100 struct SetTreeNodeSignHelper;
102 template<
class OuterSign,
class Sign,
class E,
class Pos>
103 struct SetTreeNodeSignHelper<OuterSign, TreeData<Sign, E, Pos> >
105 using Type = TreeData<OuterSign, E, Pos>;
108 template<
class OuterSign,
class Sign,
class F,
class TreeData0,
class TreeData1,
class OptimizeTag>
109 struct SetTreeNodeSignHelper<OuterSign, OperationPair<Sign, F, TreeData0, TreeData1, OptimizeTag> >
111 using Type = OperationPair<OuterSign, F, TreeData0, TreeData1, OptimizeTag>;
114 template<
class Sign,
class... Node>
115 struct SetTreeNodeSignHelper<Sign, MPL::TypeTuple<Node...> >
117 using Type = MPL::TypeTuple<typename SetTreeNodeSignHelper<Sign, Node>::Type...>;
123 template<
class Sign,
class Node>
124 using SetTreeNodeSign =
typename SetTreeNodeSignHelper<Sign, Node>::Type;
127 struct PositiveTreeNodeHelper;
129 template<
class Sign,
class E,
class Pos>
130 struct PositiveTreeNodeHelper<TreeData<Sign, E, Pos> >
132 using Type = TreeData<PlusFunctor, E, Pos>;
135 template<
class Sign,
class F,
class TreeData0,
class TreeData1,
class OptimizeTag>
136 struct PositiveTreeNodeHelper<OperationPair<Sign, F, TreeData0, TreeData1, OptimizeTag> >
138 using Type = OperationPair<PlusFunctor, F, TreeData0, TreeData1, OptimizeTag>;
141 template<
class... Node>
142 struct PositiveTreeNodeHelper<MPL::TypeTuple<Node...> >
144 using Type = MPL::TypeTuple<typename PositiveTreeNodeHelper<Node>::Type...>;
148 using PositiveTreeNode =
typename PositiveTreeNodeHelper<Node>::Type;
151 struct NegativeTreeNodeHelper;
153 template<
class Sign,
class E,
class Pos>
154 struct NegativeTreeNodeHelper<TreeData<Sign, E, Pos> >
156 using Type = TreeData<MinusFunctor, E, Pos>;
159 template<
class Sign,
class F,
class TreeData0,
class TreeData1,
class OptimizeTag>
160 struct NegativeTreeNodeHelper<OperationPair<Sign, F, TreeData0, TreeData1, OptimizeTag> >
162 using Type = OperationPair<MinusFunctor, F, TreeData0, TreeData1, OptimizeTag>;
166 using NegativeTreeNode =
typename NegativeTreeNodeHelper<Node>::Type;
169 constexpr inline bool IsPositiveTreeNodeV = std::is_same<typename Node::Sign, PlusFunctor>::value;
172 constexpr inline bool IsSimpleTreeNodeV =
false;
174 template<
class S,
class E,
class Pos>
175 constexpr inline bool IsSimpleTreeNodeV<TreeData<S, E, Pos> > =
true;
177 template<
class S,
class F,
class TreeData0,
class TreeData1,
class OptimizeTag>
178 constexpr inline bool IsSimpleTreeNodeV<OperationPair<S, F, TreeData0, TreeData1, OptimizeTag> > =
179 IsSimpleTreeNodeV<TreeData0> && IsSimpleTreeNodeV<TreeData1>;
181 template<
class T,
class SFINAE =
void>
182 struct TreeExpressionHelper
186 using TreeExpression =
typename TreeExpressionHelper<T>::Type;
188 template<
class S,
class E,
class Pos>
189 struct TreeExpressionHelper<TreeData<S, E, Pos> >
194 template<
class S,
class F,
class TreeData0,
class TreeData1,
class OptimizeTag>
195 struct TreeExpressionHelper<
196 OperationPair<S, F, TreeData0, TreeData1, OptimizeTag>,
197 std::enable_if_t<IsSimpleTreeNodeV<TreeData0> && IsSimpleTreeNodeV<TreeData1> >
200 using Type = ExpressionType<OptimizeTag, F, TreeExpression<TreeData0>, TreeExpression<TreeData1> >;
205 template<
class TreeNode>
206 constexpr inline std::size_t ComplexityV<TreeNode, std::enable_if_t<IsSimpleTreeNodeV<TreeNode> > > =
207 ComplexityV<TreeExpression<TreeNode> >;
209 template<
class S,
class F,
class TreeData0,
class TreeData1,
class OptimizeTag>
210 constexpr inline std::size_t ComplexityV<
211 OperationPair<S, F, TreeData0, TreeData1, OptimizeTag>,
212 std::enable_if_t<!IsSimpleTreeNodeV<TreeData0> || !IsSimpleTreeNodeV<TreeData1> > > =
213 1 + ComplexityV<TreeData0> + ComplexityV<TreeData1>;
219 template<
class Arg0,
class... Arg>
220 constexpr inline std::size_t ComplexityV<MPL::TypeTuple<Arg0, Arg...> > =
221 (ComplexityV<Arg0> + ... + ComplexityV<Arg>) +
sizeof...(Arg) + 1UL - IsPositiveTreeNodeV<Arg0>;
225 template<
class TreeNode>
226 constexpr inline std::size_t ExpressionWeightV<TreeNode, std::enable_if_t<IsSimpleTreeNodeV<TreeNode> > > =
227 ExpressionWeightV<TreeExpression<TreeNode> >;
229 template<
class S,
class F,
class TreeData0,
class TreeData1,
class OptimizeTag>
230 constexpr inline std::size_t ExpressionWeightV<
231 OperationPair<S, F, TreeData0, TreeData1, OptimizeTag>,
232 std::enable_if_t<!IsSimpleTreeNodeV<TreeData0> || !IsSimpleTreeNodeV<TreeData1> > > =
233 Policy::WeightDefaultV + ExpressionWeightV<TreeData0> + ExpressionWeightV<TreeData1>;
239 template<
class Arg0,
class... Arg>
240 constexpr inline std::size_t ExpressionWeightV<MPL::TypeTuple<Arg0, Arg...> > =
241 (ExpressionWeightV<Arg0> + ... + ExpressionWeightV<Arg>) + Policy::WeightDefaultV * (
sizeof...(Arg) + 1UL - IsPositiveTreeNodeV<Arg0>);
247 template<
class F,
class E,
class Pos>
248 struct ExpressionFunctor<TreeData<F, E, Pos> >
250 using Type = Functor<E>;
253 template<
class Sign,
class Functor,
class TreeData0,
class TreeData1,
class OptimizeTag>
254 struct ExpressionFunctor<OperationPair<Sign, Functor, TreeData0, TreeData1, OptimizeTag> >
256 using Type = Functor;
Collect sign, operation and data-types of the operands for a binary operation.
Definition: operationpair.hh:25
Optimization pattern disambiguation struct.
Definition: optimizationbase.hh:42
Collect type, sign and the position in an expression of one operand.
Definition: operationpair.hh:14