diff options
Diffstat (limited to 'src/boost/libs/multiprecision/test/constexpr_arithmetric_test.hpp')
-rw-r--r-- | src/boost/libs/multiprecision/test/constexpr_arithmetric_test.hpp | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/src/boost/libs/multiprecision/test/constexpr_arithmetric_test.hpp b/src/boost/libs/multiprecision/test/constexpr_arithmetric_test.hpp new file mode 100644 index 00000000..04e2a8a5 --- /dev/null +++ b/src/boost/libs/multiprecision/test/constexpr_arithmetric_test.hpp @@ -0,0 +1,297 @@ +// (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 <boost/config.hpp> +#include <boost/multiprecision/number.hpp> +#include <limits> + +// clang-format off + +template <class T, class U> +BOOST_CXX14_CONSTEXPR T do_test_constexpr_add_subtract(T a, U b) +{ + a = +b; + if constexpr(std::numeric_limits<U>::is_signed && std::numeric_limits<T>::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<U>::is_signed && std::numeric_limits<T>::is_signed) + a -= b - -a; + a += b + a; + if constexpr(std::numeric_limits<T>::is_signed) + { + a = -a; + if constexpr(std::numeric_limits<U>::is_signed) + a -= b; + } + return a; +} + +template <class T> +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<unsigned char>(2)); + a += do_test_constexpr_add_subtract(a, static_cast<signed char>(2)); + a += do_test_constexpr_add_subtract(a, static_cast<char>(2)); + a += do_test_constexpr_add_subtract(a, static_cast<short>(2)); + a += do_test_constexpr_add_subtract(a, static_cast<unsigned short>(2)); + a += do_test_constexpr_add_subtract(a, static_cast<int>(2)); + a += do_test_constexpr_add_subtract(a, static_cast<unsigned int>(2)); + a += do_test_constexpr_add_subtract(a, static_cast<long>(2)); + a += do_test_constexpr_add_subtract(a, static_cast<unsigned long>(2)); + a += do_test_constexpr_add_subtract(a, static_cast<long long>(2)); + a += do_test_constexpr_add_subtract(a, static_cast<unsigned long long>(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<unsigned __int128>(2)); + a -= do_test_constexpr_add_subtract(a, static_cast<__int128>(2)); + a -= do_test_constexpr_add_subtract(a, static_cast<unsigned __int128>(2)); +#endif + + if constexpr (boost::multiprecision::number_category<T>::value == boost::multiprecision::number_kind_floating_point) + { + a += do_test_constexpr_add_subtract(a, static_cast<float>(2)); + a += do_test_constexpr_add_subtract(a, static_cast<double>(2)); + a += do_test_constexpr_add_subtract(a, static_cast<long double>(2)); +#ifdef BOOST_HAS_FLOAT128 + a += do_test_constexpr_add_subtract(a, static_cast<__float128>(2)); +#endif + } + + return a; +} + +template <class T, class U> +BOOST_CXX14_CONSTEXPR T do_test_constexpr_mul_divide(T a, U b) +{ + a *= b; + a = a * b; + if constexpr(std::numeric_limits<T>::is_signed && std::numeric_limits<U>::is_signed) + { + a *= -b; + a = a * -b; + } + a /= b; + a = a / b; + if constexpr(std::numeric_limits<T>::is_signed && std::numeric_limits<U>::is_signed) + { + a /= -b; + a = a / -b; + } + if constexpr (boost::multiprecision::number_category<T>::value == boost::multiprecision::number_kind_integer && boost::multiprecision::number_category<U>::value == boost::multiprecision::number_kind_integer) + { + a %= b; + a = a % b; + } + return a; +} + +template <class T> +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<unsigned char>(2)); + a += do_test_constexpr_mul_divide(a, static_cast<signed char>(2)); + a += do_test_constexpr_mul_divide(a, static_cast<char>(2)); + a += do_test_constexpr_mul_divide(a, static_cast<short>(2)); + a += do_test_constexpr_mul_divide(a, static_cast<unsigned short>(2)); + a += do_test_constexpr_mul_divide(a, static_cast<int>(2)); + a += do_test_constexpr_mul_divide(a, static_cast<unsigned int>(2)); + a += do_test_constexpr_mul_divide(a, static_cast<long>(2)); + a += do_test_constexpr_mul_divide(a, static_cast<unsigned long>(2)); + a += do_test_constexpr_mul_divide(a, static_cast<long long>(2)); + a += do_test_constexpr_mul_divide(a, static_cast<unsigned long long>(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<unsigned __int128>(2)); + a -= do_test_constexpr_mul_divide(a, static_cast<__int128>(2)); + a -= do_test_constexpr_mul_divide(a, static_cast<unsigned __int128>(2)); +#endif + + if constexpr (boost::multiprecision::number_category<T>::value == boost::multiprecision::number_kind_floating_point) + { + a += do_test_constexpr_mul_divide(a, static_cast<float>(2)); + a += do_test_constexpr_mul_divide(a, static_cast<double>(2)); + a += do_test_constexpr_mul_divide(a, static_cast<long double>(2)); +#ifdef BOOST_HAS_FLOAT128 + a += do_test_constexpr_mul_divide(a, static_cast<__float128>(2)); +#endif + } + return a; +} + +template <class T, class U> +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<T>::is_signed == false) + { + a = ~a; + a >>= std::numeric_limits<T>::digits - 3; + } + + a <<= 5; + a = a << 2; + a >>= 5; + a = a >> 2; + + return a; +} + +template <class T> +BOOST_CXX14_CONSTEXPR T test_constexpr_bitwise(T a) +{ + a += do_test_constexpr_bitwise(a, a); + a += do_test_constexpr_bitwise(a, static_cast<unsigned char>(2)); + a += do_test_constexpr_bitwise(a, static_cast<signed char>(2)); + a += do_test_constexpr_bitwise(a, static_cast<char>(2)); + a += do_test_constexpr_bitwise(a, static_cast<short>(2)); + a += do_test_constexpr_bitwise(a, static_cast<unsigned short>(2)); + a += do_test_constexpr_bitwise(a, static_cast<int>(2)); + a += do_test_constexpr_bitwise(a, static_cast<unsigned int>(2)); + a += do_test_constexpr_bitwise(a, static_cast<long>(2)); + a += do_test_constexpr_bitwise(a, static_cast<unsigned long>(2)); + a += do_test_constexpr_bitwise(a, static_cast<long long>(2)); + a += do_test_constexpr_bitwise(a, static_cast<unsigned long long>(2)); +#ifdef BOOST_HAS_INT128 + a += do_test_constexpr_bitwise(a, static_cast<__int128>(2)); + a += do_test_constexpr_bitwise(a, static_cast<unsigned __int128>(2)); +#endif + + return a; +} + +template <class T, class U> +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 <class T> +BOOST_CXX14_CONSTEXPR T test_constexpr_logical(T a) +{ + a += do_test_constexpr_logical(a, a); + a += do_test_constexpr_logical(a, static_cast<unsigned char>(2)); + a += do_test_constexpr_logical(a, static_cast<signed char>(2)); + a += do_test_constexpr_logical(a, static_cast<char>(2)); + a += do_test_constexpr_logical(a, static_cast<short>(2)); + a += do_test_constexpr_logical(a, static_cast<unsigned short>(2)); + a += do_test_constexpr_logical(a, static_cast<int>(2)); + a += do_test_constexpr_logical(a, static_cast<unsigned int>(2)); + a += do_test_constexpr_logical(a, static_cast<long>(2)); + a += do_test_constexpr_logical(a, static_cast<unsigned long>(2)); + a += do_test_constexpr_logical(a, static_cast<long long>(2)); + a += do_test_constexpr_logical(a, static_cast<unsigned long long>(2)); +#ifdef BOOST_HAS_INT128 + a += do_test_constexpr_logical(a, static_cast<__int128>(2)); + a += do_test_constexpr_logical(a, static_cast<unsigned __int128>(2)); + a -= do_test_constexpr_logical(a, static_cast<__int128>(2)); + a -= do_test_constexpr_logical(a, static_cast<unsigned __int128>(2)); +#endif + + return a; +} + +template <class T, class U> +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 <class T> +BOOST_CXX14_CONSTEXPR T test_constexpr_compare(T a) +{ + a += do_test_constexpr_compare(a, a); + a += do_test_constexpr_compare(a, static_cast<unsigned char>(2)); + a += do_test_constexpr_compare(a, static_cast<signed char>(2)); + a += do_test_constexpr_compare(a, static_cast<char>(2)); + a += do_test_constexpr_compare(a, static_cast<short>(2)); + a += do_test_constexpr_compare(a, static_cast<unsigned short>(2)); + a += do_test_constexpr_compare(a, static_cast<int>(2)); + a += do_test_constexpr_compare(a, static_cast<unsigned int>(2)); + a += do_test_constexpr_compare(a, static_cast<long>(2)); + a += do_test_constexpr_compare(a, static_cast<unsigned long>(2)); + a += do_test_constexpr_compare(a, static_cast<long long>(2)); + a += do_test_constexpr_compare(a, static_cast<unsigned long long>(2)); +#ifdef BOOST_HAS_INT128 + a += do_test_constexpr_compare(a, static_cast<__int128>(2)); + a += do_test_constexpr_compare(a, static_cast<unsigned __int128>(2)); + a -= do_test_constexpr_compare(a, static_cast<__int128>(2)); + a -= do_test_constexpr_compare(a, static_cast<unsigned __int128>(2)); +#endif + + if constexpr (boost::multiprecision::number_category<T>::value == boost::multiprecision::number_kind_floating_point) + { + a += do_test_constexpr_compare(a, static_cast<float>(2)); + a += do_test_constexpr_compare(a, static_cast<double>(2)); + a += do_test_constexpr_compare(a, static_cast<long double>(2)); +#ifdef BOOST_HAS_FLOAT128 + a += do_test_constexpr_compare(a, static_cast<__float128>(2)); +#endif + } + return a; +} + +// clang-format on |