summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog30
-rw-r--r--libstdc++-v3/include/bits/random.h78
-rw-r--r--libstdc++-v3/include/bits/random.tcc9
-rw-r--r--libstdc++-v3/include/ext/random13
-rw-r--r--libstdc++-v3/include/ext/random.tcc3
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed_seq2.cc87
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed_seq2.cc88
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed_seq2.cc83
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed_seq2.cc88
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc2
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed_seq2.cc87
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed_seq2.cc83
-rw-r--r--libstdc++-v3/testsuite/ext/random/simd_fast_mersenne_twister_engine/cons/seed_seq2.cc90
13 files changed, 704 insertions, 37 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 03d4e51e85c3..8359f4f5335f 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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.
diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
index f812bbf18b1e..b76cfbb558e1 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -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);
diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc
index f398150d4160..9ec29895d27b 100644
--- a/libstdc++-v3/include/bits/random.tcc
+++ b/libstdc++-v3/include/bits/random.tcc
@@ -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];
diff --git a/libstdc++-v3/include/ext/random b/libstdc++-v3/include/ext/random
index 0a98b3509252..7e931865af33 100644
--- a/libstdc++-v3/include/ext/random
+++ b/libstdc++-v3/include/ext/random
@@ -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
diff --git a/libstdc++-v3/include/ext/random.tcc b/libstdc++-v3/include/ext/random.tcc
index 07857dd6c82b..d845f253ab74 100644
--- a/libstdc++-v3/include/ext/random.tcc
+++ b/libstdc++-v3/include/ext/random.tcc
@@ -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;
diff --git a/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed_seq2.cc b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed_seq2.cc
new file mode 100644
index 000000000000..0e44ffff2ebf
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/discard_block_engine/cons/seed_seq2.cc
@@ -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();
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed_seq2.cc b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed_seq2.cc
new file mode 100644
index 000000000000..4fad65121d63
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/independent_bits_engine/cons/seed_seq2.cc
@@ -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();
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed_seq2.cc b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed_seq2.cc
new file mode 100644
index 000000000000..3330b47ea707
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed_seq2.cc
@@ -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();
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed_seq2.cc b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed_seq2.cc
new file mode 100644
index 000000000000..d900bc378d86
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed_seq2.cc
@@ -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();
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc
index 13c052daef85..1ead99cffc47 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc
@@ -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 }
diff --git a/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed_seq2.cc b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed_seq2.cc
new file mode 100644
index 000000000000..13ad5e595e68
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/shuffle_order_engine/cons/seed_seq2.cc
@@ -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();
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed_seq2.cc b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed_seq2.cc
new file mode 100644
index 000000000000..e4a13a72b45b
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed_seq2.cc
@@ -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();
+}
diff --git a/libstdc++-v3/testsuite/ext/random/simd_fast_mersenne_twister_engine/cons/seed_seq2.cc b/libstdc++-v3/testsuite/ext/random/simd_fast_mersenne_twister_engine/cons/seed_seq2.cc
new file mode 100644
index 000000000000..325e27517b19
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/random/simd_fast_mersenne_twister_engine/cons/seed_seq2.cc
@@ -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();
+}