diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a3e0a424963..2e9e849a2db 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,27 @@ +2010-02-01 Paolo Carlini + + PR libstdc++/42408 + * include/bits/random.h (linear_congruential_engine<>:: + linear_congruential_engine(seed_seq&), + linear_congruential_engine<>::seed(seed_seq&), + mersenne_twister<>::mersenne_twister(seed_seq&), + mersenne_twister<>::seed(seed_seq&), + subtract_with_carry_engine<>::subtract_with_carry_engine(seed_seq&), + subtract_with_carry_engine<>::seed(seed_seq&), + discard_block_engine<>::discard_block_engine(seed_seq&), + discard_block_engine<>::seed(seed_seq&), + independent_bits_engine<>::independent_bits_engine(seed_seq&), + independent_bits_engine<>::seed(seed_seq&), + shuffle_order_engine<>::shuffle_order_engine(seed_seq&), + shuffle_order_engine<>::seed(seed_seq&)): Templatize. + * include/bits/random.tcc: Adjust. + * testsuite/26_numerics/random/subtract_with_carry_engine/cons/ + seed_seq.cc: New. + * testsuite/26_numerics/random/mersenne_twister_engine/cons/ + seed_seq.cc: Likewise. + * testsuite/26_numerics/random/linear_congruential_engine/ + cons/seed_seq.cc: Likewise. + 2010-02-01 Paolo Carlini * include/bits/forward_list.h (forward_list<>::resize(size_type), diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h index c86eb9947f8..528a04a0911 100644 --- a/libstdc++-v3/include/bits/random.h +++ b/libstdc++-v3/include/bits/random.h @@ -1,6 +1,6 @@ // random number generation -*- C++ -*- -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2009, 2010 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 @@ -50,8 +50,6 @@ namespace std _RealType generate_canonical(_UniformRandomNumberGenerator& __g); - class seed_seq; - /* * Implementation-space details. */ @@ -179,7 +177,7 @@ namespace std */ explicit linear_congruential_engine(result_type __s = default_seed) - { this->seed(__s); } + { seed(__s); } /** * @brief Constructs a %linear_congruential_engine random number @@ -187,9 +185,11 @@ namespace std * * @param __q the seed sequence. */ - explicit - linear_congruential_engine(seed_seq& __q) - { this->seed(__q); } + template::value>::type> + explicit + linear_congruential_engine(_Sseq& __q) + { seed<_Sseq>(__q); } /** * @brief Reseeds the %linear_congruential_engine random number generator @@ -207,8 +207,10 @@ namespace std * * @param __q the seed sequence. */ - void - seed(seed_seq& __q); + template::value>::type> + void + seed(_Sseq& __q); /** * @brief Gets the smallest possible value in the output range. @@ -398,15 +400,19 @@ namespace std * * @param __q the seed sequence. */ - explicit - mersenne_twister_engine(seed_seq& __q) - { seed(__q); } + template::value>::type> + explicit + mersenne_twister_engine(_Sseq& __q) + { seed<_Sseq>(__q); } void seed(result_type __sd = default_seed); - void - seed(seed_seq& __q); + template::value>::type> + void + seed(_Sseq& __q); /** * @brief Gets the smallest possible value in the output range. @@ -557,7 +563,7 @@ namespace std */ explicit subtract_with_carry_engine(result_type __sd = default_seed) - { this->seed(__sd); } + { seed(__sd); } /** * @brief Constructs a %subtract_with_carry_engine random number engine @@ -565,9 +571,11 @@ namespace std * * @param __q the seed sequence. */ - explicit - subtract_with_carry_engine(seed_seq& __q) - { this->seed(__q); } + template::value>::type> + explicit + subtract_with_carry_engine(_Sseq& __q) + { seed<_Sseq>(__q); } /** * @brief Seeds the initial state @f$ x_0 @f$ of the random number @@ -588,8 +596,10 @@ namespace std * @brief Seeds the initial state @f$ x_0 @f$ of the * % subtract_with_carry_engine random number generator. */ - void - seed(seed_seq& __q); + template::value>::type> + void + seed(_Sseq& __q); /** * @brief Gets the inclusive minimum value of the range of random @@ -670,7 +680,8 @@ namespace std * @p __is. * * @param __is An input stream. - * @param __x A % subtract_with_carry_engine random number generator engine. + * @param __x A % subtract_with_carry_engine random number generator + * engine. * * @returns The input stream with the state of @p __x extracted or in * an error state. @@ -751,10 +762,14 @@ namespace std * * @param __q A seed sequence. */ - explicit - discard_block_engine(seed_seq& __q) - : _M_b(__q), _M_n(0) - { } + template::value + && !std::is_same<_Sseq, _RandomNumberEngine> + ::value>::type> + explicit + discard_block_engine(_Sseq& __q) + : _M_b(__q), _M_n(0) + { } /** * @brief Reseeds the %discard_block_engine object with the default @@ -783,12 +798,14 @@ namespace std * sequence. * @param __q A seed generator function. */ - void - seed(seed_seq& __q) - { - _M_b.seed(__q); - _M_n = 0; - } + template::value>::type> + void + seed(_Sseq& __q) + { + _M_b.seed<_Sseq>(__q); + _M_n = 0; + } /** * @brief Gets a const reference to the underlying generator engine @@ -949,10 +966,14 @@ namespace std * * @param __q A seed sequence. */ - explicit - independent_bits_engine(seed_seq& __q) - : _M_b(__q) - { } + template::value + && !std::is_same<_Sseq, _RandomNumberEngine> + ::value>::type> + explicit + independent_bits_engine(_Sseq& __q) + : _M_b(__q) + { } /** * @brief Reseeds the %independent_bits_engine object with the default @@ -975,9 +996,11 @@ namespace std * seed sequence. * @param __q A seed generator function. */ - void - seed(seed_seq& __q) - { _M_b.seed(__q); } + template::value>::type> + void + seed(_Sseq& __q) + { _M_b.seed<_Sseq>(__q); } /** * @brief Gets a const reference to the underlying generator engine @@ -1150,10 +1173,14 @@ namespace std * * @param __q A seed sequence. */ - explicit - shuffle_order_engine(seed_seq& __q) - : _M_b(__q) - { _M_initialize(); } + template::value + && !std::is_same<_Sseq, _RandomNumberEngine> + ::value>::type> + explicit + shuffle_order_engine(_Sseq& __q) + : _M_b(__q) + { _M_initialize(); } /** * @brief Reseeds the %shuffle_order_engine object with the default seed @@ -1182,12 +1209,14 @@ namespace std * sequence. * @param __q A seed generator function. */ - void - seed(seed_seq& __q) - { - _M_b.seed(__q); - _M_initialize(); - } + template::value>::type> + void + seed(_Sseq& __q) + { + _M_b.seed<_Sseq>(__q); + _M_initialize(); + } /** * Gets a const reference to the underlying generator engine object. diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc index 712426ec9b6..4a8c4d86f71 100644 --- a/libstdc++-v3/include/bits/random.tcc +++ b/libstdc++-v3/include/bits/random.tcc @@ -1,6 +1,6 @@ // random number generation (out of line) -*- C++ -*- -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2009, 2010 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 @@ -126,24 +126,25 @@ namespace std * Seeds the LCR engine with a value generated by @p __q. */ template - void - linear_congruential_engine<_UIntType, __a, __c, __m>:: - seed(seed_seq& __q) - { - const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits - : std::__lg(__m); - const _UIntType __k = (__k0 + 31) / 32; - uint_least32_t __arr[__k + 3]; - __q.generate(__arr + 0, __arr + __k + 3); - _UIntType __factor = 1u; - _UIntType __sum = 0u; - for (size_t __j = 0; __j < __k; ++__j) - { - __sum += __arr[__j + 3] * __factor; - __factor *= __detail::_Shift<_UIntType, 32>::__value; - } - seed(__sum); - } + template + void + linear_congruential_engine<_UIntType, __a, __c, __m>:: + seed(_Sseq& __q) + { + const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits + : std::__lg(__m); + const _UIntType __k = (__k0 + 31) / 32; + uint_least32_t __arr[__k + 3]; + __q.generate(__arr + 0, __arr + __k + 3); + _UIntType __factor = 1u; + _UIntType __sum = 0u; + for (size_t __j = 0; __j < __k; ++__j) + { + __sum += __arr[__j + 3] * __factor; + __factor *= __detail::_Shift<_UIntType, 32>::__value; + } + seed(__sum); + } template @@ -343,43 +344,44 @@ namespace std _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> - void - mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, + template + void + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>:: - seed(seed_seq& __q) - { - const _UIntType __upper_mask = (~_UIntType()) << __r; - const size_t __k = (__w + 31) / 32; - uint_least32_t __arr[__n * __k]; - __q.generate(__arr + 0, __arr + __n * __k); + seed(_Sseq& __q) + { + const _UIntType __upper_mask = (~_UIntType()) << __r; + const size_t __k = (__w + 31) / 32; + uint_least32_t __arr[__n * __k]; + __q.generate(__arr + 0, __arr + __n * __k); - bool __zero = true; - for (size_t __i = 0; __i < state_size; ++__i) - { - _UIntType __factor = 1u; - _UIntType __sum = 0u; - for (size_t __j = 0; __j < __k; ++__j) - { - __sum += __arr[__k * __i + __j] * __factor; - __factor *= __detail::_Shift<_UIntType, 32>::__value; - } - _M_x[__i] = __detail::__mod<_UIntType, - __detail::_Shift<_UIntType, __w>::__value>(__sum); + bool __zero = true; + for (size_t __i = 0; __i < state_size; ++__i) + { + _UIntType __factor = 1u; + _UIntType __sum = 0u; + for (size_t __j = 0; __j < __k; ++__j) + { + __sum += __arr[__k * __i + __j] * __factor; + __factor *= __detail::_Shift<_UIntType, 32>::__value; + } + _M_x[__i] = __detail::__mod<_UIntType, + __detail::_Shift<_UIntType, __w>::__value>(__sum); - if (__zero) - { - if (__i == 0) - { - if ((_M_x[0] & __upper_mask) != 0u) - __zero = false; - } - else if (_M_x[__i] != 0u) - __zero = false; - } - } + if (__zero) + { + if (__i == 0) + { + if ((_M_x[0] & __upper_mask) != 0u) + __zero = false; + } + else if (_M_x[__i] != 0u) + __zero = false; + } + } if (__zero) _M_x[0] = __detail::_Shift<_UIntType, __w - 1>::__value; - } + } template - void - subtract_with_carry_engine<_UIntType, __w, __s, __r>:: - seed(seed_seq& __q) - { - const size_t __k = (__w + 31) / 32; - uint_least32_t __arr[__r * __k]; - __q.generate(__arr + 0, __arr + __r * __k); + template + void + subtract_with_carry_engine<_UIntType, __w, __s, __r>:: + seed(_Sseq& __q) + { + const size_t __k = (__w + 31) / 32; + uint_least32_t __arr[__r * __k]; + __q.generate(__arr + 0, __arr + __r * __k); - for (size_t __i = 0; __i < long_lag; ++__i) - { - _UIntType __sum = 0u; - _UIntType __factor = 1u; - for (size_t __j = 0; __j < __k; ++__j) - { - __sum += __arr[__k * __i + __j] * __factor; - __factor *= __detail::_Shift<_UIntType, 32>::__value; - } - _M_x[__i] = __detail::__mod<_UIntType, - __detail::_Shift<_UIntType, __w>::__value>(__sum); - } - _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; - _M_p = 0; - } + for (size_t __i = 0; __i < long_lag; ++__i) + { + _UIntType __sum = 0u; + _UIntType __factor = 1u; + for (size_t __j = 0; __j < __k; ++__j) + { + __sum += __arr[__k * __i + __j] * __factor; + __factor *= __detail::_Shift<_UIntType, 32>::__value; + } + _M_x[__i] = __detail::__mod<_UIntType, + __detail::_Shift<_UIntType, __w>::__value>(__sum); + } + _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; + _M_p = 0; + } template typename subtract_with_carry_engine<_UIntType, __w, __s, __r>:: diff --git a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed_seq.cc b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed_seq.cc new file mode 100644 index 00000000000..4ec39b5bd3a --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed_seq.cc @@ -0,0 +1,39 @@ +// { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } +// +// 2010-02-01 Paolo Carlini +// +// Copyright (C) 2010 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 +// . + +// 26.4.3.1 class template linear_congruential_engine [rand.eng.lcong] +// 26.4.2.2 Concept RandomNumberEngine [rand.concept.eng] + +#include + +void +test01() +{ + std::seed_seq seed; + std::linear_congruential_engine x(seed); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed_seq.cc b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed_seq.cc new file mode 100644 index 00000000000..c2fb9131d36 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed_seq.cc @@ -0,0 +1,44 @@ +// { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } +// +// 2010-02-01 Paolo Carlini +// +// Copyright (C) 2010 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 +// . + +// 26.4.3.2 Class template mersenne_twister_engine [rand.eng.mers] +// 26.4.2.2 Concept RandomNumberEngine [rand.concept.eng] + +#include + +void +test01() +{ + std::seed_seq seed; + std::mersenne_twister_engine< + unsigned long, 32, 624, 397, 31, + 0x9908b0dful, 11, + 0xfffffffful, 7, + 0x9d2c5680ul, 15, + 0xefc60000ul, 18, 1812433253ul> x(seed); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed_seq.cc b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed_seq.cc new file mode 100644 index 00000000000..617c455dab6 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed_seq.cc @@ -0,0 +1,39 @@ +// { dg-options "-std=c++0x" } +// { dg-require-cstdint "" } +// +// 2010-02-01 Paolo Carlini +// +// Copyright (C) 2010 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 +// . + +// 26.4.3.3 Class template subtract_with_carry_engine [rand.eng.sub] +// 26.4.2.2 Concept RandomNumberEngine [rand.concept.eng] + +#include + +void +test01() +{ + std::seed_seq seed; + std::subtract_with_carry_engine x(seed); +} + +int main() +{ + test01(); + return 0; +}