PR libstdc++/85749 constrain seed sequences for random number engines
Constrain constructors and member functions of random number engines so that functions taking seed sequences can only be called with types that meet the seed sequence requirements. PR libstdc++/85749 * include/bits/random.h (__detail::__is_seed_seq): New SFINAE helper. (linear_congruential_engine, mersenne_twister_engine) (subtract_with_carry_engine, discard_block_engine) (independent_bits_engine, shuffle_order_engine): Use __is_seed_seq to constrain function templates taking seed sequences. * include/bits/random.tcc (linear_congruential_engine::seed(_Sseq&)) (mersenne_twister_engine::seed(_Sseq&)) (subtract_with_carry_engine::seed(_Sseq&)): Change return types to match declarations. * include/ext/random (simd_fast_mersenne_twister_engine): Use __is_seed_seq to constrain function templates taking seed sequences. * include/ext/random.tcc (simd_fast_mersenne_twister_engine::seed): Change return type to match declaration. * testsuite/26_numerics/random/discard_block_engine/cons/seed_seq2.cc: New. * testsuite/26_numerics/random/independent_bits_engine/cons/ seed_seq2.cc: New. * testsuite/26_numerics/random/linear_congruential_engine/cons/ seed_seq2.cc: New. * testsuite/26_numerics/random/mersenne_twister_engine/cons/ seed_seq2.cc: New. * testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error lineno. * testsuite/26_numerics/random/shuffle_order_engine/cons/seed_seq2.cc: New. * testsuite/26_numerics/random/subtract_with_carry_engine/cons/ seed_seq2.cc: New. * testsuite/ext/random/simd_fast_mersenne_twister_engine/cons/ seed_seq2.cc: New. From-SVN: r260263
This commit is contained in:
parent
c3b61fdadd
commit
5a7960da41
|
@ -1,5 +1,35 @@
|
|||
2018-05-15 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/85749
|
||||
* include/bits/random.h (__detail::__is_seed_seq): New SFINAE helper.
|
||||
(linear_congruential_engine, mersenne_twister_engine)
|
||||
(subtract_with_carry_engine, discard_block_engine)
|
||||
(independent_bits_engine, shuffle_order_engine): Use __is_seed_seq to
|
||||
constrain function templates taking seed sequences.
|
||||
* include/bits/random.tcc (linear_congruential_engine::seed(_Sseq&))
|
||||
(mersenne_twister_engine::seed(_Sseq&))
|
||||
(subtract_with_carry_engine::seed(_Sseq&)): Change return types to
|
||||
match declarations.
|
||||
* include/ext/random (simd_fast_mersenne_twister_engine): Use
|
||||
__is_seed_seq to constrain function templates taking seed sequences.
|
||||
* include/ext/random.tcc (simd_fast_mersenne_twister_engine::seed):
|
||||
Change return type to match declaration.
|
||||
* testsuite/26_numerics/random/discard_block_engine/cons/seed_seq2.cc:
|
||||
New.
|
||||
* testsuite/26_numerics/random/independent_bits_engine/cons/
|
||||
seed_seq2.cc: New.
|
||||
* testsuite/26_numerics/random/linear_congruential_engine/cons/
|
||||
seed_seq2.cc: New.
|
||||
* testsuite/26_numerics/random/mersenne_twister_engine/cons/
|
||||
seed_seq2.cc: New.
|
||||
* testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error lineno.
|
||||
* testsuite/26_numerics/random/shuffle_order_engine/cons/seed_seq2.cc:
|
||||
New.
|
||||
* testsuite/26_numerics/random/subtract_with_carry_engine/cons/
|
||||
seed_seq2.cc: New.
|
||||
* testsuite/ext/random/simd_fast_mersenne_twister_engine/cons/
|
||||
seed_seq2.cc: New.
|
||||
|
||||
PR libstdc++/83891
|
||||
* include/bits/fs_path.h (path::is_absolute()): Use same definition
|
||||
for all operating systems.
|
||||
|
|
|
@ -185,6 +185,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
_Engine& _M_g;
|
||||
};
|
||||
|
||||
template<typename _Sseq>
|
||||
using __seed_seq_generate_t = decltype(
|
||||
std::declval<_Sseq&>().generate(std::declval<uint_least32_t*>(),
|
||||
std::declval<uint_least32_t*>()));
|
||||
|
||||
// Detect whether _Sseq is a valid seed sequence for
|
||||
// a random number engine _Engine with result type _Res.
|
||||
template<typename _Sseq, typename _Engine, typename _Res,
|
||||
typename _GenerateCheck = __seed_seq_generate_t<_Sseq>>
|
||||
using __is_seed_seq = __and_<
|
||||
__not_<is_same<__remove_cvref_t<_Sseq>, _Engine>>,
|
||||
is_unsigned<typename _Sseq::result_type>,
|
||||
__not_<is_convertible<_Sseq, _Res>>
|
||||
>;
|
||||
|
||||
} // namespace __detail
|
||||
|
||||
/**
|
||||
|
@ -233,6 +248,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
static_assert(__m == 0u || (__a < __m && __c < __m),
|
||||
"template argument substituting __m out of bounds");
|
||||
|
||||
template<typename _Sseq>
|
||||
using _If_seed_seq = typename enable_if<__detail::__is_seed_seq<
|
||||
_Sseq, linear_congruential_engine, _UIntType>::value>::type;
|
||||
|
||||
public:
|
||||
/** The type of the generated random value. */
|
||||
typedef _UIntType result_type;
|
||||
|
@ -262,9 +281,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
*
|
||||
* @param __q the seed sequence.
|
||||
*/
|
||||
template<typename _Sseq, typename = typename
|
||||
std::enable_if<!std::is_same<_Sseq, linear_congruential_engine>::value>
|
||||
::type>
|
||||
template<typename _Sseq, typename = _If_seed_seq<_Sseq>>
|
||||
explicit
|
||||
linear_congruential_engine(_Sseq& __q)
|
||||
{ seed(__q); }
|
||||
|
@ -286,7 +303,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
* @param __q the seed sequence.
|
||||
*/
|
||||
template<typename _Sseq>
|
||||
typename std::enable_if<std::is_class<_Sseq>::value>::type
|
||||
_If_seed_seq<_Sseq>
|
||||
seed(_Sseq& __q);
|
||||
|
||||
/**
|
||||
|
@ -463,6 +480,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
static_assert(__f <= (__detail::_Shift<_UIntType, __w>::__value - 1),
|
||||
"template argument substituting __f out of bound");
|
||||
|
||||
template<typename _Sseq>
|
||||
using _If_seed_seq = typename enable_if<__detail::__is_seed_seq<
|
||||
_Sseq, mersenne_twister_engine, _UIntType>::value>::type;
|
||||
|
||||
public:
|
||||
/** The type of the generated random value. */
|
||||
typedef _UIntType result_type;
|
||||
|
@ -494,9 +515,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
*
|
||||
* @param __q the seed sequence.
|
||||
*/
|
||||
template<typename _Sseq, typename = typename
|
||||
std::enable_if<!std::is_same<_Sseq, mersenne_twister_engine>::value>
|
||||
::type>
|
||||
template<typename _Sseq, typename = _If_seed_seq<_Sseq>>
|
||||
explicit
|
||||
mersenne_twister_engine(_Sseq& __q)
|
||||
{ seed(__q); }
|
||||
|
@ -505,7 +524,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
seed(result_type __sd = default_seed);
|
||||
|
||||
template<typename _Sseq>
|
||||
typename std::enable_if<std::is_class<_Sseq>::value>::type
|
||||
_If_seed_seq<_Sseq>
|
||||
seed(_Sseq& __q);
|
||||
|
||||
/**
|
||||
|
@ -658,6 +677,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
|
||||
"template argument substituting __w out of bounds");
|
||||
|
||||
template<typename _Sseq>
|
||||
using _If_seed_seq = typename enable_if<__detail::__is_seed_seq<
|
||||
_Sseq, subtract_with_carry_engine, _UIntType>::value>::type;
|
||||
|
||||
public:
|
||||
/** The type of the generated random value. */
|
||||
typedef _UIntType result_type;
|
||||
|
@ -682,9 +705,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
*
|
||||
* @param __q the seed sequence.
|
||||
*/
|
||||
template<typename _Sseq, typename = typename
|
||||
std::enable_if<!std::is_same<_Sseq, subtract_with_carry_engine>::value>
|
||||
::type>
|
||||
template<typename _Sseq, typename = _If_seed_seq<_Sseq>>
|
||||
explicit
|
||||
subtract_with_carry_engine(_Sseq& __q)
|
||||
{ seed(__q); }
|
||||
|
@ -709,7 +730,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
* % subtract_with_carry_engine random number generator.
|
||||
*/
|
||||
template<typename _Sseq>
|
||||
typename std::enable_if<std::is_class<_Sseq>::value>::type
|
||||
_If_seed_seq<_Sseq>
|
||||
seed(_Sseq& __q);
|
||||
|
||||
/**
|
||||
|
@ -845,6 +866,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
/** The type of the generated random value. */
|
||||
typedef typename _RandomNumberEngine::result_type result_type;
|
||||
|
||||
template<typename _Sseq>
|
||||
using _If_seed_seq = typename enable_if<__detail::__is_seed_seq<
|
||||
_Sseq, discard_block_engine, result_type>::value>::type;
|
||||
|
||||
// parameter values
|
||||
static constexpr size_t block_size = __p;
|
||||
static constexpr size_t used_block = __r;
|
||||
|
@ -892,10 +917,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
*
|
||||
* @param __q A seed sequence.
|
||||
*/
|
||||
template<typename _Sseq, typename = typename
|
||||
std::enable_if<!std::is_same<_Sseq, discard_block_engine>::value
|
||||
&& !std::is_same<_Sseq, _RandomNumberEngine>::value>
|
||||
::type>
|
||||
template<typename _Sseq, typename = _If_seed_seq<_Sseq>>
|
||||
explicit
|
||||
discard_block_engine(_Sseq& __q)
|
||||
: _M_b(__q), _M_n(0)
|
||||
|
@ -929,7 +951,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
* @param __q A seed generator function.
|
||||
*/
|
||||
template<typename _Sseq>
|
||||
void
|
||||
_If_seed_seq<_Sseq>
|
||||
seed(_Sseq& __q)
|
||||
{
|
||||
_M_b.seed(__q);
|
||||
|
@ -1063,6 +1085,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
|
||||
"template argument substituting __w out of bounds");
|
||||
|
||||
template<typename _Sseq>
|
||||
using _If_seed_seq = typename enable_if<__detail::__is_seed_seq<
|
||||
_Sseq, independent_bits_engine, _UIntType>::value>::type;
|
||||
|
||||
public:
|
||||
/** The type of the generated random value. */
|
||||
typedef _UIntType result_type;
|
||||
|
@ -1110,10 +1136,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
*
|
||||
* @param __q A seed sequence.
|
||||
*/
|
||||
template<typename _Sseq, typename = typename
|
||||
std::enable_if<!std::is_same<_Sseq, independent_bits_engine>::value
|
||||
&& !std::is_same<_Sseq, _RandomNumberEngine>::value>
|
||||
::type>
|
||||
template<typename _Sseq, typename = _If_seed_seq<_Sseq>>
|
||||
explicit
|
||||
independent_bits_engine(_Sseq& __q)
|
||||
: _M_b(__q)
|
||||
|
@ -1141,7 +1164,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
* @param __q A seed generator function.
|
||||
*/
|
||||
template<typename _Sseq>
|
||||
void
|
||||
_If_seed_seq<_Sseq>
|
||||
seed(_Sseq& __q)
|
||||
{ _M_b.seed(__q); }
|
||||
|
||||
|
@ -1283,6 +1306,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
/** The type of the generated random value. */
|
||||
typedef typename _RandomNumberEngine::result_type result_type;
|
||||
|
||||
template<typename _Sseq>
|
||||
using _If_seed_seq = typename enable_if<__detail::__is_seed_seq<
|
||||
_Sseq, shuffle_order_engine, result_type>::value>::type;
|
||||
|
||||
static constexpr size_t table_size = __k;
|
||||
|
||||
/**
|
||||
|
@ -1332,10 +1359,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
*
|
||||
* @param __q A seed sequence.
|
||||
*/
|
||||
template<typename _Sseq, typename = typename
|
||||
std::enable_if<!std::is_same<_Sseq, shuffle_order_engine>::value
|
||||
&& !std::is_same<_Sseq, _RandomNumberEngine>::value>
|
||||
::type>
|
||||
template<typename _Sseq, typename = _If_seed_seq<_Sseq>>
|
||||
explicit
|
||||
shuffle_order_engine(_Sseq& __q)
|
||||
: _M_b(__q)
|
||||
|
@ -1369,7 +1393,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
* @param __q A seed generator function.
|
||||
*/
|
||||
template<typename _Sseq>
|
||||
void
|
||||
_If_seed_seq<_Sseq>
|
||||
seed(_Sseq& __q)
|
||||
{
|
||||
_M_b.seed(__q);
|
||||
|
|
|
@ -128,9 +128,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
*/
|
||||
template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
|
||||
template<typename _Sseq>
|
||||
typename std::enable_if<std::is_class<_Sseq>::value>::type
|
||||
auto
|
||||
linear_congruential_engine<_UIntType, __a, __c, __m>::
|
||||
seed(_Sseq& __q)
|
||||
-> _If_seed_seq<_Sseq>
|
||||
{
|
||||
const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits
|
||||
: std::__lg(__m);
|
||||
|
@ -346,10 +347,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
_UIntType __b, size_t __t, _UIntType __c, size_t __l,
|
||||
_UIntType __f>
|
||||
template<typename _Sseq>
|
||||
typename std::enable_if<std::is_class<_Sseq>::value>::type
|
||||
auto
|
||||
mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
|
||||
__s, __b, __t, __c, __l, __f>::
|
||||
seed(_Sseq& __q)
|
||||
-> _If_seed_seq<_Sseq>
|
||||
{
|
||||
const _UIntType __upper_mask = (~_UIntType()) << __r;
|
||||
const size_t __k = (__w + 31) / 32;
|
||||
|
@ -564,9 +566,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
|
||||
template<typename _UIntType, size_t __w, size_t __s, size_t __r>
|
||||
template<typename _Sseq>
|
||||
typename std::enable_if<std::is_class<_Sseq>::value>::type
|
||||
auto
|
||||
subtract_with_carry_engine<_UIntType, __w, __s, __r>::
|
||||
seed(_Sseq& __q)
|
||||
-> _If_seed_seq<_Sseq>
|
||||
{
|
||||
const size_t __k = (__w + 31) / 32;
|
||||
uint_least32_t __arr[__r * __k];
|
||||
|
|
|
@ -85,6 +85,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
static_assert(16 % sizeof(_UIntType) == 0,
|
||||
"UIntType size must divide 16");
|
||||
|
||||
template<typename _Sseq>
|
||||
using _If_seed_seq
|
||||
= typename std::enable_if<std::__detail::__is_seed_seq<
|
||||
_Sseq, simd_fast_mersenne_twister_engine, result_type>::value
|
||||
>::type;
|
||||
|
||||
public:
|
||||
static constexpr size_t state_size = _M_nstate * (16
|
||||
/ sizeof(result_type));
|
||||
|
@ -95,10 +101,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
simd_fast_mersenne_twister_engine(result_type __sd = default_seed)
|
||||
{ seed(__sd); }
|
||||
|
||||
template<typename _Sseq, typename = typename
|
||||
std::enable_if<!std::is_same<_Sseq,
|
||||
simd_fast_mersenne_twister_engine>::value>
|
||||
::type>
|
||||
template<typename _Sseq, typename = _If_seed_seq<_Sseq>>
|
||||
explicit
|
||||
simd_fast_mersenne_twister_engine(_Sseq& __q)
|
||||
{ seed(__q); }
|
||||
|
@ -107,7 +110,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
seed(result_type __sd = default_seed);
|
||||
|
||||
template<typename _Sseq>
|
||||
typename std::enable_if<std::is_class<_Sseq>::value>::type
|
||||
_If_seed_seq<_Sseq>
|
||||
seed(_Sseq& __q);
|
||||
|
||||
static constexpr result_type
|
||||
|
|
|
@ -85,13 +85,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
uint32_t __parity1, uint32_t __parity2,
|
||||
uint32_t __parity3, uint32_t __parity4>
|
||||
template<typename _Sseq>
|
||||
typename std::enable_if<std::is_class<_Sseq>::value>::type
|
||||
auto
|
||||
simd_fast_mersenne_twister_engine<_UIntType, __m,
|
||||
__pos1, __sl1, __sl2, __sr1, __sr2,
|
||||
__msk1, __msk2, __msk3, __msk4,
|
||||
__parity1, __parity2, __parity3,
|
||||
__parity4>::
|
||||
seed(_Sseq& __q)
|
||||
-> _If_seed_seq<_Sseq>
|
||||
{
|
||||
size_t __lag;
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-do run { target c++11 } }
|
||||
// { dg-require-cstdint "" }
|
||||
|
||||
#include <random>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
template<typename T>
|
||||
struct seed_seq
|
||||
{
|
||||
using result_type = unsigned;
|
||||
|
||||
seed_seq() { }
|
||||
|
||||
template<class U>
|
||||
seed_seq(std::initializer_list<U>) { }
|
||||
|
||||
template<class InputIterator>
|
||||
seed_seq(InputIterator, InputIterator) { }
|
||||
|
||||
template<class RandomAccessIterator>
|
||||
void generate(RandomAccessIterator first, RandomAccessIterator last)
|
||||
{
|
||||
called = true;
|
||||
if (first != last)
|
||||
*first = 42;
|
||||
}
|
||||
|
||||
size_t size() const { called = true; return 1; }
|
||||
|
||||
template<class OutputIterator>
|
||||
void param(OutputIterator dest) const { called = true; dest = 42; }
|
||||
|
||||
// Prevents this type being considered as a seed sequence when
|
||||
// T is convertible to the engine's result_type:
|
||||
operator T() const noexcept { return T(); }
|
||||
|
||||
bool called = false;
|
||||
};
|
||||
|
||||
using engine_type
|
||||
= std::discard_block_engine
|
||||
<
|
||||
std::subtract_with_carry_engine<unsigned long, 24, 10, 24>,
|
||||
389, 24
|
||||
>;
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
seed_seq<unsigned> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( ! seed.called );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
seed_seq<void*> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( seed.called );
|
||||
|
||||
static_assert(!std::is_constructible<engine_type, const seed_seq<void>&>(),
|
||||
"Cannot construct from a const seed_seq");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-do run { target c++11 } }
|
||||
// { dg-require-cstdint "" }
|
||||
|
||||
#include <random>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
template<typename T>
|
||||
struct seed_seq
|
||||
{
|
||||
using result_type = unsigned;
|
||||
|
||||
seed_seq() { }
|
||||
|
||||
template<class U>
|
||||
seed_seq(std::initializer_list<U>) { }
|
||||
|
||||
template<class InputIterator>
|
||||
seed_seq(InputIterator, InputIterator) { }
|
||||
|
||||
template<class RandomAccessIterator>
|
||||
void generate(RandomAccessIterator first, RandomAccessIterator last)
|
||||
{
|
||||
called = true;
|
||||
if (first != last)
|
||||
*first = 42;
|
||||
}
|
||||
|
||||
size_t size() const { called = true; return 1; }
|
||||
|
||||
template<class OutputIterator>
|
||||
void param(OutputIterator dest) const { called = true; dest = 42; }
|
||||
|
||||
// Prevents this type being considered as a seed sequence when
|
||||
// T is convertible to the engine's result_type:
|
||||
operator T() const noexcept { return T(); }
|
||||
|
||||
bool called = false;
|
||||
};
|
||||
|
||||
using engine_type
|
||||
= std::independent_bits_engine
|
||||
<
|
||||
std::subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>,
|
||||
48,
|
||||
uint_fast64_t
|
||||
>;
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
seed_seq<unsigned> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( ! seed.called );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
seed_seq<void*> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( seed.called );
|
||||
|
||||
static_assert(!std::is_constructible<engine_type, const seed_seq<void>&>(),
|
||||
"Cannot construct from a const seed_seq");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-do run { target c++11 } }
|
||||
// { dg-require-cstdint "" }
|
||||
|
||||
#include <random>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
template<typename T>
|
||||
struct seed_seq
|
||||
{
|
||||
using result_type = unsigned;
|
||||
|
||||
seed_seq() { }
|
||||
|
||||
template<class U>
|
||||
seed_seq(std::initializer_list<U>) { }
|
||||
|
||||
template<class InputIterator>
|
||||
seed_seq(InputIterator, InputIterator) { }
|
||||
|
||||
template<class RandomAccessIterator>
|
||||
void generate(RandomAccessIterator first, RandomAccessIterator last)
|
||||
{
|
||||
called = true;
|
||||
if (first != last)
|
||||
*first = 42;
|
||||
}
|
||||
|
||||
size_t size() const { called = true; return 1; }
|
||||
|
||||
template<class OutputIterator>
|
||||
void param(OutputIterator dest) const { called = true; dest = 42; }
|
||||
|
||||
// Prevents this type being considered as a seed sequence when
|
||||
// T is convertible to the engine's result_type:
|
||||
operator T() const noexcept { return T(); }
|
||||
|
||||
bool called = false;
|
||||
};
|
||||
|
||||
using engine_type
|
||||
= std::linear_congruential_engine<unsigned, 48271, 0, 2147483647>;
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
seed_seq<unsigned> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( ! seed.called );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
seed_seq<void*> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( seed.called );
|
||||
|
||||
static_assert(!std::is_constructible<engine_type, const seed_seq<void>&>(),
|
||||
"Cannot construct from a const seed_seq");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-do run { target c++11 } }
|
||||
// { dg-require-cstdint "" }
|
||||
|
||||
#include <random>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
template<typename T>
|
||||
struct seed_seq
|
||||
{
|
||||
using result_type = unsigned;
|
||||
|
||||
seed_seq() { }
|
||||
|
||||
template<class U>
|
||||
seed_seq(std::initializer_list<U>) { }
|
||||
|
||||
template<class InputIterator>
|
||||
seed_seq(InputIterator, InputIterator) { }
|
||||
|
||||
template<class RandomAccessIterator>
|
||||
void generate(RandomAccessIterator first, RandomAccessIterator last)
|
||||
{
|
||||
called = true;
|
||||
if (first != last)
|
||||
*first = 42;
|
||||
}
|
||||
|
||||
size_t size() const { called = true; return 1; }
|
||||
|
||||
template<class OutputIterator>
|
||||
void param(OutputIterator dest) const { called = true; dest = 42; }
|
||||
|
||||
// Prevents this type being considered as a seed sequence when
|
||||
// T is convertible to the engine's result_type:
|
||||
operator T() const noexcept { return T(); }
|
||||
|
||||
bool called = false;
|
||||
};
|
||||
|
||||
using engine_type
|
||||
= std::mersenne_twister_engine<
|
||||
unsigned long, 32, 624, 397, 31,
|
||||
0x9908b0dful, 11,
|
||||
0xfffffffful, 7,
|
||||
0x9d2c5680ul, 15,
|
||||
0xefc60000ul, 18, 1812433253ul>;
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
seed_seq<unsigned> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( ! seed.called );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
seed_seq<void*> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( seed.called );
|
||||
|
||||
static_assert(!std::is_constructible<engine_type, const seed_seq<void>&>(),
|
||||
"Cannot construct from a const seed_seq");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
|
@ -11,4 +11,4 @@ auto x = std::generate_canonical<std::size_t,
|
|||
|
||||
// { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 156 }
|
||||
|
||||
// { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 3317 }
|
||||
// { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 3320 }
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-do run { target c++11 } }
|
||||
// { dg-require-cstdint "" }
|
||||
|
||||
#include <random>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
template<typename T>
|
||||
struct seed_seq
|
||||
{
|
||||
using result_type = unsigned;
|
||||
|
||||
seed_seq() { }
|
||||
|
||||
template<class U>
|
||||
seed_seq(std::initializer_list<U>) { }
|
||||
|
||||
template<class InputIterator>
|
||||
seed_seq(InputIterator, InputIterator) { }
|
||||
|
||||
template<class RandomAccessIterator>
|
||||
void generate(RandomAccessIterator first, RandomAccessIterator last)
|
||||
{
|
||||
called = true;
|
||||
if (first != last)
|
||||
*first = 42;
|
||||
}
|
||||
|
||||
size_t size() const { called = true; return 1; }
|
||||
|
||||
template<class OutputIterator>
|
||||
void param(OutputIterator dest) const { called = true; dest = 42; }
|
||||
|
||||
// Prevents this type being considered as a seed sequence when
|
||||
// T is convertible to the engine's result_type:
|
||||
operator T() const noexcept { return T(); }
|
||||
|
||||
bool called = false;
|
||||
};
|
||||
|
||||
using engine_type
|
||||
= std::shuffle_order_engine
|
||||
<
|
||||
std::linear_congruential_engine<uint_fast32_t,16807UL, 0UL, 2147483647UL>,
|
||||
256
|
||||
>;
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
seed_seq<unsigned> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( ! seed.called );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
seed_seq<void*> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( seed.called );
|
||||
|
||||
static_assert(!std::is_constructible<engine_type, const seed_seq<void>&>(),
|
||||
"Cannot construct from a const seed_seq");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-do run { target c++11 } }
|
||||
// { dg-require-cstdint "" }
|
||||
|
||||
#include <random>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
template<typename T>
|
||||
struct seed_seq
|
||||
{
|
||||
using result_type = unsigned;
|
||||
|
||||
seed_seq() { }
|
||||
|
||||
template<class U>
|
||||
seed_seq(std::initializer_list<U>) { }
|
||||
|
||||
template<class InputIterator>
|
||||
seed_seq(InputIterator, InputIterator) { }
|
||||
|
||||
template<class RandomAccessIterator>
|
||||
void generate(RandomAccessIterator first, RandomAccessIterator last)
|
||||
{
|
||||
called = true;
|
||||
if (first != last)
|
||||
*first = 42;
|
||||
}
|
||||
|
||||
size_t size() const { called = true; return 1; }
|
||||
|
||||
template<class OutputIterator>
|
||||
void param(OutputIterator dest) const { called = true; dest = 42; }
|
||||
|
||||
// Prevents this type being considered as a seed sequence when
|
||||
// T is convertible to the engine's result_type:
|
||||
operator T() const noexcept { return T(); }
|
||||
|
||||
bool called = false;
|
||||
};
|
||||
|
||||
using engine_type
|
||||
= std::subtract_with_carry_engine<unsigned long, 24, 10, 24>;
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
seed_seq<unsigned> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( ! seed.called );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
seed_seq<void*> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( seed.called );
|
||||
|
||||
static_assert(!std::is_constructible<engine_type, const seed_seq<void>&>(),
|
||||
"Cannot construct from a const seed_seq");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-do run { target c++11 } }
|
||||
// { dg-require-cstdint "" }
|
||||
// { dg-require-little-endian "" }
|
||||
|
||||
#include <ext/random>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
template<typename T>
|
||||
struct seed_seq
|
||||
{
|
||||
using result_type = unsigned;
|
||||
|
||||
seed_seq() { }
|
||||
|
||||
template<class U>
|
||||
seed_seq(std::initializer_list<U>) { }
|
||||
|
||||
template<class InputIterator>
|
||||
seed_seq(InputIterator, InputIterator) { }
|
||||
|
||||
template<class RandomAccessIterator>
|
||||
void generate(RandomAccessIterator first, RandomAccessIterator last)
|
||||
{
|
||||
called = true;
|
||||
if (first != last)
|
||||
*first = 42;
|
||||
}
|
||||
|
||||
size_t size() const { called = true; return 1; }
|
||||
|
||||
template<class OutputIterator>
|
||||
void param(OutputIterator dest) const { called = true; dest = 42; }
|
||||
|
||||
// Prevents this type being considered as a seed sequence when
|
||||
// T is convertible to the engine's result_type:
|
||||
operator T() const noexcept { return T(); }
|
||||
|
||||
bool called = false;
|
||||
};
|
||||
|
||||
using engine_type
|
||||
= __gnu_cxx::simd_fast_mersenne_twister_engine<
|
||||
uint32_t, 607, 2,
|
||||
15, 3, 13, 3,
|
||||
0xfdff37ffU, 0xef7f3f7dU,
|
||||
0xff777b7dU, 0x7ff7fb2fU,
|
||||
0x00000001U, 0x00000000U,
|
||||
0x00000000U, 0x5986f054U>;
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
seed_seq<unsigned> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( ! seed.called );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
seed_seq<void*> seed;
|
||||
engine_type x(seed);
|
||||
VERIFY( seed.called );
|
||||
|
||||
static_assert(!std::is_constructible<engine_type, const seed_seq<void>&>(),
|
||||
"Cannot construct from a const seed_seq");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
Loading…
Reference in New Issue