DUNE-ACFEM (unstable)

traitsdefault.hh
1#ifndef __DUNE_ACFEM_EXPRESSIONS_TRAITSDEFAULT_HH__
2#define __DUNE_ACFEM_EXPRESSIONS_TRAITSDEFAULT_HH__
3
4#include <ostream>
5
6#include "expressiontraits.hh"
7#include "signutil.hh"
8#include "storage.hh"
9#include "terminal.hh"
10
11namespace Dune {
12
13 namespace ACFem {
14
15 namespace Expressions {
16
18 template<class T>
20 {
21 using ExpressionType = std::decay_t<T>;
22
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;
26
27 static constexpr bool isZero = !isNonZero && isSemiPositive && isSemiNegative;
28 static constexpr bool isPositive = isSemiPositive && isNonZero;
29 static constexpr bool isNegative = isSemiNegative && isNonZero;
30
31 static constexpr bool isOne = std::is_base_of<OneExpression, ExpressionType>::value;
32 static constexpr bool isMinusOne = std::is_base_of<MinusOneExpression, ExpressionType>::value;
33
34 static constexpr bool isVolatile = HasTag<ExpressionType, VolatileExpression>::value;
35 static constexpr bool isTypedValue = !isVolatile && HasTag<ExpressionType, TypedValueExpression>::value;
36 static constexpr bool isConstant = isTypedValue || HasTag<ExpressionType, ConstantExpression>::value;
37 static constexpr bool isIndependent = isConstant || HasTag<ExpressionType, IndependentExpression>::value;
38
40 };
41
42 template<class Functor, class... T>
43 struct TraitsOfOperation
44 : ExpressionSignAt<0, decltype(Functor::signPropagation(typename ExpressionTraits<T>::Sign{}...))>
45 {
46 using SignOfOperation = decltype(Functor::signPropagation(typename ExpressionTraits<T>::Sign{}...));
47
48 static constexpr bool isOne = SignOfOperation::reference == 1 && SignOfOperation::isZero;
49 static constexpr bool isMinusOne = SignOfOperation::reference == -1 && SignOfOperation::isZero;
50
51 static constexpr bool isVolatile =
52 FunctorHas<IsVolatileOperation, Functor>::value || (... || ExpressionTraits<T>::isVolatile);
53
54 static constexpr bool isTypedValue =
55 !isVolatile &&
56 !FunctorHas<IsDynamicOperation, Functor>::value &&
58
59 static constexpr bool isConstant =
60 isTypedValue || (!FunctorHas<IsDynamicOperation, Functor>::value && (... && IsConstantExprArg<T>::value));
61
62 // Operations with referenced values can never be independent,
63 // unless overidden by inheriting from a tag-class.
64 static constexpr bool isIndependent =
65 isConstant || (!FunctorHas<IsDynamicOperation, Functor>::value
66 && !(... || (std::is_reference<T>::value))
68 );
69 };
70
71 namespace {
72
73 template<class T, std::size_t... I>
74 constexpr auto traitsOfOperationExpander(IndexSequence<I...>)
75 {
76 return TraitsOfOperation<Functor<T>, Operand<I, T>...>{};
77 }
78
79 }
80
81 template<class T, std::enable_if_t<IsExpression<T>::value, int> = 0>
82 constexpr auto traitsOfOperation(T&&)
83 {
84 return traitsOfOperationExpander<T>(MakeIndexSequence<Arity<T>::value>{});
85 }
86
87 template<class T>
88 struct TraitsOfOperation<T>
89 : decltype(traitsOfOperation(std::declval<T>()))
90 {};
91
92 } // Expressions::
93
98 template<class T>
100 T,
101 std::enable_if_t<(IsExpression<T>::value
102 && !IsSelfExpression<T>::value
103 && !Expressions::IsClosure<T>::value
104 )>,
105 BaseTraitsLevel>
106 {
107 using ExpressionType = T;
108
110 using TraitsOfOperation = Expressions::TraitsOfOperation<T>;
111
112 // If TraitsOfTags is false, then the tag is not there and we
113 // use the flag-value induced by the operation.
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;
117
118 static constexpr bool isZero = isSemiPositive && isSemiNegative;
119 static constexpr bool isPositive = isSemiPositive && isNonZero;
120 static constexpr bool isNegative = isSemiNegative && isNonZero;
121
122 static constexpr bool isOne = TraitsOfTags::isOne || TraitsOfOperation::isOne;
123 static constexpr bool isMinusOne = TraitsOfTags::isMinusOne || TraitsOfOperation::isMinusOne;
124
125 static constexpr bool isVolatile =
126 TraitsOfTags::isVolatile || TraitsOfOperation::isVolatile;
127
128 static constexpr bool isIndependent =
129 TraitsOfTags::isIndependent
130 ||
131 (!isVolatile && TraitsOfOperation::isIndependent);
132
133 static constexpr bool isConstant =
135 ||
136 (!isVolatile && TraitsOfOperation::isConstant);
137
138 static constexpr bool isTypedValue =
139 TraitsOfTags::isTypedValue
140 ||
141 (!isVolatile && TraitsOfOperation::isTypedValue);
142
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.");
147 static_assert(!isConstant || (isConstant && isIndependent),
148 "Constant expressions must also qualify as independet ones.");
149
151 };
152
154 template<class T>
156 T,
157 std::enable_if_t<Expressions::IsClosure<T>::value>,
158 BaseTraitsLevel>
159 : ExpressionTraits<Expressions::EnclosedType<T> >
160 {
161 using ExpressionType = T;
162 };
163
167 template<class T>
169 T,
170 std::enable_if_t<!IsExpression<T>::value || IsSelfExpression<T>::value>,
171 BaseTraitsLevel>
173 {};
174
179 template<class T>
181
183 template<class I, I V>
185 {
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; // limit!
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);
195
196 static constexpr bool isVolatile = false;
197 static constexpr bool isIndependent = true;
198 static constexpr bool isConstant = true;
199 static constexpr bool isTypedValue = true;
200
202 };
203
204 } // ACFem::
205
206} // Dune::
207
208#endif // __DUNE_ACFEM_EXPRESSIONS_TRAITSDEFAULT_HH__
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
STL namespace.
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
Deduce ExpressionTraits from tag-class overrides.
Definition: traitsdefault.hh:20
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)