[gcc r16-4063] libstdc++: Refactor std::philox_engine member functions

Jonathan Wakely redi@gcc.gnu.org
Tue Sep 23 15:40:04 GMT 2025


https://gcc.gnu.org/g:2dc3e74b9ddbc971fdf602e71943717abcf40334

commit r16-4063-g2dc3e74b9ddbc971fdf602e71943717abcf40334
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Sep 8 21:53:33 2025 +0100

    libstdc++: Refactor std::philox_engine member functions
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/random.h: Include <bits/ios_base.h> instead of
            <iomanip>. Change preprocessor checks to use internal feature
            test macro.
            (philox_engine): Reword doxygen comments. Use typename instead
            of class in template parameter lists. Reformat and adjust
            whitespace.
            (philox_engine::_If_seed_seq): Replace alias template with
            __is_seed_seq variable template.
            (philox_engine::philox_engine(result_type)): Define inline.
            (philox_engine::seed(result_type), philox_engine::set_counter)
            (philox_engine::operator(), philox_engine::discard): Likewise.
            (operator==): Define as defaulted.
            (operator<<): Reuse widened char.
            * include/bits/random.tcc: Reformat and adjust whitespace.
            (philox_engine::_M_philox): Use std::array copy constructor and
            std::array::fill instead of looping.
            * testsuite/26_numerics/random/philox4x32.cc: Gate test on
            feature test macro. Add static_assert to check typedef.
            * testsuite/26_numerics/random/philox4x64.cc: Likewise.
            * testsuite/26_numerics/random/philox_engine/cons/copy.cc: Add
            VERIFY assertions to check copies are equal. Test different
            seeds.
            * testsuite/26_numerics/random/philox_engine/cons/default.cc:
            Add VERIFY assertions to check construction results.
            * testsuite/26_numerics/random/philox_engine/cons/seed.cc:
            Likewise.
            * testsuite/26_numerics/random/philox_engine/operators/equal.cc:
            Also test inequality.
            * testsuite/26_numerics/random/philox_engine/operators/serialize.cc:
            Remove redundant include and return.
            * testsuite/26_numerics/random/philox_engine/requirements/constants.cc:
            Check values of all constants.
            * testsuite/26_numerics/random/philox_engine/requirements/typedefs.cc:
            Check typedefs are correct.
            * testsuite/26_numerics/random/philox_engine/cons/119794.cc:
            Removed.
            * testsuite/26_numerics/random/philox_engine/cons/seed_seq.cc:
            Removed.
            * testsuite/26_numerics/random/philox_engine/operators/inequal.cc:
            Removed.
            * testsuite/26_numerics/random/philox_engine/requirements/constexpr_data.cc:
            Removed.
            * testsuite/26_numerics/random/philox_engine/requirements/constexpr_functions.cc:
            Removed.
            * testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error
            line number.

Diff:
---
 libstdc++-v3/include/bits/random.h                 | 264 ++++++++++---------
 libstdc++-v3/include/bits/random.tcc               | 282 ++++++++-------------
 .../testsuite/26_numerics/random/philox4x32.cc     |  11 +-
 .../testsuite/26_numerics/random/philox4x64.cc     |  11 +-
 .../random/philox_engine/cons/119794.cc            |  39 ---
 .../26_numerics/random/philox_engine/cons/copy.cc  |  18 +-
 .../random/philox_engine/cons/default.cc           |  34 ++-
 .../26_numerics/random/philox_engine/cons/seed.cc  |  45 +++-
 .../random/philox_engine/cons/seed_seq.cc          |  24 --
 .../random/philox_engine/operators/equal.cc        |  11 +-
 .../random/philox_engine/operators/inequal.cc      |  30 ---
 .../random/philox_engine/operators/serialize.cc    |   7 +-
 .../random/philox_engine/requirements/constants.cc |  56 ++--
 .../philox_engine/requirements/constexpr_data.cc   |  50 ----
 .../requirements/constexpr_functions.cc            |  41 ---
 .../random/philox_engine/requirements/typedefs.cc  |  22 +-
 .../testsuite/26_numerics/random/pr60037-neg.cc    |   2 +-
 17 files changed, 387 insertions(+), 560 deletions(-)

diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
index e74b7bd75c03..4049a77fbf4c 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -32,8 +32,8 @@
 #define _RANDOM_H 1
 
 #include <vector>
+#include <bits/ios_base.h>
 #include <bits/uniform_int_dist.h>
-#include <iomanip>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -1689,21 +1689,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return !(__lhs == __rhs); }
 #endif
 
