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
12namespace 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>
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...> >
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>
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>
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>
196 {
197 return -t;
198 }
199
201 template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
203 {
204 return t;
205 }
206
208 template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
210 {
211 return t;
212 }
213
215 template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
217 {
218 return -t;
219 }
220
222 template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
224 {
225 return t;
226 }
227
229 template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
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>
238 {
239 return t;
240 }
241
243 template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
245 {
246 return t;
247 }
248
250 template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
252 {
253 return -t;
254 }
255
257 template<class I, class T, std::enable_if_t<IsFractionOperand<T>::value, int> = 0>
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:209
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, 0, 1 >)
t-=0.
Definition: constantoperations.hh:223
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:167
constexpr auto operator-(T &&t, FractionConstant< I, N, D > f)
t - fraction -> -fraction + t.
Definition: constantoperations.hh:603
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.111.3 (Jul 15, 22:36, 2024)