DUNE-ACFEM (unstable)

constantoperations.hh
1 #ifndef __DUNE_ACFEM_EXPRESSIONS_INTCONSTOPERATIONS_HH__
2 #define __DUNE_ACFEM_EXPRESSIONS_INTCONSTOPERATIONS_HH__
3 
4 #include "../common/types.hh"
5 #include "../common/fractionconstant.hh"
6 #include "../common/namedconstant.hh"
7 #include "expressiontraits.hh"
8 #include "fieldpromotion.hh"
9 #include "storage.hh"
10 #include "weight.hh"
11 
12 namespace Dune
13 {
14  template<class I, I N, I D>
15  struct FieldTraits<ACFem::TypedValue::FractionConstant<I, N, D> >
16  : FieldTraits<ACFem::ConditionalType<D == 1, I, ACFem::FloatingPointClosure<I> > >
17  {};
18 
19  template<class T, char... Name>
20  struct FieldTraits<ACFem::TypedValue::NamedConstant<T, Name...> >
21  : FieldTraits<T>
22  {};
23 
24  namespace ACFem
25  {
26 
28  using TypedValue::FractionConstant;
29  using TypedValue::Fraction;
30  using TypedValue::IntFraction;
31  using TypedValue::intFraction;
32  using TypedValue::numerator;
33  using TypedValue::denominator;
34  using TypedValue::Sign;
35  using TypedValue::sign;
36  using TypedValue::IsSign;
37 
49  template<class I, I N, I D>
50  struct IsScalar<TypedValue::FractionConstant<I, N, D> >
51  : TrueType
52  {};
53 
55  template<class T, char... Name>
56  struct IsScalar<TypedValue::NamedConstant<T, Name...> >
57  : IsScalar<T>
58  {};
59 
61  template<class I, I N>
62  struct IsIntegral<TypedValue::FractionConstant<I, N, 1> >
63  : TrueType
64  {};
65 
69  template<class T, bool Exclusive = true>
72  && !(Exclusive && IsFractionConstant<T>::value)
73  && !IsIntegralConstant<T>::value // leave integral constants alone
74  && !IsExpression<T>::value // don't interfere with expression optimizations
75  )>;
76 
79  template<class T, std::enable_if_t<IsFractionOperand<T, false>::value, int> = 0>
80  constexpr auto zero(T&& t)
81  {
82  return IntFraction<0, 1>{};
83  }
84 
87  template<class T, std::enable_if_t<IsFractionOperand<T, false>::value, int> = 0>
88  constexpr auto one(T&& t)
89  {
90  return IntFraction<1, 1>{};
91  }
92 
94  template<class Int, Int N, Int D>
95  struct ExpressionTraits<FractionConstant<Int, N, D> >
96  {
97  protected:
98  static constexpr ssize_t nSign = (N == 0 ? 0 : (N > 0 ? 1 : -1));
99  static constexpr ssize_t dSign = (D == 0 ? 0 : (D > 0 ? 1 : -1));
100  public:
101  static constexpr bool isSemiPositive = nSign * dSign >= 0;
102  static constexpr bool isSemiNegative = nSign * dSign <= 0;
103  static constexpr bool isZero = N == 0;
104  static constexpr bool isOne = N*D == 1;
105  static constexpr bool isMinusOne = N*D == -1;
106  static constexpr bool isNonZero = !isZero;
107  static constexpr bool isNonSingular = !isZero && D != 0;
108  static constexpr bool isPositive = nSign * dSign > 0;
109  static constexpr bool isNegaive = nSign * dSign < 0;
110 
111  static constexpr bool isVolatile = false;
112  static constexpr bool isIndependent = true;
113  static constexpr bool isConstant = true;
114  static constexpr bool isTypedValue = true;
115 
117  };
118 
120  template<class T, char... Name>
121  struct ExpressionTraits<TypedValue::NamedConstant<T, Name...> >
122  : ExpressionTraits<T>
123  {
124  static constexpr bool isVolatile = false;
125  static constexpr bool isIndependent = true;
126  static constexpr bool isConstant = true;
127  static constexpr bool isTypedValue = true;
128 
129  static_assert(IsScalar<T>::value, "NamedConstant only supported for scalars.");
130 
132  };
133 
134  namespace Expressions {
135 
136  template<class T, char... Name>
137  constexpr inline std::size_t WeightV<TypedValue::NamedConstant<T, Name...> > = (0 + ... + ((std::size_t)Name));
138 
139  template<class Int, Int N, Int D>
140  constexpr inline std::size_t WeightV<FractionConstant<Int, N, D> > = 1UL;
141 
142  }
143 
145 
146  namespace TypedValue {
147 
159  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
160  constexpr auto operator*(FractionConstant<I, 0, 1>, T&& t)
161  {
162  return zero(std::forward<T>(t));
163  }
164 
166  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
167  constexpr auto& operator*=(T& t, FractionConstant<I, 0, 1>)
168  {
169  return (t = zero(t));
170  }
171 
173  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
174  constexpr auto operator*(FractionConstant<I, 1, 1>, T&& t)
175  {
176  return t;
177  }
178 
180  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
181  constexpr auto& operator*=(T& t, FractionConstant<I, 1, 1>)
182  {
183  return t;
184  }
185 
187  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
188  constexpr auto operator*(FractionConstant<I, -1, 1>, T&& t)
189  {
190  return -t;
191  }
192 
194  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
195  constexpr auto& operator*=(T& t, FractionConstant<I, -1, 1>)
196  {
197  return -t;
198  }
199 
201  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
202  constexpr auto operator+(FractionConstant<I, 0, 1>, T&& t)
203  {
204  return t;
205  }
206 
208  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
209  constexpr auto& operator+=(T& t, FractionConstant<I, 0, 1>)
210  {
211  return t;
212  }
213 
215  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
216  constexpr auto operator-(FractionConstant<I, 0, 1>, T&& t)
217  {
218  return -t;
219  }
220 
222  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
223  constexpr auto& operator-=(T& t, FractionConstant<I, 0, 1>)
224  {
225  return t;
226  }
227 
229  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
230  constexpr auto operator/(FractionConstant<I, 0, 1>, T&& t)
231  {
232  return zero(std::forward<T>(t));
233  }
234 
236  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
237  constexpr auto operator/(T&& t, FractionConstant<I, 1, 1>)
238  {
239  return t;
240  }
241 
243  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
244  constexpr auto& operator/(T& t, FractionConstant<I, 1, 1>)
245  {
246  return t;
247  }
248 
250  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
251  constexpr auto operator/(T&&t, FractionConstant<I, -1, 1>)
252  {
253  return -t;
254  }
255 
257  template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
258  constexpr auto& operator/(T& t, FractionConstant<I, -1, 1>)
259  {
260  return -t;
261  }
262 
264 
272  template<
273  class I, I N, class T,
274  std::enable_if_t<(N*N > 1
275  && IsFractionOperand<T>::value), int> = 0>
276  constexpr auto operator*(FractionConstant<I, N, 1>, T&& t)
277  {
278  return N*t;
279  }
280 
281  template<
282  class I, I N, I D, class T,
283  std::enable_if_t<(N*N > 1
284  && D == 1
285  && IsFractionOperand<T>::value), int> = 0>
286  constexpr auto& operator*=(T& t, FractionConstant<I, N, D>)
287  {
288  return t *= N;
289  }
290 
291  template<
292  class I, I N, I D, class T,
293  std::enable_if_t<(N != 0
294  && D == 1
295  && IsFractionOperand<T>::value), int> = 0>
296  constexpr auto operator+(FractionConstant<I, N, D>, T&& t)
297  {
298  return N+t;
299  }
300 
301  template<
302  class I, I N, I D, class T,
303  std::enable_if_t<(N != 0
304  && D == 1
305  && IsFractionOperand<T>::value), int> = 0>
306  constexpr auto& operator+=(T& t, FractionConstant<I, N, D>)
307  {
308  return t += N;
309  }
310 
311  template<
312  class I, I N, I D, class T,
313  std::enable_if_t<(N != 0
314  && D == 1
315  && IsFractionOperand<T>::value), int> = 0>
316  constexpr auto operator-(FractionConstant<I, N, D>, T&& t)
317  {
318  return N-t;
319  }
320 
321  template<
322  class I, I N, I D, class T,
323  std::enable_if_t<(N != 0
324  && D == 1
325  && IsFractionOperand<T>::value), int> = 0>
326  constexpr auto operator/(FractionConstant<I, N, D>, T&& t)
327  {
328  using FType = FieldPromotionType<T, I>;
329  return (FType)N / (FType)t;
330  }
331 
332  template<
333  class I, I N, I D, class T,
334  std::enable_if_t<(N != 0
335  && D == 1
336  && IsFractionOperand<T>::value), int> = 0>
337  constexpr auto& operator/=(T& t, FractionConstant<I, N, D>)
338  {
339  return t /= N;
340  }
341 
342  template<
343  class I, I N, I D, class T,
344  std::enable_if_t<(D == 1
345  && IsFractionOperand<T>::value), int> = 0>
346  constexpr bool operator==(FractionConstant<I, N, D>, T&& t)
347  {
348  return N == t;
349  }
350 
351  template<
352  class I, I N, I D, class T,
353  std::enable_if_t<(D == 1
354  && IsFractionOperand<T>::value), int> = 0>
355  constexpr bool operator!=(FractionConstant<I, N, D>, T&& t)
356  {
357  return N != t;
358  }
359 
360  template<
361  class I, I N, I D, class T,
362  std::enable_if_t<(D == 1
363  && IsFractionOperand<T>::value), int> = 0>
364  constexpr bool operator<=(FractionConstant<I, N, D>, T&& t)
365  {
366  return N <= t;
367  }
368 
369  template<
370  class I, I N, I D, class T,
371  std::enable_if_t<(D == 1
372  && IsFractionOperand<T>::value), int> = 0>
373  constexpr bool operator<(FractionConstant<I, N, D>, T&& t)
374  {
375  return N < t;
376  }
377 
378  template<
379  class I, I N, I D, class T,
380  std::enable_if_t<(D == 1
381  && IsFractionOperand<T>::value), int> = 0>
382  constexpr bool operator>=(FractionConstant<I, N, D>, T&& t)
383  {
384  return N >= t;
385  }
386 
387  template<
388  class I, I N, I D, class T,
389  std::enable_if_t<(D == 1
390  && IsFractionOperand<T>::value), int> = 0>
391  constexpr bool operator>(FractionConstant<I, N, D>, T&& t)
392  {
393  return N > t;
394  }
395 
397 
405  template<
406  class I, I N, I D, class T,
407  std::enable_if_t<(N != 0
408  && D != 1
409  && IsFractionOperand<T>::value), int> = 0>
410  constexpr auto operator*(FractionConstant<I, N, D>, T&& t)
411  {
412  using FType = FieldPromotionType<T, I>;
413  return (FType)N/(FType)D*t;
414  }
415 
416  template<
417  class I, I N, I D, class T,
418  std::enable_if_t<(N != 0
419  && D != 1
420  && IsFractionOperand<T>::value), int> = 0>
421  constexpr auto& operator*=(T& t, FractionConstant<I, N, D>)
422  {
423  using FType = FieldPromotionType<T, I>;
424  return t *= (FType)N/(FType)D;
425  }
426 
427  template<
428  class I, I N, I D, class T,
429  std::enable_if_t<(N != 0
430  && D != 1
431  && IsFractionOperand<T>::value), int> = 0>
432  constexpr auto operator+(FractionConstant<I, N, D>, T&& t)
433  {
434  using FType = FieldPromotionType<T, I>;
435  return (FType)N/(FType)D+t;
436  }
437 
438  template<
439  class I, I N, I D, class T,
440  std::enable_if_t<(N != 0
441  && D != 1
442  && IsFractionOperand<T>::value), int> = 0>
443  constexpr auto& operator+=(T& t, FractionConstant<I, N, D>)
444  {
445  using FType = FieldPromotionType<T, I>;
446  return t += (FType)N/(FType)D;
447  }
448 
449  template<
450  class I, I N, I D, class T,
451  std::enable_if_t<(N != 0
452  && D != 1
453  && IsFractionOperand<T>::value), int> = 0>
454  constexpr auto operator-(FractionConstant<I, N, D>, T&& t)
455  {
456  using FType = FieldPromotionType<T, I>;
457  return (FType)N/(FType)D-t;
458  }
459 
460  template<
461  class I, I N, I D, class T,
462  std::enable_if_t<(N != 0
463  && D != 1
464  && IsFractionOperand<T>::value), int> = 0>
465  constexpr auto& operator-(T& t, FractionConstant<I, N, D>)
466  {
467  using FType = FieldPromotionType<T, I>;
468  return t -= (FType)N/(FType)D;
469  }
470 
471  template<
472  class I, I N, I D, class T,
473  std::enable_if_t<(N != 0
474  && D != 1
475  && IsFractionOperand<T>::value), int> = 0>
476  constexpr auto operator/(FractionConstant<I, N, D>, T&& t)
477  {
478  using FType = FieldPromotionType<T, I>;
479  return (FType)N / (FType)D / (FType)t;
480  }
481 
482  template<
483  class I, I N, I D, class T,
484  std::enable_if_t<(N != 0
485  && D != 1
486  && IsFractionOperand<T>::value), int> = 0>
487  constexpr auto& operator/(T& t, FractionConstant<I, N, D>)
488  {
489  using FType = FieldPromotionType<T, I>;
490  return t /= (FType)N / (FType)D;
491  }
492 
493  template<
494  class I, I N, I D, class T,
495  std::enable_if_t<(D != 1
496  && IsFractionOperand<T>::value), int> = 0>
497  constexpr bool operator==(FractionConstant<I, N, D>, T&& t)
498  {
499  return N == D * t;
500  }
501 
502  template<
503  class I, I N, I D, class T,
504  std::enable_if_t<(D != 1
505  && IsFractionOperand<T>::value), int> = 0>
506  constexpr bool operator!=(FractionConstant<I, N, D>, T&& t)
507  {
508  return N != D * t;
509  }
510 
511  template<
512  class I, I N, I D, class T,
513  std::enable_if_t<(D != 1
514  && IsFractionOperand<T>::value), int> = 0>
515  constexpr bool operator<=(FractionConstant<I, N, D>, T&& t)
516  {
517  return N <= D * t;
518  }
519 
520  template<
521  class I, I N, I D, class T,
522  std::enable_if_t<(D != 1
523  && IsFractionOperand<T>::value), int> = 0>
524  constexpr bool operator<(FractionConstant<I, N, D>, T&& t)
525  {
526  return N < D * t;
527  }
528 
529  template<
530  class I, I N, I D, class T,
531  std::enable_if_t<(D != 1
532  && IsFractionOperand<T>::value), int> = 0>
533  constexpr bool operator>=(FractionConstant<I, N, D>, T&& t)
534  {
535  return N >= D * t;
536  }
537 
538  template<
539  class I, I N, I D, class T,
540  std::enable_if_t<(D != 1
541  && IsFractionOperand<T>::value), int> = 0>
542  constexpr bool operator>(FractionConstant<I, N, D>, T&& t)
543  {
544  return N > D * t;
545  }
546 
547  template<
548  class I, I N, I D, class T,
549  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
550  constexpr auto min(FractionConstant<I, N, D> f, T&& t)
551  {
552  using FType = FieldPromotionType<T, I>;
553  return f <= t ? (FType)f : (FType)t;
554  }
555 
556  template<
557  class I, I N, I D, class T,
558  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
559  constexpr auto max(FractionConstant<I, N, D> f, T&& t)
560  {
561  using FType = FieldPromotionType<T, I>;
562  return f >= t ? (FType)f : (FType)t;
563  }
564 
566 
573  template<
574  class I, I N, I D, class T,
575  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
576  constexpr auto operator*(T&& t, FractionConstant<I, N, D> f)
577  {
578  return f * t;
579  }
580 
582  template<
583  class I, I N, I D, class T,
584  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
585  constexpr auto operator/(T&& t, FractionConstant<I, N, D> f)
586  {
587  return Fraction<I, D, N>{} * t;
588  }
589 
591  template<
592  class I, I N, I D, class T,
593  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
594  constexpr auto operator+(T&& t, FractionConstant<I, N, D> f)
595  {
596  return f + t;
597  }
598 
600  template<
601  class I, I N, I D, class T,
602  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
603  constexpr auto operator-(T&& t, FractionConstant<I, N, D> f)
604  {
605  return -f + t;
606  }
607 
609  template<
610  class I, I N, I D, class T,
611  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
612  constexpr bool operator==(T&& t, FractionConstant<I, N, D> f)
613  {
614  return f == t;
615  }
616 
618  template<
619  class I, I N, I D, class T,
620  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
621  constexpr bool operator!=(T&& t, FractionConstant<I, N, D> f)
622  {
623  return f != t;
624  }
625 
627  template<
628  class I, I N, I D, class T,
629  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
630  constexpr bool operator<=(T&& t, FractionConstant<I, N, D> f)
631  {
632  return f >= t;
633  }
634 
636  template<
637  class I, I N, I D, class T,
638  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
639  constexpr bool operator<(T&& t, FractionConstant<I, N, D> f)
640  {
641  return f > t;
642  }
643 
645  template<
646  class I, I N, I D, class T,
647  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
648  constexpr bool operator>=(T&& t, FractionConstant<I, N, D> f)
649  {
650  return f <= t;
651  }
652 
654  template<
655  class I, I N, I D, class T,
656  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
657  constexpr bool operator>(T&& t, FractionConstant<I, N, D> f)
658  {
659  return f < t;
660  }
661 
663  template<
664  class I, I N, I D, class T,
665  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
666  constexpr auto min(T&& t, FractionConstant<I, N, D> f)
667  {
668  return min(f, t);
669  }
670 
672  template<
673  class I, I N, I D, class T,
674  std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
675  constexpr auto max(T&& t, FractionConstant<I, N, D> f)
676  {
677  return max(f, t);
678  }
679 
681 
683 
685 
686  } // NS TypedValue
687 
688  } // NS ACFem
689 
690 } // NS Dune
691 
692 #endif // __DUNE_ACFEM_EXPRESSIONS_INTCONSTOPERATIONS_HH__
Field promotion stuff.
constexpr auto & operator*=(T &t, FractionConstant< I, 0, 1 >)
t*=0
Definition: constantoperations.hh:167
constexpr auto operator/(T &&t, FractionConstant< I, N, D > f)
t / fraction -> (1/fraction) * t.
Definition: constantoperations.hh:585
constexpr auto operator+(T &&t, FractionConstant< I, N, D > f)
t + fraction -> fraction + t.
Definition: constantoperations.hh:594
constexpr auto & operator+=(T &t, FractionConstant< I, 0, 1 >)
t+=0.
Definition: constantoperations.hh:209
constexpr auto operator-(T &&t, FractionConstant< I, N, D > f)
t - fraction -> -fraction + t.
Definition: constantoperations.hh:603
constexpr auto & operator-=(T &t, FractionConstant< I, 0, 1 >)
t-=0.
Definition: constantoperations.hh:223
constexpr std::size_t WeightV
Provide an overridable weight for expressions which defaults to their depth.
Definition: weight.hh:14
constexpr auto one(T &&t)
Use the one fraction as canonical zero element for scalars.
Definition: constantoperations.hh:88
BoolConstant<(IsScalar< T >::value &&!(Exclusive &&IsFractionConstant< T >::value) &&!IsIntegralConstant< T >::value &&!IsExpression< T >::value)> IsFractionOperand
Allow scalars to mate with FractionConstants, but do not interfere with std::integral_constant and ex...
Definition: constantoperations.hh:75
constexpr auto zero(T &&t)
Use the zero fraction as canonical zero element for scalars.
Definition: constantoperations.hh:80
auto toString(Sequence< T, I0 >)
Generate a compact string representation as a comma separated list of the values, without spaces.
Definition: tostring.hh:28
constexpr bool isConstant(Sequence< T, T0, Ts... >)
Definition: compare.hh:285
Constant< bool, V > BoolConstant
Short-cut for integral constant of type bool.
Definition: types.hh:48
BoolConstant< true > TrueType
Alias for std::true_type.
Definition: types.hh:107
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
FalseType by default.
Definition: types.hh:313
TrueType if I is an integral type.
Definition: typetraits.hh:29
std::true_type if F is an "elementary" scalar.
Definition: typetraits.hh:35
A class implementing compile-time constant fractions of integers.
Definition: fractionconstant.hh:27
Definition: fractionconstant.hh:75
A named constant wraps a constant of the given type T tagging it with the given character sequence.
Definition: namedconstant.hh:21
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 27, 22:29, 2024)