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 
11 namespace Dune {
12 
13  namespace ACFem {
14 
15  namespace Expressions {
16 
18  template<class T>
19  struct TraitsOfTags
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>
184  struct ExpressionTraits<Constant<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
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.80.0 (Apr 27, 22:29, 2024)