Hi,

On Thu, 22 May 2025, 1nfocalypse wrote:

> Implements Philox Engine (P2075R6) and associated tests.
> 
> v2 corrects a multiline comment left in error in serialize.cc, and 
> additionally corrects a bug hidden by said comment, where the stream was 
> given the output of 'y()' instead of 'y', causing state to be
> incorrectly passed. Lastly, it fixes numerous whitespace issues found in the 
> original patch. My apologies for not noticing prior to the submission of the 
> original patch, which can now be disregarded.
> 
> To reiterate from the original email, the template unpacking functions are 
> placed in a private classifier prior to the public one due to an ordering 
> bug, where in order to function correctly, they must be
> placed prior to the bulk of the header. This is counter to the style 
> recommendations, but I was unable to obtain functionality any other way. 
> Additionally, while SIMD instructions are not utilized, and I do
> not think that they would integrate well with how the generator's state is 
> currently handled, some structure choices could be made that may make them of 
> interest.
> 
> Lastly, since word width can be specified, and thus atypical, maximum value 
> is calculated via some bit manipulation rather than numeric_limits, since the 
> specified width may differ from the width of the type
> used.
> 
> Built/tested on x86_64-linux-gnu.

Sorry for the delay and thanks for your patience!  Some initial review
comments below.

> 
>  *  1nfocalypse

>  > 
>  > 
>  Subject: [PATCH] [PATCH v2] libstdc++: implement Philox Engine [PR119794]
>  
>  The template unpacking functions, while private, are placed prior
>  to the public access specifier due to issues where the template
>  pack could not be unpacked and used to populate the public member
>  arrays without being declared beforehand.
>  
>  Additionally, the tests implemented attempt to mirror the tests
>  for other engines, when they apply. Changes to random
>  provided cause for changing 'pr60037-neg.cc' because it suppresses
>  an error by explicit line number. It should still be correctly
>  suppressed in this patch. Lastly, v2 fixes an issue in
>  'serialize.cc' for Philox, where a portion of the test was
>  commented out, hiding a bug where 'y()' was passed to the
>  stream instead of 'y'. Both have been remedied in this patch.

This implements the changes to the original paper
https://wg21.link/lwg4134
https://wg21.link/lwg4153
right?  Maybe we could make a note of that in the commit message.

>  
>  Plus some whitespace fixes.
>  
>       PR libstdc++/119794
>  
>  libstdc++-v3/ChangeLog:
>  
>       * include/bits/random.h: Add Philox Engine components.
>       * include/bits/random.tcc: Implement Philox Engine components.
>       * testsuite/26_numerics/random/pr60037-neg.cc: Alter line #.
>       * testsuite/26_numerics/random/inequal.cc: New test.
>       * testsuite/26_numerics/random/philox4x32.cc: New test.
>       * testsuite/26_numerics/random/philox4x64.cc: New test.
>       * testsuite/26_numerics/random/philox_engine/cons/
>       119794.cc: New test.
>       * testsuite/26_numerics/random/philox_engine/cons/
>       copy.cc: New test.
>       * testsuite/26_numerics/random/philox_engine/cons/
>       default.cc: New test.
>       * testsuite/26_numerics/random/philox_engine/cons/
>       seed.cc: New test.
>       * testsuite/26_numerics/random/philox_engine/cons/
>       seed_seq.cc: New test.
>       * testsuite/26_numerics/random/philox_engine/operators/
>       equal.cc: New test.
>       * testsuite/26_numerics/random/philox_engine/operators/
>       inequal.cc: New test.
>       * testsuite/26_numerics/random/philox_engine/operators/
>       serialize.cc: New test.
>       * testsuite/26_numerics/random/philox_engine/requirements/
>       constants.cc: New test.
>       * testsuite/26_numerics/random/philox_engine/requirements/
>       constexpr_data.cc: New test.
>       * testsuite/26_numerics/random/philox_engine/requirements/
>       constexpr_functions.cc: New test.
>       * testsuite/26_numerics/random/philox_engine/requirements/
>       typedefs.cc: New test.
>  ---
>   libstdc++-v3/include/bits/random.h            | 340 ++++++++++++++++++
>   libstdc++-v3/include/bits/random.tcc          | 201 +++++++++++
>   .../testsuite/26_numerics/random/inequal.cc   |  49 +++
>   .../26_numerics/random/philox4x32.cc          |  42 +++
>   .../26_numerics/random/philox4x64.cc          |  42 +++
>   .../random/philox_engine/cons/119794.cc       |  57 +++
>   .../random/philox_engine/cons/copy.cc         |  44 +++
>   .../random/philox_engine/cons/default.cc      |  46 +++
>   .../random/philox_engine/cons/seed.cc         |  39 ++
>   .../random/philox_engine/cons/seed_seq.cc     |  41 +++
>   .../random/philox_engine/operators/equal.cc   |  49 +++
>   .../random/philox_engine/operators/inequal.cc |  49 +++
>   .../philox_engine/operators/serialize.cc      |  68 ++++
>   .../philox_engine/requirements/constants.cc   |  45 +++
>   .../requirements/constexpr_data.cc            |  69 ++++
>   .../requirements/constexpr_functions.cc       |  60 ++++
>   .../philox_engine/requirements/typedefs.cc    |  45 +++
>   .../26_numerics/random/pr60037-neg.cc         |   2 +-
>   18 files changed, 1287 insertions(+), 1 deletion(-)
>   create mode 100644 libstdc++-v3/testsuite/26_numerics/random/inequal.cc
>   create mode 100644 libstdc++-v3/testsuite/26_numerics/random/philox4x32.cc
>   create mode 100644 libstdc++-v3/testsuite/26_numerics/random/philox4x64.cc
>   create mode 100644 
> libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/119794.cc
>   create mode 100644 
> libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/copy.cc
>   create mode 100644 
> libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/default.cc
>   create mode 100644 
> libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/seed.cc
>   create mode 100644 
> libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/seed_seq.cc
>   create mode 100644 
> libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/equal.cc
>   create mode 100644 
> libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/inequal.cc
>   create mode 100644 
> libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/serialize.cc
>   create mode 100644 
> libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constants.cc
>   create mode 100644 
> libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constexpr_data.cc
>   create mode 100644 
> libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constexpr_functions.cc
>   create mode 100644 
> libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/typedefs.cc
>  
>  diff --git a/libstdc++-v3/include/bits/random.h 
> b/libstdc++-v3/include/bits/random.h
>  index 1fdaf51934f..5c675927515 100644
>  --- a/libstdc++-v3/include/bits/random.h
>  +++ b/libstdc++-v3/include/bits/random.h
>  @@ -1688,6 +1688,328 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>       { return !(__lhs == __rhs); }
>   #endif
>   
>  +#if __cplusplus > 202302L