-#if __cpp_lib_philox_engine
-
+#if __glibcxx_philox_engine // >= C++26
   /**
-   * @brief: A discrete pseudorandom number generator based off of weakened
-   * cryptographic primitives.
+   * @brief A discrete pseudorandom number generator with weak cryptographic
+   * properties
+   *
+   * This algorithm was designed 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.
    *
-   * 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.
+   * 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.
+   * The typedefs `philox4x32` and `philox4x64` are provided as suitable
+   * defaults for most use cases, providing high-quality random numbers
+   * with reasonable performance.
    *
    * This algorithm was created by John Salmon, Mark Moraes, Ron Dror, and
    * David Shaw as a product of D.E. Shaw Research.
@@ -1717,9 +1718,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @headerfile random
    * @since C++26
    */
-  template<class _UIntType, size_t __w,
-	      size_t __n, size_t __r,
-	      _UIntType... __consts>
+  template<typename _UIntType, size_t __w, size_t __n, size_t __r,
+	   _UIntType... __consts>
     class philox_engine
     {
       static_assert(__n == 2 || __n == 4,
@@ -1729,42 +1729,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static_assert(0 < __r, "a number of rounds must be specified");
       static_assert((0 < __w && __w <= numeric_limits<_UIntType>::digits),
 	      "specified bitlength must match input type");
+
       template<typename _Sseq>
-	using _If_seed_seq
-	  = __detail::_If_seed_seq_for<_Sseq, philox_engine, _UIntType>;
+	static constexpr bool __is_seed_seq = requires {
+	  typename __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.  */
-	template <size_t __ind0, size_t __ind1>
-	  static constexpr
-	  array<_UIntType, __n / 2>
-	  _S_popArray()
-	  {
-	    if constexpr (__n == 4)
-	      return {__consts...[__ind0], __consts...[__ind1]};
-	    else
-	      return {__consts...[__ind0]};
-	  }
+      template <size_t __ind0, size_t __ind1>
+	static constexpr
+	array<_UIntType, __n / 2>
+	_S_popArray()
+	{
+	  if constexpr (__n == 4)
+	    return {__consts...[__ind0], __consts...[__ind1]};
+	  else
+	    return {__consts...[__ind0]};
+	}
 
       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 array<result_type, __n / 2> multipliers =
-	   philox_engine::_S_popArray<0,2>();
-	static constexpr array<result_type, __n / 2> round_consts =
-	   philox_engine::_S_popArray<1,3>();
+	static constexpr array<result_type, __n / 2> multipliers
+	  = _S_popArray<0,2>();
+	static constexpr array<result_type, __n / 2> round_consts
+	  = _S_popArray<1,3>();
 
-	/** @brief returns the minimum value possible.  */
+	/// The minimum value that this engine can return
 	static constexpr result_type
 	min()
 	{ return 0; }
 
-	/** @brief returns the maximum value possible.  */
+	/// The maximum value that this engine can return
 	static constexpr result_type
 	max()
 	{
@@ -1776,16 +1774,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	// constructors
 	philox_engine()
 	: philox_engine(default_seed)
-	{}
+	{ }
 
 	explicit
-	philox_engine(result_type __value);
+	philox_engine(result_type __value)
+	: _M_x{}, _M_y{}, _M_k{}, _M_i(__n - 1)
+	{ _M_k[0] = __value & max(); }
 
 	/** @brief seed sequence constructor for %philox_engine
 	  *
-	  *  @params __q the seed sequence
+	  *  @param __q the seed sequence
 	  */
-	template<typename _Sseq, typename = _If_seed_seq<_Sseq>>
+	template<typename _Sseq> requires __is_seed_seq<_Sseq>
 	  explicit
 	  philox_engine(_Sseq& __q)
 	  {
@@ -1793,56 +1793,64 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  }
 
 	void
-	seed(result_type value = default_seed);
+	seed(result_type __value = default_seed)
+	{
+	  _M_x = {};
+	  _M_y = {};
+	  _M_k = {};
+	  _M_k[0] = __value & max();
+	  _M_i = __n - 1;
+	}
 
 	/** @brief seeds %philox_engine by seed sequence
 	  *
-	  * @params __q the seed sequence
+	  * @param __q the seed sequence
 	  */
 	template<typename _Sseq>
-	  _If_seed_seq<_Sseq>
-	  seed(_Sseq& __q);
+	  void
+	  seed(_Sseq& __q) requires __is_seed_seq<_Sseq>;
 
 	/** @brief sets the internal counter "cleartext"
 	  *
-	  * @params __counter std::array of len N
+	  * @param __counter std::array of len N
 	  */
 	void
-	set_counter(const array<result_type, __n>& __counter);
+	set_counter(const array<result_type, __n>& __counter)
+	{
+	  for (size_t __j = 0; __j < __n; ++__j)
+	    _M_x[__j] = __counter[__n - 1 - __j] & max();
+	  _M_i = __n - 1;
+	}
 
 	/** @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
+	  * @returns true if the objects will produce an identical stream,
+	  *          false otherwise
 	  */
 	friend bool
-	operator==(const philox_engine& __x, const philox_engine& __y)
-	{
-	  return (std::equal(__x._M_x.begin(), __x._M_x.end(),
-		__y._M_x.begin(), __y._M_x.end())
-	      && std::equal(__x._M_y.begin(), __x._M_y.end(),
-		__y._M_y.begin(), __y._M_y.end())
-	      && std::equal(__x._M_k.begin(), __x._M_k.end(),
-		__y._M_k.begin(), __y._M_k.end())
-	      && __x._M_i == __y._M_i);
-	}
+	operator==(const philox_engine&, const philox_engine&) = default;
 
 	/** @brief outputs a single w-bit number and handles state advancement
 	  *
 	  * @returns return_type
 	  */
-	_UIntType
-	operator()();
+	result_type
+	operator()()
+	{
+	  _M_transition();
+	  return _M_y[_M_i];
+	}
 
 	/** @brief discards __z numbers
 	  *
-	  * @params __z number of iterations to discard
+	  * @param __z number of iterations to discard
 	  */
 	void
-	discard(unsigned long long __z);
+	discard(unsigned long long __z)
+	{
+	  while (__z--)
+	    _M_transition();
+	}
 
 	/** @brief outputs the state of the generator
 	 *
@@ -1853,22 +1861,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	 */
 	template<typename _CharT, typename _Traits>
 	  friend basic_ostream<_CharT, _Traits>&
-	    operator<<(basic_ostream<_CharT, _Traits>& __os,
-	      const philox_engine& __x)
-	      {
-		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(' '));
-		for (auto &__subkey : __x._M_k)
-		  __os << __subkey << ' ';
-		for (auto &__ctr : __x._M_x)
-		  __os << __ctr << ' ';
-		__os << __x._M_i;
-		__os.flags(__flags);
-		__os.fill(__fill);
-		return __os;
-	      }
+	  operator<<(basic_ostream<_CharT, _Traits>& __os,
+		     const philox_engine& __x)
+	  {
+	    const typename ios_base::fmtflags __flags = __os.flags();
+	    const _CharT __fill = __os.fill();
+	    __os.flags(ios_base::dec | ios_base::left);
+	    _CharT __space = __os.widen(' ');
+	    __os.fill(__space);
+	    for (auto& __subkey : __x._M_k)
+	      __os << __subkey << __space;
+	    for (auto& __ctr : __x._M_x)
+	      __os << __ctr << __space;
+	    __os << __x._M_i;
+	    __os.flags(__flags);
+	    __os.fill(__fill);
+	    return __os;
+	  }
 
 	/** @brief takes input to set the state of the %philox_engine object
 	  *
@@ -1879,38 +1888,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  */
 	template <typename _CharT, typename _Traits>
 	  friend basic_istream<_CharT, _Traits>&
-	    operator>>(basic_istream<_CharT, _Traits>& __is,
-	      philox_engine& __x)
+	  operator>>(basic_istream<_CharT, _Traits>& __is,
+		     philox_engine& __x)
+	  {
+	    const typename ios_base::fmtflags __flags = __is.flags();
+	    __is.flags(ios_base::dec | ios_base::skipws);
+	    for (auto& __subkey : __x._M_k)
+	      __is >> __subkey;
+	    for (auto& __ctr : __x._M_x)
+	      __is >> __ctr;
+	    array<_UIntType, __n> __tmpCtr = __x._M_x;
+	    unsigned char __setIndex = 0;
+	    for (size_t __j = 0; __j < __x._M_x.size(); ++__j)
 	      {
-		const typename ios_base::fmtflags __flags = __is.flags();
-		__is.flags(ios_base::dec | ios_base::skipws);
-		for (auto &__subkey : __x._M_k)
-		  __is >> __subkey;
-		for (auto &__ctr : __x._M_x)
-		  __is >> __ctr;
-		array<_UIntType, __n> __tmpCtr = __x._M_x;
-		unsigned char __setIndex = 0;
-		for (size_t __j = 0; __j < __x._M_x.size(); ++__j)
-		{
-		  if (__x._M_x[__j] > 0)
+		if (__x._M_x[__j] > 0)
 		  {
 		    __setIndex = __j;
 		    break;
 		  }
-		}
-		for (size_t __j = 0; __j <= __setIndex; ++__j)
-		{
-		  if (__j != __setIndex)
-		    __x._M_x[__j] = max();
-		  else
-		    --__x._M_x[__j];
-		}
-		__x._M_philox();
-		__x._M_x = __tmpCtr;
-		__is >> __x._M_i;
-		__is.flags(__flags);
-		return __is;
 	      }
+	    for (size_t __j = 0; __j <= __setIndex; ++__j)
+	      {
+		if (__j != __setIndex)
+		  __x._M_x[__j] = max();
+		else
+		  --__x._M_x[__j];
+	      }
+	    __x._M_philox();
+	    __x._M_x = __tmpCtr;
+	    __is >> __x._M_i;
+	    __is.flags(__flags);
+	    return __is;
+	  }
+
       private:
 	// private state variables
 	array<_UIntType, __n> _M_x;
@@ -1918,39 +1928,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	array<_UIntType, __n> _M_y;
 	unsigned long long _M_i = 0;
 
-	/** @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
-	  */
-	static
-	_UIntType
+	// The high W bits of the product of __a and __b
+	static _UIntType
 	_S_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
-	  */
-	static
-	_UIntType
+	// The low W bits of the product of __a and __b
+	static _UIntType
 	_S_mullo(_UIntType __a, _UIntType __b); // (A*B)%2^W
 
-	/** @brief an R-round substitution/Feistel Network hybrid for
-	  * %philox_engine
-	  */
+	// An R-round substitution/Feistel Network hybrid for philox_engine
 	void
 	_M_philox();
 
-	/** @brief an internal transition function for the %philox_engine.  */
+	// The transition function
 	void
 	_M_transition();
     };
-
 #endif
 
   /**
@@ -2007,17 +2000,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   typedef minstd_rand0 default_random_engine;
 
-#if __cpp_lib_philox_engine
+#if __glibcxx_philox_engine
 
+  /// 32-bit four-word Philox engine.
   typedef philox_engine<
     uint_fast32_t,
     32, 4, 10,
     0xCD9E8D57, 0x9E3779B9,
     0xD2511F53, 0xBB67AE85> philox4x32;
 
-  /**
-   * Alternative Philox instance (64 bit)
-   */
+  /// 64-bit four-word Philox engine.
   typedef philox_engine<
     uint_fast64_t,
     64, 4, 10,
diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc
index 53f302da8007..f4b9778e468e 100644
--- a/libstdc++-v3/include/bits/random.tcc
+++ b/libstdc++-v3/include/bits/random.tcc
@@ -907,197 +907,129 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __is;
     }
 
-#if __cpp_lib_philox_engine
-
-  template<class _UIntType,
-	size_t __w, size_t __n,
-	size_t __r, _UIntType... __consts>
-  _UIntType
-  philox_engine<_UIntType,
-  __w, __n, __r, __consts...>::_S_mulhi(_UIntType __a, _UIntType __b)
-  {
-    const __uint128_t __num =
-	static_cast<__uint128_t>(__a) * static_cast<__uint128_t>(__b);
-    return static_cast<_UIntType>((__num >> __w) & max());
-  }
+#if __glibcxx_philox_engine // >= C++26
 
-  template<class _UIntType,
-	size_t __w, size_t __n,
-	size_t __r, _UIntType... __consts>
-  _UIntType
-  philox_engine<_UIntType,
-  __w, __n, __r, __consts...>::_S_mullo(_UIntType __a, _UIntType __b)
-  {
-    return static_cast<_UIntType>((__a * __b) & max());
-  }
+  template<typename _UIntType, size_t __w, size_t __n, size_t __r,
+	   _UIntType... __consts>
+    _UIntType
+    philox_engine<_UIntType, __w, __n, __r, __consts...>::
+    _S_mulhi(_UIntType __a, _UIntType __b)
+    {
+      const __uint128_t __num =
+	  static_cast<__uint128_t>(__a) * static_cast<__uint128_t>(__b);
+      return static_cast<_UIntType>((__num >> __w) & max());
+    }
 
-  template<class _UIntType,
-	size_t __w, size_t __n,
-	size_t __r, _UIntType... __consts>
-  void
-  philox_engine<_UIntType, __w, __n, __r, __consts...>::_M_transition()
-  {
-    ++_M_i;
-    if (_M_i == __n)
+  template<typename _UIntType, size_t __w, size_t __n, size_t __r,
+	   _UIntType... __consts>
+    _UIntType
+    philox_engine<_UIntType, __w, __n, __r, __consts...>::
+    _S_mullo(_UIntType __a, _UIntType __b)
     {
+      return static_cast<_UIntType>((__a * __b) & max());
+    }
+
+  template<typename _UIntType, size_t __w, size_t __n, size_t __r,
+	   _UIntType... __consts>
+    void
+    philox_engine<_UIntType, __w, __n, __r, __consts...>::_M_transition()
+    {
+      ++_M_i;
+      if (_M_i != __n)
+	return;
+
       _M_philox();
       if constexpr (__n == 4)
-      {
-	__uint128_t __uh =
-	  (static_cast<__uint128_t>(_M_x[1]) << __w)
-		| (static_cast<__uint128_t>(_M_x[0]) + 1);
-	__uint128_t __lh =
-	  ((static_cast<__uint128_t>(_M_x[3]) << __w)
-		| (_M_x[2]));
-	__uint128_t __bigMask =
-	  (static_cast<__uint128_t>(1) << ((2 * __w) - 1))
-	        | ((static_cast<__uint128_t>(1) << ((2 * __w) - 1)) - 1);
-	if ((__uh & __bigMask) == 0)
 	{
-	  ++__lh;
-	  __uh = 0;
+	  __uint128_t __uh =
+	    (static_cast<__uint128_t>(_M_x[1]) << __w)
+		  | (static_cast<__uint128_t>(_M_x[0]) + 1);
+	  __uint128_t __lh =
+	    ((static_cast<__uint128_t>(_M_x[3]) << __w)
+		  | (_M_x[2]));
+	  __uint128_t __bigMask =
+	    (static_cast<__uint128_t>(1) << ((2 * __w) - 1))
+		  | ((static_cast<__uint128_t>(1) << ((2 * __w) - 1)) - 1);
+	  if ((__uh & __bigMask) == 0)
+	    {
+	      ++__lh;
+	      __uh = 0;
+	    }
+	  _M_x[0] = __uh & max();
+	  _M_x[1] = (__uh >> (__w)) & max();
+	  _M_x[2] = __lh & max();
+	  _M_x[3] = (__lh >> (__w)) & max();
+	}
+      else
+	{
+	  __uint128_t __num =
+		  (static_cast<__uint128_t>(_M_x[1]) << __w)
+		  | (static_cast<__uint128_t>(_M_x[0]) + 1);
+	  _M_x[0] = __num & max();
+	  _M_x[1] = (__num >> __w) & max();
 	}
-	_M_x[0] = __uh & max();
-	_M_x[1] = (__uh >> (__w)) & max();
-	_M_x[2] = __lh & max();
-	_M_x[3] = (__lh >> (__w)) & max();
-      } else
-      {
-	__uint128_t __num =
-		(static_cast<__uint128_t>(_M_x[1]) << __w)
-		| (static_cast<__uint128_t>(_M_x[0]) + 1);
-	_M_x[0] = __num & max();
-	_M_x[1] = (__num >> __w) & max();
-      }
       _M_i = 0;
     }
-  }
 
-  template<class _UIntType,
-	size_t __w, size_t __n,
-	size_t __r, _UIntType... __consts>
-  void
-  philox_engine<_UIntType, __w, __n, __r, __consts...>::_M_philox()
-  {
-    array<_UIntType, __n> __outputSeq{};
-    for (size_t __j = 0; __j < __n; ++__j)
-      __outputSeq[__j] = _M_x[__j];
-    for (unsigned long __j = 0; __j < __r; ++__j)
+  template<typename _UIntType, size_t __w, size_t __n, size_t __r,
+	   _UIntType... __consts>
+    void
+    philox_engine<_UIntType, __w, __n, __r, __consts...>::_M_philox()
     {
-      array<_UIntType, __n> __intermedSeq{};
-      if constexpr (__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]= _S_mulhi(__intermedSeq[2*__k], multipliers[__k])
-	  ^ (((_M_k[__k] + (__j * round_consts[__k])) & max()))
-	  ^ __intermedSeq[2*__k+1];
+      array<_UIntType, __n> __outputSeq = _M_x;
+      for (size_t __j = 0; __j < __r; ++__j)
+	{
+	  array<_UIntType, __n> __intermedSeq{};
+	  if constexpr (__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]
+		= _S_mulhi(__intermedSeq[2*__k], multipliers[__k])
+		    ^ (((_M_k[__k] + (__j * round_consts[__k])) & max()))
+		    ^ __intermedSeq[2*__k+1];
 
-	__outputSeq[(2*__k)+1]= _S_mullo(__intermedSeq[2*__k],
-	  multipliers[__k]);
-      }
+	      __outputSeq[(2*__k)+1]
+		= _S_mullo(__intermedSeq[2*__k], multipliers[__k]);
+	    }
+	}
+      _M_y = __outputSeq;
     }
