1 #ifndef __DUNE_ACFEM_EXPRESSIONS_TRAITSDEFAULT_HH__
2 #define __DUNE_ACFEM_EXPRESSIONS_TRAITSDEFAULT_HH__
6 #include "expressiontraits.hh"
15 namespace Expressions {
21 using ExpressionType = std::decay_t<T>;
23 static constexpr
bool isNonZero = std::is_base_of<NonZeroExpression, ExpressionType>::value;
24 static constexpr
bool isSemiPositive = std::is_base_of<SemiPositiveExpression, ExpressionType>::value;
25 static constexpr
bool isSemiNegative = std::is_base_of<SemiNegativeExpression, ExpressionType>::value;
27 static constexpr
bool isZero = !isNonZero && isSemiPositive && isSemiNegative;
28 static constexpr
bool isPositive = isSemiPositive && isNonZero;
29 static constexpr
bool isNegative = isSemiNegative && isNonZero;
31 static constexpr
bool isOne = std::is_base_of<OneExpression, ExpressionType>::value;
32 static constexpr
bool isMinusOne = std::is_base_of<MinusOneExpression, ExpressionType>::value;
42 template<
class Functor,
class... T>
43 struct TraitsOfOperation
44 : ExpressionSignAt<0, decltype(Functor::signPropagation(typename ExpressionTraits<T>::Sign{}...))>
48 static constexpr
bool isOne = SignOfOperation::reference == 1 && SignOfOperation::isZero;
49 static constexpr
bool isMinusOne = SignOfOperation::reference == -1 && SignOfOperation::isZero;
51 static constexpr
bool isVolatile =
54 static constexpr
bool isTypedValue =
56 !FunctorHas<IsDynamicOperation, Functor>::value &&
60 isTypedValue || (!FunctorHas<IsDynamicOperation, Functor>::value && (... && IsConstantExprArg<T>::value));
64 static constexpr
bool isIndependent =
65 isConstant || (!FunctorHas<IsDynamicOperation, Functor>::value
66 && !(... || (std::is_reference<T>::value))
73 template<
class T, std::size_t... I>
74 constexpr
auto traitsOfOperationExpander(IndexSequence<I...>)
76 return TraitsOfOperation<Functor<T>, Operand<I, T>...>{};
81 template<class T, std::enable_if_t<IsExpression<T>::value,
int> = 0>
82 constexpr
auto traitsOfOperation(T&&)
88 struct TraitsOfOperation<T>
89 : decltype(traitsOfOperation(std::declval<T>()))
101 std::enable_if_t<(IsExpression<T>::value
102 && !IsSelfExpression<T>::value
103 && !Expressions::IsClosure<T>::value
107 using ExpressionType = T;
110 using TraitsOfOperation = Expressions::TraitsOfOperation<T>;
114 static constexpr
bool isNonZero = TraitsOfTags::isNonZero || TraitsOfOperation::isNonZero;
115 static constexpr
bool isSemiPositive = TraitsOfTags::isSemiPositive || TraitsOfOperation::isSemiPositive;
116 static constexpr
bool isSemiNegative = TraitsOfTags::isSemiNegative || TraitsOfOperation::isSemiNegative;
118 static constexpr
bool isZero = isSemiPositive && isSemiNegative;
119 static constexpr
bool isPositive = isSemiPositive && isNonZero;
120 static constexpr
bool isNegative = isSemiNegative && isNonZero;
122 static constexpr
bool isOne = TraitsOfTags::isOne || TraitsOfOperation::isOne;
123 static constexpr
bool isMinusOne = TraitsOfTags::isMinusOne || TraitsOfOperation::isMinusOne;
125 static constexpr
bool isVolatile =
126 TraitsOfTags::isVolatile || TraitsOfOperation::isVolatile;
128 static constexpr
bool isIndependent =
129 TraitsOfTags::isIndependent
131 (!isVolatile && TraitsOfOperation::isIndependent);
138 static constexpr
bool isTypedValue =
139 TraitsOfTags::isTypedValue
141 (!isVolatile && TraitsOfOperation::isTypedValue);
143 static_assert(!isVolatile || (isVolatile && !isIndependent && !
isConstant && !isTypedValue),
144 "Volatile expression cannot be non-volatile.");
145 static_assert(!isTypedValue || (isTypedValue &&
isConstant && isIndependent),
146 "TypedValue expressions must also qualify as constant and independent.");
148 "Constant expressions must also qualify as independet ones.");
157 std::enable_if_t<Expressions::IsClosure<T>::value>,
161 using ExpressionType = T;
170 std::enable_if_t<!IsExpression<T>::value || IsSelfExpression<T>::value>,
183 template<
class I, I V>
186 static constexpr
bool isNonZero = V != 0;
187 static constexpr
bool isNonSingular = V != 0;
188 static constexpr
bool isZero = V == 0;
189 static constexpr
bool isOne = V == 1;
190 static constexpr
bool isMinusOne = V == -1;
191 static constexpr
bool isSemiPositive = !std::numeric_limits<I>::is_signed || V >= 0;
192 static constexpr
bool isSemiNegative = (std::numeric_limits<I>::is_signed && V <= 0) || V == 0;
193 static constexpr
bool isPostive = V > 0;
194 static constexpr
bool isNegative = (std::numeric_limits<I>::is_signed && V < 0);
196 static constexpr
bool isVolatile =
false;
197 static constexpr
bool isIndependent =
true;
199 static constexpr
bool isTypedValue =
true;
std::is_base_of< Tag, std::decay_t< A > > HasTag
Evaluate to std::true_type if std::decay_t<A> is derived from Tag, otherwise to std::false_type.
Definition: tags.hh:176
MakeSequence< std::size_t, N, Offset, Stride, Repeat > MakeIndexSequence
Make a sequence of std::size_t elements.
Definition: generators.hh:34
constexpr bool isConstant(Sequence< T, T0, Ts... >)
Definition: compare.hh:285
integral_constant< T, V > Constant
Short-cut for any integral constant.
Definition: types.hh:40
Default expression traits definition is a recursion in order to ease disambiguation.
Definition: expressiontraits.hh:54
A class mainting the sign of an expression during operations.
Definition: sign.hh:30