mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
libstdc++: Implement Philox Engine (PR119794)
Conforms with errata LWG4143, LWG4153 for Philox Engine. PR libstdc++/119794 libstdc++-v3/ChangeLog: * include/bits/random.h (philox_engine): Define. * include/bits/random.tcc (philox_engine): Define member functions. * include/bits/version.def (philox_engine): New macro. * include/bits/version.h: Regenerated. * include/std/random: Define __glibcxx_want_philox_engine and include <bits/version.h>. * testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error line number. * 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.
This commit is contained in:
committed by
Jonathan Wakely
parent
52d702d72a
commit
1c06243e65
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <bits/uniform_int_dist.h>
|
||||
#include <iomanip>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
@@ -1688,6 +1689,270 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{ return !(__lhs == __rhs); }
|
||||
#endif
|
||||
|
||||
#if __cpp_lib_philox_engine
|
||||
|
||||
/**
|
||||
* @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),
|
||||
"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. */
|
||||
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>();
|
||||
|
||||
/** @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 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 (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);
|
||||
}
|
||||
|
||||
/** @brief outputs a single w-bit number and handles state advancement
|
||||
*
|
||||
* @returns return_type
|
||||
*/
|
||||
_UIntType
|
||||
operator()();
|
||||
|
||||
/** @brief discards __z numbers
|
||||
*
|
||||
* @params __z number of iterations to discard
|
||||
*/
|
||||
void
|
||||
discard(unsigned long long __z);
|
||||
|
||||
/** @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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/** @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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
__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;
|
||||
}
|
||||
private:
|
||||
// private state variables
|
||||
array<_UIntType, __n> _M_x;
|
||||
array<_UIntType, __n / 2> _M_k;
|
||||
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
|
||||
_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
|
||||
_S_mullo(_UIntType __a, _UIntType __b); // (A*B)%2^W
|
||||
|
||||
/** @brief an R-round substitution/Feistel Network hybrid for
|
||||
* %philox_engine
|
||||
*/
|
||||
void
|
||||
_M_philox();
|
||||
|
||||
/** @brief an internal transition function for the %philox_engine. */
|
||||
void
|
||||
_M_transition();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
|
||||
*/
|
||||
@@ -1742,6 +2007,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
typedef minstd_rand0 default_random_engine;
|
||||
|
||||
#if __cpp_lib_philox_engine
|
||||
|
||||
typedef philox_engine<
|
||||
uint_fast32_t,
|
||||
32, 4, 10,
|
||||
0xCD9E8D57, 0x9E3779B9,
|
||||
0xD2511F53, 0xBB67AE85> philox4x32;
|
||||
|
||||
/**
|
||||
* Alternative Philox instance (64 bit)
|
||||
*/
|
||||
typedef philox_engine<
|
||||
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).
|
||||
|
||||
@@ -907,6 +907,197 @@ _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());
|
||||
}
|
||||
|
||||
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<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)
|
||||
{
|
||||
_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;
|
||||
}
|
||||
_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)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
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 _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];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<typename _IntType, typename _CharT, typename _Traits>
|
||||
std::basic_ostream<_CharT, _Traits>&
|
||||
|
||||
@@ -2137,6 +2137,15 @@ ftms = {
|
||||
};
|
||||
};
|
||||
|
||||
ftms = {
|
||||
name = philox_engine;
|
||||
values = {
|
||||
v = 202406;
|
||||
cxxmin = 26;
|
||||
extra_cond = "__SIZEOF_INT128__";
|
||||
};
|
||||
};
|
||||
|
||||
// Standard test specifications.
|
||||
stds[97] = ">= 199711L";
|
||||
stds[03] = ">= 199711L";
|
||||
|
||||
@@ -2397,4 +2397,14 @@
|
||||
#endif /* !defined(__cpp_lib_constexpr_exceptions) && defined(__glibcxx_want_constexpr_exceptions) */
|
||||
#undef __glibcxx_want_constexpr_exceptions
|
||||
|
||||
#if !defined(__cpp_lib_philox_engine)
|
||||
# if (__cplusplus > 202302L) && (__SIZEOF_INT128__)
|
||||
# define __glibcxx_philox_engine 202406L
|
||||
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_philox_engine)
|
||||
# define __cpp_lib_philox_engine 202406L
|
||||
# endif
|
||||
# endif
|
||||
#endif /* !defined(__cpp_lib_philox_engine) && defined(__glibcxx_want_philox_engine) */
|
||||
#undef __glibcxx_want_philox_engine
|
||||
|
||||
#undef __glibcxx_want_all
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
# include <bits/c++0x_warning.h>
|
||||
#else
|
||||
|
||||
#define __glibcxx_want_philox_engine
|
||||
#include <bits/version.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint> // For uint_fast32_t, uint_fast64_t, uint_least32_t
|
||||
#include <cstdlib>
|
||||
|
||||
23
libstdc++-v3/testsuite/26_numerics/random/philox4x32.cc
Normal file
23
libstdc++-v3/testsuite/26_numerics/random/philox4x32.cc
Normal file
@@ -0,0 +1,23 @@
|
||||
// { 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::philox4x32 a;
|
||||
a.discard(9999);
|
||||
|
||||
VERIFY( a() == 1955073260 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
23
libstdc++-v3/testsuite/26_numerics/random/philox4x64.cc
Normal file
23
libstdc++-v3/testsuite/26_numerics/random/philox4x64.cc
Normal file
@@ -0,0 +1,23 @@
|
||||
// { 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::philox4x64 a;
|
||||
a.discard(9999);
|
||||
|
||||
VERIFY( a() == 3409172418970261260 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// { 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;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// { 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::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;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// { 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> philox4x32nullkey(0);
|
||||
|
||||
VERIFY( philox4x32nullkey.min() == 0 );
|
||||
VERIFY( philox4x32nullkey.max() == (1ul << 31 | (1ul << 31) - 1) );
|
||||
VERIFY( philox4x32nullkey() == 0x6627e8d5ul );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// { dg-do run { target c++26 } }
|
||||
// { dg-require-cstdint "" }
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// { 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;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// { 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;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// { 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;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// { 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 <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;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// { 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::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();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// { 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;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// { 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;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// { 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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -10,6 +10,6 @@ std::__detail::_Adaptor<std::mt19937, unsigned long> aurng(urng);
|
||||
auto x = std::generate_canonical<std::size_t,
|
||||
std::numeric_limits<std::size_t>::digits>(urng);
|
||||
|
||||
// { 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 *-*-* } 271 }
|
||||
|
||||
// { 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 *-*-* } 3548 }
|
||||
|
||||
Reference in New Issue
Block a user