-    for (unsigned long __j = 0; __j < __n; ++__j)
-      _M_y[__j] = __outputSeq[__j];
-  }
-
-  template<class _UIntType,
-	size_t __w, size_t __n,
-	size_t __r, _UIntType... __consts>
-  philox_engine<_UIntType,
-	__w, __n, __r, __consts...>::philox_engine(result_type __value)
-  {
-    std::fill(_M_x.begin(), _M_x.end(), 0);
-    std::fill(_M_k.begin(), _M_k.end(), 0);
-    std::fill(_M_y.begin(), _M_y.end(), 0);
-    _M_k[0] = __value & max();
-    _M_i = __n - 1;
-  }
 
-  template<class _UIntType,
-	size_t __w, size_t __n,
-	size_t __r, _UIntType... __consts>
-  void
-  philox_engine<_UIntType,
-  __w, __n, __r, __consts...>::seed(result_type __value)
-  {
-    std::fill(_M_x.begin(), _M_x.end(), 0);
-    std::fill(_M_k.begin(), _M_k.end(), 0);
-    std::fill(_M_y.begin(), _M_y.end(), 0);
-    _M_k[0] = __value & max();
-    _M_i = __n - 1;
-  }
-
-  template<class _UIntType,
-	size_t __w, size_t __n,
-	size_t __r, _UIntType... __consts>
-  void
-  philox_engine<_UIntType, __w,
-  __n, __r, __consts...>::set_counter(const array<result_type, __n>& __counter)
-  {
-    for (unsigned long long __j = 0; __j < __n; ++__j)
-      _M_x[__j] = __counter[__n - 1 - __j] & max();
-    _M_i = __n - 1;
-  }
-
-  template<class _UIntType,
-	size_t __w, size_t __n,
-	size_t __r, _UIntType... __consts>
+  template<typename _UIntType, size_t __w, size_t __n, size_t __r,
+	   _UIntType... __consts>
   template<typename _Sseq>
