re PR libstdc++/42408 (Missing templatized seed())

2010-02-01  Paolo Carlini  <paolo.carlini@oracle.com>

	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.

From-SVN: r156430
This commit is contained in:
Paolo Carlini 2010-02-01 19:45:23 +00:00 committed by Paolo Carlini
parent 87d05b4491
commit 15ecdcc6fc
6 changed files with 299 additions and 121 deletions

View file

@ -1,3 +1,27 @@
2010-02-01 Paolo Carlini <paolo.carlini@oracle.com>
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 <paolo.carlini@oracle.com>
* include/bits/forward_list.h (forward_list<>::resize(size_type),

View file

@ -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<typename _Sseq, typename
= typename std::enable_if<std::is_class<_Sseq>::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<typename _Sseq, typename
= typename std::enable_if<std::is_class<_Sseq>::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<typename _Sseq, typename
= typename std::enable_if<std::is_class<_Sseq>::value>::type>
explicit
mersenne_twister_engine(_Sseq& __q)
{ seed<_Sseq>(__q); }
void
seed(result_type __sd = default_seed);
void
seed(seed_seq& __q);
template<typename _Sseq, typename
= typename std::enable_if<std::is_class<_Sseq>::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<typename _Sseq, typename
= typename std::enable_if<std::is_class<_Sseq>::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<typename _Sseq, typename
= typename std::enable_if<std::is_class<_Sseq>::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<typename _Sseq, typename
= typename std::enable_if<std::is_class<_Sseq>::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<typename _Sseq, typename
= typename std::enable_if<std::is_class<_Sseq>::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<typename _Sseq, typename
= typename std::enable_if<std::is_class<_Sseq>::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<typename _Sseq, typename
= typename std::enable_if<std::is_class<_Sseq>::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<typename _Sseq, typename
= typename std::enable_if<std::is_class<_Sseq>::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<typename _Sseq, typename
= typename std::enable_if<std::is_class<_Sseq>::value>::type>
void
seed(_Sseq& __q)
{
_M_b.seed<_Sseq>(__q);
_M_initialize();
}
/**
* Gets a const reference to the underlying generator engine object.

View file

@ -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<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
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<typename _Sseq, typename>
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<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
typename _CharT, typename _Traits>
@ -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<typename _Sseq, typename>
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<typename _UIntType, size_t __w,
size_t __n, size_t __m, size_t __r,
@ -529,29 +531,30 @@ namespace std
}
template<typename _UIntType, size_t __w, size_t __s, size_t __r>
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<typename _Sseq, typename>
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 _UIntType, size_t __w, size_t __s, size_t __r>
typename subtract_with_carry_engine<_UIntType, __w, __s, __r>::

View file

@ -0,0 +1,39 @@
// { dg-options "-std=c++0x" }
// { dg-require-cstdint "" }
//
// 2010-02-01 Paolo Carlini <paolo.carlini@oracle.com>
//
// 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
// <http://www.gnu.org/licenses/>.
// 26.4.3.1 class template linear_congruential_engine [rand.eng.lcong]
// 26.4.2.2 Concept RandomNumberEngine [rand.concept.eng]
#include <random>
void
test01()
{
std::seed_seq seed;
std::linear_congruential_engine<unsigned long, 48271, 0, 2147483647> x(seed);
}
int main()
{
test01();
return 0;
}

View file

@ -0,0 +1,44 @@
// { dg-options "-std=c++0x" }
// { dg-require-cstdint "" }
//
// 2010-02-01 Paolo Carlini <paolo.carlini@oracle.com>
//
// 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
// <http://www.gnu.org/licenses/>.
// 26.4.3.2 Class template mersenne_twister_engine [rand.eng.mers]
// 26.4.2.2 Concept RandomNumberEngine [rand.concept.eng]
#include <random>
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;
}

View file

@ -0,0 +1,39 @@
// { dg-options "-std=c++0x" }
// { dg-require-cstdint "" }
//
// 2010-02-01 Paolo Carlini <paolo.carlini@oracle.com>
//
// 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
// <http://www.gnu.org/licenses/>.
// 26.4.3.3 Class template subtract_with_carry_engine [rand.eng.sub]
// 26.4.2.2 Concept RandomNumberEngine [rand.concept.eng]
#include <random>
void
test01()
{
std::seed_seq seed;
std::subtract_with_carry_engine<unsigned long, 24, 10, 24> x(seed);
}
int main()
{
test01();
return 0;
}