diff options
13 files changed, 704 insertions, 37 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 03d4e51e85c..8359f4f5335 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 f812bbf18b1..b76cfbb558e 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 f398150d416..9ec29895d27 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 0a98b350925..7e931865af3 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 07857dd6c82..d845f253ab7 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 00000000000..0e44ffff2eb --- /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 00000000000..4fad65121d6 --- /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 00000000000..3330b47ea70 --- /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 00000000000..d900bc378d8 --- /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 13c052daef8..1ead99cffc4 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 00000000000..13ad5e595e6 --- /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 00000000000..e4a13a72b45 --- /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 00000000000..325e27517b1 --- /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(); +} |