The implementation should more specifically be guarded by the
corresponding feature-test macro __cpp_lib_philox_engine
(defined to 202406L).

The way this is done nowadays in libstdc++ is to add philox_engine to
libstdc++-v3/include/bits/version.def and regenerate version.h via
'autogen version.def'.  This will define the internal feature-test macro
__glibcxx_philox_engine that we can check here.

In include/std/random, we need to do

#define __glibcxx_want_philox_engine
#include <bits/version.def>

so that the __cpp_lib_philox_engine is provided by that header.

>  +
>  +  /**
>  +   * @brief: A discrete pseudorandom number generator based off of weakened
>  +   * cryptographic primitives.
>  +   *
>  +   * This algorithm was intended to be used for highly parallel random 
> number
>  +   * generation, and is capable of immensely long periods.  It provides 
> "Crush-
>  +   * resistance", denoting an ability to pass the TestU01 Suite's "Big 
> Crush"
>  +   * test, demonstrating significant apparent entropy.  It is not intended 
> for
>  +   * cryptographic use and should not be used for such, despite being based 
> on
>  +   * cryptographic primitives.
>  +   *
>  +   * The two four-word definitions are likely the best use for this 
> algorithm,
>  +   * and are given below as defaults.
>  +   *
>  +   * This algorithm was created by John Salmon, Mark Moraes, Ron Dror, and
>  +   * David Shaw as a product of D.E. Shaw Research.
>  +   *
>  +   * @tparam __w    Word size
>  +   * @tparam __n    Buffer size
>  +   * @tparam __r    Rounds
>  +   * @tparam __consts       Multiplication and round constant pack, ordered 
> as
>  +   *                        M_{0}, C_{0}, M_{1}, C_{1}, ... , M_{N/2-1}, 
> C_{N/2-1}
>  +   *
>  +   * @headerfile random
>  +   * @since C++26
>  +   */
>  +  template<class _UIntType, size_t __w,
>  +          size_t __n, size_t __r,
>  +          _UIntType... __consts>
>  +    class philox_engine
>  +    {
>  +      static_assert(__n == 2 || __n == 4,
>  +          "template argument N must be either 2 or 4");
>  +      static_assert(sizeof...(__consts) == __n,
>  +          "length of consts array must match specified N");
>  +      static_assert(0 < __r, "a number of rounds must be specified");
>  +      static_assert((0 < __w && __w <= 
> numeric_limits<_UIntType>::digits)==1,

Can you remove the ==1?

>  +          "specified bitlength must match input type");
>  +      template<typename _Sseq>
>  +    using _If_seed_seq
>  +      = __detail::_If_seed_seq_for<_Sseq, philox_engine, _UIntType>;
>  +
>  +      private:
>  +    // the ordering here is essential to functionality.
>  +    /** @brief an internal unpacking function for %philox_engine.  */
>  +    static constexpr
>  +    std::array<_UIntType, __n / 2>
>  +    __popMultArray()
>  +    {
>  +      if constexpr (__n == 4)
>  +      {

We typically elide the braces for single-statement if branches.

>  +        return
>  +          std::array<_UIntType, __n / 2> {__consts...[0], __consts...[2]};
>  +      } else
>  +      {
>  +        return std::array<_UIntType, __n / 2> { __consts...[0] };
>  +      }
>  +    }
>  +
>  +    /** @brief an internal unpacking function for %philox_engine.  */
>  +    static constexpr
>  +    std::array<_UIntType, __n / 2>
>  +    __popConstArray()
>  +    {
>  +      if constexpr (__n == 4)
>  +      {
>  +        return
>  +          std::array<_UIntType, __n / 2> {__consts...[1], __consts...[3]};
>  +      } else
>  +      {
>  +        return std::array<_UIntType, __n / 2> {__consts...[1] };
>  +      }
>  +    }
>  +
>  +      public:
>  +    /** Type of template param.  */
>  +    using result_type = _UIntType;
>  +    // public members
>  +    static constexpr size_t word_size = __w;
>  +    static constexpr size_t word_count = __n;
>  +    static constexpr size_t round_count = __r;
>  +    static constexpr std::array<result_type, __n / 2> multipliers =
>  +       philox_engine::__popMultArray();
>  +    static constexpr std::array<result_type, __n / 2> round_consts =
>  +       philox_engine::__popConstArray();
>  +
>  +    /** @brief returns the minimum value possible.  */
>  +    static constexpr result_type
>  +    min()
>  +    { return 0; }
>  +
>  +    /** @brief returns the maximum value possible.  */
>  +    static constexpr result_type
>  +    max()
>  +    {
>  +      return ((1ull << (__w - 1)) | ((1ull << (__w - 1)) - 1));
>  +    }
>  +    // default key value
>  +    static constexpr result_type default_seed = 20111115u;
>  +
>  +    // constructors
>  +    philox_engine()
>  +    : philox_engine(default_seed)
>  +    {}
>  +
>  +    explicit
>  +    philox_engine(result_type __value);
>  +
>  +    /** @brief seed sequence constructor for %philox_engine
>  +      *
>  +      *  @params __q the seed sequence
>  +      */
>  +    template<typename _Sseq, typename = _If_seed_seq<_Sseq>>
>  +      explicit
>  +      philox_engine(_Sseq& __q)
>  +      {
>  +        seed(__q);
>  +      }
>  +
>  +
>  +    void
>  +    seed(result_type value = default_seed);
>  +
>  +    /** @brief seeds %philox_engine by seed sequence
>  +      *
>  +      * @params __q the seed sequence
>  +      */
>  +    template<typename _Sseq>
>  +      _If_seed_seq<_Sseq>
>  +      seed(_Sseq& __q);
>  +
>  +    /** @brief sets the internal counter "cleartext"
>  +      *
>  +      * @params __counter std::array of len N
>  +      */
>  +    void
>  +    set_counter(const std::array<result_type, __n>& __counter);
>  +
>  +    /** @brief compares two %philox_engine objects
>  +      *
>  +      * @params __x A %philox_engine object
>  +      * @params __y A %philox_engine object
>  +      *
>  +      * @returns true if the objects will produce an identical stream, false
>  +      * otherwise
>  +      */
>  +    friend bool
>  +    operator==(const philox_engine& __x, const philox_engine& __y)
>  +    {
>  +      return
>  +        {

Please use parens here instead.  It should be formatted as

  return (std::equal(...)
          && ...
          && __x._M_ == __y._M_i);

>  +          std::equal(__x.__x.begin(), __x.__x.end(),
>  +                    __y.__x.begin(), __y.__x.end()) &&
>  +          std::equal(__x.__y.begin(), __x.__y.end(),
>  +                    __y.__y.begin(), __y.__y.end()) &&
>  +          std::equal(__x.__k.begin(), __x.__k.end(),
>  +                    __y.__k.begin(), __y.__k.end()) &&
>  +          __x.__i == __y.__i
>  +        };
>  +    }
>  +
>  +
>  +    _UIntType
>  +    operator()();
>  +
>  +    /** @brief discards __z numbers
>  +      *
>  +      * @params __z number of iterations to discard
>  +      */
>  +    void
>  +    discard(unsigned long long __z);
>  +
>  +    // Note: hidden friend seems best, suspect a better way of doing things
>  +    // but unable to find it
>  +    /** @brief outputs the state of the generator
>  +     *
>  +     * @param __os An output stream.
>  +     * @param __x  A %philox_engine object reference
>  +     *
>  +     * @returns the state of the Philox Engine in __os
>  +     */
>  +    template<typename _charT, typename _traits>
>  +      friend basic_ostream<_charT, _traits>&
>  +        operator<<(basic_ostream<_charT, _traits>& __os,
>  +          const philox_engine& __x)
>  +          {
>  +            using __ios_base =
>  +              typename basic_ostream<_charT, _traits>::ios_base;
>  +            const typename __ios_base::fmtflags __flags = __os.flags();
>  +            const _charT __fill = __os.fill();
>  +            __os.flags(__ios_base::dec | __ios_base::left);
>  +            __os.fill(__os.widen(' '));
>  +            auto __it = __x.__k.begin();
>  +            while (__it != __x.__k.end())
>  +            {
>  +              __os << *__it << ' ';
>  +              ++__it;
>  +            }
>  +            auto __it2 = __x.__x.begin();
>  +            while (__it2 != __x.__x.end())
>  +            {
>  +              __os << *__it2 << ' ';
>  +              ++__it2;
>  +            }
>  +            __os << __x.__i;
>  +            __os.flags(__flags);
>  +            __os.fill(__fill);
>  +            return __os;
>  +          }
>  +
>  +    /** @brief takes input to set the state of the %philox_engine object
>  +      *
>  +      * @param __is An input stream.
>  +      * @param __x  A %philox_engine object reference
>  +      *
>  +      * @returns %philox_engine object is set with values from instream
>  +      */
>  +    template <typename _charT, typename _traits>
>  +      friend basic_istream<_charT, _traits>&
>  +        operator>>(basic_istream<_charT, _traits>& __is,
>  +          philox_engine& __x)
>  +          {
>  +            using __ios_base =
>  +              typename basic_istream<_charT, _traits>::ios_base;
>  +            const typename __ios_base::fmtflags __flags = __is.flags();
>  +            __is.flags(__ios_base::dec | __ios_base::skipws);
>  +            for (size_t __j = 0; __j < __x.__k.size(); ++__j)
>  +            {
>  +              __is >> __x.__k[__j];
>  +            }
>  +            for (size_t __j = 0; __j < __x.__x.size(); ++__j)
>  +            {
>  +              __is >> __x.__x[__j];
>  +            }
>  +            std::array<_UIntType, __n> __tmpCtr = __x.__x;
>  +            unsigned char __setIndex = 0;
>  +            for (size_t __j = 0; __j < __x.__x.size(); ++__j)
>  +            {
>  +              if (__x.__x[__j] > 0)
>  +              {
>  +                __setIndex = __j;
>  +                break;
>  +              }
>  +            }
>  +            for (size_t __j = 0; __j <= __setIndex; ++__j)
>  +            {
>  +              if (__j != __setIndex)
>  +              {
>  +                __x.__x[__j] = max();
>  +              } else
>  +              {
>  +                --__x.__x[__j];
>  +              }
>  +            }
>  +            __x.__philox();
>  +            __x.__x = __tmpCtr;
>  +            __is >> __x.__i;
>  +            __is.flags(__flags);
>  +            return __is;
>  +          }
>  +      private:
>  +    // private state variables
>  +    std::array<_UIntType, __n> __x;
>  +    std::array<_UIntType, __n / 2> __k;
>  +    std::array<_UIntType, __n> __y;
>  +    unsigned long long __i = 0;

In libstdc++, internal non-static data members are conventionally
uglified as _M_foo.  Internal static members are uglified as _S_foo.

>  +
>  +    /** @brief Takes the high values of the product of __a, __b
>  +      *
>  +      * @params __a an unsigned integer
>  +      * @params __b an unsigned integer
>  +      *
>  +      * @returns an unsigned integer of at most bitlength W
>  +      */
>  +    _UIntType
>  +    __mulhi(_UIntType __a, _UIntType __b); // (A*B)/2^W
>  +
>  +    /** @brief Takes the low values of the product of __a, __b
>  +      *
>  +      * @params __a an unsigned integer
>  +      * @params __b an unsigned integer
>  +      *
>  +      * @returns an unsigned integer of at most bitlength W
>  +      */
>  +    _UIntType
>  +    __mullo(_UIntType __a, _UIntType __b); // (A*B)%2^W
>  +
>  +    /** @brief an R-round SP-net followed by a Feistel Network for
>  +      * %philox_engine
>  +      */
>  +    void
>  +    __philox();
>  +
>  +    /** @brief an internal transition function for the %philox_engine.  */
>  +    void
>  +    __transition();
>  +    };
>  +
>  +  /**
>  +   * Compares two %philox_engine random number generator objects
>  +   * of the same type for inequality.
>  +   *
>  +   * @param __lhs A %philox_engine random number generator object.
>  +   * @param __rhs Another %philox_engine random number generator
>  +   *                  object.
>  +   *
>  +   * @returns true if the streams would be different, false otherwise.
>  +   */
>  +  template<class _UIntType, size_t __w,
>  +       size_t __n, size_t __r,
>  +       _UIntType... __consts>
>  +  inline bool
>  +  operator!=(const std::philox_engine<_UIntType, __w,
>  +         __n, __r, __consts...>& __lhs,
>  +         const std::philox_engine<_UIntType, __w,
>  +         __n, __r, __consts...>& __rhs)
>  +  { return !(__lhs == __rhs); }
>  +
>  +#endif
>  +
>     /**
>      * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
>      */
>  @@ -1742,6 +2064,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   
>     typedef minstd_rand0 default_random_engine;
>   
>  +#if __cplusplus > 202302L
>  +
>  +  typedef philox_engine<
>  +    uint_fast32_t,
>  +    32, 4, 10,
>  +    0xCD9E8D57, 0x9E3779B9,
>  +    0xD2511F53, 0xBB67AE85> philox4x32;
>  +
>  +  /**
>  +   * Alternative Philox instance (64 bit)
>  +   */
>  +  typedef philox_engine<
>  +    std::uint_fast64_t,
>  +    64, 4, 10,
>  +    0xCA5A826395121157, 0x9E3779B97F4A7C15,
>  +    0xD2E7470EE14C6C93, 0xBB67AE8584CAA73B> philox4x64;
>  +#endif
>  +
>     /**
>      * A standard interface to a platform-specific non-deterministic
>      * random number generator (if any are available).
>  diff --git a/libstdc++-v3/include/bits/random.tcc 
> b/libstdc++-v3/include/bits/random.tcc
>  index 53ccacb2e38..faba3b6d4b5 100644
>  --- a/libstdc++-v3/include/bits/random.tcc
>  +++ b/libstdc++-v3/include/bits/random.tcc
>  @@ -518,6 +518,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>         return __is;
>       }
>   
>  +
>  +
>   #if ! __cpp_inline_variables
>     template<typename _UIntType, size_t __w, size_t __s, size_t __r>
>       constexpr size_t
>  @@ -907,6 +909,205 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>         return __is;
>       }
>   
>  +#if __cplusplus > 202302L
>  +
>  +  template<class _UIntType,
>  +    size_t __w, size_t __n,
>  +    size_t __r, _UIntType... __consts>
>  +  _UIntType
>  +  std::philox_engine<_UIntType,

I believe std:: prefix here is unnecessary since we're already inside
the std namespace.  Why are some member functions defined inline and
some out-of-line?

>  +  __w, __n, __r, __consts...>::__mulhi(_UIntType __a, _UIntType __b)
>  +  {
>  +    const __uint128_t __num =

Since not all targets provide a 128-bit integer type, I think we need to
disable philox_engine on targets lacking it.  The easiest way would be
to add __SIZEOF_INT128__ to extra_conds in the corresponding version.def
entry.

>  +    static_cast<__uint128_t>(__a) * static_cast<__uint128_t>(__b);
>  +    const __uint128_t __div = (static_cast<__uint128_t>(1) << __w);
>  +    return static_cast<_UIntType>((__num / __div) & this->max());

Can we just right-shift by __w instead of dividing by 1 << __w?

>  +  }
>  +
>  +  template<class _UIntType,
>  +    size_t __w, size_t __n,
>  +    size_t __r, _UIntType... __consts>
>  +  _UIntType
>  +  std::philox_engine<_UIntType,
>  +  __w, __n, __r, __consts...>::__mullo(_UIntType __a, _UIntType __b)
>  +  {
>  +    return ((__a * __b) & max());
>  +  }
>  +
>  +  template<class _UIntType,
>  +    size_t __w, size_t __n,
>  +    size_t __r, _UIntType... __consts>
>  +  void
>  +  std::philox_engine<_UIntType, __w, __n, __r, __consts...>::__transition()
>  +  {
>  +    ++__i;
>  +    if (__i == __n)
>  +    {
>  +      __philox();
>  +      if (__n == 4)
>  +      {
>  +    __uint128_t __uh =
>  +    {
>  +      (static_cast<__uint128_t>(this->__x[1]) << __w)
>  +            | ((this->__x[0]) + 1)
>  +    };
>  +    __uint128_t __lh =
>  +    {
>  +      ((static_cast<__uint128_t>(this->__x[3]) << __w)
>  +            | (this->__x[2]))
>  +    };
>  +    if (!(__uh & this->max()))
>  +    {
>  +      ++__lh;
>  +      __uh = 0;
>  +    }
>  +    this->__x[0] = __uh & this->max();
>  +    this->__x[1] = (__uh >> (__w)) & this->max();
>  +    this->__x[2] = __lh & this->max();
>  +    this->__x[3] = (__lh >> (__w)) & this->max();
>  +      } else
>  +      {
>  +    __uint128_t __num = ((this->__x[1] << __w)) | ((this->__x[0]) + 1);
>  +    this->__x[0] = __num & this->max();
>  +    this->__x[1] = (__num >> __w) & this->max();
>  +      }
>  +      __i = 0;
>  +    }
>  +  }
>  +
>  +  template<class _UIntType,
>  +    size_t __w, size_t __n,
>  +    size_t __r, _UIntType... __consts>
>  +  void
>  +  std::philox_engine<_UIntType, __w, __n, __r, __consts...>::__philox()
>  +  {
>  +    std::array<_UIntType, __n> __outputSeq{};
>  +    for (size_t __j = 0; __j < __n; ++__j)
>  +    {
>  +      __outputSeq[__j] = __x[__j];
>  +    }
>  +    for (unsigned long __j = 0; __j < __r; ++__j)
>  +    {
>  +      std::array<_UIntType, __n> __intermedSeq{};
>  +      if (__n == 4)
>  +      {
>  +    __intermedSeq[0] = __outputSeq[2];
>  +    __intermedSeq[1] = __outputSeq[1];
>  +    __intermedSeq[2] = __outputSeq[0];
>  +    __intermedSeq[3] = __outputSeq[3];
>  +      } else
>  +      {
>  +    __intermedSeq[0] = __outputSeq[0];
>  +    __intermedSeq[1] = __outputSeq[1];
>  +      }
>  +      for (unsigned long __k = 0; __k < (__n/2); ++__k)
>  +      {
>  +    __outputSeq[2*__k]= __mulhi(__intermedSeq[2*__k], multipliers[__k])
>  +      ^ (((this->__k[__k] + (__j * round_consts[__k])) & this->max()))
>  +      ^ __intermedSeq[2*__k+1];
>  +
>  +    __outputSeq[(2*__k)+1]= __mullo(__intermedSeq[2*__k],
>  +      multipliers[__k]);
>  +      }
>  +    }
>  +    for (unsigned long __j = 0; __j < __n; ++__j)
>  +    {
>  +      __y[__j] = __outputSeq[__j];
>  +    }
>  +  }
>  +
>  +  template<class _UIntType,
>  +    size_t __w, size_t __n,
>  +    size_t __r, _UIntType... __consts>
>  +  std::philox_engine<_UIntType,
>  +    __w, __n, __r, __consts...>::philox_engine(result_type __value)
>  +  {
>  +    std::fill(__x.begin(), __x.end(), 0);
>  +    std::fill(__k.begin(), __k.end(), 0);
>  +    std::fill(__y.begin(), __y.end(), 0);
>  +    __k[0] = __value & this->max();
>  +    __i = __n - 1;
>  +  }
>  +
>  +  template<class _UIntType,
>  +    size_t __w, size_t __n,
>  +    size_t __r, _UIntType... __consts>
>  +  void
>  +  std::philox_engine<_UIntType,
>  +  __w, __n, __r, __consts...>::seed(result_type __value)
>  +  {
>  +    std::fill(__x.begin(), __x.end(), 0);
>  +    std::fill(__k.begin(), __k.end(), 0);
>  +    std::fill(__y.begin(), __y.end(), 0);
>  +    __k[0] = __value & this->max();
>  +    __i = __n - 1;
>  +  }
>  +
>  +  template<class _UIntType,
>  +    size_t __w, size_t __n,
>  +    size_t __r, _UIntType... __consts>
>  +  void
>  +  std::philox_engine<_UIntType, __w,
>  +  __n, __r, __consts...>::set_counter(const array<result_type, __n>& 
> __counter)
>  +  {
>  +    for (unsigned long long __j = 0; __j < __n; ++__j)
>  +    {
>  +      __x[__j] = __counter[__n - 1 - __j] & this->max();
>  +    }
>  +    __i = __n - 1;
>  +  }
>  +
>  +  template<class _UIntType,
>  +    size_t __w, size_t __n,
>  +    size_t __r, _UIntType... __consts>
>  +  template<typename _Sseq>
>  +  auto
>  +  std::philox_engine<_UIntType, __w, __n, __r, __consts...>::seed(_Sseq& 
> __q)
>  +  -> _If_seed_seq<_Sseq>
>  +  {
>  +    std::fill(__k.begin(), __k.end(), 0);
>  +    const unsigned long long __p = 1 + ((__w - 1/ 32));
>  +    uint_least32_t __tmpArr[(__n / 2) * __p];
>  +    __q.generate(__tmpArr + 0, __tmpArr + ((__n / 2) *__p));
>  +    for (unsigned long long __k = 0; __k < (__n/2) - 1; ++__k)

this->__k has n/2 elements, but this loop is up to n/2 - 1?

>  +    {
>  +      unsigned long long __precalc = 0;
>  +      for (unsigned long long __j = 0; __j < __p; ++__j)
>  +      {
>  +    unsigned long long __multiplicand = (1ull << (32 * __j - 1));

I believe this left shift is UB when __j is zero (and so the shift
amount is huge).

>  +    __precalc += (__tmpArr[__k*__p + __j] * __multiplicand) & this->max();
>  +      }
>  +      this->__k[__k] = __precalc;
>  +    }
>  +    std::fill(__x.begin(), __x.end(), 0);
>  +    std::fill(__y.begin(), __y.begin(), 0);

__y.begin(), __y.end() rather?

>  +    __i = __n - 1;
>  +  }
>  +
>  +  template<class _UIntType,
>  +    size_t __w, size_t __n,
>  +    size_t __r, _UIntType... __consts>
>  +  void
>  +  std::philox_engine<_UIntType,
>  +    __w, __n, __r, __consts...>::discard(unsigned long long __z)
>  +  {
>  +    for (unsigned long long __j = 0; __j < __z; ++__j)
>  +    {
>  +      __transition();
>  +    }
>  +  }
>  +
>  +  template<class _UIntType,
>  +    size_t __w, size_t __n,
>  +    size_t __r, _UIntType... __consts>
>  +  _UIntType
>  +  std::philox_engine<_UIntType, __w, __n, __r, __consts...>::operator()()
>  +  {
>  +    __transition();
>  +    return __y[__i];
>  +  }
>  +
>  +#endif
>   
>     template<typename _IntType, typename _CharT, typename _Traits>
>       std::basic_ostream<_CharT, _Traits>&
>  diff --git a/libstdc++-v3/testsuite/26_numerics/random/inequal.cc 
> b/libstdc++-v3/testsuite/26_numerics/random/inequal.cc
>  new file mode 100644
>  index 00000000000..081c908a3eb
>  --- /dev/null
>  +++ b/libstdc++-v3/testsuite/26_numerics/random/inequal.cc
>  @@ -0,0 +1,49 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025-04-09   1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025-2034 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library. This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3. If not see
>  +// https://www.gnu.org/licenses>

Nowadays we don't add license headers to tests.

>  +
>  +// 29.5.4 Random Number Engine Class Templates
>  +// 29.5.4.5 Class Template philox_engine
>  +
>  +#include <random>
>  +#include <testsuite_hooks.h>
>  +
>  +void
>  +test01()
>  +{
>  +  std::philox_engine<std::uint_fast32_t,
>  +                  32, 4, 10, 0xCD9E8D57,
>  +                  0x9E3779B9, 0xD2511F53,
>  +                  0xBB67AE85> x, y;
>  +
>  +  VERIFY ( !(x != y) );
>  +  x.discard(100);
>  +  y.discard(100);
>  +
>  +  VERIFY ( !(x != y) );
>  +}
>  +
>  +int
>  +main()
>  +{
>  +  test01();
>  +  return 0;
>  +}
>  diff --git a/libstdc++-v3/testsuite/26_numerics/random/philox4x32.cc 
> b/libstdc++-v3/testsuite/26_numerics/random/philox4x32.cc
>  new file mode 100644
>  index 00000000000..67fd8455f51
>  --- /dev/null
>  +++ b/libstdc++-v3/testsuite/26_numerics/random/philox4x32.cc
>  @@ -0,0 +1,42 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025-04-09       1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library. This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3. If not see
>  +// https://www.gnu.org/licenses>
>  +
>  +// 29.5.4 Random Number Engine Class Templates
>  +// 29.5.4.5 Class Template philox_engine
>  +
>  +#include <random>
>  +#include <testsuite_hooks.h>
>  +
>  +void
>  +test01()
>  +{
>  +  std::philox4x32 a;
>  +  a.discard(9999);
>  +
>  +  VERIFY( a() == 1955073260 );
>  +}
>  +
>  +int main()
>  +{
>  +  test01();
>  +  return 0;
>  +}
>  diff --git a/libstdc++-v3/testsuite/26_numerics/random/philox4x64.cc 
> b/libstdc++-v3/testsuite/26_numerics/random/philox4x64.cc
>  new file mode 100644
>  index 00000000000..9eb1722f2da
>  --- /dev/null
>  +++ b/libstdc++-v3/testsuite/26_numerics/random/philox4x64.cc
>  @@ -0,0 +1,42 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025-04-09   1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library. This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3. If not see
>  +// https://www.gnu.org/licenses>
>  +
>  +// 29.5.4 Random Number Engine Class Templates
>  +// 29.5.4.5 Class Template philox_engine
>  +
>  +#include <random>
>  +#include <testsuite_hooks.h>
>  +
>  +void
>  +test01()
>  +{
>  +  std::philox4x64 a;
>  +  a.discard(9999);
>  +
>  +  VERIFY( a() == 3409172418970261260 );
>  +}
>  +
>  +int main()
>  +{
>  +  test01();
>  +  return 0;
>  +}
>  diff --git 
> a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/119794.cc 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/119794.cc
>  new file mode 100644
>  index 00000000000..2884d6e3117
>  --- /dev/null
>  +++ b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/119794.cc
>  @@ -0,0 +1,57 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// Copyright (C) 2025 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library.  This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3.  If not see
>  +// <http://www.gnu.org/licenses/>.
>  +
>  +
>  +#include <random>
>  +#include <testsuite_hooks.h>
>  +
>  +int f(int x)
>  +{
>  +  std::seed_seq sq(&x, &x + 1);
>  +  auto rnd = std::philox4x32(sq);
>  +  return std::uniform_int_distribution<int>()(rnd);
>  +}
>  +
>  +int g(int x)
>  +{
>  +  std::seed_seq sq(&x, &x + 1);
>  +  auto rnd = std::philox4x32();
>  +  rnd.seed(sq);
>  +  return std::uniform_int_distribution<int>()(rnd);
>  +}
>  +
>  +void test01()
>  +{
>  +  const int f1 = f(0);
>  +  const int f2 = f(0);
>  +
>  +  const int g1 = g(0);
>  +  const int g2 = g(0);
>  +
>  +  VERIFY( f1 == f2 );
>  +  VERIFY( g1 == g2 );
>  +  VERIFY( f1 == g1 );
>  +}
>  +
>  +int main()
>  +{
>  +  test01();
>  +  return 0;
>  +}
>  diff --git 
> a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/copy.cc 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/copy.cc
>  new file mode 100644
>  index 00000000000..64b96a91559
>  --- /dev/null
>  +++ b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/copy.cc
>  @@ -0,0 +1,44 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025-04-09   1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library. This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3. If not see
>  +// https://www.gnu.org/licenses>
>  +
>  +// 29.5.4 Random Number Engine Class Templates
>  +// 29.5.4.5 Class Template philox_engine
>  +
>  +#include <random>
>  +
>  +void
>  +test01()
>  +{
>  +
>  +  std::philox_engine<std::uint_fast32_t, 32, 4, 10, 0xCD9E8D57,
>  +    0x9E3779B9, 0xD2511F53, 0xBB67AE85> e(1ul);
>  +
>  +  const auto f(e);
>  +  auto g(f);
>  +  g = g; // Suppress unused warning
>  +}
>  +
>  +int main()
>  +{
>  +  test01();
>  +  return 0;
>  +}
>  diff --git 
> a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/default.cc 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/default.cc
>  new file mode 100644
>  index 00000000000..1bdee6e7911
>  --- /dev/null
>  +++ b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/default.cc
>  @@ -0,0 +1,46 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025-04-09   1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025-2034 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library. This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3. If not see
>  +// https://www.gnu.org/licenses>
>  +
>  +// 29.5.4 Random Number Engine Class Templates
>  +// 29.5.4.5 Class Template philox_engine
>  +
>  +#include <random>
>  +#include <testsuite_hooks.h>
>  +
>  +void
>  +test01()
>  +{
>  +  std::philox_engine<std::uint_fast32_t,
>  +                 32, 4, 10, 0xCD9E8D57,
>  +                 0x9E3779B9, 0xD2511F53,
>  +                 0xBB67AE85> philox4x32nullkey(0);
>  +
>  +  VERIFY( philox4x32nullkey.min() == 0 );
>  +  VERIFY( philox4x32nullkey.max() == (1ul << 31 | (1ul << 31) - 1) );
>  +  VERIFY( philox4x32nullkey() == 0x6627e8d5ul );
>  +}
>  +
>  +int main()
>  +{
>  +  test01();
>  +  return 0;
>  +}
>  diff --git 
> a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/seed.cc 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/seed.cc
>  new file mode 100644
>  index 00000000000..91ef286e5e1
>  --- /dev/null
>  +++ b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/seed.cc
>  @@ -0,0 +1,39 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025  1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library.  This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3.  If not see
>  +// <http://www.gnu.org/licenses/>.
>  +
>  +#include <random>
>  +
>  +void
>  +test01()
>  +{
>  +  unsigned long seed = 2;
>  +  std::philox_engine<std::uint_fast32_t,
>  +                 32, 4, 10, 0xCD9E8D57,
>  +                 0x9E3779B9, 0xD2511F53,
>  +                 0xBB67AE85> philox4x32seeded(seed);
>  +}
>  +
>  +int main()
>  +{
>  +  test01();
>  +  return 0;
>  +}
>  diff --git 
> a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/seed_seq.cc 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/seed_seq.cc
>  new file mode 100644
>  index 00000000000..d35ce5fa05b
>  --- /dev/null
>  +++ 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/seed_seq.cc
>  @@ -0,0 +1,41 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025-04-09   1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025-2034 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library. This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3. If not see
>  +// https://www.gnu.org/licenses>
>  +
>  +// 29.5.4 Random Number Engine Class Templates
>  +// 29.5.4.5 Class Template philox_engine
>  +
>  +void
>  +test01()
>  +{
>  +  std::seed_seq sseq{ 1, 2, 3, 4 };
>  +  std::philox_engine<std::uint_fast32_t,
>  +                 32, 4, 10, 0xCD9E8D57,
>  +                 0x9E3779B9, 0xD2511F53,
>  +                 0xBB67AE85> philox4x32sseq(sseq);
>  +}
>  +
>  +int
>  +main()
>  +{
>  +  test01();
>  +  return 0;
>  +}
>  diff --git 
> a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/equal.cc 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/equal.cc
>  new file mode 100644
>  index 00000000000..17cc2216791
>  --- /dev/null
>  +++ 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/equal.cc
>  @@ -0,0 +1,49 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025-04-09   1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025-2034 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library. This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3. If not see
>  +// https://www.gnu.org/licenses>
>  +
>  +// 29.5.4 Random Number Engine Class Templates
>  +// 29.5.4.5 Class Template philox_engine
>  +
>  +#include <random>
>  +#include <testsuite_hooks.h>
>  +
>  +void
>  +test01()
>  +{
>  +  std::philox_engine<std::uint_fast32_t,
>  +                 32, 4, 10, 0xCD9E8D57,
>  +                 0x9E3779B9, 0xD2511F53,
>  +                 0xBB67AE85> x, y;
>  +
>  +  VERIFY ( x == y);
>  +  x.discard(100);
>  +  y.discard(100);
>  +
>  +  VERIFY (x == y);
>  +}
>  +
>  +int
>  +main()
>  +{
>  +  test01();
>  +  return 0;
>  +}
>  diff --git 
> a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/inequal.cc
>  
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/inequal.cc
>  new file mode 100644
>  index 00000000000..c8255249ed8
>  --- /dev/null
>  +++ 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/inequal.cc
>  @@ -0,0 +1,49 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025-04-09   1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025-2034 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library. This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3. If not see
>  +// https://www.gnu.org/licenses>
>  +
>  +// 29.5.4 Random Number Engine Class Templates
>  +// 29.5.4.5 Class Template philox_engine
>  +
>  +#include <random>
>  +#include <testsuite_hooks.h>
>  +
>  +void
>  +test01()
>  +{
>  +  std::philox_engine<std::uint_fast32_t,
>  +                32, 4, 10, 0xCD9E8D57,
>  +                0x9E3779B9, 0xD2511F53,
>  +                0xBB67AE85> x, y;
>  +
>  +  VERIFY ( !(x != y) );
>  +  x.discard(100);
>  +  y.discard(100);
>  +
>  +  VERIFY ( !(x != y) );
>  +}
>  +
>  +int
>  +main()
>  +{
>  +  test01();
>  +  return 0;
>  +}
>  diff --git 
> a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/serialize.cc
>  
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/serialize.cc
>  new file mode 100644
>  index 00000000000..f3672f956b9
>  --- /dev/null
>  +++ 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/serialize.cc
>  @@ -0,0 +1,68 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025-04-09   1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025-2034 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library. This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3. If not see
>  +// https://www.gnu.org/licenses>
>  +
>  +// 29.5.4 Random Number Engine Class Templates
>  +// 29.5.4.5 Class Template philox_engine
>  +
>  +#include <sstream>
>  +#include <random>
>  +#include <testsuite_hooks.h>
>  +#include <iostream>
>  +
>  +void
>  +test01()
>  +{
>  +  std::stringstream str;
>  +  std::philox_engine<std::uint_fast32_t,
>  +                 32, 4, 10, 0xCD9E8D57,
>  +                 0x9E3779B9, 0xD2511F53,
>  +                 0xBB67AE85> x, y;
>  +
>  +  x();
>  +  str << x;
>  +
>  +  VERIFY ( !(x == y) );
>  +  str >> y;
>  +  VERIFY ( x == y );
>  +  for (unsigned long i = 0; i < 100; ++i)
>  +  {
>  +    VERIFY (x() == y());
>  +  }
>  +  str.clear();
>  +  str << y;
>  +  x();
>  +  x();
>  +  x();
>  +  str >> x;
>  +  VERIFY ( x == y );
>  +  for (unsigned long i = 0; i < 1000; ++i)
>  +  {
>  +    VERIFY (x() == y());
>  +  }
>  +}
>  +
>  +int
>  +main()
>  +{
>  +  test01();
>  +  return 0;
>  +}
>  diff --git 
> a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constants.cc
>  
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constants.cc
>  new file mode 100644
>  index 00000000000..80579f4cf91
>  --- /dev/null
>  +++ 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constants.cc
>  @@ -0,0 +1,45 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025-04-09   1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025-2034 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library. This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3. If not see
>  +// https://www.gnu.org/licenses>
>  +
>  +// 29.5.4 Random Number Engine Class Templates
>  +// 29.5.4.5 Class Template philox_engine
>  +
>  +#include <random>
>  +
>  +void test01()
>  +{
>  +  std::philox4x32 philox;
>  +  const void* p = &philox.word_size;
>  +  p = &philox.word_count;
>  +  p = &philox.round_count;
>  +  p = &philox.multipliers;
>  +  p = &philox.round_consts;
>  +  p = &philox.default_seed;
>  +  p = p; // Suppress unused warning.
>  +}
>  +
>  +int
>  +main()
>  +{
>  +  test01;

test01(); ?

>  +  return 0;
>  +}
>  diff --git 
> a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constexpr_data.cc
>  
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constexpr_data.cc
>  new file mode 100644
>  index 00000000000..6832f17c833
>  --- /dev/null
>  +++ 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constexpr_data.cc
>  @@ -0,0 +1,69 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025-04-09   1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025-2034 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library. This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3. If not see
>  +// https://www.gnu.org/licenses>
>  +
>  +// 29.5.4 Random Number Engine Class Templates
>  +// 29.5.4.5 Class Template philox_engine
>  +
>  +#include <random>
>  +#include <testsuite_common_types.h>
>  +
>  +namespace __gnu_test
>  +{
>  +  struct constexpr_member_data
>  +  {
>  +    template<typename _Ttesttype>
>  +      void
>  +      operator()()
>  +      {
>  +    struct _Concept
>  +    {
>  +      void __constraint()
>  +      {
>  +        constexpr auto v1 __attribute__((unused))
>  +            = _Ttesttype::word_size;
>  +        constexpr auto v2 __attribute__((unused))
>  +            = _Ttesttype::word_count;
>  +        constexpr auto v3 __attribute__((unused))
>  +            = _Ttesttype::round_count;
>  +        constexpr auto v4 __attribute__((unused))
>  +            = _Ttesttype::multipliers;
>  +        constexpr auto v5 __attribute__((unused))
>  +            = _Ttesttype::round_consts;
>  +        constexpr auto v6 __attribute__((unused))
>  +            = _Ttesttype::default_seed;
>  +      }
>  +    };
>  +
>  +    _Concept c;
>  +    c.__constraint();
>  +      }
>  +  };
>  +};
>  +
>  +int
>  +main()
>  +{
>  +  __gnu_test::constexpr_member_data test;
>  +  typedef std::philox4x32 type;
>  +  test.operator()<type>();
>  +  return 0;
>  +}
>  diff --git 
> a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constexpr_functions.cc
>  
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constexpr_functions.cc
>  new file mode 100644
>  index 00000000000..6209573a211
>  --- /dev/null
>  +++ 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constexpr_functions.cc
>  @@ -0,0 +1,60 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025-04-09   1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025-2034 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library. This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3. If not see
>  +// https://www.gnu.org/licenses>
>  +
>  +// 29.5.4 Random Number Engine Class Templates
>  +// 29.5.4.5 Class Template philox_engine
>  +
>  +#include <random>
>  +#include <testsuite_common_types.h>
>  +
>  +namespace __gnu_test
>  +{
>  +  struct constexpr_member_functions
>  +  {
>  +    template<typename _Ttesttype>
>  +      void
>  +      operator()()
>  +      {
>  +    struct _Concept
>  +    {
>  +      void __constraint()
>  +      {
>  +        constexpr auto v1 __attribute__((unused))
>  +            = _Ttesttype::min();
>  +        constexpr auto v2 __attribute__((unused))
>  +            = _Ttesttype::max();
>  +      }
>  +    };
>  +    _Concept c;
>  +    c.__constraint();
>  +      }
>  +  };
>  +}
>  +
>  +int
>  +main()
>  +{
>  +  __gnu_test::constexpr_member_functions test;
>  +  typedef std::philox4x32 type;
>  +  test.operator()<type>();
>  +  return 0;
>  +}
>  diff --git 
> a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/typedefs.cc
>  
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/typedefs.cc
>  new file mode 100644
>  index 00000000000..ff4d357c5a2
>  --- /dev/null
>  +++ 
> b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/typedefs.cc
>  @@ -0,0 +1,45 @@
>  +// { dg-do run { target c++26 } }
>  +// { dg-require-cstdint "" }
>  +//
>  +// 2025-04-09   1nfocalypse <1nfocaly...@protonmail.com>
>  +//
>  +// Copyright (C) 2025-2034 Free Software Foundation, Inc.
>  +//
>  +// This file is part of the GNU ISO C++ Library. This library is free
>  +// software; you can redistribute it and/or modify it under the
>  +// terms of the GNU General Public License as published by the
>  +// Free Software Foundation; either version 3, or (at your option)
>  +// any later version.
>  +//
>  +// This library is distributed in the hope that it will be useful,
>  +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>  +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>  +// GNU General Public License for more details.
>  +//
>  +// You should have received a copy of the GNU General Public License along
>  +// with this library; see the file COPYING3. If not see
>  +// https://www.gnu.org/licenses>
>  +
>  +// 29.5.4 Random Number Engine Class Templates
>  +// 29.5.4.5 Class Template philox_engine
>  +
>  +
>  +#include <random>
>  +
>  +void
>  +test01()
>  +{
>  +  typedef std::philox_engine<std::uint_fast32_t,
>  +                 32, 4, 10, 0xCD9E8D57,
>  +                 0x9E3779B9, 0xD2511F53,
>  +                 0xBB67AE85> testType;
>  +
>  +  typedef testType::result_type result_type;
>  +}
>  +
>  +int
>  +main()
>  +{
>  +  test01();
>  +  return 0;
>  +}
>  diff --git a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc 
> b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc
>  index 0afba654152..5bb3f31eddc 100644
>  --- a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc
>  +++ b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc
>  @@ -12,4 +12,4 @@ auto x = std::generate_canonical<std::size_t,
>   
>   // { dg-error "static assertion failed: template argument must be a 
> floating point type" "" { target *-*-* } 270 }
>   
>  -// { dg-error "static assertion failed: template argument must be a 
> floating point type" "" { target *-*-* } 3357 }
>  +// { dg-error "static assertion failed: template argument must be a 
> floating point type" "" { target *-*-* } 3558 }
>  -- 
>  2.49.0
>  

Reply via email to