From a7f4ff459c154d083193ccd52e0c9b3e6150cac6 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 6 Nov 2025 10:06:51 +0100 Subject: [PATCH 1/6] Make all numeric limits specializations only a class --- include/boost/decimal/decimal128_t.hpp | 18 ++++++------ include/boost/decimal/decimal32_t.hpp | 16 ++++++----- include/boost/decimal/decimal64_t.hpp | 18 ++++++------ include/boost/decimal/decimal_fast128_t.hpp | 20 +++++++------ include/boost/decimal/decimal_fast32_t.hpp | 18 ++++++------ include/boost/decimal/decimal_fast64_t.hpp | 17 ++++++----- include/boost/decimal/fwd.hpp | 31 ++++++-------------- modules/decimal.cxx | 32 +++------------------ 8 files changed, 72 insertions(+), 98 deletions(-) diff --git a/include/boost/decimal/decimal128_t.hpp b/include/boost/decimal/decimal128_t.hpp index 81aa6e4b2..3ce71f50b 100644 --- a/include/boost/decimal/decimal128_t.hpp +++ b/include/boost/decimal/decimal128_t.hpp @@ -2233,17 +2233,15 @@ constexpr auto scalbnd128(decimal128_t num, const int expval) noexcept -> decima namespace std { +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + template<> -#ifdef _MSC_VER class numeric_limits -#else -struct numeric_limits -#endif { - -#ifdef _MSC_VER - public: -#endif +public: static constexpr bool is_specialized = true; static constexpr bool is_signed = true; @@ -2286,6 +2284,10 @@ struct numeric_limits static constexpr auto denorm_min () -> boost::decimal::decimal128_t { return {1, boost::decimal::detail::etiny_v}; } }; +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + } //namespace std #include diff --git a/include/boost/decimal/decimal32_t.hpp b/include/boost/decimal/decimal32_t.hpp index 9455b0e81..7219f2ed7 100644 --- a/include/boost/decimal/decimal32_t.hpp +++ b/include/boost/decimal/decimal32_t.hpp @@ -2302,17 +2302,15 @@ constexpr auto copysignd32(decimal32_t mag, const decimal32_t sgn) noexcept -> d namespace std { +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + template <> -#ifdef _MSC_VER class numeric_limits -#else -struct numeric_limits -#endif { - -#ifdef _MSC_VER public: -#endif static constexpr bool is_specialized = true; static constexpr bool is_signed = true; @@ -2355,6 +2353,10 @@ struct numeric_limits static constexpr auto denorm_min () -> boost::decimal::decimal32_t { return {1, boost::decimal::detail::etiny}; } }; +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + } // Namespace std #include diff --git a/include/boost/decimal/decimal64_t.hpp b/include/boost/decimal/decimal64_t.hpp index d287234e5..2de3c128a 100644 --- a/include/boost/decimal/decimal64_t.hpp +++ b/include/boost/decimal/decimal64_t.hpp @@ -2197,17 +2197,15 @@ constexpr auto copysignd64(decimal64_t mag, const decimal64_t sgn) noexcept -> d namespace std { +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + template <> -#ifdef _MSC_VER class numeric_limits -#else -struct numeric_limits -#endif { - -#ifdef _MSC_VER - public: -#endif +public: static constexpr bool is_specialized = true; static constexpr bool is_signed = true; @@ -2250,6 +2248,10 @@ struct numeric_limits static constexpr auto denorm_min () -> boost::decimal::decimal64_t { return {1, boost::decimal::detail::etiny_v}; } }; +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + } // Namespace std #include diff --git a/include/boost/decimal/decimal_fast128_t.hpp b/include/boost/decimal/decimal_fast128_t.hpp index ecd94ea54..20336b4c5 100644 --- a/include/boost/decimal/decimal_fast128_t.hpp +++ b/include/boost/decimal/decimal_fast128_t.hpp @@ -1582,17 +1582,15 @@ constexpr auto quantized128f(const decimal_fast128_t& lhs, const decimal_fast128 namespace std { -template<> -#ifdef _MSC_VER -class numeric_limits -#else -struct numeric_limits +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" #endif -{ -#ifdef _MSC_VER - public: -#endif +template <> +class numeric_limits +{ +public: static constexpr bool is_specialized = true; static constexpr bool is_signed = true; @@ -1635,6 +1633,10 @@ struct numeric_limits static constexpr auto denorm_min () -> boost::decimal::decimal_fast128_t { return min(); } }; +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + } // namespace std #include diff --git a/include/boost/decimal/decimal_fast32_t.hpp b/include/boost/decimal/decimal_fast32_t.hpp index 11de1002d..25c7a687b 100644 --- a/include/boost/decimal/decimal_fast32_t.hpp +++ b/include/boost/decimal/decimal_fast32_t.hpp @@ -1544,17 +1544,15 @@ constexpr auto quantized32f(const decimal_fast32_t lhs, const decimal_fast32_t r namespace std { +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + template <> -#ifdef _MSC_VER class numeric_limits -#else -struct numeric_limits -#endif { - -#ifdef _MSC_VER - public: -#endif +public: static constexpr bool is_specialized = true; static constexpr bool is_signed = true; @@ -1599,6 +1597,10 @@ struct numeric_limits static constexpr auto denorm_min () -> boost::decimal::decimal_fast32_t { return min(); } }; +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + } // Namespace std #include diff --git a/include/boost/decimal/decimal_fast64_t.hpp b/include/boost/decimal/decimal_fast64_t.hpp index a7ba82332..f6b8c851c 100644 --- a/include/boost/decimal/decimal_fast64_t.hpp +++ b/include/boost/decimal/decimal_fast64_t.hpp @@ -1518,16 +1518,15 @@ constexpr auto copysignd64f(decimal_fast64_t mag, const decimal_fast64_t sgn) no namespace std { +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + template <> -#ifdef _MSC_VER class numeric_limits -#else -struct numeric_limits -#endif { -#ifdef _MSC_VER - public: -#endif +public: static constexpr bool is_specialized = true; static constexpr bool is_signed = true; @@ -1573,6 +1572,10 @@ struct numeric_limits static constexpr auto denorm_min () -> boost::decimal::decimal_fast64_t { return min(); } }; +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + } // namespace std #include diff --git a/include/boost/decimal/fwd.hpp b/include/boost/decimal/fwd.hpp index 3a519b1c2..3f7649bba 100644 --- a/include/boost/decimal/fwd.hpp +++ b/include/boost/decimal/fwd.hpp @@ -25,46 +25,31 @@ class decimal_fast128_t; namespace std { +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; + +#ifdef __clang__ +# pragma clang diagnostic pop #endif } // Namespace std diff --git a/modules/decimal.cxx b/modules/decimal.cxx index d77f323f2..f6657812a 100644 --- a/modules/decimal.cxx +++ b/modules/decimal.cxx @@ -81,46 +81,22 @@ class decimal_fast128_t; export namespace std { template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif template <> -#ifdef _MSC_VER -class numeric_limits; -#else -struct numeric_limits; -#endif +class numeric_limits; template <> -#ifdef _MSC_VER -class numeric_limits; -#else -struct numeric_limits; -#endif +class numeric_limits; template <> -#ifdef _MSC_VER -class numeric_limits; -#else -struct numeric_limits; -#endif +class numeric_limits; template <> -#ifdef _MSC_VER -class numeric_limits; -#else -struct numeric_limits; -#endif +class numeric_limits; template <> -#ifdef _MSC_VER class numeric_limits; -#else -struct numeric_limits; -#endif } // Namespace std From f4163922c8523bf81d4fa9775dd5ad4d30c9d52c Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 6 Nov 2025 10:28:46 +0100 Subject: [PATCH 2/6] Add testing of ODR violation from numeric limits and charconv --- test/Jamfile | 2 ++ test/limits_link_1.cpp | 26 ++++++++++++++++++++++++++ test/limits_link_2.cpp | 26 ++++++++++++++++++++++++++ test/limits_link_3.cpp | 16 ++++++++++++++++ 4 files changed, 70 insertions(+) create mode 100644 test/limits_link_1.cpp create mode 100644 test/limits_link_2.cpp create mode 100644 test/limits_link_3.cpp diff --git a/test/Jamfile b/test/Jamfile index 591c0cc7b..7cc8df1cc 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -187,6 +187,8 @@ run test_to_string.cpp ; run test_total_ordering.cpp ; run test_zeta.cpp ; +run limits_link_1.cpp limits_link_2.cpp limits_link_3.cpp ; + # Run the examples too run ../examples/adl.cpp ; run ../examples/basic_construction.cpp ; diff --git a/test/limits_link_1.cpp b/test/limits_link_1.cpp new file mode 100644 index 000000000..ccd990a0c --- /dev/null +++ b/test/limits_link_1.cpp @@ -0,0 +1,26 @@ +// Copyright 2023 Peter Dimov +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +void test_odr_use( int const* ); + +template void test() +{ + test_odr_use( &boost::decimal::limits::max_chars ); + test_odr_use( &std::numeric_limits::digits10 ); +} + +void f1() +{ + test(); + test(); + test(); + + test(); + test(); + test(); +} diff --git a/test/limits_link_2.cpp b/test/limits_link_2.cpp new file mode 100644 index 000000000..b40dd60b4 --- /dev/null +++ b/test/limits_link_2.cpp @@ -0,0 +1,26 @@ +// Copyright 2023 Peter Dimov +// Copyright 2025 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +void test_odr_use( int const* ); + +template void test() +{ + test_odr_use( &boost::decimal::limits::max_chars ); + test_odr_use( &std::numeric_limits::digits10 ); +} + +void f2() +{ + test(); + test(); + test(); + + test(); + test(); + test(); +} diff --git a/test/limits_link_3.cpp b/test/limits_link_3.cpp new file mode 100644 index 000000000..e2bb12904 --- /dev/null +++ b/test/limits_link_3.cpp @@ -0,0 +1,16 @@ +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +void f1(); +void f2(); + +int main() +{ + f1(); + f2(); +} + +void test_odr_use( int const* ) +{ +} From 21e02a9f1f29b5a851e30f2088721e9d1f366e83 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 6 Nov 2025 10:46:17 +0100 Subject: [PATCH 3/6] Add forward decl of numeric limits impl template class --- include/boost/decimal/fwd.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/boost/decimal/fwd.hpp b/include/boost/decimal/fwd.hpp index 3f7649bba..8c7f6ca6a 100644 --- a/include/boost/decimal/fwd.hpp +++ b/include/boost/decimal/fwd.hpp @@ -13,6 +13,14 @@ namespace boost { namespace decimal { +namespace detail { + +// Needed to avoid ODR violations with numeric limits in C++14 +template +class numeric_limits_impl; + +} // namespace detail + class decimal32_t; class decimal_fast32_t; class decimal64_t; From 94f73058aa79632fca2d553cb2c1bceb032a2568 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 6 Nov 2025 10:46:53 +0100 Subject: [PATCH 4/6] Re-structure to impl class and add out of line definitions --- include/boost/decimal/decimal32_t.hpp | 64 ++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/include/boost/decimal/decimal32_t.hpp b/include/boost/decimal/decimal32_t.hpp index 7219f2ed7..ca1f088dd 100644 --- a/include/boost/decimal/decimal32_t.hpp +++ b/include/boost/decimal/decimal32_t.hpp @@ -2297,18 +2297,10 @@ constexpr auto copysignd32(decimal32_t mag, const decimal32_t sgn) noexcept -> d return mag; } -} // namespace decimal -} // namespace boost - -namespace std { - -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wmismatched-tags" -#endif +namespace detail { template <> -class numeric_limits +class numeric_limits_impl { public: @@ -2338,7 +2330,7 @@ class numeric_limits static constexpr int min_exponent10 = min_exponent; static constexpr int max_exponent = 96; static constexpr int max_exponent10 = max_exponent; - static constexpr bool traps = numeric_limits::traps; + static constexpr bool traps = std::numeric_limits::traps; static constexpr bool tinyness_before = true; // Member functions @@ -2351,8 +2343,58 @@ class numeric_limits static constexpr auto quiet_NaN () -> boost::decimal::decimal32_t { return boost::decimal::from_bits(boost::decimal::detail::d32_nan_mask); } static constexpr auto signaling_NaN() -> boost::decimal::decimal32_t { return boost::decimal::from_bits(boost::decimal::detail::d32_snan_mask); } static constexpr auto denorm_min () -> boost::decimal::decimal32_t { return {1, boost::decimal::detail::etiny}; } + }; +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +constexpr bool numeric_limits_impl::is_specialized; +constexpr bool numeric_limits_impl::is_signed; +constexpr bool numeric_limits_impl::is_integer; +constexpr bool numeric_limits_impl::is_exact; +constexpr bool numeric_limits_impl::has_infinity; +constexpr bool numeric_limits_impl::has_quiet_NaN; +constexpr bool numeric_limits_impl::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +constexpr std::float_denorm_style numeric_limits_impl::has_denorm; +constexpr bool numeric_limits_impl::has_denorm_loss; +#endif + +constexpr std::float_round_style numeric_limits_impl::round_style; +constexpr bool numeric_limits_impl::is_iec559; +constexpr bool numeric_limits_impl::is_bounded; +constexpr bool numeric_limits_impl::is_modulo; +constexpr int numeric_limits_impl::digits; +constexpr int numeric_limits_impl::digits10; +constexpr int numeric_limits_impl::max_digits10; +constexpr int numeric_limits_impl::radix; +constexpr int numeric_limits_impl::min_exponent; +constexpr int numeric_limits_impl::min_exponent10; +constexpr int numeric_limits_impl::max_exponent; +constexpr int numeric_limits_impl::max_exponent10; +constexpr bool numeric_limits_impl::traps; +constexpr bool numeric_limits_impl::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +} // namespace detail + +} // namespace decimal +} // namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::decimal::detail::numeric_limits_impl {}; + #ifdef __clang__ # pragma clang diagnostic pop #endif From 70933303928b7d502a66d1244d127c5a6da0d93d Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 6 Nov 2025 10:57:53 +0100 Subject: [PATCH 5/6] Broadly use numeric limits impl class --- include/boost/decimal/decimal128_t.hpp | 65 +++++++++++++++++---- include/boost/decimal/decimal64_t.hpp | 63 ++++++++++++++++---- include/boost/decimal/decimal_fast128_t.hpp | 63 ++++++++++++++++---- include/boost/decimal/decimal_fast32_t.hpp | 63 ++++++++++++++++---- include/boost/decimal/decimal_fast64_t.hpp | 63 ++++++++++++++++---- 5 files changed, 261 insertions(+), 56 deletions(-) diff --git a/include/boost/decimal/decimal128_t.hpp b/include/boost/decimal/decimal128_t.hpp index 3ce71f50b..d8efb0f24 100644 --- a/include/boost/decimal/decimal128_t.hpp +++ b/include/boost/decimal/decimal128_t.hpp @@ -2228,18 +2228,10 @@ constexpr auto scalbnd128(decimal128_t num, const int expval) noexcept -> decima return scalblnd128(num, static_cast(expval)); } -} //namespace decimal -} //namespace boost - -namespace std { - -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wmismatched-tags" -#endif +namespace detail { -template<> -class numeric_limits +template <> +class numeric_limits_impl { public: @@ -2269,7 +2261,7 @@ class numeric_limits static constexpr int min_exponent10 = min_exponent; static constexpr int max_exponent = 6144; static constexpr int max_exponent10 = max_exponent; - static constexpr bool traps = numeric_limits::traps; + static constexpr bool traps = std::numeric_limits::traps; static constexpr bool tinyness_before = true; // Member functions @@ -2284,6 +2276,55 @@ class numeric_limits static constexpr auto denorm_min () -> boost::decimal::decimal128_t { return {1, boost::decimal::detail::etiny_v}; } }; +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +constexpr bool numeric_limits_impl::is_specialized; +constexpr bool numeric_limits_impl::is_signed; +constexpr bool numeric_limits_impl::is_integer; +constexpr bool numeric_limits_impl::is_exact; +constexpr bool numeric_limits_impl::has_infinity; +constexpr bool numeric_limits_impl::has_quiet_NaN; +constexpr bool numeric_limits_impl::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +constexpr std::float_denorm_style numeric_limits_impl::has_denorm; +constexpr bool numeric_limits_impl::has_denorm_loss; +#endif + +constexpr std::float_round_style numeric_limits_impl::round_style; +constexpr bool numeric_limits_impl::is_iec559; +constexpr bool numeric_limits_impl::is_bounded; +constexpr bool numeric_limits_impl::is_modulo; +constexpr int numeric_limits_impl::digits; +constexpr int numeric_limits_impl::digits10; +constexpr int numeric_limits_impl::max_digits10; +constexpr int numeric_limits_impl::radix; +constexpr int numeric_limits_impl::min_exponent; +constexpr int numeric_limits_impl::min_exponent10; +constexpr int numeric_limits_impl::max_exponent; +constexpr int numeric_limits_impl::max_exponent10; +constexpr bool numeric_limits_impl::traps; +constexpr bool numeric_limits_impl::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +} // namespace detail + +} //namespace decimal +} //namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::decimal::detail::numeric_limits_impl {}; + #ifdef __clang__ # pragma clang diagnostic pop #endif diff --git a/include/boost/decimal/decimal64_t.hpp b/include/boost/decimal/decimal64_t.hpp index 2de3c128a..c167ec2f0 100644 --- a/include/boost/decimal/decimal64_t.hpp +++ b/include/boost/decimal/decimal64_t.hpp @@ -2192,18 +2192,10 @@ constexpr auto copysignd64(decimal64_t mag, const decimal64_t sgn) noexcept -> d return mag; } -} //namespace decimal -} //namespace boost - -namespace std { - -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wmismatched-tags" -#endif +namespace detail { template <> -class numeric_limits +class numeric_limits_impl { public: @@ -2233,7 +2225,7 @@ class numeric_limits static constexpr int min_exponent10 = min_exponent; static constexpr int max_exponent = 384; static constexpr int max_exponent10 = max_exponent; - static constexpr bool traps = numeric_limits::traps; + static constexpr bool traps = std::numeric_limits::traps; static constexpr bool tinyness_before = true; // Member functions @@ -2248,6 +2240,55 @@ class numeric_limits static constexpr auto denorm_min () -> boost::decimal::decimal64_t { return {1, boost::decimal::detail::etiny_v}; } }; +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +constexpr bool numeric_limits_impl::is_specialized; +constexpr bool numeric_limits_impl::is_signed; +constexpr bool numeric_limits_impl::is_integer; +constexpr bool numeric_limits_impl::is_exact; +constexpr bool numeric_limits_impl::has_infinity; +constexpr bool numeric_limits_impl::has_quiet_NaN; +constexpr bool numeric_limits_impl::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +constexpr std::float_denorm_style numeric_limits_impl::has_denorm; +constexpr bool numeric_limits_impl::has_denorm_loss; +#endif + +constexpr std::float_round_style numeric_limits_impl::round_style; +constexpr bool numeric_limits_impl::is_iec559; +constexpr bool numeric_limits_impl::is_bounded; +constexpr bool numeric_limits_impl::is_modulo; +constexpr int numeric_limits_impl::digits; +constexpr int numeric_limits_impl::digits10; +constexpr int numeric_limits_impl::max_digits10; +constexpr int numeric_limits_impl::radix; +constexpr int numeric_limits_impl::min_exponent; +constexpr int numeric_limits_impl::min_exponent10; +constexpr int numeric_limits_impl::max_exponent; +constexpr int numeric_limits_impl::max_exponent10; +constexpr bool numeric_limits_impl::traps; +constexpr bool numeric_limits_impl::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +} // namespace detail + +} //namespace decimal +} //namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::decimal::detail::numeric_limits_impl {}; + #ifdef __clang__ # pragma clang diagnostic pop #endif diff --git a/include/boost/decimal/decimal_fast128_t.hpp b/include/boost/decimal/decimal_fast128_t.hpp index 20336b4c5..108038435 100644 --- a/include/boost/decimal/decimal_fast128_t.hpp +++ b/include/boost/decimal/decimal_fast128_t.hpp @@ -1577,18 +1577,10 @@ constexpr auto quantized128f(const decimal_fast128_t& lhs, const decimal_fast128 return {lhs.full_significand(), rhs.biased_exponent(), lhs.isneg()}; } -} // namespace decimal -} // namespace boost - -namespace std { - -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wmismatched-tags" -#endif +namespace detail { template <> -class numeric_limits +class numeric_limits_impl { public: @@ -1618,7 +1610,7 @@ class numeric_limits static constexpr int min_exponent10 = min_exponent; static constexpr int max_exponent = 6144; static constexpr int max_exponent10 = max_exponent; - static constexpr bool traps = numeric_limits::traps; + static constexpr bool traps = std::numeric_limits::traps; static constexpr bool tinyness_before = true; // Member functions @@ -1633,6 +1625,55 @@ class numeric_limits static constexpr auto denorm_min () -> boost::decimal::decimal_fast128_t { return min(); } }; +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +constexpr bool numeric_limits_impl::is_specialized; +constexpr bool numeric_limits_impl::is_signed; +constexpr bool numeric_limits_impl::is_integer; +constexpr bool numeric_limits_impl::is_exact; +constexpr bool numeric_limits_impl::has_infinity; +constexpr bool numeric_limits_impl::has_quiet_NaN; +constexpr bool numeric_limits_impl::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +constexpr std::float_denorm_style numeric_limits_impl::has_denorm; +constexpr bool numeric_limits_impl::has_denorm_loss; +#endif + +constexpr std::float_round_style numeric_limits_impl::round_style; +constexpr bool numeric_limits_impl::is_iec559; +constexpr bool numeric_limits_impl::is_bounded; +constexpr bool numeric_limits_impl::is_modulo; +constexpr int numeric_limits_impl::digits; +constexpr int numeric_limits_impl::digits10; +constexpr int numeric_limits_impl::max_digits10; +constexpr int numeric_limits_impl::radix; +constexpr int numeric_limits_impl::min_exponent; +constexpr int numeric_limits_impl::min_exponent10; +constexpr int numeric_limits_impl::max_exponent; +constexpr int numeric_limits_impl::max_exponent10; +constexpr bool numeric_limits_impl::traps; +constexpr bool numeric_limits_impl::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +} // namespace detail + +} // namespace decimal +} // namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::decimal::detail::numeric_limits_impl {}; + #ifdef __clang__ # pragma clang diagnostic pop #endif diff --git a/include/boost/decimal/decimal_fast32_t.hpp b/include/boost/decimal/decimal_fast32_t.hpp index 25c7a687b..87165fafd 100644 --- a/include/boost/decimal/decimal_fast32_t.hpp +++ b/include/boost/decimal/decimal_fast32_t.hpp @@ -1539,18 +1539,10 @@ constexpr auto quantized32f(const decimal_fast32_t lhs, const decimal_fast32_t r return {lhs.full_significand(), rhs.biased_exponent(), lhs.isneg()}; } -} // namespace decimal -} // namespace boost - -namespace std { - -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wmismatched-tags" -#endif +namespace detail { template <> -class numeric_limits +class numeric_limits_impl { public: @@ -1580,7 +1572,7 @@ class numeric_limits static constexpr int min_exponent10 = min_exponent; static constexpr int max_exponent = 96; static constexpr int max_exponent10 = max_exponent; - static constexpr bool traps = numeric_limits::traps; + static constexpr bool traps = std::numeric_limits::traps; static constexpr bool tinyness_before = true; // Member functions @@ -1597,6 +1589,55 @@ class numeric_limits static constexpr auto denorm_min () -> boost::decimal::decimal_fast32_t { return min(); } }; +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +constexpr bool numeric_limits_impl::is_specialized; +constexpr bool numeric_limits_impl::is_signed; +constexpr bool numeric_limits_impl::is_integer; +constexpr bool numeric_limits_impl::is_exact; +constexpr bool numeric_limits_impl::has_infinity; +constexpr bool numeric_limits_impl::has_quiet_NaN; +constexpr bool numeric_limits_impl::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +constexpr std::float_denorm_style numeric_limits_impl::has_denorm; +constexpr bool numeric_limits_impl::has_denorm_loss; +#endif + +constexpr std::float_round_style numeric_limits_impl::round_style; +constexpr bool numeric_limits_impl::is_iec559; +constexpr bool numeric_limits_impl::is_bounded; +constexpr bool numeric_limits_impl::is_modulo; +constexpr int numeric_limits_impl::digits; +constexpr int numeric_limits_impl::digits10; +constexpr int numeric_limits_impl::max_digits10; +constexpr int numeric_limits_impl::radix; +constexpr int numeric_limits_impl::min_exponent; +constexpr int numeric_limits_impl::min_exponent10; +constexpr int numeric_limits_impl::max_exponent; +constexpr int numeric_limits_impl::max_exponent10; +constexpr bool numeric_limits_impl::traps; +constexpr bool numeric_limits_impl::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +} // namespace detail + +} // namespace decimal +} // namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::decimal::detail::numeric_limits_impl {}; + #ifdef __clang__ # pragma clang diagnostic pop #endif diff --git a/include/boost/decimal/decimal_fast64_t.hpp b/include/boost/decimal/decimal_fast64_t.hpp index f6b8c851c..de7cb34bd 100644 --- a/include/boost/decimal/decimal_fast64_t.hpp +++ b/include/boost/decimal/decimal_fast64_t.hpp @@ -1513,18 +1513,10 @@ constexpr auto copysignd64f(decimal_fast64_t mag, const decimal_fast64_t sgn) no return mag; } -} // namespace decimal -} // namespace boost - -namespace std { - -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wmismatched-tags" -#endif +namespace detail { template <> -class numeric_limits +class numeric_limits_impl { public: @@ -1554,7 +1546,7 @@ class numeric_limits static constexpr int min_exponent10 = min_exponent; static constexpr int max_exponent = 384; static constexpr int max_exponent10 = max_exponent; - static constexpr bool traps = numeric_limits::traps; + static constexpr bool traps = std::numeric_limits::traps; static constexpr bool tinyness_before = true; // Member functions @@ -1572,6 +1564,55 @@ class numeric_limits static constexpr auto denorm_min () -> boost::decimal::decimal_fast64_t { return min(); } }; +#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +constexpr bool numeric_limits_impl::is_specialized; +constexpr bool numeric_limits_impl::is_signed; +constexpr bool numeric_limits_impl::is_integer; +constexpr bool numeric_limits_impl::is_exact; +constexpr bool numeric_limits_impl::has_infinity; +constexpr bool numeric_limits_impl::has_quiet_NaN; +constexpr bool numeric_limits_impl::has_signaling_NaN; + +// These members were deprecated in C++23 +#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) +constexpr std::float_denorm_style numeric_limits_impl::has_denorm; +constexpr bool numeric_limits_impl::has_denorm_loss; +#endif + +constexpr std::float_round_style numeric_limits_impl::round_style; +constexpr bool numeric_limits_impl::is_iec559; +constexpr bool numeric_limits_impl::is_bounded; +constexpr bool numeric_limits_impl::is_modulo; +constexpr int numeric_limits_impl::digits; +constexpr int numeric_limits_impl::digits10; +constexpr int numeric_limits_impl::max_digits10; +constexpr int numeric_limits_impl::radix; +constexpr int numeric_limits_impl::min_exponent; +constexpr int numeric_limits_impl::min_exponent10; +constexpr int numeric_limits_impl::max_exponent; +constexpr int numeric_limits_impl::max_exponent10; +constexpr bool numeric_limits_impl::traps; +constexpr bool numeric_limits_impl::tinyness_before; + +#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L + +} // namespace detail + +} // namespace decimal +} // namespace boost + +namespace std { + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + +template <> +class numeric_limits : + public boost::decimal::detail::numeric_limits_impl {}; + #ifdef __clang__ # pragma clang diagnostic pop #endif From c591ec54812b372001bc781c5ea87702ab721ddc Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 6 Nov 2025 11:10:03 +0100 Subject: [PATCH 6/6] Add bool template param --- include/boost/decimal/decimal128_t.hpp | 52 ++++++++++----------- include/boost/decimal/decimal32_t.hpp | 52 ++++++++++----------- include/boost/decimal/decimal64_t.hpp | 52 ++++++++++----------- include/boost/decimal/decimal_fast128_t.hpp | 52 ++++++++++----------- include/boost/decimal/decimal_fast32_t.hpp | 52 ++++++++++----------- include/boost/decimal/decimal_fast64_t.hpp | 52 ++++++++++----------- include/boost/decimal/fwd.hpp | 8 ---- 7 files changed, 156 insertions(+), 164 deletions(-) diff --git a/include/boost/decimal/decimal128_t.hpp b/include/boost/decimal/decimal128_t.hpp index d8efb0f24..5568a71a0 100644 --- a/include/boost/decimal/decimal128_t.hpp +++ b/include/boost/decimal/decimal128_t.hpp @@ -2230,8 +2230,8 @@ constexpr auto scalbnd128(decimal128_t num, const int expval) noexcept -> decima namespace detail { -template <> -class numeric_limits_impl +template +class numeric_limits_impl128 { public: @@ -2278,34 +2278,34 @@ class numeric_limits_impl #if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L -constexpr bool numeric_limits_impl::is_specialized; -constexpr bool numeric_limits_impl::is_signed; -constexpr bool numeric_limits_impl::is_integer; -constexpr bool numeric_limits_impl::is_exact; -constexpr bool numeric_limits_impl::has_infinity; -constexpr bool numeric_limits_impl::has_quiet_NaN; -constexpr bool numeric_limits_impl::has_signaling_NaN; +template constexpr bool numeric_limits_impl128::is_specialized; +template constexpr bool numeric_limits_impl128::is_signed; +template constexpr bool numeric_limits_impl128::is_integer; +template constexpr bool numeric_limits_impl128::is_exact; +template constexpr bool numeric_limits_impl128::has_infinity; +template constexpr bool numeric_limits_impl128::has_quiet_NaN; +template constexpr bool numeric_limits_impl128::has_signaling_NaN; // These members were deprecated in C++23 #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) -constexpr std::float_denorm_style numeric_limits_impl::has_denorm; -constexpr bool numeric_limits_impl::has_denorm_loss; +template constexpr std::float_denorm_style numeric_limits_impl128::has_denorm; +template constexpr bool numeric_limits_impl128::has_denorm_loss; #endif -constexpr std::float_round_style numeric_limits_impl::round_style; -constexpr bool numeric_limits_impl::is_iec559; -constexpr bool numeric_limits_impl::is_bounded; -constexpr bool numeric_limits_impl::is_modulo; -constexpr int numeric_limits_impl::digits; -constexpr int numeric_limits_impl::digits10; -constexpr int numeric_limits_impl::max_digits10; -constexpr int numeric_limits_impl::radix; -constexpr int numeric_limits_impl::min_exponent; -constexpr int numeric_limits_impl::min_exponent10; -constexpr int numeric_limits_impl::max_exponent; -constexpr int numeric_limits_impl::max_exponent10; -constexpr bool numeric_limits_impl::traps; -constexpr bool numeric_limits_impl::tinyness_before; +template constexpr std::float_round_style numeric_limits_impl128::round_style; +template constexpr bool numeric_limits_impl128::is_iec559; +template constexpr bool numeric_limits_impl128::is_bounded; +template constexpr bool numeric_limits_impl128::is_modulo; +template constexpr int numeric_limits_impl128::digits; +template constexpr int numeric_limits_impl128::digits10; +template constexpr int numeric_limits_impl128::max_digits10; +template constexpr int numeric_limits_impl128::radix; +template constexpr int numeric_limits_impl128::min_exponent; +template constexpr int numeric_limits_impl128::min_exponent10; +template constexpr int numeric_limits_impl128::max_exponent; +template constexpr int numeric_limits_impl128::max_exponent10; +template constexpr bool numeric_limits_impl128::traps; +template constexpr bool numeric_limits_impl128::tinyness_before; #endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L @@ -2323,7 +2323,7 @@ namespace std { template <> class numeric_limits : - public boost::decimal::detail::numeric_limits_impl {}; + public boost::decimal::detail::numeric_limits_impl128 {}; #ifdef __clang__ # pragma clang diagnostic pop diff --git a/include/boost/decimal/decimal32_t.hpp b/include/boost/decimal/decimal32_t.hpp index ca1f088dd..4ad62bf46 100644 --- a/include/boost/decimal/decimal32_t.hpp +++ b/include/boost/decimal/decimal32_t.hpp @@ -2299,8 +2299,8 @@ constexpr auto copysignd32(decimal32_t mag, const decimal32_t sgn) noexcept -> d namespace detail { -template <> -class numeric_limits_impl +template +class numeric_limits_impl32 { public: @@ -2348,34 +2348,34 @@ class numeric_limits_impl #if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L -constexpr bool numeric_limits_impl::is_specialized; -constexpr bool numeric_limits_impl::is_signed; -constexpr bool numeric_limits_impl::is_integer; -constexpr bool numeric_limits_impl::is_exact; -constexpr bool numeric_limits_impl::has_infinity; -constexpr bool numeric_limits_impl::has_quiet_NaN; -constexpr bool numeric_limits_impl::has_signaling_NaN; +template constexpr bool numeric_limits_impl32::is_specialized; +template constexpr bool numeric_limits_impl32::is_signed; +template constexpr bool numeric_limits_impl32::is_integer; +template constexpr bool numeric_limits_impl32::is_exact; +template constexpr bool numeric_limits_impl32::has_infinity; +template constexpr bool numeric_limits_impl32::has_quiet_NaN; +template constexpr bool numeric_limits_impl32::has_signaling_NaN; // These members were deprecated in C++23 #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) -constexpr std::float_denorm_style numeric_limits_impl::has_denorm; -constexpr bool numeric_limits_impl::has_denorm_loss; +template constexpr std::float_denorm_style numeric_limits_impl32::has_denorm; +template constexpr bool numeric_limits_impl32::has_denorm_loss; #endif -constexpr std::float_round_style numeric_limits_impl::round_style; -constexpr bool numeric_limits_impl::is_iec559; -constexpr bool numeric_limits_impl::is_bounded; -constexpr bool numeric_limits_impl::is_modulo; -constexpr int numeric_limits_impl::digits; -constexpr int numeric_limits_impl::digits10; -constexpr int numeric_limits_impl::max_digits10; -constexpr int numeric_limits_impl::radix; -constexpr int numeric_limits_impl::min_exponent; -constexpr int numeric_limits_impl::min_exponent10; -constexpr int numeric_limits_impl::max_exponent; -constexpr int numeric_limits_impl::max_exponent10; -constexpr bool numeric_limits_impl::traps; -constexpr bool numeric_limits_impl::tinyness_before; +template constexpr std::float_round_style numeric_limits_impl32::round_style; +template constexpr bool numeric_limits_impl32::is_iec559; +template constexpr bool numeric_limits_impl32::is_bounded; +template constexpr bool numeric_limits_impl32::is_modulo; +template constexpr int numeric_limits_impl32::digits; +template constexpr int numeric_limits_impl32::digits10; +template constexpr int numeric_limits_impl32::max_digits10; +template constexpr int numeric_limits_impl32::radix; +template constexpr int numeric_limits_impl32::min_exponent; +template constexpr int numeric_limits_impl32::min_exponent10; +template constexpr int numeric_limits_impl32::max_exponent; +template constexpr int numeric_limits_impl32::max_exponent10; +template constexpr bool numeric_limits_impl32::traps; +template constexpr bool numeric_limits_impl32::tinyness_before; #endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L @@ -2393,7 +2393,7 @@ namespace std { template <> class numeric_limits : - public boost::decimal::detail::numeric_limits_impl {}; + public boost::decimal::detail::numeric_limits_impl32 {}; #ifdef __clang__ # pragma clang diagnostic pop diff --git a/include/boost/decimal/decimal64_t.hpp b/include/boost/decimal/decimal64_t.hpp index c167ec2f0..f456cfa07 100644 --- a/include/boost/decimal/decimal64_t.hpp +++ b/include/boost/decimal/decimal64_t.hpp @@ -2194,8 +2194,8 @@ constexpr auto copysignd64(decimal64_t mag, const decimal64_t sgn) noexcept -> d namespace detail { -template <> -class numeric_limits_impl +template +class numeric_limits_impl64 { public: @@ -2242,34 +2242,34 @@ class numeric_limits_impl #if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L -constexpr bool numeric_limits_impl::is_specialized; -constexpr bool numeric_limits_impl::is_signed; -constexpr bool numeric_limits_impl::is_integer; -constexpr bool numeric_limits_impl::is_exact; -constexpr bool numeric_limits_impl::has_infinity; -constexpr bool numeric_limits_impl::has_quiet_NaN; -constexpr bool numeric_limits_impl::has_signaling_NaN; +template constexpr bool numeric_limits_impl64::is_specialized; +template constexpr bool numeric_limits_impl64::is_signed; +template constexpr bool numeric_limits_impl64::is_integer; +template constexpr bool numeric_limits_impl64::is_exact; +template constexpr bool numeric_limits_impl64::has_infinity; +template constexpr bool numeric_limits_impl64::has_quiet_NaN; +template constexpr bool numeric_limits_impl64::has_signaling_NaN; // These members were deprecated in C++23 #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) -constexpr std::float_denorm_style numeric_limits_impl::has_denorm; -constexpr bool numeric_limits_impl::has_denorm_loss; +template constexpr std::float_denorm_style numeric_limits_impl64::has_denorm; +template constexpr bool numeric_limits_impl64::has_denorm_loss; #endif -constexpr std::float_round_style numeric_limits_impl::round_style; -constexpr bool numeric_limits_impl::is_iec559; -constexpr bool numeric_limits_impl::is_bounded; -constexpr bool numeric_limits_impl::is_modulo; -constexpr int numeric_limits_impl::digits; -constexpr int numeric_limits_impl::digits10; -constexpr int numeric_limits_impl::max_digits10; -constexpr int numeric_limits_impl::radix; -constexpr int numeric_limits_impl::min_exponent; -constexpr int numeric_limits_impl::min_exponent10; -constexpr int numeric_limits_impl::max_exponent; -constexpr int numeric_limits_impl::max_exponent10; -constexpr bool numeric_limits_impl::traps; -constexpr bool numeric_limits_impl::tinyness_before; +template constexpr std::float_round_style numeric_limits_impl64::round_style; +template constexpr bool numeric_limits_impl64::is_iec559; +template constexpr bool numeric_limits_impl64::is_bounded; +template constexpr bool numeric_limits_impl64::is_modulo; +template constexpr int numeric_limits_impl64::digits; +template constexpr int numeric_limits_impl64::digits10; +template constexpr int numeric_limits_impl64::max_digits10; +template constexpr int numeric_limits_impl64::radix; +template constexpr int numeric_limits_impl64::min_exponent; +template constexpr int numeric_limits_impl64::min_exponent10; +template constexpr int numeric_limits_impl64::max_exponent; +template constexpr int numeric_limits_impl64::max_exponent10; +template constexpr bool numeric_limits_impl64::traps; +template constexpr bool numeric_limits_impl64::tinyness_before; #endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L @@ -2287,7 +2287,7 @@ namespace std { template <> class numeric_limits : - public boost::decimal::detail::numeric_limits_impl {}; + public boost::decimal::detail::numeric_limits_impl64 {}; #ifdef __clang__ # pragma clang diagnostic pop diff --git a/include/boost/decimal/decimal_fast128_t.hpp b/include/boost/decimal/decimal_fast128_t.hpp index 108038435..c7470c3c9 100644 --- a/include/boost/decimal/decimal_fast128_t.hpp +++ b/include/boost/decimal/decimal_fast128_t.hpp @@ -1579,8 +1579,8 @@ constexpr auto quantized128f(const decimal_fast128_t& lhs, const decimal_fast128 namespace detail { -template <> -class numeric_limits_impl +template +class numeric_limits_impl128f { public: @@ -1627,34 +1627,34 @@ class numeric_limits_impl #if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L -constexpr bool numeric_limits_impl::is_specialized; -constexpr bool numeric_limits_impl::is_signed; -constexpr bool numeric_limits_impl::is_integer; -constexpr bool numeric_limits_impl::is_exact; -constexpr bool numeric_limits_impl::has_infinity; -constexpr bool numeric_limits_impl::has_quiet_NaN; -constexpr bool numeric_limits_impl::has_signaling_NaN; +template constexpr bool numeric_limits_impl128f::is_specialized; +template constexpr bool numeric_limits_impl128f::is_signed; +template constexpr bool numeric_limits_impl128f::is_integer; +template constexpr bool numeric_limits_impl128f::is_exact; +template constexpr bool numeric_limits_impl128f::has_infinity; +template constexpr bool numeric_limits_impl128f::has_quiet_NaN; +template constexpr bool numeric_limits_impl128f::has_signaling_NaN; // These members were deprecated in C++23 #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) -constexpr std::float_denorm_style numeric_limits_impl::has_denorm; -constexpr bool numeric_limits_impl::has_denorm_loss; +template constexpr std::float_denorm_style numeric_limits_impl128f::has_denorm; +template constexpr bool numeric_limits_impl128f::has_denorm_loss; #endif -constexpr std::float_round_style numeric_limits_impl::round_style; -constexpr bool numeric_limits_impl::is_iec559; -constexpr bool numeric_limits_impl::is_bounded; -constexpr bool numeric_limits_impl::is_modulo; -constexpr int numeric_limits_impl::digits; -constexpr int numeric_limits_impl::digits10; -constexpr int numeric_limits_impl::max_digits10; -constexpr int numeric_limits_impl::radix; -constexpr int numeric_limits_impl::min_exponent; -constexpr int numeric_limits_impl::min_exponent10; -constexpr int numeric_limits_impl::max_exponent; -constexpr int numeric_limits_impl::max_exponent10; -constexpr bool numeric_limits_impl::traps; -constexpr bool numeric_limits_impl::tinyness_before; +template constexpr std::float_round_style numeric_limits_impl128f::round_style; +template constexpr bool numeric_limits_impl128f::is_iec559; +template constexpr bool numeric_limits_impl128f::is_bounded; +template constexpr bool numeric_limits_impl128f::is_modulo; +template constexpr int numeric_limits_impl128f::digits; +template constexpr int numeric_limits_impl128f::digits10; +template constexpr int numeric_limits_impl128f::max_digits10; +template constexpr int numeric_limits_impl128f::radix; +template constexpr int numeric_limits_impl128f::min_exponent; +template constexpr int numeric_limits_impl128f::min_exponent10; +template constexpr int numeric_limits_impl128f::max_exponent; +template constexpr int numeric_limits_impl128f::max_exponent10; +template constexpr bool numeric_limits_impl128f::traps; +template constexpr bool numeric_limits_impl128f::tinyness_before; #endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L @@ -1672,7 +1672,7 @@ namespace std { template <> class numeric_limits : - public boost::decimal::detail::numeric_limits_impl {}; + public boost::decimal::detail::numeric_limits_impl128f {}; #ifdef __clang__ # pragma clang diagnostic pop diff --git a/include/boost/decimal/decimal_fast32_t.hpp b/include/boost/decimal/decimal_fast32_t.hpp index 87165fafd..b618c8774 100644 --- a/include/boost/decimal/decimal_fast32_t.hpp +++ b/include/boost/decimal/decimal_fast32_t.hpp @@ -1541,8 +1541,8 @@ constexpr auto quantized32f(const decimal_fast32_t lhs, const decimal_fast32_t r namespace detail { -template <> -class numeric_limits_impl +template +class numeric_limits_impl32f { public: @@ -1591,34 +1591,34 @@ class numeric_limits_impl #if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L -constexpr bool numeric_limits_impl::is_specialized; -constexpr bool numeric_limits_impl::is_signed; -constexpr bool numeric_limits_impl::is_integer; -constexpr bool numeric_limits_impl::is_exact; -constexpr bool numeric_limits_impl::has_infinity; -constexpr bool numeric_limits_impl::has_quiet_NaN; -constexpr bool numeric_limits_impl::has_signaling_NaN; +template constexpr bool numeric_limits_impl32f::is_specialized; +template constexpr bool numeric_limits_impl32f::is_signed; +template constexpr bool numeric_limits_impl32f::is_integer; +template constexpr bool numeric_limits_impl32f::is_exact; +template constexpr bool numeric_limits_impl32f::has_infinity; +template constexpr bool numeric_limits_impl32f::has_quiet_NaN; +template constexpr bool numeric_limits_impl32f::has_signaling_NaN; // These members were deprecated in C++23 #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) -constexpr std::float_denorm_style numeric_limits_impl::has_denorm; -constexpr bool numeric_limits_impl::has_denorm_loss; +template constexpr std::float_denorm_style numeric_limits_impl32f::has_denorm; +template constexpr bool numeric_limits_impl32f::has_denorm_loss; #endif -constexpr std::float_round_style numeric_limits_impl::round_style; -constexpr bool numeric_limits_impl::is_iec559; -constexpr bool numeric_limits_impl::is_bounded; -constexpr bool numeric_limits_impl::is_modulo; -constexpr int numeric_limits_impl::digits; -constexpr int numeric_limits_impl::digits10; -constexpr int numeric_limits_impl::max_digits10; -constexpr int numeric_limits_impl::radix; -constexpr int numeric_limits_impl::min_exponent; -constexpr int numeric_limits_impl::min_exponent10; -constexpr int numeric_limits_impl::max_exponent; -constexpr int numeric_limits_impl::max_exponent10; -constexpr bool numeric_limits_impl::traps; -constexpr bool numeric_limits_impl::tinyness_before; +template constexpr std::float_round_style numeric_limits_impl32f::round_style; +template constexpr bool numeric_limits_impl32f::is_iec559; +template constexpr bool numeric_limits_impl32f::is_bounded; +template constexpr bool numeric_limits_impl32f::is_modulo; +template constexpr int numeric_limits_impl32f::digits; +template constexpr int numeric_limits_impl32f::digits10; +template constexpr int numeric_limits_impl32f::max_digits10; +template constexpr int numeric_limits_impl32f::radix; +template constexpr int numeric_limits_impl32f::min_exponent; +template constexpr int numeric_limits_impl32f::min_exponent10; +template constexpr int numeric_limits_impl32f::max_exponent; +template constexpr int numeric_limits_impl32f::max_exponent10; +template constexpr bool numeric_limits_impl32f::traps; +template constexpr bool numeric_limits_impl32f::tinyness_before; #endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L @@ -1636,7 +1636,7 @@ namespace std { template <> class numeric_limits : - public boost::decimal::detail::numeric_limits_impl {}; + public boost::decimal::detail::numeric_limits_impl32f {}; #ifdef __clang__ # pragma clang diagnostic pop diff --git a/include/boost/decimal/decimal_fast64_t.hpp b/include/boost/decimal/decimal_fast64_t.hpp index de7cb34bd..7931e7c2e 100644 --- a/include/boost/decimal/decimal_fast64_t.hpp +++ b/include/boost/decimal/decimal_fast64_t.hpp @@ -1515,8 +1515,8 @@ constexpr auto copysignd64f(decimal_fast64_t mag, const decimal_fast64_t sgn) no namespace detail { -template <> -class numeric_limits_impl +template +class numeric_limits_impl64f { public: @@ -1566,34 +1566,34 @@ class numeric_limits_impl #if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L -constexpr bool numeric_limits_impl::is_specialized; -constexpr bool numeric_limits_impl::is_signed; -constexpr bool numeric_limits_impl::is_integer; -constexpr bool numeric_limits_impl::is_exact; -constexpr bool numeric_limits_impl::has_infinity; -constexpr bool numeric_limits_impl::has_quiet_NaN; -constexpr bool numeric_limits_impl::has_signaling_NaN; +template constexpr bool numeric_limits_impl64f::is_specialized; +template constexpr bool numeric_limits_impl64f::is_signed; +template constexpr bool numeric_limits_impl64f::is_integer; +template constexpr bool numeric_limits_impl64f::is_exact; +template constexpr bool numeric_limits_impl64f::has_infinity; +template constexpr bool numeric_limits_impl64f::has_quiet_NaN; +template constexpr bool numeric_limits_impl64f::has_signaling_NaN; // These members were deprecated in C++23 #if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L))) -constexpr std::float_denorm_style numeric_limits_impl::has_denorm; -constexpr bool numeric_limits_impl::has_denorm_loss; +template constexpr std::float_denorm_style numeric_limits_impl64f::has_denorm; +template constexpr bool numeric_limits_impl64f::has_denorm_loss; #endif -constexpr std::float_round_style numeric_limits_impl::round_style; -constexpr bool numeric_limits_impl::is_iec559; -constexpr bool numeric_limits_impl::is_bounded; -constexpr bool numeric_limits_impl::is_modulo; -constexpr int numeric_limits_impl::digits; -constexpr int numeric_limits_impl::digits10; -constexpr int numeric_limits_impl::max_digits10; -constexpr int numeric_limits_impl::radix; -constexpr int numeric_limits_impl::min_exponent; -constexpr int numeric_limits_impl::min_exponent10; -constexpr int numeric_limits_impl::max_exponent; -constexpr int numeric_limits_impl::max_exponent10; -constexpr bool numeric_limits_impl::traps; -constexpr bool numeric_limits_impl::tinyness_before; +template constexpr std::float_round_style numeric_limits_impl64f::round_style; +template constexpr bool numeric_limits_impl64f::is_iec559; +template constexpr bool numeric_limits_impl64f::is_bounded; +template constexpr bool numeric_limits_impl64f::is_modulo; +template constexpr int numeric_limits_impl64f::digits; +template constexpr int numeric_limits_impl64f::digits10; +template constexpr int numeric_limits_impl64f::max_digits10; +template constexpr int numeric_limits_impl64f::radix; +template constexpr int numeric_limits_impl64f::min_exponent; +template constexpr int numeric_limits_impl64f::min_exponent10; +template constexpr int numeric_limits_impl64f::max_exponent; +template constexpr int numeric_limits_impl64f::max_exponent10; +template constexpr bool numeric_limits_impl64f::traps; +template constexpr bool numeric_limits_impl64f::tinyness_before; #endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L @@ -1611,7 +1611,7 @@ namespace std { template <> class numeric_limits : - public boost::decimal::detail::numeric_limits_impl {}; + public boost::decimal::detail::numeric_limits_impl64f {}; #ifdef __clang__ # pragma clang diagnostic pop diff --git a/include/boost/decimal/fwd.hpp b/include/boost/decimal/fwd.hpp index 8c7f6ca6a..3f7649bba 100644 --- a/include/boost/decimal/fwd.hpp +++ b/include/boost/decimal/fwd.hpp @@ -13,14 +13,6 @@ namespace boost { namespace decimal { -namespace detail { - -// Needed to avoid ODR violations with numeric limits in C++14 -template -class numeric_limits_impl; - -} // namespace detail - class decimal32_t; class decimal_fast32_t; class decimal64_t;