Skip to content

Commit dbe89fa

Browse files
authored
Merge pull request #1276 from cppalliance/1274
Fix 128-bit integer `numeric_limits` ODR violations
2 parents 326c57f + 2e4a8bd commit dbe89fa

File tree

2 files changed

+116
-15
lines changed

2 files changed

+116
-15
lines changed

include/boost/decimal/detail/int128/detail/int128_imp.hpp

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3215,17 +3215,14 @@ inline int128_t& int128_t::operator%=(const Integer rhs) noexcept
32153215

32163216
#endif // BOOST_DECIMAL_DETAIL_INT128_HAS_MSVC_INT128
32173217

3218-
} // namespace int128
3219-
} // namespace boost
3220-
3221-
namespace std {
3218+
namespace detail {
32223219

3223-
template <>
3224-
class numeric_limits<boost::int128::int128_t>
3220+
template <bool>
3221+
class numeric_limits_impl_i128
32253222
{
32263223
public:
32273224

3228-
// Member constants
3225+
// Member constants
32293226
static constexpr bool is_specialized = true;
32303227
static constexpr bool is_signed = true;
32313228
static constexpr bool is_integer = true;
@@ -3279,6 +3276,59 @@ class numeric_limits<boost::int128::int128_t>
32793276
static constexpr auto denorm_min () -> boost::int128::int128_t { return {0, 0}; }
32803277
};
32813278

3279+
#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L
3280+
3281+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_specialized;
3282+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_signed;
3283+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_integer;
3284+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_exact;
3285+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::has_infinity;
3286+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::has_quiet_NaN;
3287+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::has_signaling_NaN;
3288+
3289+
// These members were deprecated in C++23
3290+
#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L)))
3291+
template <bool b> constexpr std::float_denorm_style numeric_limits_impl_i128<b>::has_denorm;
3292+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::has_denorm_loss;
3293+
#endif
3294+
3295+
template <bool b> constexpr std::float_round_style numeric_limits_impl_i128<b>::round_style;
3296+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_iec559;
3297+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_bounded;
3298+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_modulo;
3299+
template <bool b> constexpr int numeric_limits_impl_i128<b>::digits;
3300+
template <bool b> constexpr int numeric_limits_impl_i128<b>::digits10;
3301+
template <bool b> constexpr int numeric_limits_impl_i128<b>::max_digits10;
3302+
template <bool b> constexpr int numeric_limits_impl_i128<b>::radix;
3303+
template <bool b> constexpr int numeric_limits_impl_i128<b>::min_exponent;
3304+
template <bool b> constexpr int numeric_limits_impl_i128<b>::min_exponent10;
3305+
template <bool b> constexpr int numeric_limits_impl_i128<b>::max_exponent;
3306+
template <bool b> constexpr int numeric_limits_impl_i128<b>::max_exponent10;
3307+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::traps;
3308+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::tinyness_before;
3309+
3310+
#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L
3311+
3312+
} // namespace detail
3313+
3314+
} // namespace int128
3315+
} // namespace boost
3316+
3317+
namespace std {
3318+
3319+
#ifdef __clang__
3320+
# pragma clang diagnostic push
3321+
# pragma clang diagnostic ignored "-Wmismatched-tags"
3322+
#endif
3323+
3324+
template <>
3325+
class numeric_limits<boost::int128::int128_t> :
3326+
public boost::int128::detail::numeric_limits_impl_i128<true> {};
3327+
3328+
#ifdef __clang__
3329+
# pragma clang diagnostic pop
3330+
#endif
3331+
32823332
} // namespace std
32833333

32843334
#endif // BOOST_DECIMAL_DETAIL_INT128_DETAIL_INT128_HPP

include/boost/decimal/detail/int128/detail/uint128_imp.hpp

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3159,17 +3159,14 @@ inline uint128_t& uint128_t::operator%=(const Integer rhs) noexcept
31593159

31603160
#endif // BOOST_DECIMAL_DETAIL_INT128_HAS_MSVC_INT128
31613161

