5#ifndef DUNE_COMMON_TEST_ARITHMETICTESTSUITE_HH
6#define DUNE_COMMON_TEST_ARITHMETICTESTSUITE_HH
13#include <dune/common/test/testsuite.hh>
22# pragma GCC diagnostic push
23# pragma GCC diagnostic ignored "-Wbool-operation"
24# pragma GCC diagnostic ignored "-Wint-in-bool-context"
25# define GCC_WARNING_DISABLED
33# pragma clang diagnostic push
34# pragma clang diagnostic ignored "-Wbool-operation"
35# define CLANG_WARNING_DISABLED
65 static const char *
name(Integral ) {
return "Integral"; }
66 static const char *
name(Boolean ) {
return "Boolean"; }
67 static const char *
name(Signed ) {
return "Signed"; }
68 static const char *
name(Unsigned ) {
return "Unsigned"; }
69 static const char *
name(Floating ) {
return "Floating"; }
71 template<
class C,
class Then,
class Else =
void>
72 using Cond =
typename std::conditional<C::value, Then, Else>::type;
83 constexpr static auto tag(T = T{})
86 Cond<std::is_convertible<T, Arithmetic>, T,
87 Cond<std::is_floating_point<T>, Floating,
88 Cond<std::is_integral<T>,
89 Cond<std::is_same<bool, T>, Boolean,
90 Cond<std::is_signed<T>, Signed,
91 Cond<std::is_unsigned<T>, Unsigned
96#define DUNE_TEST_FUNCTION(T, tag) \
97 static const auto function = \
98 std::string(__func__) + "<" + className<T>() + ">(" + name(tag) + ")"
100#define DUNE_TEST_CHECK(expr) \
101 (check((expr), function) \
102 << __FILE__ << ":" << __LINE__ << ": Check \"" << #expr << "\"")
112 [[maybe_unused]] T t0;
114 [[maybe_unused]] T t1{};
115 [[maybe_unused]] T t2 = {};
122 DUNE_TEST_FUNCTION(T, arithmetic_tag);
125 T t0(0); DUNE_TEST_CHECK(
int(t0) == 0);
126 T t1(1); DUNE_TEST_CHECK(
int(t1) == 1);
133 DUNE_TEST_FUNCTION(T, arithmetic_tag);
134 for(
int i : { 0, 1 })
139 T t2 = std::move(t1);
140 T t3{ std::move(t2) };
141 T t4 = { std::move(t3) };
143 DUNE_TEST_CHECK(
bool(t4 == T(i)));
151 DUNE_TEST_FUNCTION(T, arithmetic_tag);
152 for(
int i : { 0, 1 })
161 DUNE_TEST_CHECK(
bool(t0 == T(i)));
162 DUNE_TEST_CHECK(
bool(t1 == T(i)));
163 DUNE_TEST_CHECK(
bool(t2 == T(i)));
164 DUNE_TEST_CHECK(
bool(t3 == T(i)));
165 DUNE_TEST_CHECK(
bool(t4 == T(i)));
173 DUNE_TEST_FUNCTION(T, arithmetic_tag);
174 for(
int i : { 0, 1 })
180 t4 = { std::move(t2) };
182 DUNE_TEST_CHECK(
bool(t4 == T(i)));
190 DUNE_TEST_FUNCTION(T, arithmetic_tag);
191 for(
int i : { 0, 1 })
199 DUNE_TEST_CHECK(
bool(t0 == T(i)));
200 DUNE_TEST_CHECK(
bool(t2 == T(i)));
201 DUNE_TEST_CHECK(
bool(t4 == T(i)));
213 DUNE_TEST_FUNCTION(T, arithmetic_tag);
217 DUNE_TEST_CHECK(
bool(t0 == T(0)));
218 DUNE_TEST_CHECK(
bool(t1 == T(1)));
220 DUNE_TEST_CHECK(!
bool(t0 == T(1)));
221 DUNE_TEST_CHECK(!
bool(t1 == T(0)));
222 DUNE_TEST_CHECK(!
bool(t0 == t1));
224 DUNE_TEST_CHECK(!
bool(t0 != T(0)));
225 DUNE_TEST_CHECK(!
bool(t1 != T(1)));
227 DUNE_TEST_CHECK(
bool(t0 != T(1)));
228 DUNE_TEST_CHECK(
bool(t1 != T(0)));
229 DUNE_TEST_CHECK(
bool(t0 != t1));
243 DUNE_TEST_FUNCTION(T, arithmetic_tag);
246 DUNE_TEST_CHECK(
bool(T(t0++) == T(0)));
247 DUNE_TEST_CHECK(
bool(t0 == T(1)));
259 DUNE_TEST_FUNCTION(T, arithmetic_tag);
262 DUNE_TEST_CHECK(
bool(T(t1--) == T(1)));
263 DUNE_TEST_CHECK(
bool(t1 == T(0)));
275 DUNE_TEST_FUNCTION(T, arithmetic_tag);
277 DUNE_TEST_CHECK(
bool(T(+T(0)) == T(0)));
278 DUNE_TEST_CHECK(
bool(T(+T(1)) == T(1)));
288 DUNE_TEST_FUNCTION(T, arithmetic_tag);
290 DUNE_TEST_CHECK(
bool(T(-T(0)) == T( 0)));
291 DUNE_TEST_CHECK(
bool(T(-T(1)) == T(-1)));
301 DUNE_TEST_FUNCTION(T, arithmetic_tag);
303 DUNE_TEST_CHECK(
bool(!T(0)));
304 DUNE_TEST_CHECK(!
bool(!T(1)));
314 DUNE_TEST_FUNCTION(T, arithmetic_tag);
316 DUNE_TEST_CHECK(
bool(T(~T(0))));
321 DUNE_TEST_FUNCTION(T, arithmetic_tag);
323 DUNE_TEST_CHECK(
bool(T(~T(0))));
324 DUNE_TEST_CHECK(
bool(T(~T(1))));
326 DUNE_TEST_CHECK(
bool(T(~T(~T(0))) == T(0)));
327 DUNE_TEST_CHECK(
bool(T(~T(~T(1))) == T(1)));
332 DUNE_TEST_FUNCTION(T, arithmetic_tag);
334 checkPrefixBitNot<T>(Integral{});
336 DUNE_TEST_CHECK(
bool(T(~T(0)) == T(-1)));
337 DUNE_TEST_CHECK(
bool(T(~T(1)) == T(-2)));
349 DUNE_TEST_FUNCTION(T, arithmetic_tag);
352 DUNE_TEST_CHECK(
bool(T(++t0) == T(1)));
353 DUNE_TEST_CHECK(
bool(t0 == T(1)));
355 DUNE_TEST_CHECK(
bool(t0 == T(0)));
367 DUNE_TEST_FUNCTION(T, arithmetic_tag);
370 DUNE_TEST_CHECK(
bool(T(--t1) == T(0)));
371 DUNE_TEST_CHECK(
bool(t1 == T(0)));
374 DUNE_TEST_CHECK(
bool(t1 == T(1)));
390 DUNE_TEST_FUNCTION(T, arithmetic_tag);
392 DUNE_TEST_CHECK(
bool(T(T(0)*T(0)) == T(0)));
393 DUNE_TEST_CHECK(
bool(T(T(1)*T(0)) == T(0)));
394 DUNE_TEST_CHECK(
bool(T(T(0)*T(1)) == T(0)));
395 DUNE_TEST_CHECK(
bool(T(T(1)*T(1)) == T(1)));
405 DUNE_TEST_FUNCTION(T, arithmetic_tag);
407 DUNE_TEST_CHECK(
bool(T(T(0)/T(1)) == T(0)));
408 DUNE_TEST_CHECK(
bool(T(T(1)/T(1)) == T(1)));
418 DUNE_TEST_FUNCTION(T, arithmetic_tag);
420 DUNE_TEST_CHECK(
bool(T(T(0)%T(1)) == T(0)));
421 DUNE_TEST_CHECK(
bool(T(T(1)%T(1)) == T(0)));
433 DUNE_TEST_FUNCTION(T, arithmetic_tag);
435 DUNE_TEST_CHECK(
bool(T(T(0)+T(0)) == T(0)));
436 DUNE_TEST_CHECK(
bool(T(T(1)+T(0)) == T(1)));
437 DUNE_TEST_CHECK(
bool(T(T(0)+T(1)) == T(1)));
438 DUNE_TEST_CHECK(
bool(T(T(1)+T(1)) == T(2)));
448 DUNE_TEST_FUNCTION(T, arithmetic_tag);
450 DUNE_TEST_CHECK(
bool(T(T(0)-T(0)) == T( 0)));
451 DUNE_TEST_CHECK(
bool(T(T(1)-T(0)) == T( 1)));
452 DUNE_TEST_CHECK(
bool(T(T(0)-T(1)) == T(-1)));
453 DUNE_TEST_CHECK(
bool(T(T(1)-T(1)) == T( 0)));
463 DUNE_TEST_FUNCTION(T, arithmetic_tag);
465 DUNE_TEST_CHECK(
bool(T(T(0)<<T(0)) == T(0)));
466 DUNE_TEST_CHECK(
bool(T(T(1)<<T(0)) == T(1)));
467 DUNE_TEST_CHECK(
bool(T(T(0)<<T(1)) == T(0)));
468 DUNE_TEST_CHECK(
bool(T(T(1)<<T(1)) == T(2)));
480 DUNE_TEST_FUNCTION(T, arithmetic_tag);
482 DUNE_TEST_CHECK(
bool(T(T(0)>>T(0)) == T(0)));
483 DUNE_TEST_CHECK(
bool(T(T(1)>>T(0)) == T(1)));
484 DUNE_TEST_CHECK(
bool(T(T(0)>>T(1)) == T(0)));
485 DUNE_TEST_CHECK(
bool(T(T(1)>>T(1)) == T(0)));
497 DUNE_TEST_FUNCTION(T, arithmetic_tag);
499 DUNE_TEST_CHECK(
bool(T(0)<T(0)) ==
false);
500 DUNE_TEST_CHECK(
bool(T(1)<T(0)) ==
false);
501 DUNE_TEST_CHECK(
bool(T(0)<T(1)) ==
true );
502 DUNE_TEST_CHECK(
bool(T(1)<T(1)) ==
false);
507 DUNE_TEST_FUNCTION(T, arithmetic_tag);
509 checkInfixLess<T>(Integral{});
511 DUNE_TEST_CHECK(
bool(T(-1)<T( 0)) ==
true);
516 DUNE_TEST_FUNCTION(T, arithmetic_tag);
518 checkInfixLess<T>(Integral{});
520 DUNE_TEST_CHECK(
bool(T(-1)<T( 0)) ==
false);
530 DUNE_TEST_FUNCTION(T, arithmetic_tag);
532 int values[] = { -1, 0, 1 };
535 DUNE_TEST_CHECK(
bool(T(i) > T(j)) ==
bool(T(j) < T(i)));
545 DUNE_TEST_FUNCTION(T, arithmetic_tag);
547 int values[] = { -1, 0, 1 };
550 DUNE_TEST_CHECK(
bool(T(i) <= T(j)) !=
bool(T(j) < T(i)));
560 DUNE_TEST_FUNCTION(T, arithmetic_tag);
562 int values[] = { -1, 0, 1 };
565 DUNE_TEST_CHECK(
bool(T(i) >= T(j)) !=
bool(T(i) < T(j)));
575 DUNE_TEST_FUNCTION(T, arithmetic_tag);
577 for(
int i = 0; i < 4; ++i)
578 for(
int j = 0; j < 4; ++j)
579 DUNE_TEST_CHECK(
bool(T(T(i) & T(j)) == T(i&j)));
584 DUNE_TEST_FUNCTION(T, arithmetic_tag);
586 for(
int i = 0; i < 2; ++i)
587 for(
int j = 0; j < 2; ++j)
588 DUNE_TEST_CHECK(
bool(T(T(i) & T(j)) == T(i&j)));
600 DUNE_TEST_FUNCTION(T, arithmetic_tag);
602 for(
int i = 0; i < 4; ++i)
603 for(
int j = 0; j < 4; ++j)
604 DUNE_TEST_CHECK(
bool(T(T(i) ^ T(j)) == T(i^j)));
609 DUNE_TEST_FUNCTION(T, arithmetic_tag);
611 for(
int i = 0; i < 2; ++i)
612 for(
int j = 0; j < 2; ++j)
615 DUNE_TEST_CHECK(
bool(T(~T(T(i) ^ T(j))) == T(~(i^j))));
627 DUNE_TEST_FUNCTION(T, arithmetic_tag);
629 for(
int i = 0; i < 4; ++i)
630 for(
int j = 0; j < 4; ++j)
631 DUNE_TEST_CHECK(
bool(T(T(i) | T(j)) == T(i|j)));
636 DUNE_TEST_FUNCTION(T, arithmetic_tag);
638 for(
int i = 0; i < 2; ++i)
639 for(
int j = 0; j < 2; ++j)
640 DUNE_TEST_CHECK(
bool(T(T(i) | T(j)) == T(i|j)));
652 DUNE_TEST_FUNCTION(T, arithmetic_tag);
654 for(
int i = 0; i < 4; ++i)
655 for(
int j = 0; j < 4; ++j)
656 DUNE_TEST_CHECK(
bool(T(i) && T(j)) == (i && j));
666 DUNE_TEST_FUNCTION(T, arithmetic_tag);
668 for(
int i = 0; i < 4; ++i)
669 for(
int j = 0; j < 4; ++j)
670 DUNE_TEST_CHECK(
bool(T(i) || T(j)) == (i || j));
677#define DUNE_TEST_PEEL(...) __VA_ARGS__
678#define DUNE_TEST_ASSIGN(OP, name, Tag, lrange, rrange) \
680 void checkAssign##name(Tag arithmetic_tag) \
682 DUNE_TEST_FUNCTION(T, arithmetic_tag); \
684 for(int i : { DUNE_TEST_PEEL lrange }) \
685 for(int j : { DUNE_TEST_PEEL rrange }) \
688 DUNE_TEST_CHECK(bool((t OP##= T(j)) == T(T(i) OP T(j)))); \
689 DUNE_TEST_CHECK(bool(t == T(T(i) OP T(j)))); \
693#define DUNE_TEST_ASSIGN_DISABLE(name, Tag) \
695 void checkAssign##name(Tag) {}
697 DUNE_TEST_ASSIGN(*, Mul, Arithmetic, (0, 1, 2, 3), (0, 1, 2, 3))
698 DUNE_TEST_ASSIGN(/, Div, Arithmetic, (0, 1, 2, 3), ( 1, 2, 4))
699 DUNE_TEST_ASSIGN(%, Rem, Arithmetic, (0, 1, 2, 3), ( 1, 2, 3))
700 DUNE_TEST_ASSIGN_DISABLE(Rem, Floating)
702 DUNE_TEST_ASSIGN(+, Plus, Arithmetic, (0, 1, 2, 3), (0, 1, 2, 3))
703 DUNE_TEST_ASSIGN(-, Minus, Arithmetic, (0, 1, 2, 3), (0, 1, 2, 3))
705 DUNE_TEST_ASSIGN(<<, LShift, Integral, (0, 1, 2, 3), (0, 1, 2, 3))
706 DUNE_TEST_ASSIGN(>>, RShift, Integral, (0, 1, 2, 3), (0, 1, 2, 3))
707 DUNE_TEST_ASSIGN(<<, LShift, Boolean, (0, 1 ), (0, 1 ))
708 DUNE_TEST_ASSIGN(>>, RShift, Boolean, (0, 1 ), (0, 1 ))
709 DUNE_TEST_ASSIGN_DISABLE(LShift, Floating)
710 DUNE_TEST_ASSIGN_DISABLE(RShift, Floating)
712 DUNE_TEST_ASSIGN(&, BitAnd, Integral, (0, 1, 2, 3), (0, 1, 2, 3))
713 DUNE_TEST_ASSIGN(^, BitXor, Integral, (0, 1, 2, 3), (0, 1, 2, 3))
714 DUNE_TEST_ASSIGN(|, BitOr, Integral, (0, 1, 2, 3), (0, 1, 2, 3))
715 DUNE_TEST_ASSIGN_DISABLE(BitAnd, Floating)
716 DUNE_TEST_ASSIGN_DISABLE(BitXor, Floating)
717 DUNE_TEST_ASSIGN_DISABLE(BitOr, Floating)
719#undef DUNE_TEST_ASSIGN_DISABLE
720#undef DUNE_TEST_ASSIGN
722#undef DUNE_TEST_FUNCTION
723#undef DUNE_TEST_CHECK
745 template<
class T,
class Tag>
746 void checkArithmetic(Tag = Tag{})
748 auto arithmetic_tag = this->tag<Tag>();
750 checkDefaultConstruct<T>(arithmetic_tag);
751 checkExplicitIntConvert<T>(arithmetic_tag);
752 checkMoveConstruct<T>(arithmetic_tag);
753 checkCopyConstruct<T>(arithmetic_tag);
754 checkMoveAssign<T>(arithmetic_tag);
755 checkCopyAssign<T>(arithmetic_tag);
756 checkEqual<T>(arithmetic_tag);
758 checkPostfixInc<T>(arithmetic_tag);
759 checkPostfixDec<T>(arithmetic_tag);
761 checkPrefixPlus<T>(arithmetic_tag);
762 checkPrefixMinus<T>(arithmetic_tag);
763 checkPrefixNot<T>(arithmetic_tag);
764 checkPrefixBitNot<T>(arithmetic_tag);
766 checkPrefixInc<T>(arithmetic_tag);
767 checkPrefixDec<T>(arithmetic_tag);
769 checkInfixMul<T>(arithmetic_tag);
770 checkInfixDiv<T>(arithmetic_tag);
771 checkInfixRem<T>(arithmetic_tag);
773 checkInfixPlus<T>(arithmetic_tag);
774 checkInfixMinus<T>(arithmetic_tag);
776 checkInfixLShift<T>(arithmetic_tag);
777 checkInfixRShift<T>(arithmetic_tag);
779 checkInfixLess<T>(arithmetic_tag);
780 checkInfixGreater<T>(arithmetic_tag);
781 checkInfixLessEqual<T>(arithmetic_tag);
782 checkInfixGreaterEqual<T>(arithmetic_tag);
784 checkInfixBitAnd<T>(arithmetic_tag);
785 checkInfixBitXor<T>(arithmetic_tag);
786 checkInfixBitOr<T>(arithmetic_tag);
788 checkInfixAnd<T>(arithmetic_tag);
789 checkInfixOr<T>(arithmetic_tag);
791 checkAssignMul<T>(arithmetic_tag);
792 checkAssignDiv<T>(arithmetic_tag);
793 checkAssignRem<T>(arithmetic_tag);
795 checkAssignPlus<T>(arithmetic_tag);
796 checkAssignMinus<T>(arithmetic_tag);
798 checkAssignLShift<T>(arithmetic_tag);
799 checkAssignRShift<T>(arithmetic_tag);
801 checkAssignBitAnd<T>(arithmetic_tag);
802 checkAssignBitXor<T>(arithmetic_tag);
803 checkAssignBitOr<T>(arithmetic_tag);
807#ifdef CLANG_WARNING_DISABLED
808# pragma clang diagnostic pop
809# undef CLANG_WARNING_DISABLED
812#ifdef GCC_WARNING_DISABLED
813# pragma GCC diagnostic pop
814# undef GCC_WARNING_DISABLED
Test suite for arithmetic types.
Definition: arithmetictestsuite.hh:45
void checkPrefixBitNot(Boolean arithmetic_tag)
check prefix ~
Definition: arithmetictestsuite.hh:312
void checkCopyAssign(Arithmetic arithmetic_tag)
check the copy assignment operator
Definition: arithmetictestsuite.hh:188
void checkPrefixPlus(Arithmetic arithmetic_tag)
check prefix +
Definition: arithmetictestsuite.hh:273
void checkInfixAnd(Arithmetic arithmetic_tag)
check infix &&
Definition: arithmetictestsuite.hh:650
void checkMoveConstruct(Arithmetic arithmetic_tag)
check the move constructor
Definition: arithmetictestsuite.hh:131
void checkInfixRShift(Arithmetic arithmetic_tag)
check infix >>
Definition: arithmetictestsuite.hh:478
void checkInfixLessEqual(Arithmetic arithmetic_tag)
check infix <=
Definition: arithmetictestsuite.hh:543
void checkInfixBitOr(Arithmetic arithmetic_tag)
check infix |
Definition: arithmetictestsuite.hh:625
void checkMoveAssign(Arithmetic arithmetic_tag)
check the move assignment operator
Definition: arithmetictestsuite.hh:171
void checkInfixGreater(Arithmetic arithmetic_tag)
check infix >
Definition: arithmetictestsuite.hh:528
void checkPrefixMinus(Arithmetic arithmetic_tag)
check prefix -
Definition: arithmetictestsuite.hh:286
void checkInfixLShift(Arithmetic arithmetic_tag)
check infix <<
Definition: arithmetictestsuite.hh:461
void checkInfixPlus(Arithmetic arithmetic_tag)
check infix +
Definition: arithmetictestsuite.hh:431
void checkPrefixInc(Arithmetic arithmetic_tag)
check postfix ++
Definition: arithmetictestsuite.hh:347
void checkInfixBitAnd(Arithmetic arithmetic_tag)
check infix &
Definition: arithmetictestsuite.hh:573
void checkPrefixDec(Arithmetic arithmetic_tag)
check postfix --
Definition: arithmetictestsuite.hh:365
void checkInfixDiv(Arithmetic arithmetic_tag)
check infix /
Definition: arithmetictestsuite.hh:403
void checkInfixBitXor(Arithmetic arithmetic_tag)
check infix ^
Definition: arithmetictestsuite.hh:598
void checkPrefixNot(Arithmetic arithmetic_tag)
check prefix !
Definition: arithmetictestsuite.hh:299
void checkInfixGreaterEqual(Arithmetic arithmetic_tag)
check infix >=
Definition: arithmetictestsuite.hh:558
void checkDefaultConstruct(Arithmetic arithmetic_tag)
check the default constructors
Definition: arithmetictestsuite.hh:110
void checkPostfixDec(Arithmetic arithmetic_tag)
check postfix --
Definition: arithmetictestsuite.hh:257
void checkExplicitIntConvert(Arithmetic arithmetic_tag)
check explicit conversion from and to int
Definition: arithmetictestsuite.hh:120
void checkEqual(Arithmetic arithmetic_tag)
check == and !=
Definition: arithmetictestsuite.hh:211
void checkInfixMinus(Arithmetic arithmetic_tag)
check infix -
Definition: arithmetictestsuite.hh:446
void checkPostfixInc(Arithmetic arithmetic_tag)
check postfix ++
Definition: arithmetictestsuite.hh:241
void checkInfixRem(Arithmetic arithmetic_tag)
check infix %
Definition: arithmetictestsuite.hh:416
void checkInfixOr(Arithmetic arithmetic_tag)
check infix ||
Definition: arithmetictestsuite.hh:664
void checkInfixMul(Arithmetic arithmetic_tag)
check infix *
Definition: arithmetictestsuite.hh:388
void checkCopyConstruct(Arithmetic arithmetic_tag)
check the copy constructor
Definition: arithmetictestsuite.hh:149
void checkInfixLess(Arithmetic arithmetic_tag)
check infix <
Definition: arithmetictestsuite.hh:495
static constexpr auto tag(T=T{})
determine arithmetic tag for the given type
Definition: arithmetictestsuite.hh:83
A Simple helper class to organize your test suite.
Definition: testsuite.hh:31
std::string name() const
Query name.
Definition: testsuite.hh:238
TestSuite(ThrowPolicy policy, std::string name="")
Create TestSuite.
Definition: testsuite.hh:45
A free function to provide the demangled class name of a given object or type as a string.
Dune namespace.
Definition: alignedallocator.hh:13
tag denoting any arithmetic type
Definition: arithmetictestsuite.hh:51
tag denoting boolean types
Definition: arithmetictestsuite.hh:55
tag denoting floating point types
Definition: arithmetictestsuite.hh:61
tag denoting integral types
Definition: arithmetictestsuite.hh:53
tag denoting signed integral types
Definition: arithmetictestsuite.hh:57
tag denoting unsigned integral types
Definition: arithmetictestsuite.hh:59