Good evening!

Thank you both for the review, I'll get to work on cleaning it up and send out 
a v3 soon. Additionally, don't worry about the delay, and thank you for your 
patience. Have a good weekend!

Regards,
1nfocalypse

On Friday, July 11th, 2025 at 9:29 AM, Patrick Palka <ppa...@redhat.com> wrote:

> 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); // (AB)/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); // (AB)%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