https://gcc.gnu.org/g:80fa93f2b4d46619c9410314915ef964b0690a1e

commit r17-1230-g80fa93f2b4d46619c9410314915ef964b0690a1e
Author: Tomasz Kamiński <[email protected]>
Date:   Thu Jan 15 14:45:53 2026 +0100

    libstdc++: Expand supported operations for __rand_uint128.
    
    This patch adds following operations to __rand_uint128:
    * explicit operator bool
    * operator- with __rand_uint128
    * operator* with uint64_t for _M_hi != 0
    * operator/ with uint64_t
    The division is currently stubbed by converting to __rand_uint128.
    
    When __rand_uint128 is used, the platform does not provide native 128bit
    integer types, thus random number generators will return at most 64bit
    integer. In consequence, __generate_cannonical_any will use these
    overloads when multiplying by result of generator invocation.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/random.h (__rand_uint128::operator bool):
            (__rand_uint128::operator-=(const type& __r))
            (__rand_uint128::operator-(type __l, const type& __r)):
            Implement.
            (__rand_uint128::operator/=(uint64_t __r))
            (__rand_uint128::operator/(type __l, uint64_t __r)):
            Define by converting to type.
            (__rand_uint128::operator*=(const type& __r)): Remove
            precondition and handle _M_hi != 0.
    
    Reviewed-by: Jonathan Wakely <[email protected]>
    Signed-off-by: Tomasz Kamiński <[email protected]>

Diff:
---
 libstdc++-v3/include/bits/random.h | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/random.h 
b/libstdc++-v3/include/bits/random.h
index a0592a007634..fd7b8b4fb202 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -90,6 +90,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       __rand_uint128(const __rand_uint128&) = default;
       __rand_uint128& operator=(const __rand_uint128&) = default;
 
+      constexpr explicit
+      operator bool() const noexcept
+      { return _M_lo || _M_hi; }
+
       _GLIBCXX14_CONSTEXPR type&
       operator=(uint64_t __x) noexcept
       { return *this = type(__x); }
@@ -134,6 +138,13 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       operator+(type __l, uint64_t __r) noexcept
       { return __l += type(__r); }
 
+      _GLIBCXX14_CONSTEXPR type&
+      operator-=(const type& __r) noexcept
+      {
+       _M_hi -= __r._M_hi + __builtin_sub_overflow(_M_lo, __r._M_lo, &_M_lo);
+       return *this;
+      }
+
       // Subtraction with 64-bit operand
       _GLIBCXX14_CONSTEXPR type&
       operator-=(uint64_t __r) noexcept
@@ -142,6 +153,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
        return *this;
       }
 
+      friend _GLIBCXX14_CONSTEXPR type
+      operator-(type __l, const type& __r) noexcept
+      { return __l -= __r; }
+
       friend _GLIBCXX14_CONSTEXPR type
       operator-(type __l, uint64_t __r) noexcept
       { return __l -= __r; }
@@ -172,7 +187,6 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       }
 
       // Multiplication with a 64-bit operand is simpler.
-      // pre: _M_hi == 0
       _GLIBCXX14_CONSTEXPR type&
       operator*=(uint64_t __x) noexcept
       {
@@ -190,7 +204,9 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
        // These bits are the low half of _M_hi and the high half of _M_lo.
        uint64_t __mid
          = (__l0x1 & __mask) + (__l1x0 & __mask) + (__l1x1 >> 32);
-       _M_hi = __l0x0 + (__l0x1 >> 32) + (__l1x0 >> 32) + (__mid >> 32);
+
+       _M_hi *= __x;
+       _M_hi += __l0x0 + (__l0x1 >> 32) + (__l1x0 >> 32) + (__mid >> 32);
        _M_lo = (__mid << 32) + (__l1x1 & __mask);
        return *this;
       }
@@ -296,6 +312,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
        return *this;
       }
 
+      _GLIBCXX14_CONSTEXPR type&
+      operator/=(uint64_t __r) noexcept
+      { return *this /= type(__r); }
+
       // Currently only supported for 64-bit operands.
       _GLIBCXX14_CONSTEXPR type&
       operator%=(uint64_t __m) noexcept
@@ -345,6 +365,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
       operator/(type __l, const type& __r) noexcept
       { return __l /= __r; }
 
+      friend _GLIBCXX14_CONSTEXPR type
+      operator/(type __l, uint64_t __r) noexcept
+      { return __l /= __r; }
+
       friend _GLIBCXX14_CONSTEXPR type
       operator%(type __l, uint64_t __m) noexcept
       { return __l %= __m; }

Reply via email to