diff --git a/include/boost/multiprecision/cpp_double_float.hpp b/include/boost/multiprecision/cpp_double_float.hpp index 8d41fd27..2641dc93 100644 --- a/include/boost/multiprecision/cpp_double_float.hpp +++ b/include/boost/multiprecision/cpp_double_float.hpp @@ -41,6 +41,24 @@ struct number_category> namespace backends { +namespace detail { +template struct is_arithmetic_or_float128 { +static constexpr bool value = std::is_arithmetic::value == true +#ifdef BOOST_MATH_USE_FLOAT128 + || std::is_same::type, boost::multiprecision::float128>::value == true +#endif + ; +}; + +template struct is_floating_point_or_float128 { +static constexpr bool value = std::is_floating_point::value == true +#ifdef BOOST_MATH_USE_FLOAT128 + || std::is_same::type, boost::multiprecision::float128>::value == true +#endif + ; +}; +} + /* * A cpp_double_float is represented by an unevaluated sum of two floating-point * units (say a0 and a1) which satisfy |a1| <= (1 / 2) * ulp(a0) @@ -64,8 +82,8 @@ class cpp_double_float // Constructors from other floating-point types template ::value == true) - && (std::numeric_limits::digits <= std::numeric_limits::digits))>::type const* = nullptr> + typename std::enable_if< (detail::is_floating_point_or_float128::value == true) + && (std::numeric_limits::digits <= std::numeric_limits::digits)>::type const* = nullptr> constexpr cpp_double_float(const FloatType& f) : data(std::make_pair(f, (float_type)0)) {} template (data.first) + static_cast(data.second); } +#endif // Methods constexpr cpp_double_float negative() const { return cpp_double_float(-data.first, -data.second); } @@ -593,7 +614,7 @@ cpp_double_float::operator--(int) // operator> template -inline constexpr typename std::enable_if::value, bool>::type +inline constexpr typename std::enable_if::value, bool>::type operator>(const cpp_double_float& a, const ComparisionType& b) { using first_type = typename std::remove_reference::type; @@ -624,7 +645,7 @@ operator>(const cpp_double_float& a, const cpp_double_float -inline constexpr typename std::enable_if::value, bool>::type +inline constexpr typename std::enable_if::value, bool>::type operator>(const ComparisionType& a, const cpp_double_float& b) { return b < a; @@ -632,7 +653,7 @@ operator>(const ComparisionType& a, const cpp_double_float& b // operator< template -inline constexpr typename std::enable_if::value, bool>::type +inline constexpr typename std::enable_if::value, bool>::type operator<(const cpp_double_float& a, const ComparisionType& b) { using first_type = typename std::remove_reference::type; @@ -663,7 +684,7 @@ operator<(const cpp_double_float& a, const cpp_double_float -inline constexpr typename std::enable_if::value, bool>::type +inline constexpr typename std::enable_if::value, bool>::type operator<(const ComparisionType& a, const cpp_double_float& b) { return b > a; @@ -671,7 +692,7 @@ operator<(const ComparisionType& a, const cpp_double_float& b // operator>= template -inline constexpr typename std::enable_if::value, bool>::type +inline constexpr typename std::enable_if::value, bool>::type operator>=(const cpp_double_float& a, const ComparisionType& b) { using first_type = typename std::remove_reference::type; @@ -702,7 +723,7 @@ operator>=(const cpp_double_float& a, const cpp_double_float< } template -inline constexpr typename std::enable_if::value, bool>::type +inline constexpr typename std::enable_if::value, bool>::type operator>=(const ComparisionType& a, const cpp_double_float& b) { return b <= a; @@ -710,7 +731,7 @@ operator>=(const ComparisionType& a, const cpp_double_float& // operator <= template -inline constexpr typename std::enable_if::value, bool>::type +inline constexpr typename std::enable_if::value, bool>::type operator<=(const cpp_double_float& a, const ComparisionType& b) { using first_type = typename std::remove_reference::type; @@ -741,7 +762,7 @@ operator<=(const cpp_double_float& a, const cpp_double_float< } template -inline constexpr typename std::enable_if::value, bool>::type +inline constexpr typename std::enable_if::value, bool>::type operator<=(const ComparisionType& a, const cpp_double_float& b) { return b >= a; @@ -749,7 +770,7 @@ operator<=(const ComparisionType& a, const cpp_double_float& // operator == template -inline constexpr typename std::enable_if::value, bool>::type +inline constexpr typename std::enable_if::value, bool>::type operator==(const cpp_double_float& a, const ComparisionType& b) { using first_type = typename std::remove_reference::type; @@ -780,7 +801,7 @@ operator==(const cpp_double_float& a, const cpp_double_float< } template -inline constexpr typename std::enable_if::value, bool>::type +inline constexpr typename std::enable_if::value, bool>::type operator==(const ComparisionType& a, const cpp_double_float& b) { return b == a; @@ -788,7 +809,7 @@ operator==(const ComparisionType& a, const cpp_double_float& // operator != template -inline constexpr typename std::enable_if::value, bool>::type +inline constexpr typename std::enable_if::value, bool>::type operator!=(const cpp_double_float& a, const ComparisionType& b) { using first_type = typename std::remove_reference::type; @@ -819,7 +840,7 @@ operator!=(const cpp_double_float& a, const cpp_double_float< } template -inline constexpr typename std::enable_if::value, bool>::type +inline constexpr typename std::enable_if::value, bool>::type operator!=(const ComparisionType& a, const cpp_double_float& b) { return b != a; diff --git a/test/test_cpp_double_float_arithmetic.cpp b/test/test_cpp_double_float_arithmetic.cpp index 66a38420..d27aa47c 100644 --- a/test/test_cpp_double_float_arithmetic.cpp +++ b/test/test_cpp_double_float_arithmetic.cpp @@ -22,22 +22,19 @@ #include #include -#include -#include -#include +#include #ifdef BOOST_MATH_USE_FLOAT128 #include #endif +#include +#include +#include #include namespace test_arithmetic_cpp_double_float { template ::value == true -#ifdef BOOST_MATH_USE_FLOAT128 - ||std::is_same::value == true -#endif - ), bool>::type = true> + typename std::enable_if<( boost::multiprecision::backends::detail::is_floating_point_or_float128::value == true), bool>::type = true> FloatingPointType uniform_real() { using distribution_type = boost::random::uniform_real_distribution; @@ -62,11 +59,7 @@ int rand_in_range(int a, int b) } template ::value == true -#ifdef BOOST_MATH_USE_FLOAT128 - ||std::is_same::value == true -#endif - ), bool>::type = true> + typename std::enable_if<( boost::multiprecision::backends::detail::is_floating_point_or_float128::value == true), bool>::type = true> FloatingPointType uniform_rand() { return uniform_real(); @@ -81,11 +74,7 @@ boost::multiprecision::backends::cpp_double_float -typename std::enable_if<( std::is_floating_point::value == true -#ifdef BOOST_MATH_USE_FLOAT128 - ||std::is_same::value == true -#endif - ), FloatingPointType>::type +typename std::enable_if<( boost::multiprecision::backends::detail::is_floating_point_or_float128::value == true), FloatingPointType>::type log_rand() { if (uniform_real() < (1. / 100.)) diff --git a/test/test_cpp_double_float_comparision.cpp b/test/test_cpp_double_float_comparision.cpp index ed263da7..7952ce24 100644 --- a/test/test_cpp_double_float_comparision.cpp +++ b/test/test_cpp_double_float_comparision.cpp @@ -11,12 +11,12 @@ // so please run test_cpp_double_float_constructors.cpp before this #include -#include - -#include +#include #ifdef BOOST_MATH_USE_FLOAT128 #include #endif +#include +#include #include #include #include @@ -25,18 +25,8 @@ #include namespace test_cpp_double_comparision { -// FIXME: this looks like a duplicate from test_cpp_double_float_comparision.cpp file. -template struct is_floating_point { -static const bool value; -}; -template const bool is_floating_point::value = std::is_floating_point::value -#ifdef BOOST_MATH_USE_FLOAT128 -or std::is_same::value -#endif -; - template ::value, bool>::type = true> + typename std::enable_if::value, bool>::type = true> FloatingPointType uniform_real() { //static std::random_device rd; @@ -47,7 +37,7 @@ FloatingPointType uniform_real() } template ::value && !is_floating_point::value, bool>::type = true> + typename std::enable_if::value && !boost::multiprecision::backends::detail::is_floating_point_or_float128::value, bool>::type = true> NumericType uniform_integral_number() { NumericType out = 0; @@ -64,14 +54,14 @@ int rand_in_range(int a, int b) } template ::value && !is_floating_point::value, bool>::type = true> + typename std::enable_if::value && !boost::multiprecision::backends::detail::is_floating_point_or_float128::value, bool>::type = true> NumericType uniform_rand() { return uniform_integral_number(); } template ::value, bool>::type = true> + typename std::enable_if::value, bool>::type = true> FloatingPointType uniform_rand() { return uniform_real(); @@ -91,12 +81,13 @@ NumericType log_rand() return uniform_integral_number() >> int(uniform_real() * float(std::numeric_limits::digits+1)); } -template ::value>::type const* = nullptr> +template ::value>::type const* = nullptr> FloatingPointType log_rand() { if (uniform_real() < (1. / 100.)) return 0; // throw in a few zeroes - return std::ldexp(uniform_real(), rand_in_range(std::numeric_limits::min_exponent, std::numeric_limits::max_exponent)); + using std::ldexp; + return ldexp(uniform_real(), rand_in_range(std::numeric_limits::min_exponent, std::numeric_limits::max_exponent)); } template @@ -111,7 +102,11 @@ template int test() { using double_float_t = boost::multiprecision::backends::cpp_double_float; - using largest_type = boost::multiprecision::backends::cpp_double_float; +#ifdef BOOST_MATH_USE_FLOAT128 + using largest_type = boost::multiprecision::backends::cpp_double_float; +#else + using largest_type = boost::multiprecision::backends::cpp_double_float; +#endif std::string type_name = typeid(ComparisionType).name(); size_t idx; @@ -370,15 +365,13 @@ int test_comparison() { e += test_cpp_double_comparision::test(); e += test_cpp_double_comparision::test(); #ifdef BOOST_MATH_USE_FLOAT128 -// FIXME: -// e += test_cpp_double_comparision::test(); + e += test_cpp_double_comparision::test(); #endif e += test_cpp_double_comparision::test >(); e += test_cpp_double_comparision::test >(); e += test_cpp_double_comparision::test >(); #ifdef BOOST_MATH_USE_FLOAT128 -// FIXME: -// e += test_cpp_double_comparision::test >(); + e += test_cpp_double_comparision::test >(); #endif std::cout << std::endl; return e; @@ -391,8 +384,7 @@ int main() e += test_comparison(); e += test_comparison(); #ifdef BOOST_MATH_USE_FLOAT128 -// FIXME: -// e += test_comparison(); + e += test_comparison(); #endif std::cout << (e == 0 ? "PASSED all tests" : "FAILED some test(s)") << std::endl; diff --git a/test/test_cpp_double_float_constructors.cpp b/test/test_cpp_double_float_constructors.cpp index b1746142..4b37bff9 100644 --- a/test/test_cpp_double_float_constructors.cpp +++ b/test/test_cpp_double_float_constructors.cpp @@ -12,13 +12,13 @@ // g++ -O3 -Wall -march=native -std=c++11 -I/mnt/c/MyGitRepos/BoostGSoC21_multiprecision/include -I/mnt/c/boost/boost_1_76_0 test.cpp -o test_double_float.exe #include -#include - -#include +#include #ifdef BOOST_MATH_USE_FLOAT128 #include #endif +#include #include +#include #include #include #include @@ -36,17 +36,8 @@ constexpr T max(T a, T b) } -// FIXME: this looks like a duplicate from test_cpp_double_float_comparision.cpp file. -template struct is_floating_point { - static constexpr bool value = std::is_floating_point::value -#ifdef BOOST_MATH_USE_FLOAT128 - or std::is_same::value -#endif - ; -}; - template ::value, bool>::type = true> + typename std::enable_if::value, bool>::type = true> FloatingPointType uniform_real() { static std::random_device rd; @@ -77,7 +68,7 @@ NumericType get_rand() } template ::value, bool>::type = true> + typename std::enable_if::value, bool>::type = true> FloatingPointType get_rand() { return uniform_real(); @@ -90,15 +81,17 @@ boost::multiprecision::backends::cpp_double_float(uniform_real()) * boost::multiprecision::backends::cpp_double_float(uniform_real()); } -template ::value>::type const* = nullptr> +template ::value || boost::multiprecision::backends::detail::is_floating_point_or_float128::value>::type const* = nullptr> ConstructionType construct_from(ArithmeticType f) { return ConstructionType(f); } -template ::value>::type const* = nullptr> +template ::value || boost::multiprecision::backends::detail::is_floating_point_or_float128::value)>::type const* = nullptr> ConstructionType construct_from(DoubleFloatType f) { + static_assert(std::is_same< boost::multiprecision::backends::cpp_double_float + , typename std::decay::type>::value, "Only double float should come here"); return ConstructionType(f.first()) + ConstructionType(f.second()); } @@ -172,15 +165,13 @@ int test_constructors() e += test_constructor(); e += test_constructor(); #ifdef BOOST_MATH_USE_FLOAT128 -// FIXME: -// e += test_constructor(); + e += test_constructor(); #endif e += test_constructor>(); e += test_constructor>(); e += test_constructor>(); #ifdef BOOST_MATH_USE_FLOAT128 -// FIXME: -// e += test_constructor>(); + e += test_constructor>(); #endif if (e == 0) @@ -203,8 +194,7 @@ int main() e += test_cpp_double_constructors::test_constructors(); e += test_cpp_double_constructors::test_constructors(); #ifdef BOOST_MATH_USE_FLOAT128 -// FIXME: -// e += test_cpp_double_constructors::test_constructors(); + e += test_cpp_double_constructors::test_constructors(); #endif return e; diff --git a/test/test_cpp_double_float_decomposition.cpp b/test/test_cpp_double_float_decomposition.cpp index 014cd5dd..516106c1 100644 --- a/test/test_cpp_double_float_decomposition.cpp +++ b/test/test_cpp_double_float_decomposition.cpp @@ -10,12 +10,13 @@ #include -#include -#include -#include +#include #ifdef BOOST_MATH_USE_FLOAT128 #include #endif +#include +#include +#include #include #include #include diff --git a/test/test_cpp_double_float_io.cpp b/test/test_cpp_double_float_io.cpp index 0e1272ba..0a3cc862 100644 --- a/test/test_cpp_double_float_io.cpp +++ b/test/test_cpp_double_float_io.cpp @@ -11,10 +11,11 @@ #include -#include +#include #ifdef BOOST_MATH_USE_FLOAT128 #include #endif +#include #include #include #include @@ -22,18 +23,8 @@ namespace test_cpp_double_float_io { -// FIXME: this looks like a duplicate from test_cpp_double_float_comparision.cpp file. -template struct is_floating_point { -static const bool value; -}; -template const bool is_floating_point::value = std::is_floating_point::value -#ifdef BOOST_MATH_USE_FLOAT128 -or std::is_same::value -#endif -; - template ::value, bool>::type = true> + typename std::enable_if::value, bool>::type = true> FloatingPointType uniform_real() { //static std::random_device rd; @@ -55,7 +46,7 @@ int rand_in_range(int a, int b) return a + int(float(b - a) * uniform_real()); } -template ::value>::type const* = nullptr> +template ::value>::type const* = nullptr> FloatingPointType log_rand() { if (uniform_real() < (1. / 100.)) diff --git a/test/test_cpp_double_float_io_manual.cpp b/test/test_cpp_double_float_io_manual.cpp index 2f871b59..9e2cc20d 100644 --- a/test/test_cpp_double_float_io_manual.cpp +++ b/test/test_cpp_double_float_io_manual.cpp @@ -10,10 +10,11 @@ // Note that the I/O of cpp_double_float<> is currently extremely underdeveloped #include -#include +#include #ifdef BOOST_MATH_USE_FLOAT128 #include #endif +#include #include #include