-  auto
-  philox_engine<_UIntType, __w, __n, __r, __consts...>::seed(_Sseq& __q)
-  -> _If_seed_seq<_Sseq>
-  {
-    std::fill(_M_k.begin(), _M_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); ++__k)
-    {
-      unsigned long long __precalc = 0;
-      for (unsigned long long __j = 0; __j < __p; ++__j)
-      {
-	unsigned long long __multiplicand = (1ull << (32 * __j));
-	__precalc += (__tmpArr[__k*__p + __j] * __multiplicand) & max();
-      }
-      _M_k[__k] = __precalc;
-    }
-    std::fill(_M_x.begin(), _M_x.end(), 0);
-    std::fill(_M_y.begin(), _M_y.end(), 0);
-    _M_i = __n - 1;
-  }
-
-  template<class _UIntType,
-	size_t __w, size_t __n,
-	size_t __r, _UIntType... __consts>
-  void
-  philox_engine<_UIntType,
-	__w, __n, __r, __consts...>::discard(unsigned long long __z)
-  {
-    for (unsigned long long __j = 0; __j < __z; ++__j)
-      _M_transition();
-  }
-
-  template<class _UIntType,
-	size_t __w, size_t __n,
-	size_t __r, _UIntType... __consts>
-  _UIntType
-  philox_engine<_UIntType, __w, __n, __r, __consts...>::operator()()
-  {
-    _M_transition();
-    return _M_y[_M_i];
-  }
+    void
+    philox_engine<_UIntType, __w, __n, __r, __consts...>::seed(_Sseq& __q)
+    requires __is_seed_seq<_Sseq>
+    {
+      seed(0);
 
-#endif
+      const unsigned __p = 1 + ((__w - 1) / 32);
+      uint_least32_t __tmpArr[(__n/2) * __p];
+      __q.generate(__tmpArr + 0, __tmpArr + ((__n/2) * __p));
+      for (unsigned __k = 0; __k < (__n/2); ++__k)
+	{
+	  unsigned long long __precalc = 0;
+	  for (unsigned __j = 0; __j < __p; ++__j)
+	    {
+	      unsigned long long __multiplicand = (1ull << (32 * __j));
+	      __precalc += (__tmpArr[__k * __p + __j] * __multiplicand) & max();
+	    }
+	  _M_k[__k] = __precalc;
+	}
+    }
+#endif // philox_engine
 
   template<typename _IntType, typename _CharT, typename _Traits>
     std::basic_ostream<_CharT, _Traits>&
