// (C) Copyright John Maddock 2019. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include #include #include // clang-format off template BOOST_CXX14_CONSTEXPR T do_test_constexpr_add_subtract(T a, U b) { a = +b; if constexpr(std::numeric_limits::is_signed && std::numeric_limits::is_signed) b = -b; a += b; a += a; a -= b; a -= a; ++a; --a; T bb(b); a += bb++; a += bb--; a = a + b; a += a - b; if constexpr(std::numeric_limits::is_signed && std::numeric_limits::is_signed) a -= b - -a; a += b + a; if constexpr(std::numeric_limits::is_signed) { a = -a; if constexpr(std::numeric_limits::is_signed) a -= b; } return a; } template BOOST_CXX14_CONSTEXPR T test_constexpr_add_subtract(T a) { a += do_test_constexpr_add_subtract(a, a); a += do_test_constexpr_add_subtract(a, static_cast(2)); a += do_test_constexpr_add_subtract(a, static_cast(2)); a += do_test_constexpr_add_subtract(a, static_cast(2)); a += do_test_constexpr_add_subtract(a, static_cast(2)); a += do_test_constexpr_add_subtract(a, static_cast(2)); a += do_test_constexpr_add_subtract(a, static_cast(2)); a += do_test_constexpr_add_subtract(a, static_cast(2)); a += do_test_constexpr_add_subtract(a, static_cast(2)); a += do_test_constexpr_add_subtract(a, static_cast(2)); a += do_test_constexpr_add_subtract(a, static_cast(2)); a += do_test_constexpr_add_subtract(a, static_cast(2)); #ifdef BOOST_HAS_INT128 a += do_test_constexpr_add_subtract(a, static_cast<__int128>(2)); a += do_test_constexpr_add_subtract(a, static_cast(2)); a -= do_test_constexpr_add_subtract(a, static_cast<__int128>(2)); a -= do_test_constexpr_add_subtract(a, static_cast(2)); #endif if constexpr (boost::multiprecision::number_category::value == boost::multiprecision::number_kind_floating_point) { a += do_test_constexpr_add_subtract(a, static_cast(2)); a += do_test_constexpr_add_subtract(a, static_cast(2)); a += do_test_constexpr_add_subtract(a, static_cast(2)); #ifdef BOOST_HAS_FLOAT128 a += do_test_constexpr_add_subtract(a, static_cast<__float128>(2)); #endif } return a; } template BOOST_CXX14_CONSTEXPR T do_test_constexpr_mul_divide(T a, U b) { a *= b; a = a * b; if constexpr(std::numeric_limits::is_signed && std::numeric_limits::is_signed) { a *= -b; a = a * -b; } a /= b; a = a / b; if constexpr(std::numeric_limits::is_signed && std::numeric_limits::is_signed) { a /= -b; a = a / -b; } if constexpr (boost::multiprecision::number_category::value == boost::multiprecision::number_kind_integer && boost::multiprecision::number_category::value == boost::multiprecision::number_kind_integer) { a %= b; a = a % b; } return a; } template BOOST_CXX14_CONSTEXPR T test_constexpr_mul_divide(T a) { a += do_test_constexpr_mul_divide(a, a); a += do_test_constexpr_mul_divide(a, static_cast(2)); a += do_test_constexpr_mul_divide(a, static_cast(2)); a += do_test_constexpr_mul_divide(a, static_cast(2)); a += do_test_constexpr_mul_divide(a, static_cast(2)); a += do_test_constexpr_mul_divide(a, static_cast(2)); a += do_test_constexpr_mul_divide(a, static_cast(2)); a += do_test_constexpr_mul_divide(a, static_cast(2)); a += do_test_constexpr_mul_divide(a, static_cast(2)); a += do_test_constexpr_mul_divide(a, static_cast(2)); a += do_test_constexpr_mul_divide(a, static_cast(2)); a += do_test_constexpr_mul_divide(a, static_cast(2)); #ifdef BOOST_HAS_INT128 a += do_test_constexpr_mul_divide(a, static_cast<__int128>(2)); a += do_test_constexpr_mul_divide(a, static_cast(2)); a -= do_test_constexpr_mul_divide(a, static_cast<__int128>(2)); a -= do_test_constexpr_mul_divide(a, static_cast(2)); #endif if constexpr (boost::multiprecision::number_category::value == boost::multiprecision::number_kind_floating_point) { a += do_test_constexpr_mul_divide(a, static_cast(2)); a += do_test_constexpr_mul_divide(a, static_cast(2)); a += do_test_constexpr_mul_divide(a, static_cast(2)); #ifdef BOOST_HAS_FLOAT128 a += do_test_constexpr_mul_divide(a, static_cast<__float128>(2)); #endif } return a; } template BOOST_CXX14_CONSTEXPR T do_test_constexpr_bitwise(T a, U b) { a |= b; a &= b; a <<= 2; a ^= b; a = a | b; a = a & b; a <<= 2; a = a ^ b; if constexpr (std::numeric_limits::is_signed == false) { a = ~a; a >>= std::numeric_limits::digits - 3; } a <<= 5; a = a << 2; a >>= 5; a = a >> 2; return a; } template BOOST_CXX14_CONSTEXPR T test_constexpr_bitwise(T a) { a += do_test_constexpr_bitwise(a, a); a += do_test_constexpr_bitwise(a, static_cast(2)); a += do_test_constexpr_bitwise(a, static_cast(2)); a += do_test_constexpr_bitwise(a, static_cast(2)); a += do_test_constexpr_bitwise(a, static_cast(2)); a += do_test_constexpr_bitwise(a, static_cast(2)); a += do_test_constexpr_bitwise(a, static_cast(2)); a += do_test_constexpr_bitwise(a, static_cast(2)); a += do_test_constexpr_bitwise(a, static_cast(2)); a += do_test_constexpr_bitwise(a, static_cast(2)); a += do_test_constexpr_bitwise(a, static_cast(2)); a += do_test_constexpr_bitwise(a, static_cast(2)); #ifdef BOOST_HAS_INT128 a += do_test_constexpr_bitwise(a, static_cast<__int128>(2)); a += do_test_constexpr_bitwise(a, static_cast(2)); #endif return a; } template BOOST_CXX14_CONSTEXPR T do_test_constexpr_logical(T a, U b) { T result(0); if(a || b) ++result; if(b || a) ++result; if(a && b) ++result; if(b && a) ++result; if(a) ++result; if(!a) ++result; return result; } template BOOST_CXX14_CONSTEXPR T test_constexpr_logical(T a) { a += do_test_constexpr_logical(a, a); a += do_test_constexpr_logical(a, static_cast(2)); a += do_test_constexpr_logical(a, static_cast(2)); a += do_test_constexpr_logical(a, static_cast(2)); a += do_test_constexpr_logical(a, static_cast(2)); a += do_test_constexpr_logical(a, static_cast(2)); a += do_test_constexpr_logical(a, static_cast(2)); a += do_test_constexpr_logical(a, static_cast(2)); a += do_test_constexpr_logical(a, static_cast(2)); a += do_test_constexpr_logical(a, static_cast(2)); a += do_test_constexpr_logical(a, static_cast(2)); a += do_test_constexpr_logical(a, static_cast(2)); #ifdef BOOST_HAS_INT128 a += do_test_constexpr_logical(a, static_cast<__int128>(2)); a += do_test_constexpr_logical(a, static_cast(2)); a -= do_test_constexpr_logical(a, static_cast<__int128>(2)); a -= do_test_constexpr_logical(a, static_cast(2)); #endif return a; } template BOOST_CXX14_CONSTEXPR T do_test_constexpr_compare(T a, U b) { T result(0); if(a == b) ++result; if(b == a) ++result; if(a != b) ++result; if(b != a) ++result; if(a < b) ++result; if(b < a) ++result; if(a <= b) ++result; if(b <= a) ++result; if(a > b) ++result; if(b > a) ++result; if(a >= b) ++result; if(b >= a) ++result; T u(b); if(u == a) ++result; return result; } template BOOST_CXX14_CONSTEXPR T test_constexpr_compare(T a) { a += do_test_constexpr_compare(a, a); a += do_test_constexpr_compare(a, static_cast(2)); a += do_test_constexpr_compare(a, static_cast(2)); a += do_test_constexpr_compare(a, static_cast(2)); a += do_test_constexpr_compare(a, static_cast(2)); a += do_test_constexpr_compare(a, static_cast(2)); a += do_test_constexpr_compare(a, static_cast(2)); a += do_test_constexpr_compare(a, static_cast(2)); a += do_test_constexpr_compare(a, static_cast(2)); a += do_test_constexpr_compare(a, static_cast(2)); a += do_test_constexpr_compare(a, static_cast(2)); a += do_test_constexpr_compare(a, static_cast(2)); #ifdef BOOST_HAS_INT128 a += do_test_constexpr_compare(a, static_cast<__int128>(2)); a += do_test_constexpr_compare(a, static_cast(2)); a -= do_test_constexpr_compare(a, static_cast<__int128>(2)); a -= do_test_constexpr_compare(a, static_cast(2)); #endif if constexpr (boost::multiprecision::number_category::value == boost::multiprecision::number_kind_floating_point) { a += do_test_constexpr_compare(a, static_cast(2)); a += do_test_constexpr_compare(a, static_cast(2)); a += do_test_constexpr_compare(a, static_cast(2)); #ifdef BOOST_HAS_FLOAT128 a += do_test_constexpr_compare(a, static_cast<__float128>(2)); #endif } return a; } // clang-format on