@@ -188,11 +188,11 @@ int128_t
188188
189189 // Prefix and postfix increment
190190 constexpr int128_t & operator ++() noexcept ;
191- constexpr int128_t & operator ++(int ) noexcept ;
191+ constexpr int128_t operator ++(int ) noexcept ;
192192
193193 // Prefix and postfix decrment
194194 constexpr int128_t & operator --() noexcept ;
195- constexpr int128_t & operator --(int ) noexcept ;
195+ constexpr int128_t operator --(int ) noexcept ;
196196
197197 // Compound Addition
198198 template <BOOST_INT128_DEFAULTED_INTEGER_CONCEPT>
@@ -1523,6 +1523,8 @@ namespace detail {
15231523template <typename Integer>
15241524constexpr int128_t default_ls_impl (const int128_t lhs, const Integer rhs) noexcept
15251525{
1526+ static_assert (std::is_integral<Integer>::value, " Only builtin types allowed" );
1527+
15261528 if (rhs < 0 || rhs >= 128 )
15271529 {
15281530 return {0 , 0 };
@@ -1654,10 +1656,33 @@ constexpr int128_t operator<<(const int128_t lhs, const Integer rhs) noexcept
16541656 #endif
16551657}
16561658
1657- BOOST_INT128_EXPORT template <typename Integer, std::enable_if_t <detail::is_any_integer_v<Integer> && (sizeof (Integer) * 8 > 16 ), bool > = true >
1658- constexpr Integer operator <<(const Integer lhs, const int128_t rhs) noexcept
1659+ constexpr int128_t operator <<(const int128_t lhs, const int128_t rhs) noexcept
1660+ {
1661+ if (rhs.high != 0 || rhs.low >= 128 )
1662+ {
1663+ return 0 ;
1664+ }
1665+
1666+ return lhs << rhs.low ;
1667+ }
1668+
1669+ #ifdef BOOST_INT128_HAS_INT128
1670+
1671+ BOOST_INT128_EXPORT constexpr detail::builtin_u128 operator <<(const detail::builtin_u128 lhs, const int128_t rhs) noexcept
1672+ {
1673+ constexpr auto bit_width {sizeof (detail::builtin_u128) * 8 };
1674+
1675+ if (rhs.high != 0 || rhs.low >= bit_width)
1676+ {
1677+ return 0 ;
1678+ }
1679+
1680+ return lhs << rhs.low ;
1681+ }
1682+
1683+ BOOST_INT128_EXPORT constexpr detail::builtin_i128 operator <<(const detail::builtin_i128 lhs, const int128_t rhs) noexcept
16591684{
1660- constexpr auto bit_width {sizeof (Integer ) * 8 };
1685+ constexpr auto bit_width {sizeof (detail::builtin_i128 ) * 8 };
16611686
16621687 if (rhs.high != 0 || rhs.low >= bit_width)
16631688 {
@@ -1667,6 +1692,8 @@ constexpr Integer operator<<(const Integer lhs, const int128_t rhs) noexcept
16671692 return lhs << rhs.low ;
16681693}
16691694
1695+ #endif
1696+
16701697BOOST_INT128_EXPORT template <typename SignedInteger, std::enable_if_t <detail::is_signed_integer_v<SignedInteger> && (sizeof (SignedInteger) * 8 <= 16 ), bool > = true >
16711698constexpr int operator <<(const SignedInteger lhs, const int128_t rhs) noexcept
16721699{
@@ -1863,19 +1890,44 @@ constexpr int128_t operator>>(const int128_t lhs, const Integer rhs) noexcept
18631890 #endif
18641891}
18651892
1866- BOOST_INT128_EXPORT template <typename Integer, std::enable_if_t <detail::is_any_integer_v<Integer> && (sizeof (Integer) * 8 > 16 ), bool > = true >
1867- constexpr Integer operator >>(const Integer lhs, const int128_t rhs) noexcept
1893+ BOOST_INT128_EXPORT constexpr int128_t operator >>(const int128_t lhs, const int128_t rhs) noexcept
1894+ {
1895+ if (rhs.high != 0 || rhs.low >= 128 )
1896+ {
1897+ return 0 ;
1898+ }
1899+
1900+ return lhs << rhs.low ;
1901+ }
1902+
1903+ #ifdef BOOST_INT128_HAS_INT128
1904+
1905+ BOOST_INT128_EXPORT constexpr detail::builtin_u128 operator >>(const detail::builtin_u128 lhs, const int128_t rhs) noexcept
1906+ {
1907+ constexpr auto bit_width {sizeof (detail::builtin_u128) * 8 };
1908+
1909+ if (rhs.high != 0 || rhs.low >= bit_width)
1910+ {
1911+ return 0 ;
1912+ }
1913+
1914+ return lhs << rhs.low ;
1915+ }
1916+
1917+ BOOST_INT128_EXPORT constexpr detail::builtin_i128 operator >>(const detail::builtin_i128 lhs, const int128_t rhs) noexcept
18681918{
1869- constexpr auto bit_width {sizeof (Integer ) * 8 };
1919+ constexpr auto bit_width {sizeof (detail::builtin_i128 ) * 8 };
18701920
18711921 if (rhs.high != 0 || rhs.low >= bit_width)
18721922 {
18731923 return 0 ;
18741924 }
18751925
1876- return lhs >> rhs.low ;
1926+ return lhs << rhs.low ;
18771927}
18781928
1929+ #endif
1930+
18791931BOOST_INT128_EXPORT template <typename SignedInteger, std::enable_if_t <detail::is_signed_integer_v<SignedInteger> && (sizeof (SignedInteger) * 8 <= 16 ), bool > = true >
18801932constexpr int operator >>(const SignedInteger lhs, const int128_t rhs) noexcept
18811933{
@@ -1953,14 +2005,11 @@ constexpr int128_t& int128_t::operator++() noexcept
19532005 return *this ;
19542006}
19552007
1956- constexpr int128_t & int128_t ::operator ++(int ) noexcept
2008+ constexpr int128_t int128_t ::operator ++(int ) noexcept
19572009{
1958- if (++low == UINT64_C (0 ))
1959- {
1960- ++high;
1961- }
1962-
1963- return *this ;
2010+ const auto temp {*this };
2011+ ++(*this );
2012+ return temp;
19642013}
19652014
19662015// =====================================
@@ -1977,14 +2026,11 @@ constexpr int128_t& int128_t::operator--() noexcept
19772026 return *this ;
19782027}
19792028
1980- constexpr int128_t & int128_t ::operator --(int ) noexcept
2029+ constexpr int128_t int128_t ::operator --(int ) noexcept
19812030{
1982- if (low-- == UINT64_C (0 ))
1983- {
1984- --high;
1985- }
1986-
1987- return *this ;
2031+ const auto temp {*this };
2032+ --(*this );
2033+ return temp;
19882034}
19892035
19902036// =====================================
@@ -3199,17 +3245,14 @@ inline int128_t& int128_t::operator%=(const Integer rhs) noexcept
31993245
32003246#endif // BOOST_INT128_HAS_MSVC_INT128
32013247
3202- } // namespace int128
3203- } // namespace boost
3204-
3205- namespace std {
3248+ namespace detail {
32063249
3207- template <>
3208- class numeric_limits <boost::int128:: int128_t >
3250+ template <bool >
3251+ class numeric_limits_impl_i128
32093252{
32103253public:
32113254
3212- // Member constants
3255+ // Member constants
32133256 static constexpr bool is_specialized = true ;
32143257 static constexpr bool is_signed = true ;
32153258 static constexpr bool is_integer = true ;
@@ -3263,6 +3306,59 @@ class numeric_limits<boost::int128::int128_t>
32633306 static constexpr auto denorm_min () -> boost::int128::int128_t { return {0 , 0 }; }
32643307};
32653308
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+
32663362} // namespace std
32673363
32683364#endif // BOOST_INT128_DETAIL_INT128_HPP
0 commit comments