From 7b93bdde911212694e170bb8063b11a91bbc0bcd Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 27 Aug 2012 14:13:15 +0000 Subject: [PATCH] Add interfaces to retrieve random numbers in bulk. * include/bits/random.h (uniform_int_distribution<>): Add __generate and __generate_impl functions. (uniform_real_distribution<>): Likewise. (bernoulli_distribution): Likewise. (geometric_distribution<>): Likewise. (negative_binomial_distribution<>): Likewise. (poisson_distribution<>): Likewise. (exponential_distribution<>): Likewise. (normal_distribution<>): Likewise. (lognormal_distribution<>): Likewise. (chi_squared_distribution<>): Likewise. (cauchy_distribution<>): Likewise. (fisher_f_distribution<>): Likewise. (student_t_distribution<>): Likewise. (gamma_distribution<>): Likewise. (weibull_distribution<>): Likewise. (extreme_value_distribution<>): Likewise. (discrete_distribution<>): Likewise. (piecewise_constant_distribution<>): Likewise. (piecewise_linear_distribution<>): Likewise. * include/bits/random.tcc (__detail::_Power_of_2): New function. (uniform_int_distribution<>::__generate_impl): New function. (uniform_real_distribution<>::__generate_impl): New function. (bernoulli_distribution::__generate_impl): New function. (geometric_distribution<>::__generate_impl): New function. (negative_binomial_distribution<>::__generate_impl): New function. (poisson_distribution<>::__generate_impl): New function. (exponential_distribution<>::__generate_impl): New function. (normal_distribution<>::__generate_impl): New function. (lognormal_distribution<>::__generate_impl): New function. (chi_squared_distribution<>::__generate_impl): New function. (cauchy_distribution<>::__generate_impl): New function. (fisher_f_distribution<>::__generate_impl): New function. (student_t_distribution<>::__generate_impl): New function. (gamma_distribution<>::__generate_impl): New function. (weibull_distribution<>::__generate_impl): New function. (extreme_value_distribution<>::__generate_impl): New function. (discrete_distribution<>::__generate_impl): New function. (piecewise_constant_distribution<>::__generate_impl): New function. (piecewise_linear_distribution<>::__generate_impl): New function. From-SVN: r190712 --- libstdc++-v3/ChangeLog | 54 ++- libstdc++-v3/include/bits/random.h | 627 +++++++++++++++++++++++++++ libstdc++-v3/include/bits/random.tcc | 601 +++++++++++++++++++++++++ 3 files changed, 1277 insertions(+), 5 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index bc088e8c167a..c2fcddc3bda4 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,4 +1,48 @@ -012-08-22 Ulrich Drepper +2012-08-27 Ulrich Drepper + + Add interfaces to retrieve random numbers in bulk. + * include/bits/random.h (uniform_int_distribution<>): Add __generate + and __generate_impl functions. + (uniform_real_distribution<>): Likewise. + (bernoulli_distribution): Likewise. + (geometric_distribution<>): Likewise. + (negative_binomial_distribution<>): Likewise. + (poisson_distribution<>): Likewise. + (exponential_distribution<>): Likewise. + (normal_distribution<>): Likewise. + (lognormal_distribution<>): Likewise. + (chi_squared_distribution<>): Likewise. + (cauchy_distribution<>): Likewise. + (fisher_f_distribution<>): Likewise. + (student_t_distribution<>): Likewise. + (gamma_distribution<>): Likewise. + (weibull_distribution<>): Likewise. + (extreme_value_distribution<>): Likewise. + (discrete_distribution<>): Likewise. + (piecewise_constant_distribution<>): Likewise. + (piecewise_linear_distribution<>): Likewise. + * include/bits/random.tcc (__detail::_Power_of_2): New function. + (uniform_int_distribution<>::__generate_impl): New function. + (uniform_real_distribution<>::__generate_impl): New function. + (bernoulli_distribution::__generate_impl): New function. + (geometric_distribution<>::__generate_impl): New function. + (negative_binomial_distribution<>::__generate_impl): New function. + (poisson_distribution<>::__generate_impl): New function. + (exponential_distribution<>::__generate_impl): New function. + (normal_distribution<>::__generate_impl): New function. + (lognormal_distribution<>::__generate_impl): New function. + (chi_squared_distribution<>::__generate_impl): New function. + (cauchy_distribution<>::__generate_impl): New function. + (fisher_f_distribution<>::__generate_impl): New function. + (student_t_distribution<>::__generate_impl): New function. + (gamma_distribution<>::__generate_impl): New function. + (weibull_distribution<>::__generate_impl): New function. + (extreme_value_distribution<>::__generate_impl): New function. + (discrete_distribution<>::__generate_impl): New function. + (piecewise_constant_distribution<>::__generate_impl): New function. + (piecewise_linear_distribution<>::__generate_impl): New function. + +2012-08-22 Ulrich Drepper * include/bits/random.h (mersenne_twister_engine): Don't inline discard here. New member function _M_gen_rand. @@ -7,7 +51,7 @@ (mersenne_twister_engine<>::discard): New implementation which skips in large steps. (mersenne_twister_engine<>::operator()): Use _M_gen_rand. - + 2012-08-26 Marc Glisse Paolo Carlini @@ -489,8 +533,8 @@ PR c++/53322 * include/bits/stl_algobase.h (lower_bound) - (lexicographical_compare): Do not declare unused local typedefs - here when Concepts are turned off. + (lexicographical_compare): Do not declare unused local typedefs + here when Concepts are turned off. 2012-05-21 Paolo Carlini @@ -2006,7 +2050,7 @@ PR libstdc++/52309 * include/bits/hashtable_policy.h (_Equality_base<, true,>:: - _M_equal(const _Hashtable&)): Compare values with operator==. + _M_equal(const _Hashtable&)): Compare values with operator==. * testsuite/23_containers/unordered_set/operators/52309.cc: New. 2012-02-17 Benjamin Kosnik diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h index 35aceea85676..6bedc4250fbe 100644 --- a/libstdc++-v3/include/bits/random.h +++ b/libstdc++-v3/include/bits/random.h @@ -1782,6 +1782,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; }; @@ -1962,7 +1992,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return (__aurng() * (__p.b() - __p.a())) + __p.a(); } + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; }; @@ -2151,6 +2210,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + /** * @brief Return true if two normal distributions have * the same parameters and the sequences that would @@ -2192,6 +2273,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::normal_distribution<_RealType1>& __x); private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; result_type _M_saved; bool _M_saved_available; @@ -2325,6 +2413,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const param_type& __p) { return std::exp(__p.s() * _M_nd(__urng) + __p.m()); } + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + /** * @brief Return true if two lognormal distributions have * the same parameters and the sequences that would @@ -2367,6 +2477,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::lognormal_distribution<_RealType1>& __x); private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; std::normal_distribution _M_nd; @@ -2517,6 +2634,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + /** * @brief Return true if two gamma distributions have the same * parameters and the sequences that would be generated @@ -2558,6 +2697,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::gamma_distribution<_RealType1>& __x); private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; std::normal_distribution _M_nd; @@ -2681,6 +2827,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return 2 * _M_gd(__urng, param_type(__p.n() / 2)); } + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate_impl(__f, __t, __urng, _M_gd.param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { typename std::gamma_distribution::param_type + __p2(__p.n() / 2); + this->__generate_impl(__f, __t, __urng, __p2); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng) + { typename std::gamma_distribution::param_type + __p2(_M_gd.param()); + this->__generate_impl(__f, __t, __urng, __p2); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { typename std::gamma_distribution::param_type + __p2(__p.n() / 2); + this->__generate_impl(__f, __t, __urng, __p2); } + /** * @brief Return true if two Chi-squared distributions have * the same parameters and the sequences that would be @@ -2722,6 +2902,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::chi_squared_distribution<_RealType1>& __x); private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + typename std::gamma_distribution::param_type& + __p); + param_type _M_param; std::gamma_distribution _M_gd; @@ -2851,7 +3039,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; }; @@ -3033,6 +3250,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION / (_M_gd_y(__urng, param_type(__p.n() / 2)) * m())); } + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate_impl(__f, __t, __urng); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate_impl(__f, __t, __urng); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + /** * @brief Return true if two Fisher f distributions have * the same parameters and the sequences that would @@ -3076,6 +3321,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::fisher_f_distribution<_RealType1>& __x); private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng); + + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; std::gamma_distribution _M_gd_x, _M_gd_y; @@ -3206,6 +3464,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _M_nd(__urng) * std::sqrt(__p.n() / __g); } + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate_impl(__f, __t, __urng); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate_impl(__f, __t, __urng); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + /** * @brief Return true if two Student t distributions have * the same parameters and the sequences that would @@ -3248,6 +3534,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::student_t_distribution<_RealType1>& __x); private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng); + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; std::normal_distribution _M_nd; @@ -3389,7 +3687,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return false; } + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; }; @@ -3581,6 +3907,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + /** * @brief Return true if two binomial distributions have * the same parameters and the sequences that would @@ -3628,6 +3976,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::binomial_distribution<_IntType1>& __x); private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + template result_type _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t); @@ -3764,7 +4119,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; }; @@ -3937,6 +4321,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate_impl(__f, __t, __urng); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate_impl(__f, __t, __urng); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + /** * @brief Return true if two negative binomial distributions have * the same parameters and the sequences that would be @@ -3979,6 +4391,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::negative_binomial_distribution<_IntType1>& __x); private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng); + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; std::gamma_distribution _M_gd; @@ -4120,6 +4544,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + /** * @brief Return true if two Poisson distributions have the same * parameters and the sequences that would be generated @@ -4165,6 +4611,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::poisson_distribution<_IntType1>& __x); private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined. @@ -4306,7 +4759,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return -std::log(__aurng()) / __p.lambda(); } + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; }; @@ -4481,7 +4963,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; }; @@ -4656,7 +5167,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; }; @@ -4857,6 +5397,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + /** * @brief Inserts a %discrete_distribution random number distribution * @p __x into the output stream @p __os. @@ -4889,6 +5451,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::discrete_distribution<_IntType1>& __x); private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; }; @@ -5095,6 +5664,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + /** * @brief Inserts a %piecewise_constan_distribution random * number distribution @p __x into the output stream @p __os. @@ -5128,6 +5719,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::piecewise_constant_distribution<_RealType1>& __x); private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; }; @@ -5337,6 +5935,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { this->__generate(__f, __t, __urng, this->param()); } + + template + void + __generate(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + + template + void + __generate(result_type* __f, result_type* __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { this->__generate_impl(__f, __t, __urng, __p); } + /** * @brief Inserts a %piecewise_linear_distribution random number * distribution @p __x into the output stream @p __os. @@ -5370,6 +5990,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::piecewise_linear_distribution<_RealType1>& __x); private: + template + void + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p); + param_type _M_param; }; diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc index 6f501b1e9826..9ae5e1283ba5 100644 --- a/libstdc++-v3/include/bits/random.tcc +++ b/libstdc++-v3/include/bits/random.tcc @@ -89,6 +89,12 @@ namespace std _GLIBCXX_VISIBILITY(default) return __result; } + template + bool _Power_of_2(_Tp __x) + { + return ((__x - 1) & __x) == 0; + }; + _GLIBCXX_END_NAMESPACE_VERSION } // namespace __detail @@ -936,6 +942,93 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __ret + __param.a(); } + + template + template + void + uniform_int_distribution<_IntType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __param) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + typedef typename _UniformRandomNumberGenerator::result_type + _Gresult_type; + typedef typename std::make_unsigned::type __utype; + typedef typename std::common_type<_Gresult_type, __utype>::type + __uctype; + + const __uctype __urngmin = __urng.min(); + const __uctype __urngmax = __urng.max(); + const __uctype __urngrange = __urngmax - __urngmin; + const __uctype __urange + = __uctype(__param.b()) - __uctype(__param.a()); + + __uctype __ret; + + if (__urngrange > __urange) + { + if (__detail::_Power_of_2(__urngrange + 1) + && __detail::_Power_of_2(__urange + 1)) + { + while (__f != __t) + { + __ret = __uctype(__urng()) - __urngmin; + *__f++ = (__ret & __urange) + __param.a(); + } + } + else + { + // downscaling + const __uctype __uerange = __urange + 1; // __urange can be zero + const __uctype __scaling = __urngrange / __uerange; + const __uctype __past = __uerange * __scaling; + while (__f != __t) + { + do + __ret = __uctype(__urng()) - __urngmin; + while (__ret >= __past); + *__f++ = __ret / __scaling + __param.a(); + } + } + } + else if (__urngrange < __urange) + { + // upscaling + /* + Note that every value in [0, urange] + can be written uniquely as + + (urngrange + 1) * high + low + + where + + high in [0, urange / (urngrange + 1)] + + and + + low in [0, urngrange]. + */ + __uctype __tmp; // wraparound control + while (__f != __t) + { + do + { + const __uctype __uerngrange = __urngrange + 1; + __tmp = (__uerngrange * operator() + (__urng, param_type(0, __urange / __uerngrange))); + __ret = __tmp + (__uctype(__urng()) - __urngmin); + } + while (__ret > __urange || __ret < __tmp); + *__f++ = __ret; + } + } + else + while (__f != __t) + *__f++ = __uctype(__urng()) - __urngmin + __param.a(); + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -978,6 +1071,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } + template + template + void + uniform_real_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> + __aurng(__urng); + auto __range = __p.b() - __p.a(); + while (__f != __t) + *__f++ = __aurng() * __range + __p.a(); + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -1023,6 +1133,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } + template + void + std::bernoulli_distribution:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __detail::_Adaptor<_UniformRandomNumberGenerator, double> + __aurng(__urng); + auto __limit = __p.p() * (__aurng.max() - __aurng.min()); + + while (__f != __t) + *__f++ = (__aurng() - __aurng.min()) < __limit; + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -1072,6 +1199,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return result_type(__cand + __naf); } + template + template + void + geometric_distribution<_IntType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __param) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + // About the epsilon thing see this thread: + // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html + const double __naf = + (1 - std::numeric_limits::epsilon()) / 2; + // The largest _RealType convertible to _IntType. + const double __thr = + std::numeric_limits<_IntType>::max() + __naf; + __detail::_Adaptor<_UniformRandomNumberGenerator, double> + __aurng(__urng); + + while (__f != __t) + { + double __cand; + do + __cand = std::floor(std::log(__aurng()) / __param._M_log_1_p); + while (__cand >= __thr); + + *__f++ = __cand + __naf; + } + } + template std::basic_ostream<_CharT, _Traits>& @@ -1147,6 +1305,47 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __poisson(__urng); } + template + template + void + negative_binomial_distribution<_IntType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + while (__f != __t) + { + const double __y = _M_gd(__urng); + + // XXX Is the constructor too slow? + std::poisson_distribution __poisson(__y); + *__f++ = __poisson(__urng); + } + } + + template + template + void + negative_binomial_distribution<_IntType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + typename std::gamma_distribution::param_type + __p2(__p.k(), (1.0 - __p.p()) / __p.p()); + + while (__f != __t) + { + const double __y = _M_gd(__urng, __p2); + + std::poisson_distribution __poisson(__y); + *__f++ = __poisson(__urng); + } + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -1336,6 +1535,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + template + template + void + poisson_distribution<_IntType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __param) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + // We could duplicate everything from operator()... + while (__f != __t) + *__f++ = this->operator()(__urng, __param); + } + template std::basic_ostream<_CharT, _Traits>& @@ -1584,6 +1798,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __ret; } + template + template + void + binomial_distribution<_IntType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __param) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + // We could duplicate everything from operator()... + while (__f != __t) + *__f++ = this->operator()(__urng, __param); + } + template std::basic_ostream<_CharT, _Traits>& @@ -1633,6 +1862,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } + template + template + void + std::exponential_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> + __aurng(__urng); + while (__f != __t) + *__f++ = -std::log(__aurng()) / __p.lambda(); + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -1720,6 +1965,66 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __ret; } + template + template + void + normal_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __param) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + + if (__f == __t) + return; + + if (_M_saved_available) + { + _M_saved_available = false; + *__f++ = _M_saved * __param.stddev() + __param.mean(); + + if (__f == __t) + return; + } + + __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> + __aurng(__urng); + + while (__f + 1 < __t) + { + result_type __x, __y, __r2; + do + { + __x = result_type(2.0) * __aurng() - 1.0; + __y = result_type(2.0) * __aurng() - 1.0; + __r2 = __x * __x + __y * __y; + } + while (__r2 > 1.0 || __r2 == 0.0); + + const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); + *__f++ = __y * __mult * __param.stddev() + __param.mean(); + *__f++ = __x * __mult * __param.stddev() + __param.mean(); + } + + if (__f != __t) + { + result_type __x, __y, __r2; + do + { + __x = result_type(2.0) * __aurng() - 1.0; + __y = result_type(2.0) * __aurng() - 1.0; + __r2 = __x * __x + __y * __y; + } + while (__r2 > 1.0 || __r2 == 0.0); + + const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); + _M_saved = __x * __mult; + _M_saved_available = true; + *__f = __y * __mult * __param.stddev() + __param.mean(); + } + } + template bool operator==(const std::normal_distribution<_RealType>& __d1, @@ -1791,6 +2096,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } + template + template + void + lognormal_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + while (__f != __t) + *__f++ = std::exp(__p.s() * _M_nd(__urng) + __p.m()); + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -1837,6 +2156,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } + template + template + void + std::chi_squared_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + typename std::gamma_distribution::param_type& + __p) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + while (__f != __t) + *__f++ = 2 * _M_gd(__urng, __p); + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -1900,6 +2234,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __p.a() + __p.b() * std::tan(__pi * __u); } + template + template + void + cauchy_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + const _RealType __pi = 3.1415926535897932384626433832795029L; + __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> + __aurng(__urng); + while (__f != __t) + { + _RealType __u; + do + __u = __aurng(); + while (__u == 0.5); + + *__f++ = __p.a() + __p.b() * std::tan(__pi * __u); + } + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -1945,6 +2303,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } + template + template + void + std::fisher_f_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + while (__f != __t) + *__f++ = ((_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m())); + } + + template + template + void + std::fisher_f_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + typedef typename std::gamma_distribution::param_type + param_type; + param_type __p1(__p.m() / 2); + param_type __p2(__p.n() / 2); + while (__f != __t) + *__f++ = ((_M_gd_x(__urng, __p1) * n()) + / (_M_gd_y(__urng, __p2) * m())); + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -1991,6 +2381,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } + template + template + void + std::student_t_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + while (__f != __t) + *__f++ = _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); + } + + template + template + void + std::student_t_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + typename std::gamma_distribution::param_type + __p2(__p.n() / 2, 2); + while (__f != __t) + *__f++ = _M_nd(__urng) * std::sqrt(__p.n() / _M_gd(__urng, __p2)); + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -2094,6 +2513,72 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + template + template + void + gamma_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __param) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> + __aurng(__urng); + + result_type __u, __v, __n; + const result_type __a1 = (__param._M_malpha + - _RealType(1.0) / _RealType(3.0)); + + if (__param.alpha() == __param._M_malpha) + while (__f != __t) + { + do + { + do + { + __n = _M_nd(__urng); + __v = result_type(1.0) + __param._M_a2 * __n; + } + while (__v <= 0.0); + + __v = __v * __v * __v; + __u = __aurng(); + } + while (__u > result_type(1.0) - 0.331 * __n * __n * __n * __n + && (std::log(__u) > (0.5 * __n * __n + __a1 + * (1.0 - __v + std::log(__v))))); + + *__f++ = __a1 * __v * __param.beta(); + } + else + while (__f != __t) + { + do + { + do + { + __n = _M_nd(__urng); + __v = result_type(1.0) + __param._M_a2 * __n; + } + while (__v <= 0.0); + + __v = __v * __v * __v; + __u = __aurng(); + } + while (__u > result_type(1.0) - 0.331 * __n * __n * __n * __n + && (std::log(__u) > (0.5 * __n * __n + __a1 + * (1.0 - __v + std::log(__v))))); + + do + __u = __aurng(); + while (__u == 0.0); + + *__f++ = (std::pow(__u, result_type(1.0) / __param.alpha()) + * __a1 * __v * __param.beta()); + } + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -2153,6 +2638,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION result_type(1) / __p.a()); } + template + template + void + weibull_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> + __aurng(__urng); + auto inv_a = result_type(1) / __p.a(); + + while (__f != __t) + *__f++ = __p.b() * std::pow(-std::log(__aurng()), inv_a); + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -2210,6 +2713,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __p.a() - __p.b() * std::log(-std::log(__aurng())); } + template + template + void + extreme_value_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __p) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> + __aurng(__urng); + + while (__f != __t) + *__f++ = __p.a() - __p.b() * std::log(-std::log(__aurng())); + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -2315,6 +2835,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __pos - __param._M_cp.begin(); } + template + template + void + discrete_distribution<_IntType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __param) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + + if (__param._M_cp.empty()) + { + while (__f != __t) + *__f++ = result_type(0); + return; + } + + __detail::_Adaptor<_UniformRandomNumberGenerator, double> + __aurng(__urng); + + while (__f != __t) + { + const double __p = __aurng(); + auto __pos = std::lower_bound(__param._M_cp.begin(), + __param._M_cp.end(), __p); + + *__f++ = __pos - __param._M_cp.begin(); + } + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -2490,6 +3041,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __param._M_int[__i] + (__p - __pref) / __param._M_den[__i]; } + template + template + void + piecewise_constant_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __param) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + __detail::_Adaptor<_UniformRandomNumberGenerator, double> + __aurng(__urng); + + if (__param._M_cp.empty()) + { + while (__f != __t) + *__f++ = __aurng(); + return; + } + + while (__f != __t) + { + const double __p = __aurng(); + + auto __pos = std::lower_bound(__param._M_cp.begin(), + __param._M_cp.end(), __p); + const size_t __i = __pos - __param._M_cp.begin(); + + const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0; + + *__f++ = (__param._M_int[__i] + + (__p - __pref) / __param._M_den[__i]); + } + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, @@ -2692,6 +3278,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __x; } + template + template + void + piecewise_linear_distribution<_RealType>:: + __generate_impl(_ForwardIterator __f, _ForwardIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __param) + { + __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) + // We could duplicate everything from operator()... + while (__f != __t) + *__f++ = this->operator()(__urng, __param); + } + template std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os,