31static const auto zero8u = uint8_t(0);
34static const auto one8s = int8_t(1);
35static const auto one8u = uint8_t(1);
36static const auto one64s = int64_t(1);
37static const auto one64u = uint64_t(1);
51 const std::string prefix = std::is_signed<A>::value ?
"" :
"u";
52 return prefix +
"int" + std::to_string(
sizeof(
A)*8);
59 return TypeToString<A>() +
'(' + std::to_string(+a) +
')';
62template <
typename S,
typename A,
typename B>
69template <
typename S,
typename A,
typename B,
typename C>
88template <
typename S,
typename A,
typename... Args>
92 return S(a) + RawSum<S>(args...);
101 template <
typename... Args>
107 const auto ns = NaturalSum<S>(args...);
108 CPPUNIT_ASSERT_MESSAGE(SumToString<S>(args...) +
" does not overflow",
111 const auto sum =
ns.value();
112 const auto expected = RawSum<S>(args...);
113 CPPUNIT_ASSERT_MESSAGE(
127 template <
typename... Args>
133 CPPUNIT_ASSERT_MESSAGE(SumToString<S>(args...) +
" must overflow",
134 !NaturalSum<S>(args...).has_value());
139template <
typename S,
template<
typename>
class Tester,
typename A,
typename B>
143 Tester<S>::Test(a, b);
145 Tester<S>::Test(
zero8u, a, b);
146 Tester<S>::Test(
zero8s, a, b);
147 Tester<S>::Test(
zero64u, a, b);
148 Tester<S>::Test(
zero64s, a, b);
149 Tester<S>::Test(a,
zero8u, b);
150 Tester<S>::Test(a,
zero8s, b);
151 Tester<S>::Test(a,
zero64u, b);
152 Tester<S>::Test(a,
zero64s, b);
153 Tester<S>::Test(a, b,
zero8u);
154 Tester<S>::Test(a, b,
zero8s);
155 Tester<S>::Test(a, b,
zero64u);
156 Tester<S>::Test(a, b,
zero64s);
160template <
typename S,
template<
typename>
class Tester,
typename A,
typename B>
164 TestWithZeros<S, Tester>(a, b);
165 TestWithZeros<S, Tester>(b, a);
169template <
typename A,
typename B>
173 TestOrder<A, OverflowSumTester>(a, b);
174 TestOrder<B, OverflowSumTester>(a, b);
179template <
typename A,
typename B>
183 TestOrder<A, SuccessSumTester>(a, b);
184 TestOrder<B, OverflowSumTester>(a, b);
188template <
typename A,
typename... Args,
typename S =
A>
248 CPPUNIT_ASSERT_EQUAL(2,
GoodSum(1, 1));
250 CPPUNIT_ASSERT_EQUAL(6u,
GoodSum(1u, 2, 3));
258 CPPUNIT_ASSERT_EQUAL(15, NaturalSum<int>(1, 2, 3, 4, 5).value());
259 CPPUNIT_ASSERT_EQUAL(21, NaturalSum<int>(1, 2, 3, 4, 5, 6).value());
265 CPPUNIT_ASSERT_EQUAL(expires, result);
S SetToNaturalSumOrMax(S &var, const Args... args)
static void Test(Args... args)
static S Test(Args... args)
CPPUNIT_TEST_SUITE(TestMath)
CPPUNIT_TEST(testNaturalSum)
implements test program's main() function while enabling customization
int run(int argc, char *argv[])
A const & max(A const &lhs, A const &rhs)
A const & min(A const &lhs, A const &rhs)
int main(int argc, char *argv[])
static const auto zero64s
CPPUNIT_TEST_SUITE_REGISTRATION(TestMath)
static S RawSum()
ends argument recursion for RawSum() with parameters
static void TestSuccessForFirstSummationType(const A a, const B b)
static void TestWithZeros(const A a, const B b)
checks that the summation outcome is unaffected by (not) adding zeros
static const auto zero64u
static void TestOverflowForEitherSummationType(const A a, const B b)
checks that a+b and similar sums overflow for summation types A and B
static void TestOrder(const A a, const B b)
checks that the summation outcome is unaffected by the order of operands
static std::string TypeToString()
static S GoodSum(const A a, Args... args)
static std::string OperandToString(const A a)
static std::string SumToString(const A a, const B b)