3162-
} // namespace int128
3163-
} // namespace boost
3164-
3165-
namespace std {
3162+
namespace detail {
31663163

3167-
template <>
3168-
class numeric_limits<boost::int128::uint128_t>
3164+
template <bool>
3165+
class numeric_limits_impl_u128
31693166
{
31703167
public:
31713168

3172-
// Member constants
3169+
// Member constants
31733170
static constexpr bool is_specialized = true;
31743171
static constexpr bool is_signed = false;
31753172
static constexpr bool is_integer = true;
@@ -3223,6 +3220,60 @@ class numeric_limits<boost::int128::uint128_t>
32233220
static constexpr auto denorm_min () -> boost::int128::uint128_t { return {0, 0}; }
32243221
};
32253222

3226-
}// namespace std
3223+
#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L
3224+
3225+
template <bool b> constexpr bool numeric_limits_impl_u128<b>::is_specialized;
3226+
template <bool b> constexpr bool numeric_limits_impl_u128<b>::is_signed;
3227+
template <bool b> constexpr bool numeric_limits_impl_u128<b>::is_integer;
3228+
template <bool b> constexpr bool numeric_limits_impl_u128<b>::is_exact;
3229+
template <bool b> constexpr bool numeric_limits_impl_u128<b>::has_infinity;
3230+
template <bool b> constexpr bool numeric_limits_impl_u128<b>::has_quiet_NaN;
3231+
template <bool b> constexpr bool numeric_limits_impl_u128<b>::has_signaling_NaN;
3232+
3233+
// These members were deprecated in C++23
3234+
#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L)))
3235+
template <bool b> constexpr std::float_denorm_style numeric_limits_impl_u128<b>::has_denorm;
3236+
template <bool b> constexpr bool numeric_limits_impl_u128<b>::has_denorm_loss;
3237+
#endif
3238+
3239+
template <bool b> constexpr std::float_round_style numeric_limits_impl_u128<b>::round_style;
3240+
template <bool b> constexpr bool numeric_limits_impl_u128<b>::is_iec559;
3241+
template <bool b> constexpr bool numeric_limits_impl_u128<b>::is_bounded;
3242+
template <bool b> constexpr bool numeric_limits_impl_u128<b>::is_modulo;
3243+
template <bool b> constexpr int numeric_limits_impl_u128<b>::digits;
3244+
template <bool b> constexpr int numeric_limits_impl_u128<b>::digits10;
3245+
template <bool b> constexpr int numeric_limits_impl_u128<b>::max_digits10;
3246+
template <bool b> constexpr int numeric_limits_impl_u128<b>::radix;
3247+
template <bool b> constexpr int numeric_limits_impl_u128<b>::min_exponent;
3248+
template <bool b> constexpr int numeric_limits_impl_u128<b>::min_exponent10;
3249+
template <bool b> constexpr int numeric_limits_impl_u128<b>::max_exponent;
3250+
template <bool b> constexpr int numeric_limits_impl_u128<b>::max_exponent10;
3251+
template <bool b> constexpr bool numeric_limits_impl_u128<b>::traps;
3252+
template <bool b> constexpr bool numeric_limits_impl_u128<b>::tinyness_before;
3253+
3254+
#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L
3255+
3256+
3257+
} // namespace detail
3258+
3259+
} // namespace int128
3260+
} // namespace boost
3261+
3262+
namespace std {
3263+
3264+
#ifdef __clang__
3265+
# pragma clang diagnostic push
3266+
# pragma clang diagnostic ignored "-Wmismatched-tags"
3267+
#endif
3268+
3269+
template <>
3270+
class numeric_limits<boost::int128::uint128_t> :
3271+
public boost::int128::detail::numeric_limits_impl_u128<true> {};
3272+
3273+
#ifdef __clang__
3274+
# pragma clang diagnostic pop
3275+
#endif
3276+
3277+
} // namespace std
32273278

32283279
#endif //BOOST_DECIMAL_DETAIL_INT128_DETAIL_UINT128_IMP_HPP

0 commit comments

Comments
 (0)