diff --git a/libstdc++-v3/testsuite/26_numerics/random/philox4x32.cc b/libstdc++-v3/testsuite/26_numerics/random/philox4x32.cc
index d5a8ca078eff..33842bb8db03 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/philox4x32.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/philox4x32.cc
@@ -1,12 +1,16 @@
 // { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
+// { dg-require-cpp-feature-test __cpp_lib_philox_engine }
 
-// 29.5.4 Random Number Engine Class Templates
-// 29.5.4.5 Class Template philox_engine
+// N5014 29.5.6 Engines and engine adaptors with predefined parameters
 
 #include <random>
 #include <testsuite_hooks.h>
 
+using test_type = std::philox_engine<std::uint_fast32_t, 32, 4, 10,
+				     0xCD9E8D57, 0x9E3779B9,
+				     0xD2511F53, 0xBB67AE85>;
+static_assert( std::is_same_v<test_type, std::philox4x32> );
+
 void
 test01()
 {
@@ -19,5 +23,4 @@ test01()
 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
index 131f094cb287..11a5691804e0 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/philox4x64.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/philox4x64.cc
@@ -1,12 +1,16 @@
 // { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
+// { dg-require-cpp-feature-test __cpp_lib_philox_engine }
 
-// 29.5.4 Random Number Engine Class Templates
-// 29.5.4.5 Class Template philox_engine
+// N5014 29.5.6 Engines and engine adaptors with predefined parameters
 
 #include <random>
 #include <testsuite_hooks.h>
 
+using test_type = std::philox_engine<std::uint_fast64_t, 64, 4, 10,
+				     0xCA5A826395121157, 0x9E3779B97F4A7C15,
+				     0xD2E7470EE14C6C93, 0xBB67AE8584CAA73B>;
+static_assert( std::is_same_v<test_type, std::philox4x64> );
+
 void
 test01()
 {
@@ -19,5 +23,4 @@ test01()
 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
deleted file mode 100644
index c3a5a0eb7545..000000000000
--- a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/119794.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
-
-#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
index 4f61928a1575..163aec082332 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/copy.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/copy.cc
@@ -1,25 +1,27 @@
 // { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
+// { dg-require-cpp-feature-test __cpp_lib_philox_engine }
 
-// 29.5.4 Random Number Engine Class Templates
-// 29.5.4.5 Class Template philox_engine
+// N5014 29.5.4 Random Number Engine Class Templates
+// N5014 29.5.4.5 Class Template philox_engine
 
 #include <random>
+#include <testsuite_hooks.h>
 
 void
-test01()
+test01(unsigned long seed)
 {
 
   std::philox_engine<std::uint_fast32_t, 32, 4, 10, 0xCD9E8D57,
-	0x9E3779B9, 0xD2511F53, 0xBB67AE85> e(1ul);
+	0x9E3779B9, 0xD2511F53, 0xBB67AE85> e(seed);
 
   const auto f(e);
+  VERIFY( f == e );
   auto g(f);
-  g = g; // Suppress unused warning
+  VERIFY( g == f );
 }
 
 int main()
 {
-  test01();
-  return 0;
+  test01(1ul);
+  test01(111ul);
 }
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
index 9f9ae94db0f3..183ca8201093 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/default.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/default.cc
@@ -1,14 +1,13 @@
 // { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
+// { dg-require-cpp-feature-test __cpp_lib_philox_engine }
 
-// 29.5.4 Random Number Engine Class Templates
-// 29.5.4.5 Class Template philox_engine
+// N5014 29.5.4.5 Class Template philox_engine
 
 #include <random>
 #include <testsuite_hooks.h>
 
 void
-test01()
+test_default_ctor()
 {
   std::philox_engine<std::uint_fast32_t,
 		     32, 4, 10, 0xCD9E8D57,
@@ -20,8 +19,31 @@ test01()
   VERIFY( philox4x32nullkey() == 0x6627e8d5ul );
 }
 
+void
+test_seed()
+{
+  unsigned long seed = 2;
+  std::philox4x32 seeded(seed);
+
+  std::philox4x32 default_init;
+  VERIFY( seeded != default_init );
+
+  std::philox4x32 default_seeded(std::philox4x32::default_seed);
+  VERIFY( default_seeded == default_init );
+}
+
+void
+test_seed_seq()
+{
+  std::seed_seq sseq{ 1, 2, 3, 4 };
+  std::philox4x32 seeded(sseq);
+  std::philox4x32 default_init;
+  VERIFY( seeded != default_init );
+}
+
 int main()
 {
-  test01();
-  return 0;
+  test_default_ctor();
+  test_seed();
+  test_seed_seq();
 }
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
index 5cb914f4b45c..2b667b233644 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/seed.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/seed.cc
@@ -1,20 +1,51 @@
 // { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
+// { dg-require-cpp-feature-test __cpp_lib_philox_engine }
 
 #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()
 {
-  unsigned long seed = 2;
-  std::philox_engine<std::uint_fast32_t,
-		     32, 4, 10, 0xCD9E8D57,
-		     0x9E3779B9, 0xD2511F53,
-		     0xBB67AE85> philox4x32seeded(seed);
+  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 );
+}
+
+void
+test02()
+{
+  std::philox4x64 e1(25);
+  std::philox4x64 e2;
+  VERIFY( e2 != e1 );
+  e2.seed(25);
+  VERIFY( e2 == e1 );
+
 }
 
 int main()
 {
   test01();
-  return 0;
+  test02();
 }
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
deleted file mode 100644
index 7d9e3e6540d2..000000000000
--- a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/cons/seed_seq.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
-
-// 29.5.4 Random Number Engine Class Templates
-// 29.5.4.5 Class Template philox_engine
-
-#include <random>
-
-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
index 4f62bfbbd88e..cca1654603ef 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/equal.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/equal.cc
@@ -1,8 +1,7 @@
 // { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
+// { dg-require-cpp-feature-test __cpp_lib_philox_engine }
 
-// 29.5.4 Random Number Engine Class Templates
-// 29.5.4.5 Class Template philox_engine
+// N5014 29.5.4.5 Class Template philox_engine
 
 #include <random>
 #include <testsuite_hooks.h>
@@ -20,11 +19,15 @@ test01()
   y.discard(100);
 
   VERIFY (x == y);
+
+  x.discard(2);
+  VERIFY (x != y);
+  y.discard(2);
+  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
deleted file mode 100644
index 86d757db9040..000000000000
--- a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/inequal.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
-
-// 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
index bec4b1725127..4bd40e74a6b5 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/serialize.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/operators/serialize.cc
@@ -1,13 +1,11 @@
 // { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
+// { dg-require-cpp-feature-test __cpp_lib_philox_engine }
 
-// 29.5.4 Random Number Engine Class Templates
-// 29.5.4.5 Class Template philox_engine
+// N5014 29.5.4.5 Class Template philox_engine
 
 #include <sstream>
 #include <random>
 #include <testsuite_hooks.h>
-#include <iostream>
 
 void
 test01()
@@ -45,5 +43,4 @@ 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
index c242056e0a4b..a3cb24eb0667 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constants.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constants.cc
@@ -1,26 +1,48 @@
-// { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
+// { dg-do compile { target c++26 } }
+// { dg-require-cpp-feature-test __cpp_lib_philox_engine }
 
-// 29.5.4 Random Number Engine Class Templates
-// 29.5.4.5 Class Template philox_engine
+// N5014 29.5.4.5 Class Template philox_engine
 
 #include <random>
 
-void test01()
+namespace test1
 {
-  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.
+  using P = std::philox_engine<std::uint32_t, 32, 4, 5, 9, 99, 999, 9999>;
+  constexpr std::same_as<std::uint32_t> auto min = P::min();
+  static_assert( min == 0 );
+  constexpr std::same_as<std::uint32_t> auto max = P::max();
+  static_assert( max == 0xffffffff );
+  constexpr std::same_as<std::size_t> auto w = P::word_size;
+  static_assert( w == 32 );
+  constexpr std::same_as<std::size_t> auto n = P::word_count;
+  static_assert( n == 4 );
+  constexpr std::same_as<std::size_t> auto r = P::round_count;
+  static_assert( r == 5 );
+  constexpr std::array<std::uint32_t, 2> muls = P::multipliers;
+  static_assert( muls[0] == 9 && muls[1] == 999 );
+  constexpr std::array<std::uint32_t, 2> consts = P::round_consts;
+  static_assert( consts[0] == 99 && consts[1] == 9999 );
+  constexpr std::same_as<std::uint32_t> auto def = P::default_seed;
+  static_assert( def == 20111115u );
 }
 
-int
-main()
+namespace test2
 {
-  test01();
-  return 0;
+  using P = std::philox_engine<std::uint64_t, 64, 2, 12, 77, 777>;
+  constexpr std::same_as<std::uint64_t> auto min = P::min();
+  static_assert( min == 0 );
+  constexpr std::same_as<std::uint64_t> auto max = P::max();
+  static_assert( max == 0xffffffffffffffff );
+  constexpr std::same_as<std::size_t> auto w = P::word_size;
+  static_assert( w == 64 );
+  constexpr std::same_as<std::size_t> auto n = P::word_count;
+  static_assert( n == 2 );
+  constexpr std::same_as<std::size_t> auto r = P::round_count;
+  static_assert( r == 12 );
+  constexpr std::array<std::uint64_t, 1> muls = P::multipliers;
+  static_assert( muls[0] == 77 );
+  constexpr std::array<std::uint64_t, 1> consts = P::round_consts;
+  static_assert( consts[0] == 777 );
+  constexpr std::same_as<std::uint64_t> auto def = P::default_seed;
+  static_assert( def == 20111115u );
 }
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
deleted file mode 100644
index 5be0108c88cd..000000000000
--- a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constexpr_data.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
-
-// 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
deleted file mode 100644
index eb61d15568aa..000000000000
--- a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/constexpr_functions.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
-
-// 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
index b368ee741069..1fc8fedc4c69 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/typedefs.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/philox_engine/requirements/typedefs.cc
@@ -1,9 +1,7 @@
-// { dg-do run { target c++26 } }
-// { dg-require-cstdint "" }
-
-// 29.5.4 Random Number Engine Class Templates
-// 29.5.4.5 Class Template philox_engine
+// { dg-do compile { target c++26 } }
+// { dg-require-cpp-feature-test __cpp_lib_philox_engine }
 
+// N5014 29.5.4.5 Class Template philox_engine
 
 #include <random>
 
@@ -16,11 +14,17 @@ test01()
 		     0xBB67AE85> testType;
 
   typedef testType::result_type result_type;
+  static_assert( std::is_same_v<result_type, std::uint_fast32_t> );
 }
 
-int
-main()
+void
+test02()
 {
-  test01();
-  return 0;
+  typedef std::philox_engine<std::uint_fast64_t,
+		     64, 4, 10, 0xCA5A826395121157,
+		     0x9E3779B97F4A7C15, 0xD2E7470EE14C6C93,
+		      0xBB67AE8584CAA73B> testType;
+
+  typedef testType::result_type result_type;
+  static_assert( std::is_same_v<result_type, std::uint_fast64_t> );
 }
diff --git a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc
index 13a0b8947b05..4b36f75bba26 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 *-*-* } 271 }
 
-// { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 3548 }
+// { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 3480 }


More information about the Libstdc++-cvs mailing list