Skip to content

Commit ba0a639

Browse files
authored
Merge pull request #279 from cppalliance/odr
2 parents 7d5f2ac + e1e5ec3 commit ba0a639

File tree

6 files changed

+183
-15
lines changed

6 files changed

+183
-15
lines changed

include/boost/int128/detail/int128_imp.hpp

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

32463246
#endif // BOOST_INT128_HAS_MSVC_INT128
32473247

3248-
} // namespace int128
3249-
} // namespace boost
3250-
3251-
namespace std {
3248+
namespace detail {
32523249

3253-
template <>
3254-
class numeric_limits<boost::int128::int128_t>
3250+
template <bool>
3251+
class numeric_limits_impl_i128
32553252
{
32563253
public:
32573254

3258-
// Member constants
3255+
// Member constants
32593256
static constexpr bool is_specialized = true;
32603257
static constexpr bool is_signed = true;
32613258
static constexpr bool is_integer = true;
@@ -3309,6 +3306,59 @@ class numeric_limits<boost::int128::int128_t>
33093306
static constexpr auto denorm_min () -> boost::int128::int128_t { return {0, 0}; }
33103307
};
33113308

3309+
#if !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L
3310+
3311+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_specialized;
3312+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_signed;
3313+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_integer;
3314+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_exact;
3315+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::has_infinity;
3316+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::has_quiet_NaN;
3317+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::has_signaling_NaN;
3318+
3319+
// These members were deprecated in C++23
3320+
#if ((!defined(_MSC_VER) && (__cplusplus <= 202002L)) || (defined(_MSC_VER) && (_MSVC_LANG <= 202002L)))
3321+
template <bool b> constexpr std::float_denorm_style numeric_limits_impl_i128<b>::has_denorm;
3322+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::has_denorm_loss;
3323+
#endif
3324+
3325+
template <bool b> constexpr std::float_round_style numeric_limits_impl_i128<b>::round_style;
3326+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_iec559;
3327+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_bounded;
3328+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::is_modulo;
3329+
template <bool b> constexpr int numeric_limits_impl_i128<b>::digits;
3330+
template <bool b> constexpr int numeric_limits_impl_i128<b>::digits10;
3331+
template <bool b> constexpr int numeric_limits_impl_i128<b>::max_digits10;
3332+
template <bool b> constexpr int numeric_limits_impl_i128<b>::radix;
3333+
template <bool b> constexpr int numeric_limits_impl_i128<b>::min_exponent;
3334+
template <bool b> constexpr int numeric_limits_impl_i128<b>::min_exponent10;
3335+
template <bool b> constexpr int numeric_limits_impl_i128<b>::max_exponent;
3336+
template <bool b> constexpr int numeric_limits_impl_i128<b>::max_exponent10;
3337+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::traps;
3338+
template <bool b> constexpr bool numeric_limits_impl_i128<b>::tinyness_before;
3339+
3340+
#endif // !defined(__cpp_inline_variables) || __cpp_inline_variables < 201606L
3341+
3342+
} // namespace detail
3343+
3344+
} // namespace int128
3345+
} // namespace boost
3346+
3347+
namespace std {
3348+
3349+
#ifdef __clang__
3350+
# pragma clang diagnostic push
3351+
# pragma clang diagnostic ignored "-Wmismatched-tags"
3352+
#endif
3353+
3354+
template <>
3355+
class numeric_limits<boost::int128::int128_t> :
3356+
public boost::int128::detail::numeric_limits_impl_i128<true> {};
3357+
3358+
#ifdef __clang__
3359+
# pragma clang diagnostic pop
3360+
#endif
3361+
33123362
} // namespace std
33133363

33143364
#endif // BOOST_INT128_DETAIL_INT128_HPP

include/boost/int128/detail/uint128_imp.hpp

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

31733173
#endif // BOOST_INT128_HAS_MSVC_INT128
31743174

3175-
} // namespace int128
3176-
} // namespace boost
3177-
3178-
namespace std {
3175+
namespace detail {
31793176

3180-
template <>
3181-
class numeric_limits<boost::int128::uint128_t>
3177+
template <bool>
3178+
class numeric_limits_impl_u128
31823179
{
31833180
public:
31843181

3185-
// Member constants
3182+
// Member constants
31863183
static constexpr bool is_specialized = true;
31873184
static constexpr bool is_signed = false;
31883185
static constexpr bool is_integer = true;
@@ -3236,6 +3233,60 @@ class numeric_limits<boost::int128::uint128_t>
32363233
static constexpr auto denorm_min () -> boost::int128::uint128_t { return {0, 0}; }
32373234
};
32383235

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

32413292
#endif //BOOST_INT128_DETAIL_UINT128_IMP_HPP

test/Jamfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ run ../examples/basic_arithmetic.cpp ;
9393
run ../examples/math_and_random.cpp ;
9494
run ../examples/charconv.cpp ;
9595

96+
run limits_link_1.cpp limits_link_2.cpp limits_link_3.cpp ;
97+
9698
# Github Issues
9799
run github_issue_207.cpp ;
98100
run github_issue_210.cpp ;

test/limits_link_1.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2023 Peter Dimov
2+
// Copyright 2025 Matt Borland
3+
// Distributed under the Boost Software License, Version 1.0.
4+
// https://www.boost.org/LICENSE_1_0.txt
5+
6+
#include <boost/int128.hpp>
7+
#include <limits>
8+
9+
void test_odr_use( int const* );
10+
void test_odr_use( std::size_t const* );
11+
12+
template<typename T> void test()
13+
{
14+
test_odr_use( &std::numeric_limits<T>::digits10 );
15+
}
16+
17+
void f1()
18+
{
19+
test<boost::int128::int128_t>();
20+
test<boost::int128::uint128_t>();
21+
}

test/limits_link_2.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2023 Peter Dimov
2+
// Copyright 2025 Matt Borland
3+
// Distributed under the Boost Software License, Version 1.0.
4+
// https://www.boost.org/LICENSE_1_0.txt
5+
6+
#include <boost/int128.hpp>
7+
#include <limits>
8+
9+
void test_odr_use( int const* );
10+
void test_odr_use( std::size_t const* );
11+
12+
template<typename T> void test()
13+
{
14+
test_odr_use( &std::numeric_limits<T>::digits10 );
15+
}
16+
17+
void f2()
18+
{
19+
test<boost::int128::int128_t>();
20+
test<boost::int128::uint128_t>();
21+
}

test/limits_link_3.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2023 Peter Dimov
2+
// Copyright 2025 Matt Borland
3+
// Distributed under the Boost Software License, Version 1.0.
4+
// https://www.boost.org/LICENSE_1_0.txt
5+
6+
#include <cstddef>
7+
8+
void f1();
9+
void f2();
10+
11+
int main()
12+
{
13+
f1();
14+
f2();
15+
}
16+
17+
void test_odr_use( int const* )
18+
{
19+
}
20+
21+
void test_odr_use ( std::size_t const* )
22+
{
23+
}

0 commit comments

Comments
 (0)