xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/random.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj // random number generation -*- C++ -*-
2*38fd1498Szrj 
3*38fd1498Szrj // Copyright (C) 2009-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj 
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj 
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj 
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj 
25*38fd1498Szrj /**
26*38fd1498Szrj  * @file bits/random.h
27*38fd1498Szrj  *  This is an internal header file, included by other library headers.
28*38fd1498Szrj  *  Do not attempt to use it directly. @headername{random}
29*38fd1498Szrj  */
30*38fd1498Szrj 
31*38fd1498Szrj #ifndef _RANDOM_H
32*38fd1498Szrj #define _RANDOM_H 1
33*38fd1498Szrj 
34*38fd1498Szrj #include <vector>
35*38fd1498Szrj #include <bits/uniform_int_dist.h>
36*38fd1498Szrj 
_GLIBCXX_VISIBILITY(default)37*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
38*38fd1498Szrj {
39*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
40*38fd1498Szrj 
41*38fd1498Szrj   // [26.4] Random number generation
42*38fd1498Szrj 
43*38fd1498Szrj   /**
44*38fd1498Szrj    * @defgroup random Random Number Generation
45*38fd1498Szrj    * @ingroup numerics
46*38fd1498Szrj    *
47*38fd1498Szrj    * A facility for generating random numbers on selected distributions.
48*38fd1498Szrj    * @{
49*38fd1498Szrj    */
50*38fd1498Szrj 
51*38fd1498Szrj   /**
52*38fd1498Szrj    * @brief A function template for converting the output of a (integral)
53*38fd1498Szrj    * uniform random number generator to a floatng point result in the range
54*38fd1498Szrj    * [0-1).
55*38fd1498Szrj    */
56*38fd1498Szrj   template<typename _RealType, size_t __bits,
57*38fd1498Szrj 	   typename _UniformRandomNumberGenerator>
58*38fd1498Szrj     _RealType
59*38fd1498Szrj     generate_canonical(_UniformRandomNumberGenerator& __g);
60*38fd1498Szrj 
61*38fd1498Szrj   /*
62*38fd1498Szrj    * Implementation-space details.
63*38fd1498Szrj    */
64*38fd1498Szrj   namespace __detail
65*38fd1498Szrj   {
66*38fd1498Szrj     template<typename _UIntType, size_t __w,
67*38fd1498Szrj 	     bool = __w < static_cast<size_t>
68*38fd1498Szrj 			  (std::numeric_limits<_UIntType>::digits)>
69*38fd1498Szrj       struct _Shift
70*38fd1498Szrj       { static const _UIntType __value = 0; };
71*38fd1498Szrj 
72*38fd1498Szrj     template<typename _UIntType, size_t __w>
73*38fd1498Szrj       struct _Shift<_UIntType, __w, true>
74*38fd1498Szrj       { static const _UIntType __value = _UIntType(1) << __w; };
75*38fd1498Szrj 
76*38fd1498Szrj     template<int __s,
77*38fd1498Szrj 	     int __which = ((__s <= __CHAR_BIT__ * sizeof (int))
78*38fd1498Szrj 			    + (__s <= __CHAR_BIT__ * sizeof (long))
79*38fd1498Szrj 			    + (__s <= __CHAR_BIT__ * sizeof (long long))
80*38fd1498Szrj 			    /* assume long long no bigger than __int128 */
81*38fd1498Szrj 			    + (__s <= 128))>
82*38fd1498Szrj       struct _Select_uint_least_t
83*38fd1498Szrj       {
84*38fd1498Szrj 	static_assert(__which < 0, /* needs to be dependent */
85*38fd1498Szrj 		      "sorry, would be too much trouble for a slow result");
86*38fd1498Szrj       };
87*38fd1498Szrj 
88*38fd1498Szrj     template<int __s>
89*38fd1498Szrj       struct _Select_uint_least_t<__s, 4>
90*38fd1498Szrj       { typedef unsigned int type; };
91*38fd1498Szrj 
92*38fd1498Szrj     template<int __s>
93*38fd1498Szrj       struct _Select_uint_least_t<__s, 3>
94*38fd1498Szrj       { typedef unsigned long type; };
95*38fd1498Szrj 
96*38fd1498Szrj     template<int __s>
97*38fd1498Szrj       struct _Select_uint_least_t<__s, 2>
98*38fd1498Szrj       { typedef unsigned long long type; };
99*38fd1498Szrj 
100*38fd1498Szrj #ifdef _GLIBCXX_USE_INT128
101*38fd1498Szrj     template<int __s>
102*38fd1498Szrj       struct _Select_uint_least_t<__s, 1>
103*38fd1498Szrj       { typedef unsigned __int128 type; };
104*38fd1498Szrj #endif
105*38fd1498Szrj 
106*38fd1498Szrj     // Assume a != 0, a < m, c < m, x < m.
107*38fd1498Szrj     template<typename _Tp, _Tp __m, _Tp __a, _Tp __c,
108*38fd1498Szrj 	     bool __big_enough = (!(__m & (__m - 1))
109*38fd1498Szrj 				  || (_Tp(-1) - __c) / __a >= __m - 1),
110*38fd1498Szrj              bool __schrage_ok = __m % __a < __m / __a>
111*38fd1498Szrj       struct _Mod
112*38fd1498Szrj       {
113*38fd1498Szrj 	typedef typename _Select_uint_least_t<std::__lg(__a)
114*38fd1498Szrj 					      + std::__lg(__m) + 2>::type _Tp2;
115*38fd1498Szrj 	static _Tp
116*38fd1498Szrj 	__calc(_Tp __x)
117*38fd1498Szrj 	{ return static_cast<_Tp>((_Tp2(__a) * __x + __c) % __m); }
118*38fd1498Szrj       };
119*38fd1498Szrj 
120*38fd1498Szrj     // Schrage.
121*38fd1498Szrj     template<typename _Tp, _Tp __m, _Tp __a, _Tp __c>
122*38fd1498Szrj       struct _Mod<_Tp, __m, __a, __c, false, true>
123*38fd1498Szrj       {
124*38fd1498Szrj 	static _Tp
125*38fd1498Szrj 	__calc(_Tp __x);
126*38fd1498Szrj       };
127*38fd1498Szrj 
128*38fd1498Szrj     // Special cases:
129*38fd1498Szrj     // - for m == 2^n or m == 0, unsigned integer overflow is safe.
130*38fd1498Szrj     // - a * (m - 1) + c fits in _Tp, there is no overflow.
131*38fd1498Szrj     template<typename _Tp, _Tp __m, _Tp __a, _Tp __c, bool __s>
132*38fd1498Szrj       struct _Mod<_Tp, __m, __a, __c, true, __s>
133*38fd1498Szrj       {
134*38fd1498Szrj 	static _Tp
135*38fd1498Szrj 	__calc(_Tp __x)
136*38fd1498Szrj 	{
137*38fd1498Szrj 	  _Tp __res = __a * __x + __c;
138*38fd1498Szrj 	  if (__m)
139*38fd1498Szrj 	    __res %= __m;
140*38fd1498Szrj 	  return __res;
141*38fd1498Szrj 	}
142*38fd1498Szrj       };
143*38fd1498Szrj 
144*38fd1498Szrj     template<typename _Tp, _Tp __m, _Tp __a = 1, _Tp __c = 0>
145*38fd1498Szrj       inline _Tp
146*38fd1498Szrj       __mod(_Tp __x)
147*38fd1498Szrj       { return _Mod<_Tp, __m, __a, __c>::__calc(__x); }
148*38fd1498Szrj 
149*38fd1498Szrj     /*
150*38fd1498Szrj      * An adaptor class for converting the output of any Generator into
151*38fd1498Szrj      * the input for a specific Distribution.
152*38fd1498Szrj      */
153*38fd1498Szrj     template<typename _Engine, typename _DInputType>
154*38fd1498Szrj       struct _Adaptor
155*38fd1498Szrj       {
156*38fd1498Szrj 	static_assert(std::is_floating_point<_DInputType>::value,
157*38fd1498Szrj 		      "template argument must be a floating point type");
158*38fd1498Szrj 
159*38fd1498Szrj       public:
160*38fd1498Szrj 	_Adaptor(_Engine& __g)
161*38fd1498Szrj 	: _M_g(__g) { }
162*38fd1498Szrj 
163*38fd1498Szrj 	_DInputType
164*38fd1498Szrj 	min() const
165*38fd1498Szrj 	{ return _DInputType(0); }
166*38fd1498Szrj 
167*38fd1498Szrj 	_DInputType
168*38fd1498Szrj 	max() const
169*38fd1498Szrj 	{ return _DInputType(1); }
170*38fd1498Szrj 
171*38fd1498Szrj 	/*
172*38fd1498Szrj 	 * Converts a value generated by the adapted random number generator
173*38fd1498Szrj 	 * into a value in the input domain for the dependent random number
174*38fd1498Szrj 	 * distribution.
175*38fd1498Szrj 	 */
176*38fd1498Szrj 	_DInputType
177*38fd1498Szrj 	operator()()
178*38fd1498Szrj 	{
179*38fd1498Szrj 	  return std::generate_canonical<_DInputType,
180*38fd1498Szrj 	                            std::numeric_limits<_DInputType>::digits,
181*38fd1498Szrj 	                            _Engine>(_M_g);
182*38fd1498Szrj 	}
183*38fd1498Szrj 
184*38fd1498Szrj       private:
185*38fd1498Szrj 	_Engine& _M_g;
186*38fd1498Szrj       };
187*38fd1498Szrj 
188*38fd1498Szrj   } // namespace __detail
189*38fd1498Szrj 
190*38fd1498Szrj   /**
191*38fd1498Szrj    * @addtogroup random_generators Random Number Generators
192*38fd1498Szrj    * @ingroup random
193*38fd1498Szrj    *
194*38fd1498Szrj    * These classes define objects which provide random or pseudorandom
195*38fd1498Szrj    * numbers, either from a discrete or a continuous interval.  The
196*38fd1498Szrj    * random number generator supplied as a part of this library are
197*38fd1498Szrj    * all uniform random number generators which provide a sequence of
198*38fd1498Szrj    * random number uniformly distributed over their range.
199*38fd1498Szrj    *
200*38fd1498Szrj    * A number generator is a function object with an operator() that
201*38fd1498Szrj    * takes zero arguments and returns a number.
202*38fd1498Szrj    *
203*38fd1498Szrj    * A compliant random number generator must satisfy the following
204*38fd1498Szrj    * requirements.  <table border=1 cellpadding=10 cellspacing=0>
205*38fd1498Szrj    * <caption align=top>Random Number Generator Requirements</caption>
206*38fd1498Szrj    * <tr><td>To be documented.</td></tr> </table>
207*38fd1498Szrj    *
208*38fd1498Szrj    * @{
209*38fd1498Szrj    */
210*38fd1498Szrj 
211*38fd1498Szrj   /**
212*38fd1498Szrj    * @brief A model of a linear congruential random number generator.
213*38fd1498Szrj    *
214*38fd1498Szrj    * A random number generator that produces pseudorandom numbers via
215*38fd1498Szrj    * linear function:
216*38fd1498Szrj    * @f[
217*38fd1498Szrj    *     x_{i+1}\leftarrow(ax_{i} + c) \bmod m
218*38fd1498Szrj    * @f]
219*38fd1498Szrj    *
220*38fd1498Szrj    * The template parameter @p _UIntType must be an unsigned integral type
221*38fd1498Szrj    * large enough to store values up to (__m-1). If the template parameter
222*38fd1498Szrj    * @p __m is 0, the modulus @p __m used is
223*38fd1498Szrj    * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
224*38fd1498Szrj    * parameters @p __a and @p __c must be less than @p __m.
225*38fd1498Szrj    *
226*38fd1498Szrj    * The size of the state is @f$1@f$.
227*38fd1498Szrj    */
228*38fd1498Szrj   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
229*38fd1498Szrj     class linear_congruential_engine
230*38fd1498Szrj     {
231*38fd1498Szrj       static_assert(std::is_unsigned<_UIntType>::value,
232*38fd1498Szrj 		    "result_type must be an unsigned integral type");
233*38fd1498Szrj       static_assert(__m == 0u || (__a < __m && __c < __m),
234*38fd1498Szrj 		    "template argument substituting __m out of bounds");
235*38fd1498Szrj 
236*38fd1498Szrj     public:
237*38fd1498Szrj       /** The type of the generated random value. */
238*38fd1498Szrj       typedef _UIntType result_type;
239*38fd1498Szrj 
240*38fd1498Szrj       /** The multiplier. */
241*38fd1498Szrj       static constexpr result_type multiplier   = __a;
242*38fd1498Szrj       /** An increment. */
243*38fd1498Szrj       static constexpr result_type increment    = __c;
244*38fd1498Szrj       /** The modulus. */
245*38fd1498Szrj       static constexpr result_type modulus      = __m;
246*38fd1498Szrj       static constexpr result_type default_seed = 1u;
247*38fd1498Szrj 
248*38fd1498Szrj       /**
249*38fd1498Szrj        * @brief Constructs a %linear_congruential_engine random number
250*38fd1498Szrj        *        generator engine with seed @p __s.  The default seed value
251*38fd1498Szrj        *        is 1.
252*38fd1498Szrj        *
253*38fd1498Szrj        * @param __s The initial seed value.
254*38fd1498Szrj        */
255*38fd1498Szrj       explicit
256*38fd1498Szrj       linear_congruential_engine(result_type __s = default_seed)
257*38fd1498Szrj       { seed(__s); }
258*38fd1498Szrj 
259*38fd1498Szrj       /**
260*38fd1498Szrj        * @brief Constructs a %linear_congruential_engine random number
261*38fd1498Szrj        *        generator engine seeded from the seed sequence @p __q.
262*38fd1498Szrj        *
263*38fd1498Szrj        * @param __q the seed sequence.
264*38fd1498Szrj        */
265*38fd1498Szrj       template<typename _Sseq, typename = typename
266*38fd1498Szrj 	std::enable_if<!std::is_same<_Sseq, linear_congruential_engine>::value>
267*38fd1498Szrj 	       ::type>
268*38fd1498Szrj         explicit
269*38fd1498Szrj         linear_congruential_engine(_Sseq& __q)
270*38fd1498Szrj         { seed(__q); }
271*38fd1498Szrj 
272*38fd1498Szrj       /**
273*38fd1498Szrj        * @brief Reseeds the %linear_congruential_engine random number generator
274*38fd1498Szrj        *        engine sequence to the seed @p __s.
275*38fd1498Szrj        *
276*38fd1498Szrj        * @param __s The new seed.
277*38fd1498Szrj        */
278*38fd1498Szrj       void
279*38fd1498Szrj       seed(result_type __s = default_seed);
280*38fd1498Szrj 
281*38fd1498Szrj       /**
282*38fd1498Szrj        * @brief Reseeds the %linear_congruential_engine random number generator
283*38fd1498Szrj        *        engine
284*38fd1498Szrj        * sequence using values from the seed sequence @p __q.
285*38fd1498Szrj        *
286*38fd1498Szrj        * @param __q the seed sequence.
287*38fd1498Szrj        */
288*38fd1498Szrj       template<typename _Sseq>
289*38fd1498Szrj         typename std::enable_if<std::is_class<_Sseq>::value>::type
290*38fd1498Szrj         seed(_Sseq& __q);
291*38fd1498Szrj 
292*38fd1498Szrj       /**
293*38fd1498Szrj        * @brief Gets the smallest possible value in the output range.
294*38fd1498Szrj        *
295*38fd1498Szrj        * The minimum depends on the @p __c parameter: if it is zero, the
296*38fd1498Szrj        * minimum generated must be > 0, otherwise 0 is allowed.
297*38fd1498Szrj        */
298*38fd1498Szrj       static constexpr result_type
299*38fd1498Szrj       min()
300*38fd1498Szrj       { return __c == 0u ? 1u : 0u; }
301*38fd1498Szrj 
302*38fd1498Szrj       /**
303*38fd1498Szrj        * @brief Gets the largest possible value in the output range.
304*38fd1498Szrj        */
305*38fd1498Szrj       static constexpr result_type
306*38fd1498Szrj       max()
307*38fd1498Szrj       { return __m - 1u; }
308*38fd1498Szrj 
309*38fd1498Szrj       /**
310*38fd1498Szrj        * @brief Discard a sequence of random numbers.
311*38fd1498Szrj        */
312*38fd1498Szrj       void
313*38fd1498Szrj       discard(unsigned long long __z)
314*38fd1498Szrj       {
315*38fd1498Szrj 	for (; __z != 0ULL; --__z)
316*38fd1498Szrj 	  (*this)();
317*38fd1498Szrj       }
318*38fd1498Szrj 
319*38fd1498Szrj       /**
320*38fd1498Szrj        * @brief Gets the next random number in the sequence.
321*38fd1498Szrj        */
322*38fd1498Szrj       result_type
323*38fd1498Szrj       operator()()
324*38fd1498Szrj       {
325*38fd1498Szrj 	_M_x = __detail::__mod<_UIntType, __m, __a, __c>(_M_x);
326*38fd1498Szrj 	return _M_x;
327*38fd1498Szrj       }
328*38fd1498Szrj 
329*38fd1498Szrj       /**
330*38fd1498Szrj        * @brief Compares two linear congruential random number generator
331*38fd1498Szrj        * objects of the same type for equality.
332*38fd1498Szrj        *
333*38fd1498Szrj        * @param __lhs A linear congruential random number generator object.
334*38fd1498Szrj        * @param __rhs Another linear congruential random number generator
335*38fd1498Szrj        *              object.
336*38fd1498Szrj        *
337*38fd1498Szrj        * @returns true if the infinite sequences of generated values
338*38fd1498Szrj        *          would be equal, false otherwise.
339*38fd1498Szrj        */
340*38fd1498Szrj       friend bool
341*38fd1498Szrj       operator==(const linear_congruential_engine& __lhs,
342*38fd1498Szrj 		 const linear_congruential_engine& __rhs)
343*38fd1498Szrj       { return __lhs._M_x == __rhs._M_x; }
344*38fd1498Szrj 
345*38fd1498Szrj       /**
346*38fd1498Szrj        * @brief Writes the textual representation of the state x(i) of x to
347*38fd1498Szrj        *        @p __os.
348*38fd1498Szrj        *
349*38fd1498Szrj        * @param __os  The output stream.
350*38fd1498Szrj        * @param __lcr A % linear_congruential_engine random number generator.
351*38fd1498Szrj        * @returns __os.
352*38fd1498Szrj        */
353*38fd1498Szrj       template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
354*38fd1498Szrj 	       _UIntType1 __m1, typename _CharT, typename _Traits>
355*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
356*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
357*38fd1498Szrj 		   const std::linear_congruential_engine<_UIntType1,
358*38fd1498Szrj 		   __a1, __c1, __m1>& __lcr);
359*38fd1498Szrj 
360*38fd1498Szrj       /**
361*38fd1498Szrj        * @brief Sets the state of the engine by reading its textual
362*38fd1498Szrj        *        representation from @p __is.
363*38fd1498Szrj        *
364*38fd1498Szrj        * The textual representation must have been previously written using
365*38fd1498Szrj        * an output stream whose imbued locale and whose type's template
366*38fd1498Szrj        * specialization arguments _CharT and _Traits were the same as those
367*38fd1498Szrj        * of @p __is.
368*38fd1498Szrj        *
369*38fd1498Szrj        * @param __is  The input stream.
370*38fd1498Szrj        * @param __lcr A % linear_congruential_engine random number generator.
371*38fd1498Szrj        * @returns __is.
372*38fd1498Szrj        */
373*38fd1498Szrj       template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
374*38fd1498Szrj 	       _UIntType1 __m1, typename _CharT, typename _Traits>
375*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
376*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
377*38fd1498Szrj 		   std::linear_congruential_engine<_UIntType1, __a1,
378*38fd1498Szrj 		   __c1, __m1>& __lcr);
379*38fd1498Szrj 
380*38fd1498Szrj     private:
381*38fd1498Szrj       _UIntType _M_x;
382*38fd1498Szrj     };
383*38fd1498Szrj 
384*38fd1498Szrj   /**
385*38fd1498Szrj    * @brief Compares two linear congruential random number generator
386*38fd1498Szrj    * objects of the same type for inequality.
387*38fd1498Szrj    *
388*38fd1498Szrj    * @param __lhs A linear congruential random number generator object.
389*38fd1498Szrj    * @param __rhs Another linear congruential random number generator
390*38fd1498Szrj    *              object.
391*38fd1498Szrj    *
392*38fd1498Szrj    * @returns true if the infinite sequences of generated values
393*38fd1498Szrj    *          would be different, false otherwise.
394*38fd1498Szrj    */
395*38fd1498Szrj   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
396*38fd1498Szrj     inline bool
397*38fd1498Szrj     operator!=(const std::linear_congruential_engine<_UIntType, __a,
398*38fd1498Szrj 	       __c, __m>& __lhs,
399*38fd1498Szrj 	       const std::linear_congruential_engine<_UIntType, __a,
400*38fd1498Szrj 	       __c, __m>& __rhs)
401*38fd1498Szrj     { return !(__lhs == __rhs); }
402*38fd1498Szrj 
403*38fd1498Szrj 
404*38fd1498Szrj   /**
405*38fd1498Szrj    * A generalized feedback shift register discrete random number generator.
406*38fd1498Szrj    *
407*38fd1498Szrj    * This algorithm avoids multiplication and division and is designed to be
408*38fd1498Szrj    * friendly to a pipelined architecture.  If the parameters are chosen
409*38fd1498Szrj    * correctly, this generator will produce numbers with a very long period and
410*38fd1498Szrj    * fairly good apparent entropy, although still not cryptographically strong.
411*38fd1498Szrj    *
412*38fd1498Szrj    * The best way to use this generator is with the predefined mt19937 class.
413*38fd1498Szrj    *
414*38fd1498Szrj    * This algorithm was originally invented by Makoto Matsumoto and
415*38fd1498Szrj    * Takuji Nishimura.
416*38fd1498Szrj    *
417*38fd1498Szrj    * @tparam __w  Word size, the number of bits in each element of
418*38fd1498Szrj    *              the state vector.
419*38fd1498Szrj    * @tparam __n  The degree of recursion.
420*38fd1498Szrj    * @tparam __m  The period parameter.
421*38fd1498Szrj    * @tparam __r  The separation point bit index.
422*38fd1498Szrj    * @tparam __a  The last row of the twist matrix.
423*38fd1498Szrj    * @tparam __u  The first right-shift tempering matrix parameter.
424*38fd1498Szrj    * @tparam __d  The first right-shift tempering matrix mask.
425*38fd1498Szrj    * @tparam __s  The first left-shift tempering matrix parameter.
426*38fd1498Szrj    * @tparam __b  The first left-shift tempering matrix mask.
427*38fd1498Szrj    * @tparam __t  The second left-shift tempering matrix parameter.
428*38fd1498Szrj    * @tparam __c  The second left-shift tempering matrix mask.
429*38fd1498Szrj    * @tparam __l  The second right-shift tempering matrix parameter.
430*38fd1498Szrj    * @tparam __f  Initialization multiplier.
431*38fd1498Szrj    */
432*38fd1498Szrj   template<typename _UIntType, size_t __w,
433*38fd1498Szrj 	   size_t __n, size_t __m, size_t __r,
434*38fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
435*38fd1498Szrj 	   _UIntType __b, size_t __t,
436*38fd1498Szrj 	   _UIntType __c, size_t __l, _UIntType __f>
437*38fd1498Szrj     class mersenne_twister_engine
438*38fd1498Szrj     {
439*38fd1498Szrj       static_assert(std::is_unsigned<_UIntType>::value,
440*38fd1498Szrj 		    "result_type must be an unsigned integral type");
441*38fd1498Szrj       static_assert(1u <= __m && __m <= __n,
442*38fd1498Szrj 		    "template argument substituting __m out of bounds");
443*38fd1498Szrj       static_assert(__r <= __w, "template argument substituting "
444*38fd1498Szrj 		    "__r out of bound");
445*38fd1498Szrj       static_assert(__u <= __w, "template argument substituting "
446*38fd1498Szrj 		    "__u out of bound");
447*38fd1498Szrj       static_assert(__s <= __w, "template argument substituting "
448*38fd1498Szrj 		    "__s out of bound");
449*38fd1498Szrj       static_assert(__t <= __w, "template argument substituting "
450*38fd1498Szrj 		    "__t out of bound");
451*38fd1498Szrj       static_assert(__l <= __w, "template argument substituting "
452*38fd1498Szrj 		    "__l out of bound");
453*38fd1498Szrj       static_assert(__w <= std::numeric_limits<_UIntType>::digits,
454*38fd1498Szrj 		    "template argument substituting __w out of bound");
455*38fd1498Szrj       static_assert(__a <= (__detail::_Shift<_UIntType, __w>::__value - 1),
456*38fd1498Szrj 		    "template argument substituting __a out of bound");
457*38fd1498Szrj       static_assert(__b <= (__detail::_Shift<_UIntType, __w>::__value - 1),
458*38fd1498Szrj 		    "template argument substituting __b out of bound");
459*38fd1498Szrj       static_assert(__c <= (__detail::_Shift<_UIntType, __w>::__value - 1),
460*38fd1498Szrj 		    "template argument substituting __c out of bound");
461*38fd1498Szrj       static_assert(__d <= (__detail::_Shift<_UIntType, __w>::__value - 1),
462*38fd1498Szrj 		    "template argument substituting __d out of bound");
463*38fd1498Szrj       static_assert(__f <= (__detail::_Shift<_UIntType, __w>::__value - 1),
464*38fd1498Szrj 		    "template argument substituting __f out of bound");
465*38fd1498Szrj 
466*38fd1498Szrj     public:
467*38fd1498Szrj       /** The type of the generated random value. */
468*38fd1498Szrj       typedef _UIntType result_type;
469*38fd1498Szrj 
470*38fd1498Szrj       // parameter values
471*38fd1498Szrj       static constexpr size_t      word_size                 = __w;
472*38fd1498Szrj       static constexpr size_t      state_size                = __n;
473*38fd1498Szrj       static constexpr size_t      shift_size                = __m;
474*38fd1498Szrj       static constexpr size_t      mask_bits                 = __r;
475*38fd1498Szrj       static constexpr result_type xor_mask                  = __a;
476*38fd1498Szrj       static constexpr size_t      tempering_u               = __u;
477*38fd1498Szrj       static constexpr result_type tempering_d               = __d;
478*38fd1498Szrj       static constexpr size_t      tempering_s               = __s;
479*38fd1498Szrj       static constexpr result_type tempering_b               = __b;
480*38fd1498Szrj       static constexpr size_t      tempering_t               = __t;
481*38fd1498Szrj       static constexpr result_type tempering_c               = __c;
482*38fd1498Szrj       static constexpr size_t      tempering_l               = __l;
483*38fd1498Szrj       static constexpr result_type initialization_multiplier = __f;
484*38fd1498Szrj       static constexpr result_type default_seed = 5489u;
485*38fd1498Szrj 
486*38fd1498Szrj       // constructors and member function
487*38fd1498Szrj       explicit
488*38fd1498Szrj       mersenne_twister_engine(result_type __sd = default_seed)
489*38fd1498Szrj       { seed(__sd); }
490*38fd1498Szrj 
491*38fd1498Szrj       /**
492*38fd1498Szrj        * @brief Constructs a %mersenne_twister_engine random number generator
493*38fd1498Szrj        *        engine seeded from the seed sequence @p __q.
494*38fd1498Szrj        *
495*38fd1498Szrj        * @param __q the seed sequence.
496*38fd1498Szrj        */
497*38fd1498Szrj       template<typename _Sseq, typename = typename
498*38fd1498Szrj         std::enable_if<!std::is_same<_Sseq, mersenne_twister_engine>::value>
499*38fd1498Szrj 	       ::type>
500*38fd1498Szrj         explicit
501*38fd1498Szrj         mersenne_twister_engine(_Sseq& __q)
502*38fd1498Szrj         { seed(__q); }
503*38fd1498Szrj 
504*38fd1498Szrj       void
505*38fd1498Szrj       seed(result_type __sd = default_seed);
506*38fd1498Szrj 
507*38fd1498Szrj       template<typename _Sseq>
508*38fd1498Szrj 	typename std::enable_if<std::is_class<_Sseq>::value>::type
509*38fd1498Szrj         seed(_Sseq& __q);
510*38fd1498Szrj 
511*38fd1498Szrj       /**
512*38fd1498Szrj        * @brief Gets the smallest possible value in the output range.
513*38fd1498Szrj        */
514*38fd1498Szrj       static constexpr result_type
515*38fd1498Szrj       min()
516*38fd1498Szrj       { return 0; }
517*38fd1498Szrj 
518*38fd1498Szrj       /**
519*38fd1498Szrj        * @brief Gets the largest possible value in the output range.
520*38fd1498Szrj        */
521*38fd1498Szrj       static constexpr result_type
522*38fd1498Szrj       max()
523*38fd1498Szrj       { return __detail::_Shift<_UIntType, __w>::__value - 1; }
524*38fd1498Szrj 
525*38fd1498Szrj       /**
526*38fd1498Szrj        * @brief Discard a sequence of random numbers.
527*38fd1498Szrj        */
528*38fd1498Szrj       void
529*38fd1498Szrj       discard(unsigned long long __z);
530*38fd1498Szrj 
531*38fd1498Szrj       result_type
532*38fd1498Szrj       operator()();
533*38fd1498Szrj 
534*38fd1498Szrj       /**
535*38fd1498Szrj        * @brief Compares two % mersenne_twister_engine random number generator
536*38fd1498Szrj        *        objects of the same type for equality.
537*38fd1498Szrj        *
538*38fd1498Szrj        * @param __lhs A % mersenne_twister_engine random number generator
539*38fd1498Szrj        *              object.
540*38fd1498Szrj        * @param __rhs Another % mersenne_twister_engine random number
541*38fd1498Szrj        *              generator object.
542*38fd1498Szrj        *
543*38fd1498Szrj        * @returns true if the infinite sequences of generated values
544*38fd1498Szrj        *          would be equal, false otherwise.
545*38fd1498Szrj        */
546*38fd1498Szrj       friend bool
547*38fd1498Szrj       operator==(const mersenne_twister_engine& __lhs,
548*38fd1498Szrj 		 const mersenne_twister_engine& __rhs)
549*38fd1498Szrj       { return (std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x)
550*38fd1498Szrj 		&& __lhs._M_p == __rhs._M_p); }
551*38fd1498Szrj 
552*38fd1498Szrj       /**
553*38fd1498Szrj        * @brief Inserts the current state of a % mersenne_twister_engine
554*38fd1498Szrj        *        random number generator engine @p __x into the output stream
555*38fd1498Szrj        *        @p __os.
556*38fd1498Szrj        *
557*38fd1498Szrj        * @param __os An output stream.
558*38fd1498Szrj        * @param __x  A % mersenne_twister_engine random number generator
559*38fd1498Szrj        *             engine.
560*38fd1498Szrj        *
561*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
562*38fd1498Szrj        * an error state.
563*38fd1498Szrj        */
564*38fd1498Szrj       template<typename _UIntType1,
565*38fd1498Szrj 	       size_t __w1, size_t __n1,
566*38fd1498Szrj 	       size_t __m1, size_t __r1,
567*38fd1498Szrj 	       _UIntType1 __a1, size_t __u1,
568*38fd1498Szrj 	       _UIntType1 __d1, size_t __s1,
569*38fd1498Szrj 	       _UIntType1 __b1, size_t __t1,
570*38fd1498Szrj 	       _UIntType1 __c1, size_t __l1, _UIntType1 __f1,
571*38fd1498Szrj 	       typename _CharT, typename _Traits>
572*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
573*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
574*38fd1498Szrj 		   const std::mersenne_twister_engine<_UIntType1, __w1, __n1,
575*38fd1498Szrj 		   __m1, __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
576*38fd1498Szrj 		   __l1, __f1>& __x);
577*38fd1498Szrj 
578*38fd1498Szrj       /**
579*38fd1498Szrj        * @brief Extracts the current state of a % mersenne_twister_engine
580*38fd1498Szrj        *        random number generator engine @p __x from the input stream
581*38fd1498Szrj        *        @p __is.
582*38fd1498Szrj        *
583*38fd1498Szrj        * @param __is An input stream.
584*38fd1498Szrj        * @param __x  A % mersenne_twister_engine random number generator
585*38fd1498Szrj        *             engine.
586*38fd1498Szrj        *
587*38fd1498Szrj        * @returns The input stream with the state of @p __x extracted or in
588*38fd1498Szrj        * an error state.
589*38fd1498Szrj        */
590*38fd1498Szrj       template<typename _UIntType1,
591*38fd1498Szrj 	       size_t __w1, size_t __n1,
592*38fd1498Szrj 	       size_t __m1, size_t __r1,
593*38fd1498Szrj 	       _UIntType1 __a1, size_t __u1,
594*38fd1498Szrj 	       _UIntType1 __d1, size_t __s1,
595*38fd1498Szrj 	       _UIntType1 __b1, size_t __t1,
596*38fd1498Szrj 	       _UIntType1 __c1, size_t __l1, _UIntType1 __f1,
597*38fd1498Szrj 	       typename _CharT, typename _Traits>
598*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
599*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
600*38fd1498Szrj 		   std::mersenne_twister_engine<_UIntType1, __w1, __n1, __m1,
601*38fd1498Szrj 		   __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
602*38fd1498Szrj 		   __l1, __f1>& __x);
603*38fd1498Szrj 
604*38fd1498Szrj     private:
605*38fd1498Szrj       void _M_gen_rand();
606*38fd1498Szrj 
607*38fd1498Szrj       _UIntType _M_x[state_size];
608*38fd1498Szrj       size_t    _M_p;
609*38fd1498Szrj     };
610*38fd1498Szrj 
611*38fd1498Szrj   /**
612*38fd1498Szrj    * @brief Compares two % mersenne_twister_engine random number generator
613*38fd1498Szrj    *        objects of the same type for inequality.
614*38fd1498Szrj    *
615*38fd1498Szrj    * @param __lhs A % mersenne_twister_engine random number generator
616*38fd1498Szrj    *              object.
617*38fd1498Szrj    * @param __rhs Another % mersenne_twister_engine random number
618*38fd1498Szrj    *              generator object.
619*38fd1498Szrj    *
620*38fd1498Szrj    * @returns true if the infinite sequences of generated values
621*38fd1498Szrj    *          would be different, false otherwise.
622*38fd1498Szrj    */
623*38fd1498Szrj   template<typename _UIntType, size_t __w,
624*38fd1498Szrj 	   size_t __n, size_t __m, size_t __r,
625*38fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
626*38fd1498Szrj 	   _UIntType __b, size_t __t,
627*38fd1498Szrj 	   _UIntType __c, size_t __l, _UIntType __f>
628*38fd1498Szrj     inline bool
629*38fd1498Szrj     operator!=(const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
630*38fd1498Szrj 	       __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __lhs,
631*38fd1498Szrj 	       const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
632*38fd1498Szrj 	       __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __rhs)
633*38fd1498Szrj     { return !(__lhs == __rhs); }
634*38fd1498Szrj 
635*38fd1498Szrj 
636*38fd1498Szrj   /**
637*38fd1498Szrj    * @brief The Marsaglia-Zaman generator.
638*38fd1498Szrj    *
639*38fd1498Szrj    * This is a model of a Generalized Fibonacci discrete random number
640*38fd1498Szrj    * generator, sometimes referred to as the SWC generator.
641*38fd1498Szrj    *
642*38fd1498Szrj    * A discrete random number generator that produces pseudorandom
643*38fd1498Szrj    * numbers using:
644*38fd1498Szrj    * @f[
645*38fd1498Szrj    *     x_{i}\leftarrow(x_{i - s} - x_{i - r} - carry_{i-1}) \bmod m
646*38fd1498Szrj    * @f]
647*38fd1498Szrj    *
648*38fd1498Szrj    * The size of the state is @f$r@f$
649*38fd1498Szrj    * and the maximum period of the generator is @f$(m^r - m^s - 1)@f$.
650*38fd1498Szrj    */
651*38fd1498Szrj   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
652*38fd1498Szrj     class subtract_with_carry_engine
653*38fd1498Szrj     {
654*38fd1498Szrj       static_assert(std::is_unsigned<_UIntType>::value,
655*38fd1498Szrj 		    "result_type must be an unsigned integral type");
656*38fd1498Szrj       static_assert(0u < __s && __s < __r,
657*38fd1498Szrj 		    "0 < s < r");
658*38fd1498Szrj       static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
659*38fd1498Szrj 		    "template argument substituting __w out of bounds");
660*38fd1498Szrj 
661*38fd1498Szrj     public:
662*38fd1498Szrj       /** The type of the generated random value. */
663*38fd1498Szrj       typedef _UIntType result_type;
664*38fd1498Szrj 
665*38fd1498Szrj       // parameter values
666*38fd1498Szrj       static constexpr size_t      word_size    = __w;
667*38fd1498Szrj       static constexpr size_t      short_lag    = __s;
668*38fd1498Szrj       static constexpr size_t      long_lag     = __r;
669*38fd1498Szrj       static constexpr result_type default_seed = 19780503u;
670*38fd1498Szrj 
671*38fd1498Szrj       /**
672*38fd1498Szrj        * @brief Constructs an explicitly seeded % subtract_with_carry_engine
673*38fd1498Szrj        *        random number generator.
674*38fd1498Szrj        */
675*38fd1498Szrj       explicit
676*38fd1498Szrj       subtract_with_carry_engine(result_type __sd = default_seed)
677*38fd1498Szrj       { seed(__sd); }
678*38fd1498Szrj 
679*38fd1498Szrj       /**
680*38fd1498Szrj        * @brief Constructs a %subtract_with_carry_engine random number engine
681*38fd1498Szrj        *        seeded from the seed sequence @p __q.
682*38fd1498Szrj        *
683*38fd1498Szrj        * @param __q the seed sequence.
684*38fd1498Szrj        */
685*38fd1498Szrj       template<typename _Sseq, typename = typename
686*38fd1498Szrj         std::enable_if<!std::is_same<_Sseq, subtract_with_carry_engine>::value>
687*38fd1498Szrj 	       ::type>
688*38fd1498Szrj         explicit
689*38fd1498Szrj         subtract_with_carry_engine(_Sseq& __q)
690*38fd1498Szrj         { seed(__q); }
691*38fd1498Szrj 
692*38fd1498Szrj       /**
693*38fd1498Szrj        * @brief Seeds the initial state @f$x_0@f$ of the random number
694*38fd1498Szrj        *        generator.
695*38fd1498Szrj        *
696*38fd1498Szrj        * N1688[4.19] modifies this as follows.  If @p __value == 0,
697*38fd1498Szrj        * sets value to 19780503.  In any case, with a linear
698*38fd1498Szrj        * congruential generator lcg(i) having parameters @f$ m_{lcg} =
699*38fd1498Szrj        * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
700*38fd1498Szrj        * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
701*38fd1498Szrj        * \dots lcg(r) \bmod m @f$ respectively.  If @f$ x_{-1} = 0 @f$
702*38fd1498Szrj        * set carry to 1, otherwise sets carry to 0.
703*38fd1498Szrj        */
704*38fd1498Szrj       void
705*38fd1498Szrj       seed(result_type __sd = default_seed);
706*38fd1498Szrj 
707*38fd1498Szrj       /**
708*38fd1498Szrj        * @brief Seeds the initial state @f$x_0@f$ of the
709*38fd1498Szrj        * % subtract_with_carry_engine random number generator.
710*38fd1498Szrj        */
711*38fd1498Szrj       template<typename _Sseq>
712*38fd1498Szrj 	typename std::enable_if<std::is_class<_Sseq>::value>::type
713*38fd1498Szrj         seed(_Sseq& __q);
714*38fd1498Szrj 
715*38fd1498Szrj       /**
716*38fd1498Szrj        * @brief Gets the inclusive minimum value of the range of random
717*38fd1498Szrj        * integers returned by this generator.
718*38fd1498Szrj        */
719*38fd1498Szrj       static constexpr result_type
720*38fd1498Szrj       min()
721*38fd1498Szrj       { return 0; }
722*38fd1498Szrj 
723*38fd1498Szrj       /**
724*38fd1498Szrj        * @brief Gets the inclusive maximum value of the range of random
725*38fd1498Szrj        * integers returned by this generator.
726*38fd1498Szrj        */
727*38fd1498Szrj       static constexpr result_type
728*38fd1498Szrj       max()
729*38fd1498Szrj       { return __detail::_Shift<_UIntType, __w>::__value - 1; }
730*38fd1498Szrj 
731*38fd1498Szrj       /**
732*38fd1498Szrj        * @brief Discard a sequence of random numbers.
733*38fd1498Szrj        */
734*38fd1498Szrj       void
735*38fd1498Szrj       discard(unsigned long long __z)
736*38fd1498Szrj       {
737*38fd1498Szrj 	for (; __z != 0ULL; --__z)
738*38fd1498Szrj 	  (*this)();
739*38fd1498Szrj       }
740*38fd1498Szrj 
741*38fd1498Szrj       /**
742*38fd1498Szrj        * @brief Gets the next random number in the sequence.
743*38fd1498Szrj        */
744*38fd1498Szrj       result_type
745*38fd1498Szrj       operator()();
746*38fd1498Szrj 
747*38fd1498Szrj       /**
748*38fd1498Szrj        * @brief Compares two % subtract_with_carry_engine random number
749*38fd1498Szrj        *        generator objects of the same type for equality.
750*38fd1498Szrj        *
751*38fd1498Szrj        * @param __lhs A % subtract_with_carry_engine random number generator
752*38fd1498Szrj        *              object.
753*38fd1498Szrj        * @param __rhs Another % subtract_with_carry_engine random number
754*38fd1498Szrj        *              generator object.
755*38fd1498Szrj        *
756*38fd1498Szrj        * @returns true if the infinite sequences of generated values
757*38fd1498Szrj        *          would be equal, false otherwise.
758*38fd1498Szrj       */
759*38fd1498Szrj       friend bool
760*38fd1498Szrj       operator==(const subtract_with_carry_engine& __lhs,
761*38fd1498Szrj 		 const subtract_with_carry_engine& __rhs)
762*38fd1498Szrj       { return (std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x)
763*38fd1498Szrj 		&& __lhs._M_carry == __rhs._M_carry
764*38fd1498Szrj 		&& __lhs._M_p == __rhs._M_p); }
765*38fd1498Szrj 
766*38fd1498Szrj       /**
767*38fd1498Szrj        * @brief Inserts the current state of a % subtract_with_carry_engine
768*38fd1498Szrj        *        random number generator engine @p __x into the output stream
769*38fd1498Szrj        *        @p __os.
770*38fd1498Szrj        *
771*38fd1498Szrj        * @param __os An output stream.
772*38fd1498Szrj        * @param __x  A % subtract_with_carry_engine random number generator
773*38fd1498Szrj        *             engine.
774*38fd1498Szrj        *
775*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
776*38fd1498Szrj        * an error state.
777*38fd1498Szrj        */
778*38fd1498Szrj       template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1,
779*38fd1498Szrj 	       typename _CharT, typename _Traits>
780*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
781*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
782*38fd1498Szrj 		   const std::subtract_with_carry_engine<_UIntType1, __w1,
783*38fd1498Szrj 		   __s1, __r1>& __x);
784*38fd1498Szrj 
785*38fd1498Szrj       /**
786*38fd1498Szrj        * @brief Extracts the current state of a % subtract_with_carry_engine
787*38fd1498Szrj        *        random number generator engine @p __x from the input stream
788*38fd1498Szrj        *        @p __is.
789*38fd1498Szrj        *
790*38fd1498Szrj        * @param __is An input stream.
791*38fd1498Szrj        * @param __x  A % subtract_with_carry_engine random number generator
792*38fd1498Szrj        *             engine.
793*38fd1498Szrj        *
794*38fd1498Szrj        * @returns The input stream with the state of @p __x extracted or in
795*38fd1498Szrj        * an error state.
796*38fd1498Szrj        */
797*38fd1498Szrj       template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1,
798*38fd1498Szrj 	       typename _CharT, typename _Traits>
799*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
800*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
801*38fd1498Szrj 		   std::subtract_with_carry_engine<_UIntType1, __w1,
802*38fd1498Szrj 		   __s1, __r1>& __x);
803*38fd1498Szrj 
804*38fd1498Szrj     private:
805*38fd1498Szrj       /// The state of the generator.  This is a ring buffer.
806*38fd1498Szrj       _UIntType  _M_x[long_lag];
807*38fd1498Szrj       _UIntType  _M_carry;		///< The carry
808*38fd1498Szrj       size_t     _M_p;			///< Current index of x(i - r).
809*38fd1498Szrj     };
810*38fd1498Szrj 
811*38fd1498Szrj   /**
812*38fd1498Szrj    * @brief Compares two % subtract_with_carry_engine random number
813*38fd1498Szrj    *        generator objects of the same type for inequality.
814*38fd1498Szrj    *
815*38fd1498Szrj    * @param __lhs A % subtract_with_carry_engine random number generator
816*38fd1498Szrj    *              object.
817*38fd1498Szrj    * @param __rhs Another % subtract_with_carry_engine random number
818*38fd1498Szrj    *              generator object.
819*38fd1498Szrj    *
820*38fd1498Szrj    * @returns true if the infinite sequences of generated values
821*38fd1498Szrj    *          would be different, false otherwise.
822*38fd1498Szrj    */
823*38fd1498Szrj   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
824*38fd1498Szrj     inline bool
825*38fd1498Szrj     operator!=(const std::subtract_with_carry_engine<_UIntType, __w,
826*38fd1498Szrj 	       __s, __r>& __lhs,
827*38fd1498Szrj 	       const std::subtract_with_carry_engine<_UIntType, __w,
828*38fd1498Szrj 	       __s, __r>& __rhs)
829*38fd1498Szrj     { return !(__lhs == __rhs); }
830*38fd1498Szrj 
831*38fd1498Szrj 
832*38fd1498Szrj   /**
833*38fd1498Szrj    * Produces random numbers from some base engine by discarding blocks of
834*38fd1498Szrj    * data.
835*38fd1498Szrj    *
836*38fd1498Szrj    * 0 <= @p __r <= @p __p
837*38fd1498Szrj    */
838*38fd1498Szrj   template<typename _RandomNumberEngine, size_t __p, size_t __r>
839*38fd1498Szrj     class discard_block_engine
840*38fd1498Szrj     {
841*38fd1498Szrj       static_assert(1 <= __r && __r <= __p,
842*38fd1498Szrj 		    "template argument substituting __r out of bounds");
843*38fd1498Szrj 
844*38fd1498Szrj     public:
845*38fd1498Szrj       /** The type of the generated random value. */
846*38fd1498Szrj       typedef typename _RandomNumberEngine::result_type result_type;
847*38fd1498Szrj 
848*38fd1498Szrj       // parameter values
849*38fd1498Szrj       static constexpr size_t block_size = __p;
850*38fd1498Szrj       static constexpr size_t used_block = __r;
851*38fd1498Szrj 
852*38fd1498Szrj       /**
853*38fd1498Szrj        * @brief Constructs a default %discard_block_engine engine.
854*38fd1498Szrj        *
855*38fd1498Szrj        * The underlying engine is default constructed as well.
856*38fd1498Szrj        */
857*38fd1498Szrj       discard_block_engine()
858*38fd1498Szrj       : _M_b(), _M_n(0) { }
859*38fd1498Szrj 
860*38fd1498Szrj       /**
861*38fd1498Szrj        * @brief Copy constructs a %discard_block_engine engine.
862*38fd1498Szrj        *
863*38fd1498Szrj        * Copies an existing base class random number generator.
864*38fd1498Szrj        * @param __rng An existing (base class) engine object.
865*38fd1498Szrj        */
866*38fd1498Szrj       explicit
867*38fd1498Szrj       discard_block_engine(const _RandomNumberEngine& __rng)
868*38fd1498Szrj       : _M_b(__rng), _M_n(0) { }
869*38fd1498Szrj 
870*38fd1498Szrj       /**
871*38fd1498Szrj        * @brief Move constructs a %discard_block_engine engine.
872*38fd1498Szrj        *
873*38fd1498Szrj        * Copies an existing base class random number generator.
874*38fd1498Szrj        * @param __rng An existing (base class) engine object.
875*38fd1498Szrj        */
876*38fd1498Szrj       explicit
877*38fd1498Szrj       discard_block_engine(_RandomNumberEngine&& __rng)
878*38fd1498Szrj       : _M_b(std::move(__rng)), _M_n(0) { }
879*38fd1498Szrj 
880*38fd1498Szrj       /**
881*38fd1498Szrj        * @brief Seed constructs a %discard_block_engine engine.
882*38fd1498Szrj        *
883*38fd1498Szrj        * Constructs the underlying generator engine seeded with @p __s.
884*38fd1498Szrj        * @param __s A seed value for the base class engine.
885*38fd1498Szrj        */
886*38fd1498Szrj       explicit
887*38fd1498Szrj       discard_block_engine(result_type __s)
888*38fd1498Szrj       : _M_b(__s), _M_n(0) { }
889*38fd1498Szrj 
890*38fd1498Szrj       /**
891*38fd1498Szrj        * @brief Generator construct a %discard_block_engine engine.
892*38fd1498Szrj        *
893*38fd1498Szrj        * @param __q A seed sequence.
894*38fd1498Szrj        */
895*38fd1498Szrj       template<typename _Sseq, typename = typename
896*38fd1498Szrj 	std::enable_if<!std::is_same<_Sseq, discard_block_engine>::value
897*38fd1498Szrj 		       && !std::is_same<_Sseq, _RandomNumberEngine>::value>
898*38fd1498Szrj 	       ::type>
899*38fd1498Szrj         explicit
900*38fd1498Szrj         discard_block_engine(_Sseq& __q)
901*38fd1498Szrj 	: _M_b(__q), _M_n(0)
902*38fd1498Szrj         { }
903*38fd1498Szrj 
904*38fd1498Szrj       /**
905*38fd1498Szrj        * @brief Reseeds the %discard_block_engine object with the default
906*38fd1498Szrj        *        seed for the underlying base class generator engine.
907*38fd1498Szrj        */
908*38fd1498Szrj       void
909*38fd1498Szrj       seed()
910*38fd1498Szrj       {
911*38fd1498Szrj 	_M_b.seed();
912*38fd1498Szrj 	_M_n = 0;
913*38fd1498Szrj       }
914*38fd1498Szrj 
915*38fd1498Szrj       /**
916*38fd1498Szrj        * @brief Reseeds the %discard_block_engine object with the default
917*38fd1498Szrj        *        seed for the underlying base class generator engine.
918*38fd1498Szrj        */
919*38fd1498Szrj       void
920*38fd1498Szrj       seed(result_type __s)
921*38fd1498Szrj       {
922*38fd1498Szrj 	_M_b.seed(__s);
923*38fd1498Szrj 	_M_n = 0;
924*38fd1498Szrj       }
925*38fd1498Szrj 
926*38fd1498Szrj       /**
927*38fd1498Szrj        * @brief Reseeds the %discard_block_engine object with the given seed
928*38fd1498Szrj        *        sequence.
929*38fd1498Szrj        * @param __q A seed generator function.
930*38fd1498Szrj        */
931*38fd1498Szrj       template<typename _Sseq>
932*38fd1498Szrj         void
933*38fd1498Szrj         seed(_Sseq& __q)
934*38fd1498Szrj         {
935*38fd1498Szrj 	  _M_b.seed(__q);
936*38fd1498Szrj 	  _M_n = 0;
937*38fd1498Szrj 	}
938*38fd1498Szrj 
939*38fd1498Szrj       /**
940*38fd1498Szrj        * @brief Gets a const reference to the underlying generator engine
941*38fd1498Szrj        *        object.
942*38fd1498Szrj        */
943*38fd1498Szrj       const _RandomNumberEngine&
944*38fd1498Szrj       base() const noexcept
945*38fd1498Szrj       { return _M_b; }
946*38fd1498Szrj 
947*38fd1498Szrj       /**
948*38fd1498Szrj        * @brief Gets the minimum value in the generated random number range.
949*38fd1498Szrj        */
950*38fd1498Szrj       static constexpr result_type
951*38fd1498Szrj       min()
952*38fd1498Szrj       { return _RandomNumberEngine::min(); }
953*38fd1498Szrj 
954*38fd1498Szrj       /**
955*38fd1498Szrj        * @brief Gets the maximum value in the generated random number range.
956*38fd1498Szrj        */
957*38fd1498Szrj       static constexpr result_type
958*38fd1498Szrj       max()
959*38fd1498Szrj       { return _RandomNumberEngine::max(); }
960*38fd1498Szrj 
961*38fd1498Szrj       /**
962*38fd1498Szrj        * @brief Discard a sequence of random numbers.
963*38fd1498Szrj        */
964*38fd1498Szrj       void
965*38fd1498Szrj       discard(unsigned long long __z)
966*38fd1498Szrj       {
967*38fd1498Szrj 	for (; __z != 0ULL; --__z)
968*38fd1498Szrj 	  (*this)();
969*38fd1498Szrj       }
970*38fd1498Szrj 
971*38fd1498Szrj       /**
972*38fd1498Szrj        * @brief Gets the next value in the generated random number sequence.
973*38fd1498Szrj        */
974*38fd1498Szrj       result_type
975*38fd1498Szrj       operator()();
976*38fd1498Szrj 
977*38fd1498Szrj       /**
978*38fd1498Szrj        * @brief Compares two %discard_block_engine random number generator
979*38fd1498Szrj        *        objects of the same type for equality.
980*38fd1498Szrj        *
981*38fd1498Szrj        * @param __lhs A %discard_block_engine random number generator object.
982*38fd1498Szrj        * @param __rhs Another %discard_block_engine random number generator
983*38fd1498Szrj        *              object.
984*38fd1498Szrj        *
985*38fd1498Szrj        * @returns true if the infinite sequences of generated values
986*38fd1498Szrj        *          would be equal, false otherwise.
987*38fd1498Szrj        */
988*38fd1498Szrj       friend bool
989*38fd1498Szrj       operator==(const discard_block_engine& __lhs,
990*38fd1498Szrj 		 const discard_block_engine& __rhs)
991*38fd1498Szrj       { return __lhs._M_b == __rhs._M_b && __lhs._M_n == __rhs._M_n; }
992*38fd1498Szrj 
993*38fd1498Szrj       /**
994*38fd1498Szrj        * @brief Inserts the current state of a %discard_block_engine random
995*38fd1498Szrj        *        number generator engine @p __x into the output stream
996*38fd1498Szrj        *        @p __os.
997*38fd1498Szrj        *
998*38fd1498Szrj        * @param __os An output stream.
999*38fd1498Szrj        * @param __x  A %discard_block_engine random number generator engine.
1000*38fd1498Szrj        *
1001*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
1002*38fd1498Szrj        * an error state.
1003*38fd1498Szrj        */
1004*38fd1498Szrj       template<typename _RandomNumberEngine1, size_t __p1, size_t __r1,
1005*38fd1498Szrj 	       typename _CharT, typename _Traits>
1006*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
1007*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1008*38fd1498Szrj 		   const std::discard_block_engine<_RandomNumberEngine1,
1009*38fd1498Szrj 		   __p1, __r1>& __x);
1010*38fd1498Szrj 
1011*38fd1498Szrj       /**
1012*38fd1498Szrj        * @brief Extracts the current state of a % subtract_with_carry_engine
1013*38fd1498Szrj        *        random number generator engine @p __x from the input stream
1014*38fd1498Szrj        *        @p __is.
1015*38fd1498Szrj        *
1016*38fd1498Szrj        * @param __is An input stream.
1017*38fd1498Szrj        * @param __x  A %discard_block_engine random number generator engine.
1018*38fd1498Szrj        *
1019*38fd1498Szrj        * @returns The input stream with the state of @p __x extracted or in
1020*38fd1498Szrj        * an error state.
1021*38fd1498Szrj        */
1022*38fd1498Szrj       template<typename _RandomNumberEngine1, size_t __p1, size_t __r1,
1023*38fd1498Szrj 	       typename _CharT, typename _Traits>
1024*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
1025*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
1026*38fd1498Szrj 		   std::discard_block_engine<_RandomNumberEngine1,
1027*38fd1498Szrj 		   __p1, __r1>& __x);
1028*38fd1498Szrj 
1029*38fd1498Szrj     private:
1030*38fd1498Szrj       _RandomNumberEngine _M_b;
1031*38fd1498Szrj       size_t _M_n;
1032*38fd1498Szrj     };
1033*38fd1498Szrj 
1034*38fd1498Szrj   /**
1035*38fd1498Szrj    * @brief Compares two %discard_block_engine random number generator
1036*38fd1498Szrj    *        objects of the same type for inequality.
1037*38fd1498Szrj    *
1038*38fd1498Szrj    * @param __lhs A %discard_block_engine random number generator object.
1039*38fd1498Szrj    * @param __rhs Another %discard_block_engine random number generator
1040*38fd1498Szrj    *              object.
1041*38fd1498Szrj    *
1042*38fd1498Szrj    * @returns true if the infinite sequences of generated values
1043*38fd1498Szrj    *          would be different, false otherwise.
1044*38fd1498Szrj    */
1045*38fd1498Szrj   template<typename _RandomNumberEngine, size_t __p, size_t __r>
1046*38fd1498Szrj     inline bool
1047*38fd1498Szrj     operator!=(const std::discard_block_engine<_RandomNumberEngine, __p,
1048*38fd1498Szrj 	       __r>& __lhs,
1049*38fd1498Szrj 	       const std::discard_block_engine<_RandomNumberEngine, __p,
1050*38fd1498Szrj 	       __r>& __rhs)
1051*38fd1498Szrj     { return !(__lhs == __rhs); }
1052*38fd1498Szrj 
1053*38fd1498Szrj 
1054*38fd1498Szrj   /**
1055*38fd1498Szrj    * Produces random numbers by combining random numbers from some base
1056*38fd1498Szrj    * engine to produce random numbers with a specifies number of bits @p __w.
1057*38fd1498Szrj    */
1058*38fd1498Szrj   template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
1059*38fd1498Szrj     class independent_bits_engine
1060*38fd1498Szrj     {
1061*38fd1498Szrj       static_assert(std::is_unsigned<_UIntType>::value,
1062*38fd1498Szrj 		    "result_type must be an unsigned integral type");
1063*38fd1498Szrj       static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
1064*38fd1498Szrj 		    "template argument substituting __w out of bounds");
1065*38fd1498Szrj 
1066*38fd1498Szrj     public:
1067*38fd1498Szrj       /** The type of the generated random value. */
1068*38fd1498Szrj       typedef _UIntType result_type;
1069*38fd1498Szrj 
1070*38fd1498Szrj       /**
1071*38fd1498Szrj        * @brief Constructs a default %independent_bits_engine engine.
1072*38fd1498Szrj        *
1073*38fd1498Szrj        * The underlying engine is default constructed as well.
1074*38fd1498Szrj        */
1075*38fd1498Szrj       independent_bits_engine()
1076*38fd1498Szrj       : _M_b() { }
1077*38fd1498Szrj 
1078*38fd1498Szrj       /**
1079*38fd1498Szrj        * @brief Copy constructs a %independent_bits_engine engine.
1080*38fd1498Szrj        *
1081*38fd1498Szrj        * Copies an existing base class random number generator.
1082*38fd1498Szrj        * @param __rng An existing (base class) engine object.
1083*38fd1498Szrj        */
1084*38fd1498Szrj       explicit
1085*38fd1498Szrj       independent_bits_engine(const _RandomNumberEngine& __rng)
1086*38fd1498Szrj       : _M_b(__rng) { }
1087*38fd1498Szrj 
1088*38fd1498Szrj       /**
1089*38fd1498Szrj        * @brief Move constructs a %independent_bits_engine engine.
1090*38fd1498Szrj        *
1091*38fd1498Szrj        * Copies an existing base class random number generator.
1092*38fd1498Szrj        * @param __rng An existing (base class) engine object.
1093*38fd1498Szrj        */
1094*38fd1498Szrj       explicit
1095*38fd1498Szrj       independent_bits_engine(_RandomNumberEngine&& __rng)
1096*38fd1498Szrj       : _M_b(std::move(__rng)) { }
1097*38fd1498Szrj 
1098*38fd1498Szrj       /**
1099*38fd1498Szrj        * @brief Seed constructs a %independent_bits_engine engine.
1100*38fd1498Szrj        *
1101*38fd1498Szrj        * Constructs the underlying generator engine seeded with @p __s.
1102*38fd1498Szrj        * @param __s A seed value for the base class engine.
1103*38fd1498Szrj        */
1104*38fd1498Szrj       explicit
1105*38fd1498Szrj       independent_bits_engine(result_type __s)
1106*38fd1498Szrj       : _M_b(__s) { }
1107*38fd1498Szrj 
1108*38fd1498Szrj       /**
1109*38fd1498Szrj        * @brief Generator construct a %independent_bits_engine engine.
1110*38fd1498Szrj        *
1111*38fd1498Szrj        * @param __q A seed sequence.
1112*38fd1498Szrj        */
1113*38fd1498Szrj       template<typename _Sseq, typename = typename
1114*38fd1498Szrj 	std::enable_if<!std::is_same<_Sseq, independent_bits_engine>::value
1115*38fd1498Szrj 		       && !std::is_same<_Sseq, _RandomNumberEngine>::value>
1116*38fd1498Szrj                ::type>
1117*38fd1498Szrj         explicit
1118*38fd1498Szrj         independent_bits_engine(_Sseq& __q)
1119*38fd1498Szrj         : _M_b(__q)
1120*38fd1498Szrj         { }
1121*38fd1498Szrj 
1122*38fd1498Szrj       /**
1123*38fd1498Szrj        * @brief Reseeds the %independent_bits_engine object with the default
1124*38fd1498Szrj        *        seed for the underlying base class generator engine.
1125*38fd1498Szrj        */
1126*38fd1498Szrj       void
1127*38fd1498Szrj       seed()
1128*38fd1498Szrj       { _M_b.seed(); }
1129*38fd1498Szrj 
1130*38fd1498Szrj       /**
1131*38fd1498Szrj        * @brief Reseeds the %independent_bits_engine object with the default
1132*38fd1498Szrj        *        seed for the underlying base class generator engine.
1133*38fd1498Szrj        */
1134*38fd1498Szrj       void
1135*38fd1498Szrj       seed(result_type __s)
1136*38fd1498Szrj       { _M_b.seed(__s); }
1137*38fd1498Szrj 
1138*38fd1498Szrj       /**
1139*38fd1498Szrj        * @brief Reseeds the %independent_bits_engine object with the given
1140*38fd1498Szrj        *        seed sequence.
1141*38fd1498Szrj        * @param __q A seed generator function.
1142*38fd1498Szrj        */
1143*38fd1498Szrj       template<typename _Sseq>
1144*38fd1498Szrj         void
1145*38fd1498Szrj         seed(_Sseq& __q)
1146*38fd1498Szrj         { _M_b.seed(__q); }
1147*38fd1498Szrj 
1148*38fd1498Szrj       /**
1149*38fd1498Szrj        * @brief Gets a const reference to the underlying generator engine
1150*38fd1498Szrj        *        object.
1151*38fd1498Szrj        */
1152*38fd1498Szrj       const _RandomNumberEngine&
1153*38fd1498Szrj       base() const noexcept
1154*38fd1498Szrj       { return _M_b; }
1155*38fd1498Szrj 
1156*38fd1498Szrj       /**
1157*38fd1498Szrj        * @brief Gets the minimum value in the generated random number range.
1158*38fd1498Szrj        */
1159*38fd1498Szrj       static constexpr result_type
1160*38fd1498Szrj       min()
1161*38fd1498Szrj       { return 0U; }
1162*38fd1498Szrj 
1163*38fd1498Szrj       /**
1164*38fd1498Szrj        * @brief Gets the maximum value in the generated random number range.
1165*38fd1498Szrj        */
1166*38fd1498Szrj       static constexpr result_type
1167*38fd1498Szrj       max()
1168*38fd1498Szrj       { return __detail::_Shift<_UIntType, __w>::__value - 1; }
1169*38fd1498Szrj 
1170*38fd1498Szrj       /**
1171*38fd1498Szrj        * @brief Discard a sequence of random numbers.
1172*38fd1498Szrj        */
1173*38fd1498Szrj       void
1174*38fd1498Szrj       discard(unsigned long long __z)
1175*38fd1498Szrj       {
1176*38fd1498Szrj 	for (; __z != 0ULL; --__z)
1177*38fd1498Szrj 	  (*this)();
1178*38fd1498Szrj       }
1179*38fd1498Szrj 
1180*38fd1498Szrj       /**
1181*38fd1498Szrj        * @brief Gets the next value in the generated random number sequence.
1182*38fd1498Szrj        */
1183*38fd1498Szrj       result_type
1184*38fd1498Szrj       operator()();
1185*38fd1498Szrj 
1186*38fd1498Szrj       /**
1187*38fd1498Szrj        * @brief Compares two %independent_bits_engine random number generator
1188*38fd1498Szrj        * objects of the same type for equality.
1189*38fd1498Szrj        *
1190*38fd1498Szrj        * @param __lhs A %independent_bits_engine random number generator
1191*38fd1498Szrj        *              object.
1192*38fd1498Szrj        * @param __rhs Another %independent_bits_engine random number generator
1193*38fd1498Szrj        *              object.
1194*38fd1498Szrj        *
1195*38fd1498Szrj        * @returns true if the infinite sequences of generated values
1196*38fd1498Szrj        *          would be equal, false otherwise.
1197*38fd1498Szrj        */
1198*38fd1498Szrj       friend bool
1199*38fd1498Szrj       operator==(const independent_bits_engine& __lhs,
1200*38fd1498Szrj 		 const independent_bits_engine& __rhs)
1201*38fd1498Szrj       { return __lhs._M_b == __rhs._M_b; }
1202*38fd1498Szrj 
1203*38fd1498Szrj       /**
1204*38fd1498Szrj        * @brief Extracts the current state of a % subtract_with_carry_engine
1205*38fd1498Szrj        *        random number generator engine @p __x from the input stream
1206*38fd1498Szrj        *        @p __is.
1207*38fd1498Szrj        *
1208*38fd1498Szrj        * @param __is An input stream.
1209*38fd1498Szrj        * @param __x  A %independent_bits_engine random number generator
1210*38fd1498Szrj        *             engine.
1211*38fd1498Szrj        *
1212*38fd1498Szrj        * @returns The input stream with the state of @p __x extracted or in
1213*38fd1498Szrj        *          an error state.
1214*38fd1498Szrj        */
1215*38fd1498Szrj       template<typename _CharT, typename _Traits>
1216*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
1217*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
1218*38fd1498Szrj 		   std::independent_bits_engine<_RandomNumberEngine,
1219*38fd1498Szrj 		   __w, _UIntType>& __x)
1220*38fd1498Szrj 	{
1221*38fd1498Szrj 	  __is >> __x._M_b;
1222*38fd1498Szrj 	  return __is;
1223*38fd1498Szrj 	}
1224*38fd1498Szrj 
1225*38fd1498Szrj     private:
1226*38fd1498Szrj       _RandomNumberEngine _M_b;
1227*38fd1498Szrj     };
1228*38fd1498Szrj 
1229*38fd1498Szrj   /**
1230*38fd1498Szrj    * @brief Compares two %independent_bits_engine random number generator
1231*38fd1498Szrj    * objects of the same type for inequality.
1232*38fd1498Szrj    *
1233*38fd1498Szrj    * @param __lhs A %independent_bits_engine random number generator
1234*38fd1498Szrj    *              object.
1235*38fd1498Szrj    * @param __rhs Another %independent_bits_engine random number generator
1236*38fd1498Szrj    *              object.
1237*38fd1498Szrj    *
1238*38fd1498Szrj    * @returns true if the infinite sequences of generated values
1239*38fd1498Szrj    *          would be different, false otherwise.
1240*38fd1498Szrj    */
1241*38fd1498Szrj   template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
1242*38fd1498Szrj     inline bool
1243*38fd1498Szrj     operator!=(const std::independent_bits_engine<_RandomNumberEngine, __w,
1244*38fd1498Szrj 	       _UIntType>& __lhs,
1245*38fd1498Szrj 	       const std::independent_bits_engine<_RandomNumberEngine, __w,
1246*38fd1498Szrj 	       _UIntType>& __rhs)
1247*38fd1498Szrj     { return !(__lhs == __rhs); }
1248*38fd1498Szrj 
1249*38fd1498Szrj   /**
1250*38fd1498Szrj    * @brief Inserts the current state of a %independent_bits_engine random
1251*38fd1498Szrj    *        number generator engine @p __x into the output stream @p __os.
1252*38fd1498Szrj    *
1253*38fd1498Szrj    * @param __os An output stream.
1254*38fd1498Szrj    * @param __x  A %independent_bits_engine random number generator engine.
1255*38fd1498Szrj    *
1256*38fd1498Szrj    * @returns The output stream with the state of @p __x inserted or in
1257*38fd1498Szrj    *          an error state.
1258*38fd1498Szrj    */
1259*38fd1498Szrj   template<typename _RandomNumberEngine, size_t __w, typename _UIntType,
1260*38fd1498Szrj 	   typename _CharT, typename _Traits>
1261*38fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
1262*38fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1263*38fd1498Szrj 	       const std::independent_bits_engine<_RandomNumberEngine,
1264*38fd1498Szrj 	       __w, _UIntType>& __x)
1265*38fd1498Szrj     {
1266*38fd1498Szrj       __os << __x.base();
1267*38fd1498Szrj       return __os;
1268*38fd1498Szrj     }
1269*38fd1498Szrj 
1270*38fd1498Szrj 
1271*38fd1498Szrj   /**
1272*38fd1498Szrj    * @brief Produces random numbers by combining random numbers from some
1273*38fd1498Szrj    * base engine to produce random numbers with a specifies number of bits
1274*38fd1498Szrj    * @p __k.
1275*38fd1498Szrj    */
1276*38fd1498Szrj   template<typename _RandomNumberEngine, size_t __k>
1277*38fd1498Szrj     class shuffle_order_engine
1278*38fd1498Szrj     {
1279*38fd1498Szrj       static_assert(1u <= __k, "template argument substituting "
1280*38fd1498Szrj 		    "__k out of bound");
1281*38fd1498Szrj 
1282*38fd1498Szrj     public:
1283*38fd1498Szrj       /** The type of the generated random value. */
1284*38fd1498Szrj       typedef typename _RandomNumberEngine::result_type result_type;
1285*38fd1498Szrj 
1286*38fd1498Szrj       static constexpr size_t table_size = __k;
1287*38fd1498Szrj 
1288*38fd1498Szrj       /**
1289*38fd1498Szrj        * @brief Constructs a default %shuffle_order_engine engine.
1290*38fd1498Szrj        *
1291*38fd1498Szrj        * The underlying engine is default constructed as well.
1292*38fd1498Szrj        */
1293*38fd1498Szrj       shuffle_order_engine()
1294*38fd1498Szrj       : _M_b()
1295*38fd1498Szrj       { _M_initialize(); }
1296*38fd1498Szrj 
1297*38fd1498Szrj       /**
1298*38fd1498Szrj        * @brief Copy constructs a %shuffle_order_engine engine.
1299*38fd1498Szrj        *
1300*38fd1498Szrj        * Copies an existing base class random number generator.
1301*38fd1498Szrj        * @param __rng An existing (base class) engine object.
1302*38fd1498Szrj        */
1303*38fd1498Szrj       explicit
1304*38fd1498Szrj       shuffle_order_engine(const _RandomNumberEngine& __rng)
1305*38fd1498Szrj       : _M_b(__rng)
1306*38fd1498Szrj       { _M_initialize(); }
1307*38fd1498Szrj 
1308*38fd1498Szrj       /**
1309*38fd1498Szrj        * @brief Move constructs a %shuffle_order_engine engine.
1310*38fd1498Szrj        *
1311*38fd1498Szrj        * Copies an existing base class random number generator.
1312*38fd1498Szrj        * @param __rng An existing (base class) engine object.
1313*38fd1498Szrj        */
1314*38fd1498Szrj       explicit
1315*38fd1498Szrj       shuffle_order_engine(_RandomNumberEngine&& __rng)
1316*38fd1498Szrj       : _M_b(std::move(__rng))
1317*38fd1498Szrj       { _M_initialize(); }
1318*38fd1498Szrj 
1319*38fd1498Szrj       /**
1320*38fd1498Szrj        * @brief Seed constructs a %shuffle_order_engine engine.
1321*38fd1498Szrj        *
1322*38fd1498Szrj        * Constructs the underlying generator engine seeded with @p __s.
1323*38fd1498Szrj        * @param __s A seed value for the base class engine.
1324*38fd1498Szrj        */
1325*38fd1498Szrj       explicit
1326*38fd1498Szrj       shuffle_order_engine(result_type __s)
1327*38fd1498Szrj       : _M_b(__s)
1328*38fd1498Szrj       { _M_initialize(); }
1329*38fd1498Szrj 
1330*38fd1498Szrj       /**
1331*38fd1498Szrj        * @brief Generator construct a %shuffle_order_engine engine.
1332*38fd1498Szrj        *
1333*38fd1498Szrj        * @param __q A seed sequence.
1334*38fd1498Szrj        */
1335*38fd1498Szrj       template<typename _Sseq, typename = typename
1336*38fd1498Szrj 	std::enable_if<!std::is_same<_Sseq, shuffle_order_engine>::value
1337*38fd1498Szrj 		       && !std::is_same<_Sseq, _RandomNumberEngine>::value>
1338*38fd1498Szrj 	       ::type>
1339*38fd1498Szrj         explicit
1340*38fd1498Szrj         shuffle_order_engine(_Sseq& __q)
1341*38fd1498Szrj         : _M_b(__q)
1342*38fd1498Szrj         { _M_initialize(); }
1343*38fd1498Szrj 
1344*38fd1498Szrj       /**
1345*38fd1498Szrj        * @brief Reseeds the %shuffle_order_engine object with the default seed
1346*38fd1498Szrj                 for the underlying base class generator engine.
1347*38fd1498Szrj        */
1348*38fd1498Szrj       void
1349*38fd1498Szrj       seed()
1350*38fd1498Szrj       {
1351*38fd1498Szrj 	_M_b.seed();
1352*38fd1498Szrj 	_M_initialize();
1353*38fd1498Szrj       }
1354*38fd1498Szrj 
1355*38fd1498Szrj       /**
1356*38fd1498Szrj        * @brief Reseeds the %shuffle_order_engine object with the default seed
1357*38fd1498Szrj        *        for the underlying base class generator engine.
1358*38fd1498Szrj        */
1359*38fd1498Szrj       void
1360*38fd1498Szrj       seed(result_type __s)
1361*38fd1498Szrj       {
1362*38fd1498Szrj 	_M_b.seed(__s);
1363*38fd1498Szrj 	_M_initialize();
1364*38fd1498Szrj       }
1365*38fd1498Szrj 
1366*38fd1498Szrj       /**
1367*38fd1498Szrj        * @brief Reseeds the %shuffle_order_engine object with the given seed
1368*38fd1498Szrj        *        sequence.
1369*38fd1498Szrj        * @param __q A seed generator function.
1370*38fd1498Szrj        */
1371*38fd1498Szrj       template<typename _Sseq>
1372*38fd1498Szrj         void
1373*38fd1498Szrj         seed(_Sseq& __q)
1374*38fd1498Szrj         {
1375*38fd1498Szrj 	  _M_b.seed(__q);
1376*38fd1498Szrj 	  _M_initialize();
1377*38fd1498Szrj 	}
1378*38fd1498Szrj 
1379*38fd1498Szrj       /**
1380*38fd1498Szrj        * Gets a const reference to the underlying generator engine object.
1381*38fd1498Szrj        */
1382*38fd1498Szrj       const _RandomNumberEngine&
1383*38fd1498Szrj       base() const noexcept
1384*38fd1498Szrj       { return _M_b; }
1385*38fd1498Szrj 
1386*38fd1498Szrj       /**
1387*38fd1498Szrj        * Gets the minimum value in the generated random number range.
1388*38fd1498Szrj        */
1389*38fd1498Szrj       static constexpr result_type
1390*38fd1498Szrj       min()
1391*38fd1498Szrj       { return _RandomNumberEngine::min(); }
1392*38fd1498Szrj 
1393*38fd1498Szrj       /**
1394*38fd1498Szrj        * Gets the maximum value in the generated random number range.
1395*38fd1498Szrj        */
1396*38fd1498Szrj       static constexpr result_type
1397*38fd1498Szrj       max()
1398*38fd1498Szrj       { return _RandomNumberEngine::max(); }
1399*38fd1498Szrj 
1400*38fd1498Szrj       /**
1401*38fd1498Szrj        * Discard a sequence of random numbers.
1402*38fd1498Szrj        */
1403*38fd1498Szrj       void
1404*38fd1498Szrj       discard(unsigned long long __z)
1405*38fd1498Szrj       {
1406*38fd1498Szrj 	for (; __z != 0ULL; --__z)
1407*38fd1498Szrj 	  (*this)();
1408*38fd1498Szrj       }
1409*38fd1498Szrj 
1410*38fd1498Szrj       /**
1411*38fd1498Szrj        * Gets the next value in the generated random number sequence.
1412*38fd1498Szrj        */
1413*38fd1498Szrj       result_type
1414*38fd1498Szrj       operator()();
1415*38fd1498Szrj 
1416*38fd1498Szrj       /**
1417*38fd1498Szrj        * Compares two %shuffle_order_engine random number generator objects
1418*38fd1498Szrj        * of the same type for equality.
1419*38fd1498Szrj        *
1420*38fd1498Szrj        * @param __lhs A %shuffle_order_engine random number generator object.
1421*38fd1498Szrj        * @param __rhs Another %shuffle_order_engine random number generator
1422*38fd1498Szrj        *              object.
1423*38fd1498Szrj        *
1424*38fd1498Szrj        * @returns true if the infinite sequences of generated values
1425*38fd1498Szrj        *          would be equal, false otherwise.
1426*38fd1498Szrj       */
1427*38fd1498Szrj       friend bool
1428*38fd1498Szrj       operator==(const shuffle_order_engine& __lhs,
1429*38fd1498Szrj 		 const shuffle_order_engine& __rhs)
1430*38fd1498Szrj       { return (__lhs._M_b == __rhs._M_b
1431*38fd1498Szrj 		&& std::equal(__lhs._M_v, __lhs._M_v + __k, __rhs._M_v)
1432*38fd1498Szrj 		&& __lhs._M_y == __rhs._M_y); }
1433*38fd1498Szrj 
1434*38fd1498Szrj       /**
1435*38fd1498Szrj        * @brief Inserts the current state of a %shuffle_order_engine random
1436*38fd1498Szrj        *        number generator engine @p __x into the output stream
1437*38fd1498Szrj 	@p __os.
1438*38fd1498Szrj        *
1439*38fd1498Szrj        * @param __os An output stream.
1440*38fd1498Szrj        * @param __x  A %shuffle_order_engine random number generator engine.
1441*38fd1498Szrj        *
1442*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
1443*38fd1498Szrj        * an error state.
1444*38fd1498Szrj        */
1445*38fd1498Szrj       template<typename _RandomNumberEngine1, size_t __k1,
1446*38fd1498Szrj 	       typename _CharT, typename _Traits>
1447*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
1448*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1449*38fd1498Szrj 		   const std::shuffle_order_engine<_RandomNumberEngine1,
1450*38fd1498Szrj 		   __k1>& __x);
1451*38fd1498Szrj 
1452*38fd1498Szrj       /**
1453*38fd1498Szrj        * @brief Extracts the current state of a % subtract_with_carry_engine
1454*38fd1498Szrj        *        random number generator engine @p __x from the input stream
1455*38fd1498Szrj        *        @p __is.
1456*38fd1498Szrj        *
1457*38fd1498Szrj        * @param __is An input stream.
1458*38fd1498Szrj        * @param __x  A %shuffle_order_engine random number generator engine.
1459*38fd1498Szrj        *
1460*38fd1498Szrj        * @returns The input stream with the state of @p __x extracted or in
1461*38fd1498Szrj        * an error state.
1462*38fd1498Szrj        */
1463*38fd1498Szrj       template<typename _RandomNumberEngine1, size_t __k1,
1464*38fd1498Szrj 	       typename _CharT, typename _Traits>
1465*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
1466*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
1467*38fd1498Szrj 		   std::shuffle_order_engine<_RandomNumberEngine1, __k1>& __x);
1468*38fd1498Szrj 
1469*38fd1498Szrj     private:
1470*38fd1498Szrj       void _M_initialize()
1471*38fd1498Szrj       {
1472*38fd1498Szrj 	for (size_t __i = 0; __i < __k; ++__i)
1473*38fd1498Szrj 	  _M_v[__i] = _M_b();
1474*38fd1498Szrj 	_M_y = _M_b();
1475*38fd1498Szrj       }
1476*38fd1498Szrj 
1477*38fd1498Szrj       _RandomNumberEngine _M_b;
1478*38fd1498Szrj       result_type _M_v[__k];
1479*38fd1498Szrj       result_type _M_y;
1480*38fd1498Szrj     };
1481*38fd1498Szrj 
1482*38fd1498Szrj   /**
1483*38fd1498Szrj    * Compares two %shuffle_order_engine random number generator objects
1484*38fd1498Szrj    * of the same type for inequality.
1485*38fd1498Szrj    *
1486*38fd1498Szrj    * @param __lhs A %shuffle_order_engine random number generator object.
1487*38fd1498Szrj    * @param __rhs Another %shuffle_order_engine random number generator
1488*38fd1498Szrj    *              object.
1489*38fd1498Szrj    *
1490*38fd1498Szrj    * @returns true if the infinite sequences of generated values
1491*38fd1498Szrj    *          would be different, false otherwise.
1492*38fd1498Szrj    */
1493*38fd1498Szrj   template<typename _RandomNumberEngine, size_t __k>
1494*38fd1498Szrj     inline bool
1495*38fd1498Szrj     operator!=(const std::shuffle_order_engine<_RandomNumberEngine,
1496*38fd1498Szrj 	       __k>& __lhs,
1497*38fd1498Szrj 	       const std::shuffle_order_engine<_RandomNumberEngine,
1498*38fd1498Szrj 	       __k>& __rhs)
1499*38fd1498Szrj     { return !(__lhs == __rhs); }
1500*38fd1498Szrj 
1501*38fd1498Szrj 
1502*38fd1498Szrj   /**
1503*38fd1498Szrj    * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
1504*38fd1498Szrj    */
1505*38fd1498Szrj   typedef linear_congruential_engine<uint_fast32_t, 16807UL, 0UL, 2147483647UL>
1506*38fd1498Szrj   minstd_rand0;
1507*38fd1498Szrj 
1508*38fd1498Szrj   /**
1509*38fd1498Szrj    * An alternative LCR (Lehmer Generator function).
1510*38fd1498Szrj    */
1511*38fd1498Szrj   typedef linear_congruential_engine<uint_fast32_t, 48271UL, 0UL, 2147483647UL>
1512*38fd1498Szrj   minstd_rand;
1513*38fd1498Szrj 
1514*38fd1498Szrj   /**
1515*38fd1498Szrj    * The classic Mersenne Twister.
1516*38fd1498Szrj    *
1517*38fd1498Szrj    * Reference:
1518*38fd1498Szrj    * M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally
1519*38fd1498Szrj    * Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions
1520*38fd1498Szrj    * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
1521*38fd1498Szrj    */
1522*38fd1498Szrj   typedef mersenne_twister_engine<
1523*38fd1498Szrj     uint_fast32_t,
1524*38fd1498Szrj     32, 624, 397, 31,
1525*38fd1498Szrj     0x9908b0dfUL, 11,
1526*38fd1498Szrj     0xffffffffUL, 7,
1527*38fd1498Szrj     0x9d2c5680UL, 15,
1528*38fd1498Szrj     0xefc60000UL, 18, 1812433253UL> mt19937;
1529*38fd1498Szrj 
1530*38fd1498Szrj   /**
1531*38fd1498Szrj    * An alternative Mersenne Twister.
1532*38fd1498Szrj    */
1533*38fd1498Szrj   typedef mersenne_twister_engine<
1534*38fd1498Szrj     uint_fast64_t,
1535*38fd1498Szrj     64, 312, 156, 31,
1536*38fd1498Szrj     0xb5026f5aa96619e9ULL, 29,
1537*38fd1498Szrj     0x5555555555555555ULL, 17,
1538*38fd1498Szrj     0x71d67fffeda60000ULL, 37,
1539*38fd1498Szrj     0xfff7eee000000000ULL, 43,
1540*38fd1498Szrj     6364136223846793005ULL> mt19937_64;
1541*38fd1498Szrj 
1542*38fd1498Szrj   typedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>
1543*38fd1498Szrj     ranlux24_base;
1544*38fd1498Szrj 
1545*38fd1498Szrj   typedef subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>
1546*38fd1498Szrj     ranlux48_base;
1547*38fd1498Szrj 
1548*38fd1498Szrj   typedef discard_block_engine<ranlux24_base, 223, 23> ranlux24;
1549*38fd1498Szrj 
1550*38fd1498Szrj   typedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;
1551*38fd1498Szrj 
1552*38fd1498Szrj   typedef shuffle_order_engine<minstd_rand0, 256> knuth_b;
1553*38fd1498Szrj 
1554*38fd1498Szrj   typedef minstd_rand0 default_random_engine;
1555*38fd1498Szrj 
1556*38fd1498Szrj   /**
1557*38fd1498Szrj    * A standard interface to a platform-specific non-deterministic
1558*38fd1498Szrj    * random number generator (if any are available).
1559*38fd1498Szrj    */
1560*38fd1498Szrj   class random_device
1561*38fd1498Szrj   {
1562*38fd1498Szrj   public:
1563*38fd1498Szrj     /** The type of the generated random value. */
1564*38fd1498Szrj     typedef unsigned int result_type;
1565*38fd1498Szrj 
1566*38fd1498Szrj     // constructors, destructors and member functions
1567*38fd1498Szrj 
1568*38fd1498Szrj #ifdef _GLIBCXX_USE_RANDOM_TR1
1569*38fd1498Szrj 
1570*38fd1498Szrj     explicit
1571*38fd1498Szrj     random_device(const std::string& __token = "default")
1572*38fd1498Szrj     {
1573*38fd1498Szrj       _M_init(__token);
1574*38fd1498Szrj     }
1575*38fd1498Szrj 
1576*38fd1498Szrj     ~random_device()
1577*38fd1498Szrj     { _M_fini(); }
1578*38fd1498Szrj 
1579*38fd1498Szrj #else
1580*38fd1498Szrj 
1581*38fd1498Szrj     explicit
1582*38fd1498Szrj     random_device(const std::string& __token = "mt19937")
1583*38fd1498Szrj     { _M_init_pretr1(__token); }
1584*38fd1498Szrj 
1585*38fd1498Szrj   public:
1586*38fd1498Szrj 
1587*38fd1498Szrj #endif
1588*38fd1498Szrj 
1589*38fd1498Szrj     static constexpr result_type
1590*38fd1498Szrj     min()
1591*38fd1498Szrj     { return std::numeric_limits<result_type>::min(); }
1592*38fd1498Szrj 
1593*38fd1498Szrj     static constexpr result_type
1594*38fd1498Szrj     max()
1595*38fd1498Szrj     { return std::numeric_limits<result_type>::max(); }
1596*38fd1498Szrj 
1597*38fd1498Szrj     double
1598*38fd1498Szrj     entropy() const noexcept
1599*38fd1498Szrj     {
1600*38fd1498Szrj #ifdef _GLIBCXX_USE_RANDOM_TR1
1601*38fd1498Szrj       return this->_M_getentropy();
1602*38fd1498Szrj #else
1603*38fd1498Szrj       return 0.0;
1604*38fd1498Szrj #endif
1605*38fd1498Szrj     }
1606*38fd1498Szrj 
1607*38fd1498Szrj     result_type
1608*38fd1498Szrj     operator()()
1609*38fd1498Szrj     {
1610*38fd1498Szrj #ifdef _GLIBCXX_USE_RANDOM_TR1
1611*38fd1498Szrj       return this->_M_getval();
1612*38fd1498Szrj #else
1613*38fd1498Szrj       return this->_M_getval_pretr1();
1614*38fd1498Szrj #endif
1615*38fd1498Szrj     }
1616*38fd1498Szrj 
1617*38fd1498Szrj     // No copy functions.
1618*38fd1498Szrj     random_device(const random_device&) = delete;
1619*38fd1498Szrj     void operator=(const random_device&) = delete;
1620*38fd1498Szrj 
1621*38fd1498Szrj   private:
1622*38fd1498Szrj 
1623*38fd1498Szrj     void _M_init(const std::string& __token);
1624*38fd1498Szrj     void _M_init_pretr1(const std::string& __token);
1625*38fd1498Szrj     void _M_fini();
1626*38fd1498Szrj 
1627*38fd1498Szrj     result_type _M_getval();
1628*38fd1498Szrj     result_type _M_getval_pretr1();
1629*38fd1498Szrj     double _M_getentropy() const noexcept;
1630*38fd1498Szrj 
1631*38fd1498Szrj     union
1632*38fd1498Szrj     {
1633*38fd1498Szrj       void*      _M_file;
1634*38fd1498Szrj       mt19937    _M_mt;
1635*38fd1498Szrj     };
1636*38fd1498Szrj   };
1637*38fd1498Szrj 
1638*38fd1498Szrj   /* @} */ // group random_generators
1639*38fd1498Szrj 
1640*38fd1498Szrj   /**
1641*38fd1498Szrj    * @addtogroup random_distributions Random Number Distributions
1642*38fd1498Szrj    * @ingroup random
1643*38fd1498Szrj    * @{
1644*38fd1498Szrj    */
1645*38fd1498Szrj 
1646*38fd1498Szrj   /**
1647*38fd1498Szrj    * @addtogroup random_distributions_uniform Uniform Distributions
1648*38fd1498Szrj    * @ingroup random_distributions
1649*38fd1498Szrj    * @{
1650*38fd1498Szrj    */
1651*38fd1498Szrj 
1652*38fd1498Szrj   // std::uniform_int_distribution is defined in <bits/uniform_int_dist.h>
1653*38fd1498Szrj 
1654*38fd1498Szrj   /**
1655*38fd1498Szrj    * @brief Return true if two uniform integer distributions have
1656*38fd1498Szrj    *        different parameters.
1657*38fd1498Szrj    */
1658*38fd1498Szrj   template<typename _IntType>
1659*38fd1498Szrj     inline bool
1660*38fd1498Szrj     operator!=(const std::uniform_int_distribution<_IntType>& __d1,
1661*38fd1498Szrj 	       const std::uniform_int_distribution<_IntType>& __d2)
1662*38fd1498Szrj     { return !(__d1 == __d2); }
1663*38fd1498Szrj 
1664*38fd1498Szrj   /**
1665*38fd1498Szrj    * @brief Inserts a %uniform_int_distribution random number
1666*38fd1498Szrj    *        distribution @p __x into the output stream @p os.
1667*38fd1498Szrj    *
1668*38fd1498Szrj    * @param __os An output stream.
1669*38fd1498Szrj    * @param __x  A %uniform_int_distribution random number distribution.
1670*38fd1498Szrj    *
1671*38fd1498Szrj    * @returns The output stream with the state of @p __x inserted or in
1672*38fd1498Szrj    * an error state.
1673*38fd1498Szrj    */
1674*38fd1498Szrj   template<typename _IntType, typename _CharT, typename _Traits>
1675*38fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
1676*38fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>&,
1677*38fd1498Szrj 	       const std::uniform_int_distribution<_IntType>&);
1678*38fd1498Szrj 
1679*38fd1498Szrj   /**
1680*38fd1498Szrj    * @brief Extracts a %uniform_int_distribution random number distribution
1681*38fd1498Szrj    * @p __x from the input stream @p __is.
1682*38fd1498Szrj    *
1683*38fd1498Szrj    * @param __is An input stream.
1684*38fd1498Szrj    * @param __x  A %uniform_int_distribution random number generator engine.
1685*38fd1498Szrj    *
1686*38fd1498Szrj    * @returns The input stream with @p __x extracted or in an error state.
1687*38fd1498Szrj    */
1688*38fd1498Szrj   template<typename _IntType, typename _CharT, typename _Traits>
1689*38fd1498Szrj     std::basic_istream<_CharT, _Traits>&
1690*38fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>&,
1691*38fd1498Szrj 	       std::uniform_int_distribution<_IntType>&);
1692*38fd1498Szrj 
1693*38fd1498Szrj 
1694*38fd1498Szrj   /**
1695*38fd1498Szrj    * @brief Uniform continuous distribution for random numbers.
1696*38fd1498Szrj    *
1697*38fd1498Szrj    * A continuous random distribution on the range [min, max) with equal
1698*38fd1498Szrj    * probability throughout the range.  The URNG should be real-valued and
1699*38fd1498Szrj    * deliver number in the range [0, 1).
1700*38fd1498Szrj    */
1701*38fd1498Szrj   template<typename _RealType = double>
1702*38fd1498Szrj     class uniform_real_distribution
1703*38fd1498Szrj     {
1704*38fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
1705*38fd1498Szrj 		    "result_type must be a floating point type");
1706*38fd1498Szrj 
1707*38fd1498Szrj     public:
1708*38fd1498Szrj       /** The type of the range of the distribution. */
1709*38fd1498Szrj       typedef _RealType result_type;
1710*38fd1498Szrj 
1711*38fd1498Szrj       /** Parameter type. */
1712*38fd1498Szrj       struct param_type
1713*38fd1498Szrj       {
1714*38fd1498Szrj 	typedef uniform_real_distribution<_RealType> distribution_type;
1715*38fd1498Szrj 
1716*38fd1498Szrj 	explicit
1717*38fd1498Szrj 	param_type(_RealType __a = _RealType(0),
1718*38fd1498Szrj 		   _RealType __b = _RealType(1))
1719*38fd1498Szrj 	: _M_a(__a), _M_b(__b)
1720*38fd1498Szrj 	{
1721*38fd1498Szrj 	  __glibcxx_assert(_M_a <= _M_b);
1722*38fd1498Szrj 	}
1723*38fd1498Szrj 
1724*38fd1498Szrj 	result_type
1725*38fd1498Szrj 	a() const
1726*38fd1498Szrj 	{ return _M_a; }
1727*38fd1498Szrj 
1728*38fd1498Szrj 	result_type
1729*38fd1498Szrj 	b() const
1730*38fd1498Szrj 	{ return _M_b; }
1731*38fd1498Szrj 
1732*38fd1498Szrj 	friend bool
1733*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
1734*38fd1498Szrj 	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
1735*38fd1498Szrj 
1736*38fd1498Szrj 	friend bool
1737*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
1738*38fd1498Szrj 	{ return !(__p1 == __p2); }
1739*38fd1498Szrj 
1740*38fd1498Szrj       private:
1741*38fd1498Szrj 	_RealType _M_a;
1742*38fd1498Szrj 	_RealType _M_b;
1743*38fd1498Szrj       };
1744*38fd1498Szrj 
1745*38fd1498Szrj     public:
1746*38fd1498Szrj       /**
1747*38fd1498Szrj        * @brief Constructs a uniform_real_distribution object.
1748*38fd1498Szrj        *
1749*38fd1498Szrj        * @param __a [IN]  The lower bound of the distribution.
1750*38fd1498Szrj        * @param __b [IN]  The upper bound of the distribution.
1751*38fd1498Szrj        */
1752*38fd1498Szrj       explicit
1753*38fd1498Szrj       uniform_real_distribution(_RealType __a = _RealType(0),
1754*38fd1498Szrj 				_RealType __b = _RealType(1))
1755*38fd1498Szrj       : _M_param(__a, __b)
1756*38fd1498Szrj       { }
1757*38fd1498Szrj 
1758*38fd1498Szrj       explicit
1759*38fd1498Szrj       uniform_real_distribution(const param_type& __p)
1760*38fd1498Szrj       : _M_param(__p)
1761*38fd1498Szrj       { }
1762*38fd1498Szrj 
1763*38fd1498Szrj       /**
1764*38fd1498Szrj        * @brief Resets the distribution state.
1765*38fd1498Szrj        *
1766*38fd1498Szrj        * Does nothing for the uniform real distribution.
1767*38fd1498Szrj        */
1768*38fd1498Szrj       void
1769*38fd1498Szrj       reset() { }
1770*38fd1498Szrj 
1771*38fd1498Szrj       result_type
1772*38fd1498Szrj       a() const
1773*38fd1498Szrj       { return _M_param.a(); }
1774*38fd1498Szrj 
1775*38fd1498Szrj       result_type
1776*38fd1498Szrj       b() const
1777*38fd1498Szrj       { return _M_param.b(); }
1778*38fd1498Szrj 
1779*38fd1498Szrj       /**
1780*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
1781*38fd1498Szrj        */
1782*38fd1498Szrj       param_type
1783*38fd1498Szrj       param() const
1784*38fd1498Szrj       { return _M_param; }
1785*38fd1498Szrj 
1786*38fd1498Szrj       /**
1787*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
1788*38fd1498Szrj        * @param __param The new parameter set of the distribution.
1789*38fd1498Szrj        */
1790*38fd1498Szrj       void
1791*38fd1498Szrj       param(const param_type& __param)
1792*38fd1498Szrj       { _M_param = __param; }
1793*38fd1498Szrj 
1794*38fd1498Szrj       /**
1795*38fd1498Szrj        * @brief Returns the inclusive lower bound of the distribution range.
1796*38fd1498Szrj        */
1797*38fd1498Szrj       result_type
1798*38fd1498Szrj       min() const
1799*38fd1498Szrj       { return this->a(); }
1800*38fd1498Szrj 
1801*38fd1498Szrj       /**
1802*38fd1498Szrj        * @brief Returns the inclusive upper bound of the distribution range.
1803*38fd1498Szrj        */
1804*38fd1498Szrj       result_type
1805*38fd1498Szrj       max() const
1806*38fd1498Szrj       { return this->b(); }
1807*38fd1498Szrj 
1808*38fd1498Szrj       /**
1809*38fd1498Szrj        * @brief Generating functions.
1810*38fd1498Szrj        */
1811*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
1812*38fd1498Szrj 	result_type
1813*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
1814*38fd1498Szrj         { return this->operator()(__urng, _M_param); }
1815*38fd1498Szrj 
1816*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
1817*38fd1498Szrj 	result_type
1818*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
1819*38fd1498Szrj 		   const param_type& __p)
1820*38fd1498Szrj 	{
1821*38fd1498Szrj 	  __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1822*38fd1498Szrj 	    __aurng(__urng);
1823*38fd1498Szrj 	  return (__aurng() * (__p.b() - __p.a())) + __p.a();
1824*38fd1498Szrj 	}
1825*38fd1498Szrj 
1826*38fd1498Szrj       template<typename _ForwardIterator,
1827*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
1828*38fd1498Szrj 	void
1829*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
1830*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
1831*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
1832*38fd1498Szrj 
1833*38fd1498Szrj       template<typename _ForwardIterator,
1834*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
1835*38fd1498Szrj 	void
1836*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
1837*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
1838*38fd1498Szrj 		   const param_type& __p)
1839*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
1840*38fd1498Szrj 
1841*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
1842*38fd1498Szrj 	void
1843*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
1844*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
1845*38fd1498Szrj 		   const param_type& __p)
1846*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
1847*38fd1498Szrj 
1848*38fd1498Szrj       /**
1849*38fd1498Szrj        * @brief Return true if two uniform real distributions have
1850*38fd1498Szrj        *        the same parameters.
1851*38fd1498Szrj        */
1852*38fd1498Szrj       friend bool
1853*38fd1498Szrj       operator==(const uniform_real_distribution& __d1,
1854*38fd1498Szrj 		 const uniform_real_distribution& __d2)
1855*38fd1498Szrj       { return __d1._M_param == __d2._M_param; }
1856*38fd1498Szrj 
1857*38fd1498Szrj     private:
1858*38fd1498Szrj       template<typename _ForwardIterator,
1859*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
1860*38fd1498Szrj 	void
1861*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1862*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
1863*38fd1498Szrj 			const param_type& __p);
1864*38fd1498Szrj 
1865*38fd1498Szrj       param_type _M_param;
1866*38fd1498Szrj     };
1867*38fd1498Szrj 
1868*38fd1498Szrj   /**
1869*38fd1498Szrj    * @brief Return true if two uniform real distributions have
1870*38fd1498Szrj    *        different parameters.
1871*38fd1498Szrj    */
1872*38fd1498Szrj   template<typename _IntType>
1873*38fd1498Szrj     inline bool
1874*38fd1498Szrj     operator!=(const std::uniform_real_distribution<_IntType>& __d1,
1875*38fd1498Szrj 	       const std::uniform_real_distribution<_IntType>& __d2)
1876*38fd1498Szrj     { return !(__d1 == __d2); }
1877*38fd1498Szrj 
1878*38fd1498Szrj   /**
1879*38fd1498Szrj    * @brief Inserts a %uniform_real_distribution random number
1880*38fd1498Szrj    *        distribution @p __x into the output stream @p __os.
1881*38fd1498Szrj    *
1882*38fd1498Szrj    * @param __os An output stream.
1883*38fd1498Szrj    * @param __x  A %uniform_real_distribution random number distribution.
1884*38fd1498Szrj    *
1885*38fd1498Szrj    * @returns The output stream with the state of @p __x inserted or in
1886*38fd1498Szrj    *          an error state.
1887*38fd1498Szrj    */
1888*38fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
1889*38fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
1890*38fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>&,
1891*38fd1498Szrj 	       const std::uniform_real_distribution<_RealType>&);
1892*38fd1498Szrj 
1893*38fd1498Szrj   /**
1894*38fd1498Szrj    * @brief Extracts a %uniform_real_distribution random number distribution
1895*38fd1498Szrj    * @p __x from the input stream @p __is.
1896*38fd1498Szrj    *
1897*38fd1498Szrj    * @param __is An input stream.
1898*38fd1498Szrj    * @param __x  A %uniform_real_distribution random number generator engine.
1899*38fd1498Szrj    *
1900*38fd1498Szrj    * @returns The input stream with @p __x extracted or in an error state.
1901*38fd1498Szrj    */
1902*38fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
1903*38fd1498Szrj     std::basic_istream<_CharT, _Traits>&
1904*38fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>&,
1905*38fd1498Szrj 	       std::uniform_real_distribution<_RealType>&);
1906*38fd1498Szrj 
1907*38fd1498Szrj   /* @} */ // group random_distributions_uniform
1908*38fd1498Szrj 
1909*38fd1498Szrj   /**
1910*38fd1498Szrj    * @addtogroup random_distributions_normal Normal Distributions
1911*38fd1498Szrj    * @ingroup random_distributions
1912*38fd1498Szrj    * @{
1913*38fd1498Szrj    */
1914*38fd1498Szrj 
1915*38fd1498Szrj   /**
1916*38fd1498Szrj    * @brief A normal continuous distribution for random numbers.
1917*38fd1498Szrj    *
1918*38fd1498Szrj    * The formula for the normal probability density function is
1919*38fd1498Szrj    * @f[
1920*38fd1498Szrj    *     p(x|\mu,\sigma) = \frac{1}{\sigma \sqrt{2 \pi}}
1921*38fd1498Szrj    *            e^{- \frac{{x - \mu}^ {2}}{2 \sigma ^ {2}} }
1922*38fd1498Szrj    * @f]
1923*38fd1498Szrj    */
1924*38fd1498Szrj   template<typename _RealType = double>
1925*38fd1498Szrj     class normal_distribution
1926*38fd1498Szrj     {
1927*38fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
1928*38fd1498Szrj 		    "result_type must be a floating point type");
1929*38fd1498Szrj 
1930*38fd1498Szrj     public:
1931*38fd1498Szrj       /** The type of the range of the distribution. */
1932*38fd1498Szrj       typedef _RealType result_type;
1933*38fd1498Szrj 
1934*38fd1498Szrj       /** Parameter type. */
1935*38fd1498Szrj       struct param_type
1936*38fd1498Szrj       {
1937*38fd1498Szrj 	typedef normal_distribution<_RealType> distribution_type;
1938*38fd1498Szrj 
1939*38fd1498Szrj 	explicit
1940*38fd1498Szrj 	param_type(_RealType __mean = _RealType(0),
1941*38fd1498Szrj 		   _RealType __stddev = _RealType(1))
1942*38fd1498Szrj 	: _M_mean(__mean), _M_stddev(__stddev)
1943*38fd1498Szrj 	{
1944*38fd1498Szrj 	  __glibcxx_assert(_M_stddev > _RealType(0));
1945*38fd1498Szrj 	}
1946*38fd1498Szrj 
1947*38fd1498Szrj 	_RealType
1948*38fd1498Szrj 	mean() const
1949*38fd1498Szrj 	{ return _M_mean; }
1950*38fd1498Szrj 
1951*38fd1498Szrj 	_RealType
1952*38fd1498Szrj 	stddev() const
1953*38fd1498Szrj 	{ return _M_stddev; }
1954*38fd1498Szrj 
1955*38fd1498Szrj 	friend bool
1956*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
1957*38fd1498Szrj 	{ return (__p1._M_mean == __p2._M_mean
1958*38fd1498Szrj 		  && __p1._M_stddev == __p2._M_stddev); }
1959*38fd1498Szrj 
1960*38fd1498Szrj 	friend bool
1961*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
1962*38fd1498Szrj 	{ return !(__p1 == __p2); }
1963*38fd1498Szrj 
1964*38fd1498Szrj       private:
1965*38fd1498Szrj 	_RealType _M_mean;
1966*38fd1498Szrj 	_RealType _M_stddev;
1967*38fd1498Szrj       };
1968*38fd1498Szrj 
1969*38fd1498Szrj     public:
1970*38fd1498Szrj       /**
1971*38fd1498Szrj        * Constructs a normal distribution with parameters @f$mean@f$ and
1972*38fd1498Szrj        * standard deviation.
1973*38fd1498Szrj        */
1974*38fd1498Szrj       explicit
1975*38fd1498Szrj       normal_distribution(result_type __mean = result_type(0),
1976*38fd1498Szrj 			  result_type __stddev = result_type(1))
1977*38fd1498Szrj       : _M_param(__mean, __stddev), _M_saved_available(false)
1978*38fd1498Szrj       { }
1979*38fd1498Szrj 
1980*38fd1498Szrj       explicit
1981*38fd1498Szrj       normal_distribution(const param_type& __p)
1982*38fd1498Szrj       : _M_param(__p), _M_saved_available(false)
1983*38fd1498Szrj       { }
1984*38fd1498Szrj 
1985*38fd1498Szrj       /**
1986*38fd1498Szrj        * @brief Resets the distribution state.
1987*38fd1498Szrj        */
1988*38fd1498Szrj       void
1989*38fd1498Szrj       reset()
1990*38fd1498Szrj       { _M_saved_available = false; }
1991*38fd1498Szrj 
1992*38fd1498Szrj       /**
1993*38fd1498Szrj        * @brief Returns the mean of the distribution.
1994*38fd1498Szrj        */
1995*38fd1498Szrj       _RealType
1996*38fd1498Szrj       mean() const
1997*38fd1498Szrj       { return _M_param.mean(); }
1998*38fd1498Szrj 
1999*38fd1498Szrj       /**
2000*38fd1498Szrj        * @brief Returns the standard deviation of the distribution.
2001*38fd1498Szrj        */
2002*38fd1498Szrj       _RealType
2003*38fd1498Szrj       stddev() const
2004*38fd1498Szrj       { return _M_param.stddev(); }
2005*38fd1498Szrj 
2006*38fd1498Szrj       /**
2007*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
2008*38fd1498Szrj        */
2009*38fd1498Szrj       param_type
2010*38fd1498Szrj       param() const
2011*38fd1498Szrj       { return _M_param; }
2012*38fd1498Szrj 
2013*38fd1498Szrj       /**
2014*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
2015*38fd1498Szrj        * @param __param The new parameter set of the distribution.
2016*38fd1498Szrj        */
2017*38fd1498Szrj       void
2018*38fd1498Szrj       param(const param_type& __param)
2019*38fd1498Szrj       { _M_param = __param; }
2020*38fd1498Szrj 
2021*38fd1498Szrj       /**
2022*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
2023*38fd1498Szrj        */
2024*38fd1498Szrj       result_type
2025*38fd1498Szrj       min() const
2026*38fd1498Szrj       { return std::numeric_limits<result_type>::lowest(); }
2027*38fd1498Szrj 
2028*38fd1498Szrj       /**
2029*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
2030*38fd1498Szrj        */
2031*38fd1498Szrj       result_type
2032*38fd1498Szrj       max() const
2033*38fd1498Szrj       { return std::numeric_limits<result_type>::max(); }
2034*38fd1498Szrj 
2035*38fd1498Szrj       /**
2036*38fd1498Szrj        * @brief Generating functions.
2037*38fd1498Szrj        */
2038*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2039*38fd1498Szrj 	result_type
2040*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
2041*38fd1498Szrj 	{ return this->operator()(__urng, _M_param); }
2042*38fd1498Szrj 
2043*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2044*38fd1498Szrj 	result_type
2045*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
2046*38fd1498Szrj 		   const param_type& __p);
2047*38fd1498Szrj 
2048*38fd1498Szrj       template<typename _ForwardIterator,
2049*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2050*38fd1498Szrj 	void
2051*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
2052*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
2053*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
2054*38fd1498Szrj 
2055*38fd1498Szrj       template<typename _ForwardIterator,
2056*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2057*38fd1498Szrj 	void
2058*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
2059*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
2060*38fd1498Szrj 		   const param_type& __p)
2061*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
2062*38fd1498Szrj 
2063*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2064*38fd1498Szrj 	void
2065*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
2066*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
2067*38fd1498Szrj 		   const param_type& __p)
2068*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
2069*38fd1498Szrj 
2070*38fd1498Szrj       /**
2071*38fd1498Szrj        * @brief Return true if two normal distributions have
2072*38fd1498Szrj        *        the same parameters and the sequences that would
2073*38fd1498Szrj        *        be generated are equal.
2074*38fd1498Szrj        */
2075*38fd1498Szrj       template<typename _RealType1>
2076*38fd1498Szrj 	friend bool
2077*38fd1498Szrj         operator==(const std::normal_distribution<_RealType1>& __d1,
2078*38fd1498Szrj 		   const std::normal_distribution<_RealType1>& __d2);
2079*38fd1498Szrj 
2080*38fd1498Szrj       /**
2081*38fd1498Szrj        * @brief Inserts a %normal_distribution random number distribution
2082*38fd1498Szrj        * @p __x into the output stream @p __os.
2083*38fd1498Szrj        *
2084*38fd1498Szrj        * @param __os An output stream.
2085*38fd1498Szrj        * @param __x  A %normal_distribution random number distribution.
2086*38fd1498Szrj        *
2087*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
2088*38fd1498Szrj        * an error state.
2089*38fd1498Szrj        */
2090*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
2091*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
2092*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2093*38fd1498Szrj 		   const std::normal_distribution<_RealType1>& __x);
2094*38fd1498Szrj 
2095*38fd1498Szrj       /**
2096*38fd1498Szrj        * @brief Extracts a %normal_distribution random number distribution
2097*38fd1498Szrj        * @p __x from the input stream @p __is.
2098*38fd1498Szrj        *
2099*38fd1498Szrj        * @param __is An input stream.
2100*38fd1498Szrj        * @param __x  A %normal_distribution random number generator engine.
2101*38fd1498Szrj        *
2102*38fd1498Szrj        * @returns The input stream with @p __x extracted or in an error
2103*38fd1498Szrj        *          state.
2104*38fd1498Szrj        */
2105*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
2106*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
2107*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
2108*38fd1498Szrj 		   std::normal_distribution<_RealType1>& __x);
2109*38fd1498Szrj 
2110*38fd1498Szrj     private:
2111*38fd1498Szrj       template<typename _ForwardIterator,
2112*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2113*38fd1498Szrj 	void
2114*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2115*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
2116*38fd1498Szrj 			const param_type& __p);
2117*38fd1498Szrj 
2118*38fd1498Szrj       param_type  _M_param;
2119*38fd1498Szrj       result_type _M_saved;
2120*38fd1498Szrj       bool        _M_saved_available;
2121*38fd1498Szrj     };
2122*38fd1498Szrj 
2123*38fd1498Szrj   /**
2124*38fd1498Szrj    * @brief Return true if two normal distributions are different.
2125*38fd1498Szrj    */
2126*38fd1498Szrj   template<typename _RealType>
2127*38fd1498Szrj     inline bool
2128*38fd1498Szrj     operator!=(const std::normal_distribution<_RealType>& __d1,
2129*38fd1498Szrj 	       const std::normal_distribution<_RealType>& __d2)
2130*38fd1498Szrj     { return !(__d1 == __d2); }
2131*38fd1498Szrj 
2132*38fd1498Szrj 
2133*38fd1498Szrj   /**
2134*38fd1498Szrj    * @brief A lognormal_distribution random number distribution.
2135*38fd1498Szrj    *
2136*38fd1498Szrj    * The formula for the normal probability mass function is
2137*38fd1498Szrj    * @f[
2138*38fd1498Szrj    *     p(x|m,s) = \frac{1}{sx\sqrt{2\pi}}
2139*38fd1498Szrj    *                \exp{-\frac{(\ln{x} - m)^2}{2s^2}}
2140*38fd1498Szrj    * @f]
2141*38fd1498Szrj    */
2142*38fd1498Szrj   template<typename _RealType = double>
2143*38fd1498Szrj     class lognormal_distribution
2144*38fd1498Szrj     {
2145*38fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
2146*38fd1498Szrj 		    "result_type must be a floating point type");
2147*38fd1498Szrj 
2148*38fd1498Szrj     public:
2149*38fd1498Szrj       /** The type of the range of the distribution. */
2150*38fd1498Szrj       typedef _RealType result_type;
2151*38fd1498Szrj 
2152*38fd1498Szrj       /** Parameter type. */
2153*38fd1498Szrj       struct param_type
2154*38fd1498Szrj       {
2155*38fd1498Szrj 	typedef lognormal_distribution<_RealType> distribution_type;
2156*38fd1498Szrj 
2157*38fd1498Szrj 	explicit
2158*38fd1498Szrj 	param_type(_RealType __m = _RealType(0),
2159*38fd1498Szrj 		   _RealType __s = _RealType(1))
2160*38fd1498Szrj 	: _M_m(__m), _M_s(__s)
2161*38fd1498Szrj 	{ }
2162*38fd1498Szrj 
2163*38fd1498Szrj 	_RealType
2164*38fd1498Szrj 	m() const
2165*38fd1498Szrj 	{ return _M_m; }
2166*38fd1498Szrj 
2167*38fd1498Szrj 	_RealType
2168*38fd1498Szrj 	s() const
2169*38fd1498Szrj 	{ return _M_s; }
2170*38fd1498Szrj 
2171*38fd1498Szrj 	friend bool
2172*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
2173*38fd1498Szrj 	{ return __p1._M_m == __p2._M_m && __p1._M_s == __p2._M_s; }
2174*38fd1498Szrj 
2175*38fd1498Szrj 	friend bool
2176*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
2177*38fd1498Szrj 	{ return !(__p1 == __p2); }
2178*38fd1498Szrj 
2179*38fd1498Szrj       private:
2180*38fd1498Szrj 	_RealType _M_m;
2181*38fd1498Szrj 	_RealType _M_s;
2182*38fd1498Szrj       };
2183*38fd1498Szrj 
2184*38fd1498Szrj       explicit
2185*38fd1498Szrj       lognormal_distribution(_RealType __m = _RealType(0),
2186*38fd1498Szrj 			     _RealType __s = _RealType(1))
2187*38fd1498Szrj       : _M_param(__m, __s), _M_nd()
2188*38fd1498Szrj       { }
2189*38fd1498Szrj 
2190*38fd1498Szrj       explicit
2191*38fd1498Szrj       lognormal_distribution(const param_type& __p)
2192*38fd1498Szrj       : _M_param(__p), _M_nd()
2193*38fd1498Szrj       { }
2194*38fd1498Szrj 
2195*38fd1498Szrj       /**
2196*38fd1498Szrj        * Resets the distribution state.
2197*38fd1498Szrj        */
2198*38fd1498Szrj       void
2199*38fd1498Szrj       reset()
2200*38fd1498Szrj       { _M_nd.reset(); }
2201*38fd1498Szrj 
2202*38fd1498Szrj       /**
2203*38fd1498Szrj        *
2204*38fd1498Szrj        */
2205*38fd1498Szrj       _RealType
2206*38fd1498Szrj       m() const
2207*38fd1498Szrj       { return _M_param.m(); }
2208*38fd1498Szrj 
2209*38fd1498Szrj       _RealType
2210*38fd1498Szrj       s() const
2211*38fd1498Szrj       { return _M_param.s(); }
2212*38fd1498Szrj 
2213*38fd1498Szrj       /**
2214*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
2215*38fd1498Szrj        */
2216*38fd1498Szrj       param_type
2217*38fd1498Szrj       param() const
2218*38fd1498Szrj       { return _M_param; }
2219*38fd1498Szrj 
2220*38fd1498Szrj       /**
2221*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
2222*38fd1498Szrj        * @param __param The new parameter set of the distribution.
2223*38fd1498Szrj        */
2224*38fd1498Szrj       void
2225*38fd1498Szrj       param(const param_type& __param)
2226*38fd1498Szrj       { _M_param = __param; }
2227*38fd1498Szrj 
2228*38fd1498Szrj       /**
2229*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
2230*38fd1498Szrj        */
2231*38fd1498Szrj       result_type
2232*38fd1498Szrj       min() const
2233*38fd1498Szrj       { return result_type(0); }
2234*38fd1498Szrj 
2235*38fd1498Szrj       /**
2236*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
2237*38fd1498Szrj        */
2238*38fd1498Szrj       result_type
2239*38fd1498Szrj       max() const
2240*38fd1498Szrj       { return std::numeric_limits<result_type>::max(); }
2241*38fd1498Szrj 
2242*38fd1498Szrj       /**
2243*38fd1498Szrj        * @brief Generating functions.
2244*38fd1498Szrj        */
2245*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2246*38fd1498Szrj 	result_type
2247*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
2248*38fd1498Szrj         { return this->operator()(__urng, _M_param); }
2249*38fd1498Szrj 
2250*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2251*38fd1498Szrj 	result_type
2252*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
2253*38fd1498Szrj 		   const param_type& __p)
2254*38fd1498Szrj         { return std::exp(__p.s() * _M_nd(__urng) + __p.m()); }
2255*38fd1498Szrj 
2256*38fd1498Szrj       template<typename _ForwardIterator,
2257*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2258*38fd1498Szrj 	void
2259*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
2260*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
2261*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
2262*38fd1498Szrj 
2263*38fd1498Szrj       template<typename _ForwardIterator,
2264*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2265*38fd1498Szrj 	void
2266*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
2267*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
2268*38fd1498Szrj 		   const param_type& __p)
2269*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
2270*38fd1498Szrj 
2271*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2272*38fd1498Szrj 	void
2273*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
2274*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
2275*38fd1498Szrj 		   const param_type& __p)
2276*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
2277*38fd1498Szrj 
2278*38fd1498Szrj       /**
2279*38fd1498Szrj        * @brief Return true if two lognormal distributions have
2280*38fd1498Szrj        *        the same parameters and the sequences that would
2281*38fd1498Szrj        *        be generated are equal.
2282*38fd1498Szrj        */
2283*38fd1498Szrj       friend bool
2284*38fd1498Szrj       operator==(const lognormal_distribution& __d1,
2285*38fd1498Szrj 		 const lognormal_distribution& __d2)
2286*38fd1498Szrj       { return (__d1._M_param == __d2._M_param
2287*38fd1498Szrj 		&& __d1._M_nd == __d2._M_nd); }
2288*38fd1498Szrj 
2289*38fd1498Szrj       /**
2290*38fd1498Szrj        * @brief Inserts a %lognormal_distribution random number distribution
2291*38fd1498Szrj        * @p __x into the output stream @p __os.
2292*38fd1498Szrj        *
2293*38fd1498Szrj        * @param __os An output stream.
2294*38fd1498Szrj        * @param __x  A %lognormal_distribution random number distribution.
2295*38fd1498Szrj        *
2296*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
2297*38fd1498Szrj        * an error state.
2298*38fd1498Szrj        */
2299*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
2300*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
2301*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2302*38fd1498Szrj 		   const std::lognormal_distribution<_RealType1>& __x);
2303*38fd1498Szrj 
2304*38fd1498Szrj       /**
2305*38fd1498Szrj        * @brief Extracts a %lognormal_distribution random number distribution
2306*38fd1498Szrj        * @p __x from the input stream @p __is.
2307*38fd1498Szrj        *
2308*38fd1498Szrj        * @param __is An input stream.
2309*38fd1498Szrj        * @param __x A %lognormal_distribution random number
2310*38fd1498Szrj        *            generator engine.
2311*38fd1498Szrj        *
2312*38fd1498Szrj        * @returns The input stream with @p __x extracted or in an error state.
2313*38fd1498Szrj        */
2314*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
2315*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
2316*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
2317*38fd1498Szrj 		   std::lognormal_distribution<_RealType1>& __x);
2318*38fd1498Szrj 
2319*38fd1498Szrj     private:
2320*38fd1498Szrj       template<typename _ForwardIterator,
2321*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2322*38fd1498Szrj 	void
2323*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2324*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
2325*38fd1498Szrj 			const param_type& __p);
2326*38fd1498Szrj 
2327*38fd1498Szrj       param_type _M_param;
2328*38fd1498Szrj 
2329*38fd1498Szrj       std::normal_distribution<result_type> _M_nd;
2330*38fd1498Szrj     };
2331*38fd1498Szrj 
2332*38fd1498Szrj   /**
2333*38fd1498Szrj    * @brief Return true if two lognormal distributions are different.
2334*38fd1498Szrj    */
2335*38fd1498Szrj   template<typename _RealType>
2336*38fd1498Szrj     inline bool
2337*38fd1498Szrj     operator!=(const std::lognormal_distribution<_RealType>& __d1,
2338*38fd1498Szrj 	       const std::lognormal_distribution<_RealType>& __d2)
2339*38fd1498Szrj     { return !(__d1 == __d2); }
2340*38fd1498Szrj 
2341*38fd1498Szrj 
2342*38fd1498Szrj   /**
2343*38fd1498Szrj    * @brief A gamma continuous distribution for random numbers.
2344*38fd1498Szrj    *
2345*38fd1498Szrj    * The formula for the gamma probability density function is:
2346*38fd1498Szrj    * @f[
2347*38fd1498Szrj    *     p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
2348*38fd1498Szrj    *                         (x/\beta)^{\alpha - 1} e^{-x/\beta}
2349*38fd1498Szrj    * @f]
2350*38fd1498Szrj    */
2351*38fd1498Szrj   template<typename _RealType = double>
2352*38fd1498Szrj     class gamma_distribution
2353*38fd1498Szrj     {
2354*38fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
2355*38fd1498Szrj 		    "result_type must be a floating point type");
2356*38fd1498Szrj 
2357*38fd1498Szrj     public:
2358*38fd1498Szrj       /** The type of the range of the distribution. */
2359*38fd1498Szrj       typedef _RealType result_type;
2360*38fd1498Szrj 
2361*38fd1498Szrj       /** Parameter type. */
2362*38fd1498Szrj       struct param_type
2363*38fd1498Szrj       {
2364*38fd1498Szrj 	typedef gamma_distribution<_RealType> distribution_type;
2365*38fd1498Szrj 	friend class gamma_distribution<_RealType>;
2366*38fd1498Szrj 
2367*38fd1498Szrj 	explicit
2368*38fd1498Szrj 	param_type(_RealType __alpha_val = _RealType(1),
2369*38fd1498Szrj 		   _RealType __beta_val = _RealType(1))
2370*38fd1498Szrj 	: _M_alpha(__alpha_val), _M_beta(__beta_val)
2371*38fd1498Szrj 	{
2372*38fd1498Szrj 	  __glibcxx_assert(_M_alpha > _RealType(0));
2373*38fd1498Szrj 	  _M_initialize();
2374*38fd1498Szrj 	}
2375*38fd1498Szrj 
2376*38fd1498Szrj 	_RealType
2377*38fd1498Szrj 	alpha() const
2378*38fd1498Szrj 	{ return _M_alpha; }
2379*38fd1498Szrj 
2380*38fd1498Szrj 	_RealType
2381*38fd1498Szrj 	beta() const
2382*38fd1498Szrj 	{ return _M_beta; }
2383*38fd1498Szrj 
2384*38fd1498Szrj 	friend bool
2385*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
2386*38fd1498Szrj 	{ return (__p1._M_alpha == __p2._M_alpha
2387*38fd1498Szrj 		  && __p1._M_beta == __p2._M_beta); }
2388*38fd1498Szrj 
2389*38fd1498Szrj 	friend bool
2390*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
2391*38fd1498Szrj 	{ return !(__p1 == __p2); }
2392*38fd1498Szrj 
2393*38fd1498Szrj       private:
2394*38fd1498Szrj 	void
2395*38fd1498Szrj 	_M_initialize();
2396*38fd1498Szrj 
2397*38fd1498Szrj 	_RealType _M_alpha;
2398*38fd1498Szrj 	_RealType _M_beta;
2399*38fd1498Szrj 
2400*38fd1498Szrj 	_RealType _M_malpha, _M_a2;
2401*38fd1498Szrj       };
2402*38fd1498Szrj 
2403*38fd1498Szrj     public:
2404*38fd1498Szrj       /**
2405*38fd1498Szrj        * @brief Constructs a gamma distribution with parameters
2406*38fd1498Szrj        * @f$\alpha@f$ and @f$\beta@f$.
2407*38fd1498Szrj        */
2408*38fd1498Szrj       explicit
2409*38fd1498Szrj       gamma_distribution(_RealType __alpha_val = _RealType(1),
2410*38fd1498Szrj 			 _RealType __beta_val = _RealType(1))
2411*38fd1498Szrj       : _M_param(__alpha_val, __beta_val), _M_nd()
2412*38fd1498Szrj       { }
2413*38fd1498Szrj 
2414*38fd1498Szrj       explicit
2415*38fd1498Szrj       gamma_distribution(const param_type& __p)
2416*38fd1498Szrj       : _M_param(__p), _M_nd()
2417*38fd1498Szrj       { }
2418*38fd1498Szrj 
2419*38fd1498Szrj       /**
2420*38fd1498Szrj        * @brief Resets the distribution state.
2421*38fd1498Szrj        */
2422*38fd1498Szrj       void
2423*38fd1498Szrj       reset()
2424*38fd1498Szrj       { _M_nd.reset(); }
2425*38fd1498Szrj 
2426*38fd1498Szrj       /**
2427*38fd1498Szrj        * @brief Returns the @f$\alpha@f$ of the distribution.
2428*38fd1498Szrj        */
2429*38fd1498Szrj       _RealType
2430*38fd1498Szrj       alpha() const
2431*38fd1498Szrj       { return _M_param.alpha(); }
2432*38fd1498Szrj 
2433*38fd1498Szrj       /**
2434*38fd1498Szrj        * @brief Returns the @f$\beta@f$ of the distribution.
2435*38fd1498Szrj        */
2436*38fd1498Szrj       _RealType
2437*38fd1498Szrj       beta() const
2438*38fd1498Szrj       { return _M_param.beta(); }
2439*38fd1498Szrj 
2440*38fd1498Szrj       /**
2441*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
2442*38fd1498Szrj        */
2443*38fd1498Szrj       param_type
2444*38fd1498Szrj       param() const
2445*38fd1498Szrj       { return _M_param; }
2446*38fd1498Szrj 
2447*38fd1498Szrj       /**
2448*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
2449*38fd1498Szrj        * @param __param The new parameter set of the distribution.
2450*38fd1498Szrj        */
2451*38fd1498Szrj       void
2452*38fd1498Szrj       param(const param_type& __param)
2453*38fd1498Szrj       { _M_param = __param; }
2454*38fd1498Szrj 
2455*38fd1498Szrj       /**
2456*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
2457*38fd1498Szrj        */
2458*38fd1498Szrj       result_type
2459*38fd1498Szrj       min() const
2460*38fd1498Szrj       { return result_type(0); }
2461*38fd1498Szrj 
2462*38fd1498Szrj       /**
2463*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
2464*38fd1498Szrj        */
2465*38fd1498Szrj       result_type
2466*38fd1498Szrj       max() const
2467*38fd1498Szrj       { return std::numeric_limits<result_type>::max(); }
2468*38fd1498Szrj 
2469*38fd1498Szrj       /**
2470*38fd1498Szrj        * @brief Generating functions.
2471*38fd1498Szrj        */
2472*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2473*38fd1498Szrj 	result_type
2474*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
2475*38fd1498Szrj 	{ return this->operator()(__urng, _M_param); }
2476*38fd1498Szrj 
2477*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2478*38fd1498Szrj 	result_type
2479*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
2480*38fd1498Szrj 		   const param_type& __p);
2481*38fd1498Szrj 
2482*38fd1498Szrj       template<typename _ForwardIterator,
2483*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2484*38fd1498Szrj 	void
2485*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
2486*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
2487*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
2488*38fd1498Szrj 
2489*38fd1498Szrj       template<typename _ForwardIterator,
2490*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2491*38fd1498Szrj 	void
2492*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
2493*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
2494*38fd1498Szrj 		   const param_type& __p)
2495*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
2496*38fd1498Szrj 
2497*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2498*38fd1498Szrj 	void
2499*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
2500*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
2501*38fd1498Szrj 		   const param_type& __p)
2502*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
2503*38fd1498Szrj 
2504*38fd1498Szrj       /**
2505*38fd1498Szrj        * @brief Return true if two gamma distributions have the same
2506*38fd1498Szrj        *        parameters and the sequences that would be generated
2507*38fd1498Szrj        *        are equal.
2508*38fd1498Szrj        */
2509*38fd1498Szrj       friend bool
2510*38fd1498Szrj       operator==(const gamma_distribution& __d1,
2511*38fd1498Szrj 		 const gamma_distribution& __d2)
2512*38fd1498Szrj       { return (__d1._M_param == __d2._M_param
2513*38fd1498Szrj 		&& __d1._M_nd == __d2._M_nd); }
2514*38fd1498Szrj 
2515*38fd1498Szrj       /**
2516*38fd1498Szrj        * @brief Inserts a %gamma_distribution random number distribution
2517*38fd1498Szrj        * @p __x into the output stream @p __os.
2518*38fd1498Szrj        *
2519*38fd1498Szrj        * @param __os An output stream.
2520*38fd1498Szrj        * @param __x  A %gamma_distribution random number distribution.
2521*38fd1498Szrj        *
2522*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
2523*38fd1498Szrj        * an error state.
2524*38fd1498Szrj        */
2525*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
2526*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
2527*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2528*38fd1498Szrj 		   const std::gamma_distribution<_RealType1>& __x);
2529*38fd1498Szrj 
2530*38fd1498Szrj       /**
2531*38fd1498Szrj        * @brief Extracts a %gamma_distribution random number distribution
2532*38fd1498Szrj        * @p __x from the input stream @p __is.
2533*38fd1498Szrj        *
2534*38fd1498Szrj        * @param __is An input stream.
2535*38fd1498Szrj        * @param __x  A %gamma_distribution random number generator engine.
2536*38fd1498Szrj        *
2537*38fd1498Szrj        * @returns The input stream with @p __x extracted or in an error state.
2538*38fd1498Szrj        */
2539*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
2540*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
2541*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
2542*38fd1498Szrj 		   std::gamma_distribution<_RealType1>& __x);
2543*38fd1498Szrj 
2544*38fd1498Szrj     private:
2545*38fd1498Szrj       template<typename _ForwardIterator,
2546*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2547*38fd1498Szrj 	void
2548*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2549*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
2550*38fd1498Szrj 			const param_type& __p);
2551*38fd1498Szrj 
2552*38fd1498Szrj       param_type _M_param;
2553*38fd1498Szrj 
2554*38fd1498Szrj       std::normal_distribution<result_type> _M_nd;
2555*38fd1498Szrj     };
2556*38fd1498Szrj 
2557*38fd1498Szrj   /**
2558*38fd1498Szrj    * @brief Return true if two gamma distributions are different.
2559*38fd1498Szrj    */
2560*38fd1498Szrj    template<typename _RealType>
2561*38fd1498Szrj      inline bool
2562*38fd1498Szrj      operator!=(const std::gamma_distribution<_RealType>& __d1,
2563*38fd1498Szrj 		const std::gamma_distribution<_RealType>& __d2)
2564*38fd1498Szrj     { return !(__d1 == __d2); }
2565*38fd1498Szrj 
2566*38fd1498Szrj 
2567*38fd1498Szrj   /**
2568*38fd1498Szrj    * @brief A chi_squared_distribution random number distribution.
2569*38fd1498Szrj    *
2570*38fd1498Szrj    * The formula for the normal probability mass function is
2571*38fd1498Szrj    * @f$p(x|n) = \frac{x^{(n/2) - 1}e^{-x/2}}{\Gamma(n/2) 2^{n/2}}@f$
2572*38fd1498Szrj    */
2573*38fd1498Szrj   template<typename _RealType = double>
2574*38fd1498Szrj     class chi_squared_distribution
2575*38fd1498Szrj     {
2576*38fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
2577*38fd1498Szrj 		    "result_type must be a floating point type");
2578*38fd1498Szrj 
2579*38fd1498Szrj     public:
2580*38fd1498Szrj       /** The type of the range of the distribution. */
2581*38fd1498Szrj       typedef _RealType result_type;
2582*38fd1498Szrj 
2583*38fd1498Szrj       /** Parameter type. */
2584*38fd1498Szrj       struct param_type
2585*38fd1498Szrj       {
2586*38fd1498Szrj 	typedef chi_squared_distribution<_RealType> distribution_type;
2587*38fd1498Szrj 
2588*38fd1498Szrj 	explicit
2589*38fd1498Szrj 	param_type(_RealType __n = _RealType(1))
2590*38fd1498Szrj 	: _M_n(__n)
2591*38fd1498Szrj 	{ }
2592*38fd1498Szrj 
2593*38fd1498Szrj 	_RealType
2594*38fd1498Szrj 	n() const
2595*38fd1498Szrj 	{ return _M_n; }
2596*38fd1498Szrj 
2597*38fd1498Szrj 	friend bool
2598*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
2599*38fd1498Szrj 	{ return __p1._M_n == __p2._M_n; }
2600*38fd1498Szrj 
2601*38fd1498Szrj 	friend bool
2602*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
2603*38fd1498Szrj 	{ return !(__p1 == __p2); }
2604*38fd1498Szrj 
2605*38fd1498Szrj       private:
2606*38fd1498Szrj 	_RealType _M_n;
2607*38fd1498Szrj       };
2608*38fd1498Szrj 
2609*38fd1498Szrj       explicit
2610*38fd1498Szrj       chi_squared_distribution(_RealType __n = _RealType(1))
2611*38fd1498Szrj       : _M_param(__n), _M_gd(__n / 2)
2612*38fd1498Szrj       { }
2613*38fd1498Szrj 
2614*38fd1498Szrj       explicit
2615*38fd1498Szrj       chi_squared_distribution(const param_type& __p)
2616*38fd1498Szrj       : _M_param(__p), _M_gd(__p.n() / 2)
2617*38fd1498Szrj       { }
2618*38fd1498Szrj 
2619*38fd1498Szrj       /**
2620*38fd1498Szrj        * @brief Resets the distribution state.
2621*38fd1498Szrj        */
2622*38fd1498Szrj       void
2623*38fd1498Szrj       reset()
2624*38fd1498Szrj       { _M_gd.reset(); }
2625*38fd1498Szrj 
2626*38fd1498Szrj       /**
2627*38fd1498Szrj        *
2628*38fd1498Szrj        */
2629*38fd1498Szrj       _RealType
2630*38fd1498Szrj       n() const
2631*38fd1498Szrj       { return _M_param.n(); }
2632*38fd1498Szrj 
2633*38fd1498Szrj       /**
2634*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
2635*38fd1498Szrj        */
2636*38fd1498Szrj       param_type
2637*38fd1498Szrj       param() const
2638*38fd1498Szrj       { return _M_param; }
2639*38fd1498Szrj 
2640*38fd1498Szrj       /**
2641*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
2642*38fd1498Szrj        * @param __param The new parameter set of the distribution.
2643*38fd1498Szrj        */
2644*38fd1498Szrj       void
2645*38fd1498Szrj       param(const param_type& __param)
2646*38fd1498Szrj       {
2647*38fd1498Szrj 	_M_param = __param;
2648*38fd1498Szrj 	typedef typename std::gamma_distribution<result_type>::param_type
2649*38fd1498Szrj 	  param_type;
2650*38fd1498Szrj 	_M_gd.param(param_type{__param.n() / 2});
2651*38fd1498Szrj       }
2652*38fd1498Szrj 
2653*38fd1498Szrj       /**
2654*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
2655*38fd1498Szrj        */
2656*38fd1498Szrj       result_type
2657*38fd1498Szrj       min() const
2658*38fd1498Szrj       { return result_type(0); }
2659*38fd1498Szrj 
2660*38fd1498Szrj       /**
2661*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
2662*38fd1498Szrj        */
2663*38fd1498Szrj       result_type
2664*38fd1498Szrj       max() const
2665*38fd1498Szrj       { return std::numeric_limits<result_type>::max(); }
2666*38fd1498Szrj 
2667*38fd1498Szrj       /**
2668*38fd1498Szrj        * @brief Generating functions.
2669*38fd1498Szrj        */
2670*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2671*38fd1498Szrj 	result_type
2672*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
2673*38fd1498Szrj 	{ return 2 * _M_gd(__urng); }
2674*38fd1498Szrj 
2675*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2676*38fd1498Szrj 	result_type
2677*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
2678*38fd1498Szrj 		   const param_type& __p)
2679*38fd1498Szrj         {
2680*38fd1498Szrj 	  typedef typename std::gamma_distribution<result_type>::param_type
2681*38fd1498Szrj 	    param_type;
2682*38fd1498Szrj 	  return 2 * _M_gd(__urng, param_type(__p.n() / 2));
2683*38fd1498Szrj 	}
2684*38fd1498Szrj 
2685*38fd1498Szrj       template<typename _ForwardIterator,
2686*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2687*38fd1498Szrj 	void
2688*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
2689*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
2690*38fd1498Szrj         { this->__generate_impl(__f, __t, __urng); }
2691*38fd1498Szrj 
2692*38fd1498Szrj       template<typename _ForwardIterator,
2693*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2694*38fd1498Szrj 	void
2695*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
2696*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
2697*38fd1498Szrj 		   const param_type& __p)
2698*38fd1498Szrj 	{ typename std::gamma_distribution<result_type>::param_type
2699*38fd1498Szrj 	    __p2(__p.n() / 2);
2700*38fd1498Szrj 	  this->__generate_impl(__f, __t, __urng, __p2); }
2701*38fd1498Szrj 
2702*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2703*38fd1498Szrj 	void
2704*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
2705*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
2706*38fd1498Szrj         { this->__generate_impl(__f, __t, __urng); }
2707*38fd1498Szrj 
2708*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2709*38fd1498Szrj 	void
2710*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
2711*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
2712*38fd1498Szrj 		   const param_type& __p)
2713*38fd1498Szrj 	{ typename std::gamma_distribution<result_type>::param_type
2714*38fd1498Szrj 	    __p2(__p.n() / 2);
2715*38fd1498Szrj 	  this->__generate_impl(__f, __t, __urng, __p2); }
2716*38fd1498Szrj 
2717*38fd1498Szrj       /**
2718*38fd1498Szrj        * @brief Return true if two Chi-squared distributions have
2719*38fd1498Szrj        *        the same parameters and the sequences that would be
2720*38fd1498Szrj        *        generated are equal.
2721*38fd1498Szrj        */
2722*38fd1498Szrj       friend bool
2723*38fd1498Szrj       operator==(const chi_squared_distribution& __d1,
2724*38fd1498Szrj 		 const chi_squared_distribution& __d2)
2725*38fd1498Szrj       { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; }
2726*38fd1498Szrj 
2727*38fd1498Szrj       /**
2728*38fd1498Szrj        * @brief Inserts a %chi_squared_distribution random number distribution
2729*38fd1498Szrj        * @p __x into the output stream @p __os.
2730*38fd1498Szrj        *
2731*38fd1498Szrj        * @param __os An output stream.
2732*38fd1498Szrj        * @param __x  A %chi_squared_distribution random number distribution.
2733*38fd1498Szrj        *
2734*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
2735*38fd1498Szrj        * an error state.
2736*38fd1498Szrj        */
2737*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
2738*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
2739*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2740*38fd1498Szrj 		   const std::chi_squared_distribution<_RealType1>& __x);
2741*38fd1498Szrj 
2742*38fd1498Szrj       /**
2743*38fd1498Szrj        * @brief Extracts a %chi_squared_distribution random number distribution
2744*38fd1498Szrj        * @p __x from the input stream @p __is.
2745*38fd1498Szrj        *
2746*38fd1498Szrj        * @param __is An input stream.
2747*38fd1498Szrj        * @param __x A %chi_squared_distribution random number
2748*38fd1498Szrj        *            generator engine.
2749*38fd1498Szrj        *
2750*38fd1498Szrj        * @returns The input stream with @p __x extracted or in an error state.
2751*38fd1498Szrj        */
2752*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
2753*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
2754*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
2755*38fd1498Szrj 		   std::chi_squared_distribution<_RealType1>& __x);
2756*38fd1498Szrj 
2757*38fd1498Szrj     private:
2758*38fd1498Szrj       template<typename _ForwardIterator,
2759*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2760*38fd1498Szrj 	void
2761*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2762*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng);
2763*38fd1498Szrj 
2764*38fd1498Szrj       template<typename _ForwardIterator,
2765*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2766*38fd1498Szrj 	void
2767*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2768*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
2769*38fd1498Szrj 			const typename
2770*38fd1498Szrj 			std::gamma_distribution<result_type>::param_type& __p);
2771*38fd1498Szrj 
2772*38fd1498Szrj       param_type _M_param;
2773*38fd1498Szrj 
2774*38fd1498Szrj       std::gamma_distribution<result_type> _M_gd;
2775*38fd1498Szrj     };
2776*38fd1498Szrj 
2777*38fd1498Szrj   /**
2778*38fd1498Szrj    * @brief Return true if two Chi-squared distributions are different.
2779*38fd1498Szrj    */
2780*38fd1498Szrj   template<typename _RealType>
2781*38fd1498Szrj     inline bool
2782*38fd1498Szrj     operator!=(const std::chi_squared_distribution<_RealType>& __d1,
2783*38fd1498Szrj 	       const std::chi_squared_distribution<_RealType>& __d2)
2784*38fd1498Szrj     { return !(__d1 == __d2); }
2785*38fd1498Szrj 
2786*38fd1498Szrj 
2787*38fd1498Szrj   /**
2788*38fd1498Szrj    * @brief A cauchy_distribution random number distribution.
2789*38fd1498Szrj    *
2790*38fd1498Szrj    * The formula for the normal probability mass function is
2791*38fd1498Szrj    * @f$p(x|a,b) = (\pi b (1 + (\frac{x-a}{b})^2))^{-1}@f$
2792*38fd1498Szrj    */
2793*38fd1498Szrj   template<typename _RealType = double>
2794*38fd1498Szrj     class cauchy_distribution
2795*38fd1498Szrj     {
2796*38fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
2797*38fd1498Szrj 		    "result_type must be a floating point type");
2798*38fd1498Szrj 
2799*38fd1498Szrj     public:
2800*38fd1498Szrj       /** The type of the range of the distribution. */
2801*38fd1498Szrj       typedef _RealType result_type;
2802*38fd1498Szrj 
2803*38fd1498Szrj       /** Parameter type. */
2804*38fd1498Szrj       struct param_type
2805*38fd1498Szrj       {
2806*38fd1498Szrj 	typedef cauchy_distribution<_RealType> distribution_type;
2807*38fd1498Szrj 
2808*38fd1498Szrj 	explicit
2809*38fd1498Szrj 	param_type(_RealType __a = _RealType(0),
2810*38fd1498Szrj 		   _RealType __b = _RealType(1))
2811*38fd1498Szrj 	: _M_a(__a), _M_b(__b)
2812*38fd1498Szrj 	{ }
2813*38fd1498Szrj 
2814*38fd1498Szrj 	_RealType
2815*38fd1498Szrj 	a() const
2816*38fd1498Szrj 	{ return _M_a; }
2817*38fd1498Szrj 
2818*38fd1498Szrj 	_RealType
2819*38fd1498Szrj 	b() const
2820*38fd1498Szrj 	{ return _M_b; }
2821*38fd1498Szrj 
2822*38fd1498Szrj 	friend bool
2823*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
2824*38fd1498Szrj 	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
2825*38fd1498Szrj 
2826*38fd1498Szrj 	friend bool
2827*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
2828*38fd1498Szrj 	{ return !(__p1 == __p2); }
2829*38fd1498Szrj 
2830*38fd1498Szrj       private:
2831*38fd1498Szrj 	_RealType _M_a;
2832*38fd1498Szrj 	_RealType _M_b;
2833*38fd1498Szrj       };
2834*38fd1498Szrj 
2835*38fd1498Szrj       explicit
2836*38fd1498Szrj       cauchy_distribution(_RealType __a = _RealType(0),
2837*38fd1498Szrj 			  _RealType __b = _RealType(1))
2838*38fd1498Szrj       : _M_param(__a, __b)
2839*38fd1498Szrj       { }
2840*38fd1498Szrj 
2841*38fd1498Szrj       explicit
2842*38fd1498Szrj       cauchy_distribution(const param_type& __p)
2843*38fd1498Szrj       : _M_param(__p)
2844*38fd1498Szrj       { }
2845*38fd1498Szrj 
2846*38fd1498Szrj       /**
2847*38fd1498Szrj        * @brief Resets the distribution state.
2848*38fd1498Szrj        */
2849*38fd1498Szrj       void
2850*38fd1498Szrj       reset()
2851*38fd1498Szrj       { }
2852*38fd1498Szrj 
2853*38fd1498Szrj       /**
2854*38fd1498Szrj        *
2855*38fd1498Szrj        */
2856*38fd1498Szrj       _RealType
2857*38fd1498Szrj       a() const
2858*38fd1498Szrj       { return _M_param.a(); }
2859*38fd1498Szrj 
2860*38fd1498Szrj       _RealType
2861*38fd1498Szrj       b() const
2862*38fd1498Szrj       { return _M_param.b(); }
2863*38fd1498Szrj 
2864*38fd1498Szrj       /**
2865*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
2866*38fd1498Szrj        */
2867*38fd1498Szrj       param_type
2868*38fd1498Szrj       param() const
2869*38fd1498Szrj       { return _M_param; }
2870*38fd1498Szrj 
2871*38fd1498Szrj       /**
2872*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
2873*38fd1498Szrj        * @param __param The new parameter set of the distribution.
2874*38fd1498Szrj        */
2875*38fd1498Szrj       void
2876*38fd1498Szrj       param(const param_type& __param)
2877*38fd1498Szrj       { _M_param = __param; }
2878*38fd1498Szrj 
2879*38fd1498Szrj       /**
2880*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
2881*38fd1498Szrj        */
2882*38fd1498Szrj       result_type
2883*38fd1498Szrj       min() const
2884*38fd1498Szrj       { return std::numeric_limits<result_type>::lowest(); }
2885*38fd1498Szrj 
2886*38fd1498Szrj       /**
2887*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
2888*38fd1498Szrj        */
2889*38fd1498Szrj       result_type
2890*38fd1498Szrj       max() const
2891*38fd1498Szrj       { return std::numeric_limits<result_type>::max(); }
2892*38fd1498Szrj 
2893*38fd1498Szrj       /**
2894*38fd1498Szrj        * @brief Generating functions.
2895*38fd1498Szrj        */
2896*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2897*38fd1498Szrj 	result_type
2898*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
2899*38fd1498Szrj 	{ return this->operator()(__urng, _M_param); }
2900*38fd1498Szrj 
2901*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2902*38fd1498Szrj 	result_type
2903*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
2904*38fd1498Szrj 		   const param_type& __p);
2905*38fd1498Szrj 
2906*38fd1498Szrj       template<typename _ForwardIterator,
2907*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2908*38fd1498Szrj 	void
2909*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
2910*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
2911*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
2912*38fd1498Szrj 
2913*38fd1498Szrj       template<typename _ForwardIterator,
2914*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2915*38fd1498Szrj 	void
2916*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
2917*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
2918*38fd1498Szrj 		   const param_type& __p)
2919*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
2920*38fd1498Szrj 
2921*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
2922*38fd1498Szrj 	void
2923*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
2924*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
2925*38fd1498Szrj 		   const param_type& __p)
2926*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
2927*38fd1498Szrj 
2928*38fd1498Szrj       /**
2929*38fd1498Szrj        * @brief Return true if two Cauchy distributions have
2930*38fd1498Szrj        *        the same parameters.
2931*38fd1498Szrj        */
2932*38fd1498Szrj       friend bool
2933*38fd1498Szrj       operator==(const cauchy_distribution& __d1,
2934*38fd1498Szrj 		 const cauchy_distribution& __d2)
2935*38fd1498Szrj       { return __d1._M_param == __d2._M_param; }
2936*38fd1498Szrj 
2937*38fd1498Szrj     private:
2938*38fd1498Szrj       template<typename _ForwardIterator,
2939*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
2940*38fd1498Szrj 	void
2941*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2942*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
2943*38fd1498Szrj 			const param_type& __p);
2944*38fd1498Szrj 
2945*38fd1498Szrj       param_type _M_param;
2946*38fd1498Szrj     };
2947*38fd1498Szrj 
2948*38fd1498Szrj   /**
2949*38fd1498Szrj    * @brief Return true if two Cauchy distributions have
2950*38fd1498Szrj    *        different parameters.
2951*38fd1498Szrj    */
2952*38fd1498Szrj   template<typename _RealType>
2953*38fd1498Szrj     inline bool
2954*38fd1498Szrj     operator!=(const std::cauchy_distribution<_RealType>& __d1,
2955*38fd1498Szrj 	       const std::cauchy_distribution<_RealType>& __d2)
2956*38fd1498Szrj     { return !(__d1 == __d2); }
2957*38fd1498Szrj 
2958*38fd1498Szrj   /**
2959*38fd1498Szrj    * @brief Inserts a %cauchy_distribution random number distribution
2960*38fd1498Szrj    * @p __x into the output stream @p __os.
2961*38fd1498Szrj    *
2962*38fd1498Szrj    * @param __os An output stream.
2963*38fd1498Szrj    * @param __x  A %cauchy_distribution random number distribution.
2964*38fd1498Szrj    *
2965*38fd1498Szrj    * @returns The output stream with the state of @p __x inserted or in
2966*38fd1498Szrj    * an error state.
2967*38fd1498Szrj    */
2968*38fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
2969*38fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
2970*38fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2971*38fd1498Szrj 	       const std::cauchy_distribution<_RealType>& __x);
2972*38fd1498Szrj 
2973*38fd1498Szrj   /**
2974*38fd1498Szrj    * @brief Extracts a %cauchy_distribution random number distribution
2975*38fd1498Szrj    * @p __x from the input stream @p __is.
2976*38fd1498Szrj    *
2977*38fd1498Szrj    * @param __is An input stream.
2978*38fd1498Szrj    * @param __x A %cauchy_distribution random number
2979*38fd1498Szrj    *            generator engine.
2980*38fd1498Szrj    *
2981*38fd1498Szrj    * @returns The input stream with @p __x extracted or in an error state.
2982*38fd1498Szrj    */
2983*38fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
2984*38fd1498Szrj     std::basic_istream<_CharT, _Traits>&
2985*38fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
2986*38fd1498Szrj 	       std::cauchy_distribution<_RealType>& __x);
2987*38fd1498Szrj 
2988*38fd1498Szrj 
2989*38fd1498Szrj   /**
2990*38fd1498Szrj    * @brief A fisher_f_distribution random number distribution.
2991*38fd1498Szrj    *
2992*38fd1498Szrj    * The formula for the normal probability mass function is
2993*38fd1498Szrj    * @f[
2994*38fd1498Szrj    *     p(x|m,n) = \frac{\Gamma((m+n)/2)}{\Gamma(m/2)\Gamma(n/2)}
2995*38fd1498Szrj    *                (\frac{m}{n})^{m/2} x^{(m/2)-1}
2996*38fd1498Szrj    *                (1 + \frac{mx}{n})^{-(m+n)/2}
2997*38fd1498Szrj    * @f]
2998*38fd1498Szrj    */
2999*38fd1498Szrj   template<typename _RealType = double>
3000*38fd1498Szrj     class fisher_f_distribution
3001*38fd1498Szrj     {
3002*38fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
3003*38fd1498Szrj 		    "result_type must be a floating point type");
3004*38fd1498Szrj 
3005*38fd1498Szrj     public:
3006*38fd1498Szrj       /** The type of the range of the distribution. */
3007*38fd1498Szrj       typedef _RealType result_type;
3008*38fd1498Szrj 
3009*38fd1498Szrj       /** Parameter type. */
3010*38fd1498Szrj       struct param_type
3011*38fd1498Szrj       {
3012*38fd1498Szrj 	typedef fisher_f_distribution<_RealType> distribution_type;
3013*38fd1498Szrj 
3014*38fd1498Szrj 	explicit
3015*38fd1498Szrj 	param_type(_RealType __m = _RealType(1),
3016*38fd1498Szrj 		   _RealType __n = _RealType(1))
3017*38fd1498Szrj 	: _M_m(__m), _M_n(__n)
3018*38fd1498Szrj 	{ }
3019*38fd1498Szrj 
3020*38fd1498Szrj 	_RealType
3021*38fd1498Szrj 	m() const
3022*38fd1498Szrj 	{ return _M_m; }
3023*38fd1498Szrj 
3024*38fd1498Szrj 	_RealType
3025*38fd1498Szrj 	n() const
3026*38fd1498Szrj 	{ return _M_n; }
3027*38fd1498Szrj 
3028*38fd1498Szrj 	friend bool
3029*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
3030*38fd1498Szrj 	{ return __p1._M_m == __p2._M_m && __p1._M_n == __p2._M_n; }
3031*38fd1498Szrj 
3032*38fd1498Szrj 	friend bool
3033*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
3034*38fd1498Szrj 	{ return !(__p1 == __p2); }
3035*38fd1498Szrj 
3036*38fd1498Szrj       private:
3037*38fd1498Szrj 	_RealType _M_m;
3038*38fd1498Szrj 	_RealType _M_n;
3039*38fd1498Szrj       };
3040*38fd1498Szrj 
3041*38fd1498Szrj       explicit
3042*38fd1498Szrj       fisher_f_distribution(_RealType __m = _RealType(1),
3043*38fd1498Szrj 			    _RealType __n = _RealType(1))
3044*38fd1498Szrj       : _M_param(__m, __n), _M_gd_x(__m / 2), _M_gd_y(__n / 2)
3045*38fd1498Szrj       { }
3046*38fd1498Szrj 
3047*38fd1498Szrj       explicit
3048*38fd1498Szrj       fisher_f_distribution(const param_type& __p)
3049*38fd1498Szrj       : _M_param(__p), _M_gd_x(__p.m() / 2), _M_gd_y(__p.n() / 2)
3050*38fd1498Szrj       { }
3051*38fd1498Szrj 
3052*38fd1498Szrj       /**
3053*38fd1498Szrj        * @brief Resets the distribution state.
3054*38fd1498Szrj        */
3055*38fd1498Szrj       void
3056*38fd1498Szrj       reset()
3057*38fd1498Szrj       {
3058*38fd1498Szrj 	_M_gd_x.reset();
3059*38fd1498Szrj 	_M_gd_y.reset();
3060*38fd1498Szrj       }
3061*38fd1498Szrj 
3062*38fd1498Szrj       /**
3063*38fd1498Szrj        *
3064*38fd1498Szrj        */
3065*38fd1498Szrj       _RealType
3066*38fd1498Szrj       m() const
3067*38fd1498Szrj       { return _M_param.m(); }
3068*38fd1498Szrj 
3069*38fd1498Szrj       _RealType
3070*38fd1498Szrj       n() const
3071*38fd1498Szrj       { return _M_param.n(); }
3072*38fd1498Szrj 
3073*38fd1498Szrj       /**
3074*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
3075*38fd1498Szrj        */
3076*38fd1498Szrj       param_type
3077*38fd1498Szrj       param() const
3078*38fd1498Szrj       { return _M_param; }
3079*38fd1498Szrj 
3080*38fd1498Szrj       /**
3081*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
3082*38fd1498Szrj        * @param __param The new parameter set of the distribution.
3083*38fd1498Szrj        */
3084*38fd1498Szrj       void
3085*38fd1498Szrj       param(const param_type& __param)
3086*38fd1498Szrj       { _M_param = __param; }
3087*38fd1498Szrj 
3088*38fd1498Szrj       /**
3089*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
3090*38fd1498Szrj        */
3091*38fd1498Szrj       result_type
3092*38fd1498Szrj       min() const
3093*38fd1498Szrj       { return result_type(0); }
3094*38fd1498Szrj 
3095*38fd1498Szrj       /**
3096*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
3097*38fd1498Szrj        */
3098*38fd1498Szrj       result_type
3099*38fd1498Szrj       max() const
3100*38fd1498Szrj       { return std::numeric_limits<result_type>::max(); }
3101*38fd1498Szrj 
3102*38fd1498Szrj       /**
3103*38fd1498Szrj        * @brief Generating functions.
3104*38fd1498Szrj        */
3105*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
3106*38fd1498Szrj 	result_type
3107*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
3108*38fd1498Szrj 	{ return (_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()); }
3109*38fd1498Szrj 
3110*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
3111*38fd1498Szrj 	result_type
3112*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
3113*38fd1498Szrj 		   const param_type& __p)
3114*38fd1498Szrj         {
3115*38fd1498Szrj 	  typedef typename std::gamma_distribution<result_type>::param_type
3116*38fd1498Szrj 	    param_type;
3117*38fd1498Szrj 	  return ((_M_gd_x(__urng, param_type(__p.m() / 2)) * n())
3118*38fd1498Szrj 		  / (_M_gd_y(__urng, param_type(__p.n() / 2)) * m()));
3119*38fd1498Szrj 	}
3120*38fd1498Szrj 
3121*38fd1498Szrj       template<typename _ForwardIterator,
3122*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
3123*38fd1498Szrj 	void
3124*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
3125*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
3126*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng); }
3127*38fd1498Szrj 
3128*38fd1498Szrj       template<typename _ForwardIterator,
3129*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
3130*38fd1498Szrj 	void
3131*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
3132*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
3133*38fd1498Szrj 		   const param_type& __p)
3134*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
3135*38fd1498Szrj 
3136*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
3137*38fd1498Szrj 	void
3138*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
3139*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
3140*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng); }
3141*38fd1498Szrj 
3142*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
3143*38fd1498Szrj 	void
3144*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
3145*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
3146*38fd1498Szrj 		   const param_type& __p)
3147*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
3148*38fd1498Szrj 
3149*38fd1498Szrj       /**
3150*38fd1498Szrj        * @brief Return true if two Fisher f distributions have
3151*38fd1498Szrj        *        the same parameters and the sequences that would
3152*38fd1498Szrj        *        be generated are equal.
3153*38fd1498Szrj        */
3154*38fd1498Szrj       friend bool
3155*38fd1498Szrj       operator==(const fisher_f_distribution& __d1,
3156*38fd1498Szrj 		 const fisher_f_distribution& __d2)
3157*38fd1498Szrj       { return (__d1._M_param == __d2._M_param
3158*38fd1498Szrj 		&& __d1._M_gd_x == __d2._M_gd_x
3159*38fd1498Szrj 		&& __d1._M_gd_y == __d2._M_gd_y); }
3160*38fd1498Szrj 
3161*38fd1498Szrj       /**
3162*38fd1498Szrj        * @brief Inserts a %fisher_f_distribution random number distribution
3163*38fd1498Szrj        * @p __x into the output stream @p __os.
3164*38fd1498Szrj        *
3165*38fd1498Szrj        * @param __os An output stream.
3166*38fd1498Szrj        * @param __x  A %fisher_f_distribution random number distribution.
3167*38fd1498Szrj        *
3168*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
3169*38fd1498Szrj        * an error state.
3170*38fd1498Szrj        */
3171*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
3172*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
3173*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3174*38fd1498Szrj 		   const std::fisher_f_distribution<_RealType1>& __x);
3175*38fd1498Szrj 
3176*38fd1498Szrj       /**
3177*38fd1498Szrj        * @brief Extracts a %fisher_f_distribution random number distribution
3178*38fd1498Szrj        * @p __x from the input stream @p __is.
3179*38fd1498Szrj        *
3180*38fd1498Szrj        * @param __is An input stream.
3181*38fd1498Szrj        * @param __x A %fisher_f_distribution random number
3182*38fd1498Szrj        *            generator engine.
3183*38fd1498Szrj        *
3184*38fd1498Szrj        * @returns The input stream with @p __x extracted or in an error state.
3185*38fd1498Szrj        */
3186*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
3187*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
3188*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
3189*38fd1498Szrj 		   std::fisher_f_distribution<_RealType1>& __x);
3190*38fd1498Szrj 
3191*38fd1498Szrj     private:
3192*38fd1498Szrj       template<typename _ForwardIterator,
3193*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
3194*38fd1498Szrj 	void
3195*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3196*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng);
3197*38fd1498Szrj 
3198*38fd1498Szrj       template<typename _ForwardIterator,
3199*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
3200*38fd1498Szrj 	void
3201*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3202*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
3203*38fd1498Szrj 			const param_type& __p);
3204*38fd1498Szrj 
3205*38fd1498Szrj       param_type _M_param;
3206*38fd1498Szrj 
3207*38fd1498Szrj       std::gamma_distribution<result_type> _M_gd_x, _M_gd_y;
3208*38fd1498Szrj     };
3209*38fd1498Szrj 
3210*38fd1498Szrj   /**
3211*38fd1498Szrj    * @brief Return true if two Fisher f distributions are different.
3212*38fd1498Szrj    */
3213*38fd1498Szrj   template<typename _RealType>
3214*38fd1498Szrj     inline bool
3215*38fd1498Szrj     operator!=(const std::fisher_f_distribution<_RealType>& __d1,
3216*38fd1498Szrj 	       const std::fisher_f_distribution<_RealType>& __d2)
3217*38fd1498Szrj     { return !(__d1 == __d2); }
3218*38fd1498Szrj 
3219*38fd1498Szrj   /**
3220*38fd1498Szrj    * @brief A student_t_distribution random number distribution.
3221*38fd1498Szrj    *
3222*38fd1498Szrj    * The formula for the normal probability mass function is:
3223*38fd1498Szrj    * @f[
3224*38fd1498Szrj    *     p(x|n) = \frac{1}{\sqrt(n\pi)} \frac{\Gamma((n+1)/2)}{\Gamma(n/2)}
3225*38fd1498Szrj    *              (1 + \frac{x^2}{n}) ^{-(n+1)/2}
3226*38fd1498Szrj    * @f]
3227*38fd1498Szrj    */
3228*38fd1498Szrj   template<typename _RealType = double>
3229*38fd1498Szrj     class student_t_distribution
3230*38fd1498Szrj     {
3231*38fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
3232*38fd1498Szrj 		    "result_type must be a floating point type");
3233*38fd1498Szrj 
3234*38fd1498Szrj     public:
3235*38fd1498Szrj       /** The type of the range of the distribution. */
3236*38fd1498Szrj       typedef _RealType result_type;
3237*38fd1498Szrj 
3238*38fd1498Szrj       /** Parameter type. */
3239*38fd1498Szrj       struct param_type
3240*38fd1498Szrj       {
3241*38fd1498Szrj 	typedef student_t_distribution<_RealType> distribution_type;
3242*38fd1498Szrj 
3243*38fd1498Szrj 	explicit
3244*38fd1498Szrj 	param_type(_RealType __n = _RealType(1))
3245*38fd1498Szrj 	: _M_n(__n)
3246*38fd1498Szrj 	{ }
3247*38fd1498Szrj 
3248*38fd1498Szrj 	_RealType
3249*38fd1498Szrj 	n() const
3250*38fd1498Szrj 	{ return _M_n; }
3251*38fd1498Szrj 
3252*38fd1498Szrj 	friend bool
3253*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
3254*38fd1498Szrj 	{ return __p1._M_n == __p2._M_n; }
3255*38fd1498Szrj 
3256*38fd1498Szrj 	friend bool
3257*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
3258*38fd1498Szrj 	{ return !(__p1 == __p2); }
3259*38fd1498Szrj 
3260*38fd1498Szrj       private:
3261*38fd1498Szrj 	_RealType _M_n;
3262*38fd1498Szrj       };
3263*38fd1498Szrj 
3264*38fd1498Szrj       explicit
3265*38fd1498Szrj       student_t_distribution(_RealType __n = _RealType(1))
3266*38fd1498Szrj       : _M_param(__n), _M_nd(), _M_gd(__n / 2, 2)
3267*38fd1498Szrj       { }
3268*38fd1498Szrj 
3269*38fd1498Szrj       explicit
3270*38fd1498Szrj       student_t_distribution(const param_type& __p)
3271*38fd1498Szrj       : _M_param(__p), _M_nd(), _M_gd(__p.n() / 2, 2)
3272*38fd1498Szrj       { }
3273*38fd1498Szrj 
3274*38fd1498Szrj       /**
3275*38fd1498Szrj        * @brief Resets the distribution state.
3276*38fd1498Szrj        */
3277*38fd1498Szrj       void
3278*38fd1498Szrj       reset()
3279*38fd1498Szrj       {
3280*38fd1498Szrj 	_M_nd.reset();
3281*38fd1498Szrj 	_M_gd.reset();
3282*38fd1498Szrj       }
3283*38fd1498Szrj 
3284*38fd1498Szrj       /**
3285*38fd1498Szrj        *
3286*38fd1498Szrj        */
3287*38fd1498Szrj       _RealType
3288*38fd1498Szrj       n() const
3289*38fd1498Szrj       { return _M_param.n(); }
3290*38fd1498Szrj 
3291*38fd1498Szrj       /**
3292*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
3293*38fd1498Szrj        */
3294*38fd1498Szrj       param_type
3295*38fd1498Szrj       param() const
3296*38fd1498Szrj       { return _M_param; }
3297*38fd1498Szrj 
3298*38fd1498Szrj       /**
3299*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
3300*38fd1498Szrj        * @param __param The new parameter set of the distribution.
3301*38fd1498Szrj        */
3302*38fd1498Szrj       void
3303*38fd1498Szrj       param(const param_type& __param)
3304*38fd1498Szrj       { _M_param = __param; }
3305*38fd1498Szrj 
3306*38fd1498Szrj       /**
3307*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
3308*38fd1498Szrj        */
3309*38fd1498Szrj       result_type
3310*38fd1498Szrj       min() const
3311*38fd1498Szrj       { return std::numeric_limits<result_type>::lowest(); }
3312*38fd1498Szrj 
3313*38fd1498Szrj       /**
3314*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
3315*38fd1498Szrj        */
3316*38fd1498Szrj       result_type
3317*38fd1498Szrj       max() const
3318*38fd1498Szrj       { return std::numeric_limits<result_type>::max(); }
3319*38fd1498Szrj 
3320*38fd1498Szrj       /**
3321*38fd1498Szrj        * @brief Generating functions.
3322*38fd1498Szrj        */
3323*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
3324*38fd1498Szrj 	result_type
3325*38fd1498Szrj         operator()(_UniformRandomNumberGenerator& __urng)
3326*38fd1498Szrj         { return _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); }
3327*38fd1498Szrj 
3328*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
3329*38fd1498Szrj 	result_type
3330*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
3331*38fd1498Szrj 		   const param_type& __p)
3332*38fd1498Szrj         {
3333*38fd1498Szrj 	  typedef typename std::gamma_distribution<result_type>::param_type
3334*38fd1498Szrj 	    param_type;
3335*38fd1498Szrj 
3336*38fd1498Szrj 	  const result_type __g = _M_gd(__urng, param_type(__p.n() / 2, 2));
3337*38fd1498Szrj 	  return _M_nd(__urng) * std::sqrt(__p.n() / __g);
3338*38fd1498Szrj         }
3339*38fd1498Szrj 
3340*38fd1498Szrj       template<typename _ForwardIterator,
3341*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
3342*38fd1498Szrj 	void
3343*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
3344*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
3345*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng); }
3346*38fd1498Szrj 
3347*38fd1498Szrj       template<typename _ForwardIterator,
3348*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
3349*38fd1498Szrj 	void
3350*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
3351*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
3352*38fd1498Szrj 		   const param_type& __p)
3353*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
3354*38fd1498Szrj 
3355*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
3356*38fd1498Szrj 	void
3357*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
3358*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
3359*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng); }
3360*38fd1498Szrj 
3361*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
3362*38fd1498Szrj 	void
3363*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
3364*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
3365*38fd1498Szrj 		   const param_type& __p)
3366*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
3367*38fd1498Szrj 
3368*38fd1498Szrj       /**
3369*38fd1498Szrj        * @brief Return true if two Student t distributions have
3370*38fd1498Szrj        *        the same parameters and the sequences that would
3371*38fd1498Szrj        *        be generated are equal.
3372*38fd1498Szrj        */
3373*38fd1498Szrj       friend bool
3374*38fd1498Szrj       operator==(const student_t_distribution& __d1,
3375*38fd1498Szrj 		 const student_t_distribution& __d2)
3376*38fd1498Szrj       { return (__d1._M_param == __d2._M_param
3377*38fd1498Szrj 		&& __d1._M_nd == __d2._M_nd && __d1._M_gd == __d2._M_gd); }
3378*38fd1498Szrj 
3379*38fd1498Szrj       /**
3380*38fd1498Szrj        * @brief Inserts a %student_t_distribution random number distribution
3381*38fd1498Szrj        * @p __x into the output stream @p __os.
3382*38fd1498Szrj        *
3383*38fd1498Szrj        * @param __os An output stream.
3384*38fd1498Szrj        * @param __x  A %student_t_distribution random number distribution.
3385*38fd1498Szrj        *
3386*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
3387*38fd1498Szrj        * an error state.
3388*38fd1498Szrj        */
3389*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
3390*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
3391*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3392*38fd1498Szrj 		   const std::student_t_distribution<_RealType1>& __x);
3393*38fd1498Szrj 
3394*38fd1498Szrj       /**
3395*38fd1498Szrj        * @brief Extracts a %student_t_distribution random number distribution
3396*38fd1498Szrj        * @p __x from the input stream @p __is.
3397*38fd1498Szrj        *
3398*38fd1498Szrj        * @param __is An input stream.
3399*38fd1498Szrj        * @param __x A %student_t_distribution random number
3400*38fd1498Szrj        *            generator engine.
3401*38fd1498Szrj        *
3402*38fd1498Szrj        * @returns The input stream with @p __x extracted or in an error state.
3403*38fd1498Szrj        */
3404*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
3405*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
3406*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
3407*38fd1498Szrj 		   std::student_t_distribution<_RealType1>& __x);
3408*38fd1498Szrj 
3409*38fd1498Szrj     private:
3410*38fd1498Szrj       template<typename _ForwardIterator,
3411*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
3412*38fd1498Szrj 	void
3413*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3414*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng);
3415*38fd1498Szrj       template<typename _ForwardIterator,
3416*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
3417*38fd1498Szrj 	void
3418*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3419*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
3420*38fd1498Szrj 			const param_type& __p);
3421*38fd1498Szrj 
3422*38fd1498Szrj       param_type _M_param;
3423*38fd1498Szrj 
3424*38fd1498Szrj       std::normal_distribution<result_type> _M_nd;
3425*38fd1498Szrj       std::gamma_distribution<result_type> _M_gd;
3426*38fd1498Szrj     };
3427*38fd1498Szrj 
3428*38fd1498Szrj   /**
3429*38fd1498Szrj    * @brief Return true if two Student t distributions are different.
3430*38fd1498Szrj    */
3431*38fd1498Szrj   template<typename _RealType>
3432*38fd1498Szrj     inline bool
3433*38fd1498Szrj     operator!=(const std::student_t_distribution<_RealType>& __d1,
3434*38fd1498Szrj 	       const std::student_t_distribution<_RealType>& __d2)
3435*38fd1498Szrj     { return !(__d1 == __d2); }
3436*38fd1498Szrj 
3437*38fd1498Szrj 
3438*38fd1498Szrj   /* @} */ // group random_distributions_normal
3439*38fd1498Szrj 
3440*38fd1498Szrj   /**
3441*38fd1498Szrj    * @addtogroup random_distributions_bernoulli Bernoulli Distributions
3442*38fd1498Szrj    * @ingroup random_distributions
3443*38fd1498Szrj    * @{
3444*38fd1498Szrj    */
3445*38fd1498Szrj 
3446*38fd1498Szrj   /**
3447*38fd1498Szrj    * @brief A Bernoulli random number distribution.
3448*38fd1498Szrj    *
3449*38fd1498Szrj    * Generates a sequence of true and false values with likelihood @f$p@f$
3450*38fd1498Szrj    * that true will come up and @f$(1 - p)@f$ that false will appear.
3451*38fd1498Szrj    */
3452*38fd1498Szrj   class bernoulli_distribution
3453*38fd1498Szrj   {
3454*38fd1498Szrj   public:
3455*38fd1498Szrj     /** The type of the range of the distribution. */
3456*38fd1498Szrj     typedef bool result_type;
3457*38fd1498Szrj 
3458*38fd1498Szrj     /** Parameter type. */
3459*38fd1498Szrj     struct param_type
3460*38fd1498Szrj     {
3461*38fd1498Szrj       typedef bernoulli_distribution distribution_type;
3462*38fd1498Szrj 
3463*38fd1498Szrj       explicit
3464*38fd1498Szrj       param_type(double __p = 0.5)
3465*38fd1498Szrj       : _M_p(__p)
3466*38fd1498Szrj       {
3467*38fd1498Szrj 	__glibcxx_assert((_M_p >= 0.0) && (_M_p <= 1.0));
3468*38fd1498Szrj       }
3469*38fd1498Szrj 
3470*38fd1498Szrj       double
3471*38fd1498Szrj       p() const
3472*38fd1498Szrj       { return _M_p; }
3473*38fd1498Szrj 
3474*38fd1498Szrj       friend bool
3475*38fd1498Szrj       operator==(const param_type& __p1, const param_type& __p2)
3476*38fd1498Szrj       { return __p1._M_p == __p2._M_p; }
3477*38fd1498Szrj 
3478*38fd1498Szrj       friend bool
3479*38fd1498Szrj       operator!=(const param_type& __p1, const param_type& __p2)
3480*38fd1498Szrj       { return !(__p1 == __p2); }
3481*38fd1498Szrj 
3482*38fd1498Szrj     private:
3483*38fd1498Szrj       double _M_p;
3484*38fd1498Szrj     };
3485*38fd1498Szrj 
3486*38fd1498Szrj   public:
3487*38fd1498Szrj     /**
3488*38fd1498Szrj      * @brief Constructs a Bernoulli distribution with likelihood @p p.
3489*38fd1498Szrj      *
3490*38fd1498Szrj      * @param __p  [IN]  The likelihood of a true result being returned.
3491*38fd1498Szrj      *                   Must be in the interval @f$[0, 1]@f$.
3492*38fd1498Szrj      */
3493*38fd1498Szrj     explicit
3494*38fd1498Szrj     bernoulli_distribution(double __p = 0.5)
3495*38fd1498Szrj     : _M_param(__p)
3496*38fd1498Szrj     { }
3497*38fd1498Szrj 
3498*38fd1498Szrj     explicit
3499*38fd1498Szrj     bernoulli_distribution(const param_type& __p)
3500*38fd1498Szrj     : _M_param(__p)
3501*38fd1498Szrj     { }
3502*38fd1498Szrj 
3503*38fd1498Szrj     /**
3504*38fd1498Szrj      * @brief Resets the distribution state.
3505*38fd1498Szrj      *
3506*38fd1498Szrj      * Does nothing for a Bernoulli distribution.
3507*38fd1498Szrj      */
3508*38fd1498Szrj     void
3509*38fd1498Szrj     reset() { }
3510*38fd1498Szrj 
3511*38fd1498Szrj     /**
3512*38fd1498Szrj      * @brief Returns the @p p parameter of the distribution.
3513*38fd1498Szrj      */
3514*38fd1498Szrj     double
3515*38fd1498Szrj     p() const
3516*38fd1498Szrj     { return _M_param.p(); }
3517*38fd1498Szrj 
3518*38fd1498Szrj     /**
3519*38fd1498Szrj      * @brief Returns the parameter set of the distribution.
3520*38fd1498Szrj      */
3521*38fd1498Szrj     param_type
3522*38fd1498Szrj     param() const
3523*38fd1498Szrj     { return _M_param; }
3524*38fd1498Szrj 
3525*38fd1498Szrj     /**
3526*38fd1498Szrj      * @brief Sets the parameter set of the distribution.
3527*38fd1498Szrj      * @param __param The new parameter set of the distribution.
3528*38fd1498Szrj      */
3529*38fd1498Szrj     void
3530*38fd1498Szrj     param(const param_type& __param)
3531*38fd1498Szrj     { _M_param = __param; }
3532*38fd1498Szrj 
3533*38fd1498Szrj     /**
3534*38fd1498Szrj      * @brief Returns the greatest lower bound value of the distribution.
3535*38fd1498Szrj      */
3536*38fd1498Szrj     result_type
3537*38fd1498Szrj     min() const
3538*38fd1498Szrj     { return std::numeric_limits<result_type>::min(); }
3539*38fd1498Szrj 
3540*38fd1498Szrj     /**
3541*38fd1498Szrj      * @brief Returns the least upper bound value of the distribution.
3542*38fd1498Szrj      */
3543*38fd1498Szrj     result_type
3544*38fd1498Szrj     max() const
3545*38fd1498Szrj     { return std::numeric_limits<result_type>::max(); }
3546*38fd1498Szrj 
3547*38fd1498Szrj     /**
3548*38fd1498Szrj      * @brief Generating functions.
3549*38fd1498Szrj      */
3550*38fd1498Szrj     template<typename _UniformRandomNumberGenerator>
3551*38fd1498Szrj       result_type
3552*38fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng)
3553*38fd1498Szrj       { return this->operator()(__urng, _M_param); }
3554*38fd1498Szrj 
3555*38fd1498Szrj     template<typename _UniformRandomNumberGenerator>
3556*38fd1498Szrj       result_type
3557*38fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng,
3558*38fd1498Szrj 		 const param_type& __p)
3559*38fd1498Szrj       {
3560*38fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
3561*38fd1498Szrj 	  __aurng(__urng);
3562*38fd1498Szrj 	if ((__aurng() - __aurng.min())
3563*38fd1498Szrj 	     < __p.p() * (__aurng.max() - __aurng.min()))
3564*38fd1498Szrj 	  return true;
3565*38fd1498Szrj 	return false;
3566*38fd1498Szrj       }
3567*38fd1498Szrj 
3568*38fd1498Szrj     template<typename _ForwardIterator,
3569*38fd1498Szrj 	     typename _UniformRandomNumberGenerator>
3570*38fd1498Szrj       void
3571*38fd1498Szrj       __generate(_ForwardIterator __f, _ForwardIterator __t,
3572*38fd1498Szrj 		 _UniformRandomNumberGenerator& __urng)
3573*38fd1498Szrj       { this->__generate(__f, __t, __urng, _M_param); }
3574*38fd1498Szrj 
3575*38fd1498Szrj     template<typename _ForwardIterator,
3576*38fd1498Szrj 	     typename _UniformRandomNumberGenerator>
3577*38fd1498Szrj       void
3578*38fd1498Szrj       __generate(_ForwardIterator __f, _ForwardIterator __t,
3579*38fd1498Szrj 		 _UniformRandomNumberGenerator& __urng, const param_type& __p)
3580*38fd1498Szrj       { this->__generate_impl(__f, __t, __urng, __p); }
3581*38fd1498Szrj 
3582*38fd1498Szrj     template<typename _UniformRandomNumberGenerator>
3583*38fd1498Szrj       void
3584*38fd1498Szrj       __generate(result_type* __f, result_type* __t,
3585*38fd1498Szrj 		 _UniformRandomNumberGenerator& __urng,
3586*38fd1498Szrj 		 const param_type& __p)
3587*38fd1498Szrj       { this->__generate_impl(__f, __t, __urng, __p); }
3588*38fd1498Szrj 
3589*38fd1498Szrj     /**
3590*38fd1498Szrj      * @brief Return true if two Bernoulli distributions have
3591*38fd1498Szrj      *        the same parameters.
3592*38fd1498Szrj      */
3593*38fd1498Szrj     friend bool
3594*38fd1498Szrj     operator==(const bernoulli_distribution& __d1,
3595*38fd1498Szrj 	       const bernoulli_distribution& __d2)
3596*38fd1498Szrj     { return __d1._M_param == __d2._M_param; }
3597*38fd1498Szrj 
3598*38fd1498Szrj   private:
3599*38fd1498Szrj     template<typename _ForwardIterator,
3600*38fd1498Szrj 	     typename _UniformRandomNumberGenerator>
3601*38fd1498Szrj       void
3602*38fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3603*38fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
3604*38fd1498Szrj 		      const param_type& __p);
3605*38fd1498Szrj 
3606*38fd1498Szrj     param_type _M_param;
3607*38fd1498Szrj   };
3608*38fd1498Szrj 
3609*38fd1498Szrj   /**
3610*38fd1498Szrj    * @brief Return true if two Bernoulli distributions have
3611*38fd1498Szrj    *        different parameters.
3612*38fd1498Szrj    */
3613*38fd1498Szrj   inline bool
3614*38fd1498Szrj   operator!=(const std::bernoulli_distribution& __d1,
3615*38fd1498Szrj 	     const std::bernoulli_distribution& __d2)
3616*38fd1498Szrj   { return !(__d1 == __d2); }
3617*38fd1498Szrj 
3618*38fd1498Szrj   /**
3619*38fd1498Szrj    * @brief Inserts a %bernoulli_distribution random number distribution
3620*38fd1498Szrj    * @p __x into the output stream @p __os.
3621*38fd1498Szrj    *
3622*38fd1498Szrj    * @param __os An output stream.
3623*38fd1498Szrj    * @param __x  A %bernoulli_distribution random number distribution.
3624*38fd1498Szrj    *
3625*38fd1498Szrj    * @returns The output stream with the state of @p __x inserted or in
3626*38fd1498Szrj    * an error state.
3627*38fd1498Szrj    */
3628*38fd1498Szrj   template<typename _CharT, typename _Traits>
3629*38fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
3630*38fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3631*38fd1498Szrj 	       const std::bernoulli_distribution& __x);
3632*38fd1498Szrj 
3633*38fd1498Szrj   /**
3634*38fd1498Szrj    * @brief Extracts a %bernoulli_distribution random number distribution
3635*38fd1498Szrj    * @p __x from the input stream @p __is.
3636*38fd1498Szrj    *
3637*38fd1498Szrj    * @param __is An input stream.
3638*38fd1498Szrj    * @param __x  A %bernoulli_distribution random number generator engine.
3639*38fd1498Szrj    *
3640*38fd1498Szrj    * @returns The input stream with @p __x extracted or in an error state.
3641*38fd1498Szrj    */
3642*38fd1498Szrj   template<typename _CharT, typename _Traits>
3643*38fd1498Szrj     std::basic_istream<_CharT, _Traits>&
3644*38fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
3645*38fd1498Szrj 	       std::bernoulli_distribution& __x)
3646*38fd1498Szrj     {
3647*38fd1498Szrj       double __p;
3648*38fd1498Szrj       __is >> __p;
3649*38fd1498Szrj       __x.param(bernoulli_distribution::param_type(__p));
3650*38fd1498Szrj       return __is;
3651*38fd1498Szrj     }
3652*38fd1498Szrj 
3653*38fd1498Szrj 
3654*38fd1498Szrj   /**
3655*38fd1498Szrj    * @brief A discrete binomial random number distribution.
3656*38fd1498Szrj    *
3657*38fd1498Szrj    * The formula for the binomial probability density function is
3658*38fd1498Szrj    * @f$p(i|t,p) = \binom{t}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
3659*38fd1498Szrj    * and @f$p@f$ are the parameters of the distribution.
3660*38fd1498Szrj    */
3661*38fd1498Szrj   template<typename _IntType = int>
3662*38fd1498Szrj     class binomial_distribution
3663*38fd1498Szrj     {
3664*38fd1498Szrj       static_assert(std::is_integral<_IntType>::value,
3665*38fd1498Szrj 		    "result_type must be an integral type");
3666*38fd1498Szrj 
3667*38fd1498Szrj     public:
3668*38fd1498Szrj       /** The type of the range of the distribution. */
3669*38fd1498Szrj       typedef _IntType result_type;
3670*38fd1498Szrj 
3671*38fd1498Szrj       /** Parameter type. */
3672*38fd1498Szrj       struct param_type
3673*38fd1498Szrj       {
3674*38fd1498Szrj 	typedef binomial_distribution<_IntType> distribution_type;
3675*38fd1498Szrj 	friend class binomial_distribution<_IntType>;
3676*38fd1498Szrj 
3677*38fd1498Szrj 	explicit
3678*38fd1498Szrj 	param_type(_IntType __t = _IntType(1), double __p = 0.5)
3679*38fd1498Szrj 	: _M_t(__t), _M_p(__p)
3680*38fd1498Szrj 	{
3681*38fd1498Szrj 	  __glibcxx_assert((_M_t >= _IntType(0))
3682*38fd1498Szrj 				&& (_M_p >= 0.0)
3683*38fd1498Szrj 				&& (_M_p <= 1.0));
3684*38fd1498Szrj 	  _M_initialize();
3685*38fd1498Szrj 	}
3686*38fd1498Szrj 
3687*38fd1498Szrj 	_IntType
3688*38fd1498Szrj 	t() const
3689*38fd1498Szrj 	{ return _M_t; }
3690*38fd1498Szrj 
3691*38fd1498Szrj 	double
3692*38fd1498Szrj 	p() const
3693*38fd1498Szrj 	{ return _M_p; }
3694*38fd1498Szrj 
3695*38fd1498Szrj 	friend bool
3696*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
3697*38fd1498Szrj 	{ return __p1._M_t == __p2._M_t && __p1._M_p == __p2._M_p; }
3698*38fd1498Szrj 
3699*38fd1498Szrj 	friend bool
3700*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
3701*38fd1498Szrj 	{ return !(__p1 == __p2); }
3702*38fd1498Szrj 
3703*38fd1498Szrj       private:
3704*38fd1498Szrj 	void
3705*38fd1498Szrj 	_M_initialize();
3706*38fd1498Szrj 
3707*38fd1498Szrj 	_IntType _M_t;
3708*38fd1498Szrj 	double _M_p;
3709*38fd1498Szrj 
3710*38fd1498Szrj 	double _M_q;
3711*38fd1498Szrj #if _GLIBCXX_USE_C99_MATH_TR1
3712*38fd1498Szrj 	double _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
3713*38fd1498Szrj 	       _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
3714*38fd1498Szrj #endif
3715*38fd1498Szrj 	bool   _M_easy;
3716*38fd1498Szrj       };
3717*38fd1498Szrj 
3718*38fd1498Szrj       // constructors and member function
3719*38fd1498Szrj       explicit
3720*38fd1498Szrj       binomial_distribution(_IntType __t = _IntType(1),
3721*38fd1498Szrj 			    double __p = 0.5)
3722*38fd1498Szrj       : _M_param(__t, __p), _M_nd()
3723*38fd1498Szrj       { }
3724*38fd1498Szrj 
3725*38fd1498Szrj       explicit
3726*38fd1498Szrj       binomial_distribution(const param_type& __p)
3727*38fd1498Szrj       : _M_param(__p), _M_nd()
3728*38fd1498Szrj       { }
3729*38fd1498Szrj 
3730*38fd1498Szrj       /**
3731*38fd1498Szrj        * @brief Resets the distribution state.
3732*38fd1498Szrj        */
3733*38fd1498Szrj       void
3734*38fd1498Szrj       reset()
3735*38fd1498Szrj       { _M_nd.reset(); }
3736*38fd1498Szrj 
3737*38fd1498Szrj       /**
3738*38fd1498Szrj        * @brief Returns the distribution @p t parameter.
3739*38fd1498Szrj        */
3740*38fd1498Szrj       _IntType
3741*38fd1498Szrj       t() const
3742*38fd1498Szrj       { return _M_param.t(); }
3743*38fd1498Szrj 
3744*38fd1498Szrj       /**
3745*38fd1498Szrj        * @brief Returns the distribution @p p parameter.
3746*38fd1498Szrj        */
3747*38fd1498Szrj       double
3748*38fd1498Szrj       p() const
3749*38fd1498Szrj       { return _M_param.p(); }
3750*38fd1498Szrj 
3751*38fd1498Szrj       /**
3752*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
3753*38fd1498Szrj        */
3754*38fd1498Szrj       param_type
3755*38fd1498Szrj       param() const
3756*38fd1498Szrj       { return _M_param; }
3757*38fd1498Szrj 
3758*38fd1498Szrj       /**
3759*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
3760*38fd1498Szrj        * @param __param The new parameter set of the distribution.
3761*38fd1498Szrj        */
3762*38fd1498Szrj       void
3763*38fd1498Szrj       param(const param_type& __param)
3764*38fd1498Szrj       { _M_param = __param; }
3765*38fd1498Szrj 
3766*38fd1498Szrj       /**
3767*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
3768*38fd1498Szrj        */
3769*38fd1498Szrj       result_type
3770*38fd1498Szrj       min() const
3771*38fd1498Szrj       { return 0; }
3772*38fd1498Szrj 
3773*38fd1498Szrj       /**
3774*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
3775*38fd1498Szrj        */
3776*38fd1498Szrj       result_type
3777*38fd1498Szrj       max() const
3778*38fd1498Szrj       { return _M_param.t(); }
3779*38fd1498Szrj 
3780*38fd1498Szrj       /**
3781*38fd1498Szrj        * @brief Generating functions.
3782*38fd1498Szrj        */
3783*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
3784*38fd1498Szrj 	result_type
3785*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
3786*38fd1498Szrj 	{ return this->operator()(__urng, _M_param); }
3787*38fd1498Szrj 
3788*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
3789*38fd1498Szrj 	result_type
3790*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
3791*38fd1498Szrj 		   const param_type& __p);
3792*38fd1498Szrj 
3793*38fd1498Szrj       template<typename _ForwardIterator,
3794*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
3795*38fd1498Szrj 	void
3796*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
3797*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
3798*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
3799*38fd1498Szrj 
3800*38fd1498Szrj       template<typename _ForwardIterator,
3801*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
3802*38fd1498Szrj 	void
3803*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
3804*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
3805*38fd1498Szrj 		   const param_type& __p)
3806*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
3807*38fd1498Szrj 
3808*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
3809*38fd1498Szrj 	void
3810*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
3811*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
3812*38fd1498Szrj 		   const param_type& __p)
3813*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
3814*38fd1498Szrj 
3815*38fd1498Szrj       /**
3816*38fd1498Szrj        * @brief Return true if two binomial distributions have
3817*38fd1498Szrj        *        the same parameters and the sequences that would
3818*38fd1498Szrj        *        be generated are equal.
3819*38fd1498Szrj        */
3820*38fd1498Szrj 	friend bool
3821*38fd1498Szrj         operator==(const binomial_distribution& __d1,
3822*38fd1498Szrj 		   const binomial_distribution& __d2)
3823*38fd1498Szrj #ifdef _GLIBCXX_USE_C99_MATH_TR1
3824*38fd1498Szrj 	{ return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; }
3825*38fd1498Szrj #else
3826*38fd1498Szrj         { return __d1._M_param == __d2._M_param; }
3827*38fd1498Szrj #endif
3828*38fd1498Szrj 
3829*38fd1498Szrj       /**
3830*38fd1498Szrj        * @brief Inserts a %binomial_distribution random number distribution
3831*38fd1498Szrj        * @p __x into the output stream @p __os.
3832*38fd1498Szrj        *
3833*38fd1498Szrj        * @param __os An output stream.
3834*38fd1498Szrj        * @param __x  A %binomial_distribution random number distribution.
3835*38fd1498Szrj        *
3836*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
3837*38fd1498Szrj        * an error state.
3838*38fd1498Szrj        */
3839*38fd1498Szrj       template<typename _IntType1,
3840*38fd1498Szrj 	       typename _CharT, typename _Traits>
3841*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
3842*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3843*38fd1498Szrj 		   const std::binomial_distribution<_IntType1>& __x);
3844*38fd1498Szrj 
3845*38fd1498Szrj       /**
3846*38fd1498Szrj        * @brief Extracts a %binomial_distribution random number distribution
3847*38fd1498Szrj        * @p __x from the input stream @p __is.
3848*38fd1498Szrj        *
3849*38fd1498Szrj        * @param __is An input stream.
3850*38fd1498Szrj        * @param __x  A %binomial_distribution random number generator engine.
3851*38fd1498Szrj        *
3852*38fd1498Szrj        * @returns The input stream with @p __x extracted or in an error
3853*38fd1498Szrj        *          state.
3854*38fd1498Szrj        */
3855*38fd1498Szrj       template<typename _IntType1,
3856*38fd1498Szrj 	       typename _CharT, typename _Traits>
3857*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
3858*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
3859*38fd1498Szrj 		   std::binomial_distribution<_IntType1>& __x);
3860*38fd1498Szrj 
3861*38fd1498Szrj     private:
3862*38fd1498Szrj       template<typename _ForwardIterator,
3863*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
3864*38fd1498Szrj 	void
3865*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3866*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
3867*38fd1498Szrj 			const param_type& __p);
3868*38fd1498Szrj 
3869*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
3870*38fd1498Szrj 	result_type
3871*38fd1498Szrj 	_M_waiting(_UniformRandomNumberGenerator& __urng,
3872*38fd1498Szrj 		   _IntType __t, double __q);
3873*38fd1498Szrj 
3874*38fd1498Szrj       param_type _M_param;
3875*38fd1498Szrj 
3876*38fd1498Szrj       // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
3877*38fd1498Szrj       std::normal_distribution<double> _M_nd;
3878*38fd1498Szrj     };
3879*38fd1498Szrj 
3880*38fd1498Szrj   /**
3881*38fd1498Szrj    * @brief Return true if two binomial distributions are different.
3882*38fd1498Szrj    */
3883*38fd1498Szrj   template<typename _IntType>
3884*38fd1498Szrj     inline bool
3885*38fd1498Szrj     operator!=(const std::binomial_distribution<_IntType>& __d1,
3886*38fd1498Szrj 	       const std::binomial_distribution<_IntType>& __d2)
3887*38fd1498Szrj     { return !(__d1 == __d2); }
3888*38fd1498Szrj 
3889*38fd1498Szrj 
3890*38fd1498Szrj   /**
3891*38fd1498Szrj    * @brief A discrete geometric random number distribution.
3892*38fd1498Szrj    *
3893*38fd1498Szrj    * The formula for the geometric probability density function is
3894*38fd1498Szrj    * @f$p(i|p) = p(1 - p)^{i}@f$ where @f$p@f$ is the parameter of the
3895*38fd1498Szrj    * distribution.
3896*38fd1498Szrj    */
3897*38fd1498Szrj   template<typename _IntType = int>
3898*38fd1498Szrj     class geometric_distribution
3899*38fd1498Szrj     {
3900*38fd1498Szrj       static_assert(std::is_integral<_IntType>::value,
3901*38fd1498Szrj 		    "result_type must be an integral type");
3902*38fd1498Szrj 
3903*38fd1498Szrj     public:
3904*38fd1498Szrj       /** The type of the range of the distribution. */
3905*38fd1498Szrj       typedef _IntType  result_type;
3906*38fd1498Szrj 
3907*38fd1498Szrj       /** Parameter type. */
3908*38fd1498Szrj       struct param_type
3909*38fd1498Szrj       {
3910*38fd1498Szrj 	typedef geometric_distribution<_IntType> distribution_type;
3911*38fd1498Szrj 	friend class geometric_distribution<_IntType>;
3912*38fd1498Szrj 
3913*38fd1498Szrj 	explicit
3914*38fd1498Szrj 	param_type(double __p = 0.5)
3915*38fd1498Szrj 	: _M_p(__p)
3916*38fd1498Szrj 	{
3917*38fd1498Szrj 	  __glibcxx_assert((_M_p > 0.0) && (_M_p < 1.0));
3918*38fd1498Szrj 	  _M_initialize();
3919*38fd1498Szrj 	}
3920*38fd1498Szrj 
3921*38fd1498Szrj 	double
3922*38fd1498Szrj 	p() const
3923*38fd1498Szrj 	{ return _M_p; }
3924*38fd1498Szrj 
3925*38fd1498Szrj 	friend bool
3926*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
3927*38fd1498Szrj 	{ return __p1._M_p == __p2._M_p; }
3928*38fd1498Szrj 
3929*38fd1498Szrj 	friend bool
3930*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
3931*38fd1498Szrj 	{ return !(__p1 == __p2); }
3932*38fd1498Szrj 
3933*38fd1498Szrj       private:
3934*38fd1498Szrj 	void
3935*38fd1498Szrj 	_M_initialize()
3936*38fd1498Szrj 	{ _M_log_1_p = std::log(1.0 - _M_p); }
3937*38fd1498Szrj 
3938*38fd1498Szrj 	double _M_p;
3939*38fd1498Szrj 
3940*38fd1498Szrj 	double _M_log_1_p;
3941*38fd1498Szrj       };
3942*38fd1498Szrj 
3943*38fd1498Szrj       // constructors and member function
3944*38fd1498Szrj       explicit
3945*38fd1498Szrj       geometric_distribution(double __p = 0.5)
3946*38fd1498Szrj       : _M_param(__p)
3947*38fd1498Szrj       { }
3948*38fd1498Szrj 
3949*38fd1498Szrj       explicit
3950*38fd1498Szrj       geometric_distribution(const param_type& __p)
3951*38fd1498Szrj       : _M_param(__p)
3952*38fd1498Szrj       { }
3953*38fd1498Szrj 
3954*38fd1498Szrj       /**
3955*38fd1498Szrj        * @brief Resets the distribution state.
3956*38fd1498Szrj        *
3957*38fd1498Szrj        * Does nothing for the geometric distribution.
3958*38fd1498Szrj        */
3959*38fd1498Szrj       void
3960*38fd1498Szrj       reset() { }
3961*38fd1498Szrj 
3962*38fd1498Szrj       /**
3963*38fd1498Szrj        * @brief Returns the distribution parameter @p p.
3964*38fd1498Szrj        */
3965*38fd1498Szrj       double
3966*38fd1498Szrj       p() const
3967*38fd1498Szrj       { return _M_param.p(); }
3968*38fd1498Szrj 
3969*38fd1498Szrj       /**
3970*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
3971*38fd1498Szrj        */
3972*38fd1498Szrj       param_type
3973*38fd1498Szrj       param() const
3974*38fd1498Szrj       { return _M_param; }
3975*38fd1498Szrj 
3976*38fd1498Szrj       /**
3977*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
3978*38fd1498Szrj        * @param __param The new parameter set of the distribution.
3979*38fd1498Szrj        */
3980*38fd1498Szrj       void
3981*38fd1498Szrj       param(const param_type& __param)
3982*38fd1498Szrj       { _M_param = __param; }
3983*38fd1498Szrj 
3984*38fd1498Szrj       /**
3985*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
3986*38fd1498Szrj        */
3987*38fd1498Szrj       result_type
3988*38fd1498Szrj       min() const
3989*38fd1498Szrj       { return 0; }
3990*38fd1498Szrj 
3991*38fd1498Szrj       /**
3992*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
3993*38fd1498Szrj        */
3994*38fd1498Szrj       result_type
3995*38fd1498Szrj       max() const
3996*38fd1498Szrj       { return std::numeric_limits<result_type>::max(); }
3997*38fd1498Szrj 
3998*38fd1498Szrj       /**
3999*38fd1498Szrj        * @brief Generating functions.
4000*38fd1498Szrj        */
4001*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4002*38fd1498Szrj 	result_type
4003*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
4004*38fd1498Szrj 	{ return this->operator()(__urng, _M_param); }
4005*38fd1498Szrj 
4006*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4007*38fd1498Szrj 	result_type
4008*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
4009*38fd1498Szrj 		   const param_type& __p);
4010*38fd1498Szrj 
4011*38fd1498Szrj       template<typename _ForwardIterator,
4012*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4013*38fd1498Szrj 	void
4014*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
4015*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
4016*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
4017*38fd1498Szrj 
4018*38fd1498Szrj       template<typename _ForwardIterator,
4019*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4020*38fd1498Szrj 	void
4021*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
4022*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
4023*38fd1498Szrj 		   const param_type& __p)
4024*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
4025*38fd1498Szrj 
4026*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4027*38fd1498Szrj 	void
4028*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
4029*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
4030*38fd1498Szrj 		   const param_type& __p)
4031*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
4032*38fd1498Szrj 
4033*38fd1498Szrj       /**
4034*38fd1498Szrj        * @brief Return true if two geometric distributions have
4035*38fd1498Szrj        *        the same parameters.
4036*38fd1498Szrj        */
4037*38fd1498Szrj       friend bool
4038*38fd1498Szrj       operator==(const geometric_distribution& __d1,
4039*38fd1498Szrj 		 const geometric_distribution& __d2)
4040*38fd1498Szrj       { return __d1._M_param == __d2._M_param; }
4041*38fd1498Szrj 
4042*38fd1498Szrj     private:
4043*38fd1498Szrj       template<typename _ForwardIterator,
4044*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4045*38fd1498Szrj 	void
4046*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4047*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
4048*38fd1498Szrj 			const param_type& __p);
4049*38fd1498Szrj 
4050*38fd1498Szrj       param_type _M_param;
4051*38fd1498Szrj     };
4052*38fd1498Szrj 
4053*38fd1498Szrj   /**
4054*38fd1498Szrj    * @brief Return true if two geometric distributions have
4055*38fd1498Szrj    *        different parameters.
4056*38fd1498Szrj    */
4057*38fd1498Szrj   template<typename _IntType>
4058*38fd1498Szrj     inline bool
4059*38fd1498Szrj     operator!=(const std::geometric_distribution<_IntType>& __d1,
4060*38fd1498Szrj 	       const std::geometric_distribution<_IntType>& __d2)
4061*38fd1498Szrj     { return !(__d1 == __d2); }
4062*38fd1498Szrj 
4063*38fd1498Szrj   /**
4064*38fd1498Szrj    * @brief Inserts a %geometric_distribution random number distribution
4065*38fd1498Szrj    * @p __x into the output stream @p __os.
4066*38fd1498Szrj    *
4067*38fd1498Szrj    * @param __os An output stream.
4068*38fd1498Szrj    * @param __x  A %geometric_distribution random number distribution.
4069*38fd1498Szrj    *
4070*38fd1498Szrj    * @returns The output stream with the state of @p __x inserted or in
4071*38fd1498Szrj    * an error state.
4072*38fd1498Szrj    */
4073*38fd1498Szrj   template<typename _IntType,
4074*38fd1498Szrj 	   typename _CharT, typename _Traits>
4075*38fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
4076*38fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4077*38fd1498Szrj 	       const std::geometric_distribution<_IntType>& __x);
4078*38fd1498Szrj 
4079*38fd1498Szrj   /**
4080*38fd1498Szrj    * @brief Extracts a %geometric_distribution random number distribution
4081*38fd1498Szrj    * @p __x from the input stream @p __is.
4082*38fd1498Szrj    *
4083*38fd1498Szrj    * @param __is An input stream.
4084*38fd1498Szrj    * @param __x  A %geometric_distribution random number generator engine.
4085*38fd1498Szrj    *
4086*38fd1498Szrj    * @returns The input stream with @p __x extracted or in an error state.
4087*38fd1498Szrj    */
4088*38fd1498Szrj   template<typename _IntType,
4089*38fd1498Szrj 	   typename _CharT, typename _Traits>
4090*38fd1498Szrj     std::basic_istream<_CharT, _Traits>&
4091*38fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
4092*38fd1498Szrj 	       std::geometric_distribution<_IntType>& __x);
4093*38fd1498Szrj 
4094*38fd1498Szrj 
4095*38fd1498Szrj   /**
4096*38fd1498Szrj    * @brief A negative_binomial_distribution random number distribution.
4097*38fd1498Szrj    *
4098*38fd1498Szrj    * The formula for the negative binomial probability mass function is
4099*38fd1498Szrj    * @f$p(i) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
4100*38fd1498Szrj    * and @f$p@f$ are the parameters of the distribution.
4101*38fd1498Szrj    */
4102*38fd1498Szrj   template<typename _IntType = int>
4103*38fd1498Szrj     class negative_binomial_distribution
4104*38fd1498Szrj     {
4105*38fd1498Szrj       static_assert(std::is_integral<_IntType>::value,
4106*38fd1498Szrj 		    "result_type must be an integral type");
4107*38fd1498Szrj 
4108*38fd1498Szrj     public:
4109*38fd1498Szrj       /** The type of the range of the distribution. */
4110*38fd1498Szrj       typedef _IntType result_type;
4111*38fd1498Szrj 
4112*38fd1498Szrj       /** Parameter type. */
4113*38fd1498Szrj       struct param_type
4114*38fd1498Szrj       {
4115*38fd1498Szrj 	typedef negative_binomial_distribution<_IntType> distribution_type;
4116*38fd1498Szrj 
4117*38fd1498Szrj 	explicit
4118*38fd1498Szrj 	param_type(_IntType __k = 1, double __p = 0.5)
4119*38fd1498Szrj 	: _M_k(__k), _M_p(__p)
4120*38fd1498Szrj 	{
4121*38fd1498Szrj 	  __glibcxx_assert((_M_k > 0) && (_M_p > 0.0) && (_M_p <= 1.0));
4122*38fd1498Szrj 	}
4123*38fd1498Szrj 
4124*38fd1498Szrj 	_IntType
4125*38fd1498Szrj 	k() const
4126*38fd1498Szrj 	{ return _M_k; }
4127*38fd1498Szrj 
4128*38fd1498Szrj 	double
4129*38fd1498Szrj 	p() const
4130*38fd1498Szrj 	{ return _M_p; }
4131*38fd1498Szrj 
4132*38fd1498Szrj 	friend bool
4133*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
4134*38fd1498Szrj 	{ return __p1._M_k == __p2._M_k && __p1._M_p == __p2._M_p; }
4135*38fd1498Szrj 
4136*38fd1498Szrj 	friend bool
4137*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
4138*38fd1498Szrj 	{ return !(__p1 == __p2); }
4139*38fd1498Szrj 
4140*38fd1498Szrj       private:
4141*38fd1498Szrj 	_IntType _M_k;
4142*38fd1498Szrj 	double _M_p;
4143*38fd1498Szrj       };
4144*38fd1498Szrj 
4145*38fd1498Szrj       explicit
4146*38fd1498Szrj       negative_binomial_distribution(_IntType __k = 1, double __p = 0.5)
4147*38fd1498Szrj       : _M_param(__k, __p), _M_gd(__k, (1.0 - __p) / __p)
4148*38fd1498Szrj       { }
4149*38fd1498Szrj 
4150*38fd1498Szrj       explicit
4151*38fd1498Szrj       negative_binomial_distribution(const param_type& __p)
4152*38fd1498Szrj       : _M_param(__p), _M_gd(__p.k(), (1.0 - __p.p()) / __p.p())
4153*38fd1498Szrj       { }
4154*38fd1498Szrj 
4155*38fd1498Szrj       /**
4156*38fd1498Szrj        * @brief Resets the distribution state.
4157*38fd1498Szrj        */
4158*38fd1498Szrj       void
4159*38fd1498Szrj       reset()
4160*38fd1498Szrj       { _M_gd.reset(); }
4161*38fd1498Szrj 
4162*38fd1498Szrj       /**
4163*38fd1498Szrj        * @brief Return the @f$k@f$ parameter of the distribution.
4164*38fd1498Szrj        */
4165*38fd1498Szrj       _IntType
4166*38fd1498Szrj       k() const
4167*38fd1498Szrj       { return _M_param.k(); }
4168*38fd1498Szrj 
4169*38fd1498Szrj       /**
4170*38fd1498Szrj        * @brief Return the @f$p@f$ parameter of the distribution.
4171*38fd1498Szrj        */
4172*38fd1498Szrj       double
4173*38fd1498Szrj       p() const
4174*38fd1498Szrj       { return _M_param.p(); }
4175*38fd1498Szrj 
4176*38fd1498Szrj       /**
4177*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
4178*38fd1498Szrj        */
4179*38fd1498Szrj       param_type
4180*38fd1498Szrj       param() const
4181*38fd1498Szrj       { return _M_param; }
4182*38fd1498Szrj 
4183*38fd1498Szrj       /**
4184*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
4185*38fd1498Szrj        * @param __param The new parameter set of the distribution.
4186*38fd1498Szrj        */
4187*38fd1498Szrj       void
4188*38fd1498Szrj       param(const param_type& __param)
4189*38fd1498Szrj       { _M_param = __param; }
4190*38fd1498Szrj 
4191*38fd1498Szrj       /**
4192*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
4193*38fd1498Szrj        */
4194*38fd1498Szrj       result_type
4195*38fd1498Szrj       min() const
4196*38fd1498Szrj       { return result_type(0); }
4197*38fd1498Szrj 
4198*38fd1498Szrj       /**
4199*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
4200*38fd1498Szrj        */
4201*38fd1498Szrj       result_type
4202*38fd1498Szrj       max() const
4203*38fd1498Szrj       { return std::numeric_limits<result_type>::max(); }
4204*38fd1498Szrj 
4205*38fd1498Szrj       /**
4206*38fd1498Szrj        * @brief Generating functions.
4207*38fd1498Szrj        */
4208*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4209*38fd1498Szrj 	result_type
4210*38fd1498Szrj         operator()(_UniformRandomNumberGenerator& __urng);
4211*38fd1498Szrj 
4212*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4213*38fd1498Szrj 	result_type
4214*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
4215*38fd1498Szrj 		   const param_type& __p);
4216*38fd1498Szrj 
4217*38fd1498Szrj       template<typename _ForwardIterator,
4218*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4219*38fd1498Szrj 	void
4220*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
4221*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
4222*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng); }
4223*38fd1498Szrj 
4224*38fd1498Szrj       template<typename _ForwardIterator,
4225*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4226*38fd1498Szrj 	void
4227*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
4228*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
4229*38fd1498Szrj 		   const param_type& __p)
4230*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
4231*38fd1498Szrj 
4232*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4233*38fd1498Szrj 	void
4234*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
4235*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
4236*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng); }
4237*38fd1498Szrj 
4238*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4239*38fd1498Szrj 	void
4240*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
4241*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
4242*38fd1498Szrj 		   const param_type& __p)
4243*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
4244*38fd1498Szrj 
4245*38fd1498Szrj       /**
4246*38fd1498Szrj        * @brief Return true if two negative binomial distributions have
4247*38fd1498Szrj        *        the same parameters and the sequences that would be
4248*38fd1498Szrj        *        generated are equal.
4249*38fd1498Szrj        */
4250*38fd1498Szrj       friend bool
4251*38fd1498Szrj       operator==(const negative_binomial_distribution& __d1,
4252*38fd1498Szrj 		 const negative_binomial_distribution& __d2)
4253*38fd1498Szrj       { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; }
4254*38fd1498Szrj 
4255*38fd1498Szrj       /**
4256*38fd1498Szrj        * @brief Inserts a %negative_binomial_distribution random
4257*38fd1498Szrj        *        number distribution @p __x into the output stream @p __os.
4258*38fd1498Szrj        *
4259*38fd1498Szrj        * @param __os An output stream.
4260*38fd1498Szrj        * @param __x  A %negative_binomial_distribution random number
4261*38fd1498Szrj        *             distribution.
4262*38fd1498Szrj        *
4263*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
4264*38fd1498Szrj        *          an error state.
4265*38fd1498Szrj        */
4266*38fd1498Szrj       template<typename _IntType1, typename _CharT, typename _Traits>
4267*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
4268*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4269*38fd1498Szrj 		   const std::negative_binomial_distribution<_IntType1>& __x);
4270*38fd1498Szrj 
4271*38fd1498Szrj       /**
4272*38fd1498Szrj        * @brief Extracts a %negative_binomial_distribution random number
4273*38fd1498Szrj        *        distribution @p __x from the input stream @p __is.
4274*38fd1498Szrj        *
4275*38fd1498Szrj        * @param __is An input stream.
4276*38fd1498Szrj        * @param __x A %negative_binomial_distribution random number
4277*38fd1498Szrj        *            generator engine.
4278*38fd1498Szrj        *
4279*38fd1498Szrj        * @returns The input stream with @p __x extracted or in an error state.
4280*38fd1498Szrj        */
4281*38fd1498Szrj       template<typename _IntType1, typename _CharT, typename _Traits>
4282*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
4283*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
4284*38fd1498Szrj 		   std::negative_binomial_distribution<_IntType1>& __x);
4285*38fd1498Szrj 
4286*38fd1498Szrj     private:
4287*38fd1498Szrj       template<typename _ForwardIterator,
4288*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4289*38fd1498Szrj 	void
4290*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4291*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng);
4292*38fd1498Szrj       template<typename _ForwardIterator,
4293*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4294*38fd1498Szrj 	void
4295*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4296*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
4297*38fd1498Szrj 			const param_type& __p);
4298*38fd1498Szrj 
4299*38fd1498Szrj       param_type _M_param;
4300*38fd1498Szrj 
4301*38fd1498Szrj       std::gamma_distribution<double> _M_gd;
4302*38fd1498Szrj     };
4303*38fd1498Szrj 
4304*38fd1498Szrj   /**
4305*38fd1498Szrj    * @brief Return true if two negative binomial distributions are different.
4306*38fd1498Szrj    */
4307*38fd1498Szrj   template<typename _IntType>
4308*38fd1498Szrj     inline bool
4309*38fd1498Szrj     operator!=(const std::negative_binomial_distribution<_IntType>& __d1,
4310*38fd1498Szrj 	       const std::negative_binomial_distribution<_IntType>& __d2)
4311*38fd1498Szrj     { return !(__d1 == __d2); }
4312*38fd1498Szrj 
4313*38fd1498Szrj 
4314*38fd1498Szrj   /* @} */ // group random_distributions_bernoulli
4315*38fd1498Szrj 
4316*38fd1498Szrj   /**
4317*38fd1498Szrj    * @addtogroup random_distributions_poisson Poisson Distributions
4318*38fd1498Szrj    * @ingroup random_distributions
4319*38fd1498Szrj    * @{
4320*38fd1498Szrj    */
4321*38fd1498Szrj 
4322*38fd1498Szrj   /**
4323*38fd1498Szrj    * @brief A discrete Poisson random number distribution.
4324*38fd1498Szrj    *
4325*38fd1498Szrj    * The formula for the Poisson probability density function is
4326*38fd1498Szrj    * @f$p(i|\mu) = \frac{\mu^i}{i!} e^{-\mu}@f$ where @f$\mu@f$ is the
4327*38fd1498Szrj    * parameter of the distribution.
4328*38fd1498Szrj    */
4329*38fd1498Szrj   template<typename _IntType = int>
4330*38fd1498Szrj     class poisson_distribution
4331*38fd1498Szrj     {
4332*38fd1498Szrj       static_assert(std::is_integral<_IntType>::value,
4333*38fd1498Szrj 		    "result_type must be an integral type");
4334*38fd1498Szrj 
4335*38fd1498Szrj     public:
4336*38fd1498Szrj       /** The type of the range of the distribution. */
4337*38fd1498Szrj       typedef _IntType  result_type;
4338*38fd1498Szrj 
4339*38fd1498Szrj       /** Parameter type. */
4340*38fd1498Szrj       struct param_type
4341*38fd1498Szrj       {
4342*38fd1498Szrj 	typedef poisson_distribution<_IntType> distribution_type;
4343*38fd1498Szrj 	friend class poisson_distribution<_IntType>;
4344*38fd1498Szrj 
4345*38fd1498Szrj 	explicit
4346*38fd1498Szrj 	param_type(double __mean = 1.0)
4347*38fd1498Szrj 	: _M_mean(__mean)
4348*38fd1498Szrj 	{
4349*38fd1498Szrj 	  __glibcxx_assert(_M_mean > 0.0);
4350*38fd1498Szrj 	  _M_initialize();
4351*38fd1498Szrj 	}
4352*38fd1498Szrj 
4353*38fd1498Szrj 	double
4354*38fd1498Szrj 	mean() const
4355*38fd1498Szrj 	{ return _M_mean; }
4356*38fd1498Szrj 
4357*38fd1498Szrj 	friend bool
4358*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
4359*38fd1498Szrj 	{ return __p1._M_mean == __p2._M_mean; }
4360*38fd1498Szrj 
4361*38fd1498Szrj 	friend bool
4362*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
4363*38fd1498Szrj 	{ return !(__p1 == __p2); }
4364*38fd1498Szrj 
4365*38fd1498Szrj       private:
4366*38fd1498Szrj 	// Hosts either log(mean) or the threshold of the simple method.
4367*38fd1498Szrj 	void
4368*38fd1498Szrj 	_M_initialize();
4369*38fd1498Szrj 
4370*38fd1498Szrj 	double _M_mean;
4371*38fd1498Szrj 
4372*38fd1498Szrj 	double _M_lm_thr;
4373*38fd1498Szrj #if _GLIBCXX_USE_C99_MATH_TR1
4374*38fd1498Szrj 	double _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
4375*38fd1498Szrj #endif
4376*38fd1498Szrj       };
4377*38fd1498Szrj 
4378*38fd1498Szrj       // constructors and member function
4379*38fd1498Szrj       explicit
4380*38fd1498Szrj       poisson_distribution(double __mean = 1.0)
4381*38fd1498Szrj       : _M_param(__mean), _M_nd()
4382*38fd1498Szrj       { }
4383*38fd1498Szrj 
4384*38fd1498Szrj       explicit
4385*38fd1498Szrj       poisson_distribution(const param_type& __p)
4386*38fd1498Szrj       : _M_param(__p), _M_nd()
4387*38fd1498Szrj       { }
4388*38fd1498Szrj 
4389*38fd1498Szrj       /**
4390*38fd1498Szrj        * @brief Resets the distribution state.
4391*38fd1498Szrj        */
4392*38fd1498Szrj       void
4393*38fd1498Szrj       reset()
4394*38fd1498Szrj       { _M_nd.reset(); }
4395*38fd1498Szrj 
4396*38fd1498Szrj       /**
4397*38fd1498Szrj        * @brief Returns the distribution parameter @p mean.
4398*38fd1498Szrj        */
4399*38fd1498Szrj       double
4400*38fd1498Szrj       mean() const
4401*38fd1498Szrj       { return _M_param.mean(); }
4402*38fd1498Szrj 
4403*38fd1498Szrj       /**
4404*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
4405*38fd1498Szrj        */
4406*38fd1498Szrj       param_type
4407*38fd1498Szrj       param() const
4408*38fd1498Szrj       { return _M_param; }
4409*38fd1498Szrj 
4410*38fd1498Szrj       /**
4411*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
4412*38fd1498Szrj        * @param __param The new parameter set of the distribution.
4413*38fd1498Szrj        */
4414*38fd1498Szrj       void
4415*38fd1498Szrj       param(const param_type& __param)
4416*38fd1498Szrj       { _M_param = __param; }
4417*38fd1498Szrj 
4418*38fd1498Szrj       /**
4419*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
4420*38fd1498Szrj        */
4421*38fd1498Szrj       result_type
4422*38fd1498Szrj       min() const
4423*38fd1498Szrj       { return 0; }
4424*38fd1498Szrj 
4425*38fd1498Szrj       /**
4426*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
4427*38fd1498Szrj        */
4428*38fd1498Szrj       result_type
4429*38fd1498Szrj       max() const
4430*38fd1498Szrj       { return std::numeric_limits<result_type>::max(); }
4431*38fd1498Szrj 
4432*38fd1498Szrj       /**
4433*38fd1498Szrj        * @brief Generating functions.
4434*38fd1498Szrj        */
4435*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4436*38fd1498Szrj 	result_type
4437*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
4438*38fd1498Szrj 	{ return this->operator()(__urng, _M_param); }
4439*38fd1498Szrj 
4440*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4441*38fd1498Szrj 	result_type
4442*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
4443*38fd1498Szrj 		   const param_type& __p);
4444*38fd1498Szrj 
4445*38fd1498Szrj       template<typename _ForwardIterator,
4446*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4447*38fd1498Szrj 	void
4448*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
4449*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
4450*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
4451*38fd1498Szrj 
4452*38fd1498Szrj       template<typename _ForwardIterator,
4453*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4454*38fd1498Szrj 	void
4455*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
4456*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
4457*38fd1498Szrj 		   const param_type& __p)
4458*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
4459*38fd1498Szrj 
4460*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4461*38fd1498Szrj 	void
4462*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
4463*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
4464*38fd1498Szrj 		   const param_type& __p)
4465*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
4466*38fd1498Szrj 
4467*38fd1498Szrj        /**
4468*38fd1498Szrj 	* @brief Return true if two Poisson distributions have the same
4469*38fd1498Szrj 	*        parameters and the sequences that would be generated
4470*38fd1498Szrj 	*        are equal.
4471*38fd1498Szrj 	*/
4472*38fd1498Szrj       friend bool
4473*38fd1498Szrj       operator==(const poisson_distribution& __d1,
4474*38fd1498Szrj 		 const poisson_distribution& __d2)
4475*38fd1498Szrj #ifdef _GLIBCXX_USE_C99_MATH_TR1
4476*38fd1498Szrj       { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; }
4477*38fd1498Szrj #else
4478*38fd1498Szrj       { return __d1._M_param == __d2._M_param; }
4479*38fd1498Szrj #endif
4480*38fd1498Szrj 
4481*38fd1498Szrj       /**
4482*38fd1498Szrj        * @brief Inserts a %poisson_distribution random number distribution
4483*38fd1498Szrj        * @p __x into the output stream @p __os.
4484*38fd1498Szrj        *
4485*38fd1498Szrj        * @param __os An output stream.
4486*38fd1498Szrj        * @param __x  A %poisson_distribution random number distribution.
4487*38fd1498Szrj        *
4488*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
4489*38fd1498Szrj        * an error state.
4490*38fd1498Szrj        */
4491*38fd1498Szrj       template<typename _IntType1, typename _CharT, typename _Traits>
4492*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
4493*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4494*38fd1498Szrj 		   const std::poisson_distribution<_IntType1>& __x);
4495*38fd1498Szrj 
4496*38fd1498Szrj       /**
4497*38fd1498Szrj        * @brief Extracts a %poisson_distribution random number distribution
4498*38fd1498Szrj        * @p __x from the input stream @p __is.
4499*38fd1498Szrj        *
4500*38fd1498Szrj        * @param __is An input stream.
4501*38fd1498Szrj        * @param __x  A %poisson_distribution random number generator engine.
4502*38fd1498Szrj        *
4503*38fd1498Szrj        * @returns The input stream with @p __x extracted or in an error
4504*38fd1498Szrj        *          state.
4505*38fd1498Szrj        */
4506*38fd1498Szrj       template<typename _IntType1, typename _CharT, typename _Traits>
4507*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
4508*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
4509*38fd1498Szrj 		   std::poisson_distribution<_IntType1>& __x);
4510*38fd1498Szrj 
4511*38fd1498Szrj     private:
4512*38fd1498Szrj       template<typename _ForwardIterator,
4513*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4514*38fd1498Szrj 	void
4515*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4516*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
4517*38fd1498Szrj 			const param_type& __p);
4518*38fd1498Szrj 
4519*38fd1498Szrj       param_type _M_param;
4520*38fd1498Szrj 
4521*38fd1498Szrj       // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
4522*38fd1498Szrj       std::normal_distribution<double> _M_nd;
4523*38fd1498Szrj     };
4524*38fd1498Szrj 
4525*38fd1498Szrj   /**
4526*38fd1498Szrj    * @brief Return true if two Poisson distributions are different.
4527*38fd1498Szrj    */
4528*38fd1498Szrj   template<typename _IntType>
4529*38fd1498Szrj     inline bool
4530*38fd1498Szrj     operator!=(const std::poisson_distribution<_IntType>& __d1,
4531*38fd1498Szrj 	       const std::poisson_distribution<_IntType>& __d2)
4532*38fd1498Szrj     { return !(__d1 == __d2); }
4533*38fd1498Szrj 
4534*38fd1498Szrj 
4535*38fd1498Szrj   /**
4536*38fd1498Szrj    * @brief An exponential continuous distribution for random numbers.
4537*38fd1498Szrj    *
4538*38fd1498Szrj    * The formula for the exponential probability density function is
4539*38fd1498Szrj    * @f$p(x|\lambda) = \lambda e^{-\lambda x}@f$.
4540*38fd1498Szrj    *
4541*38fd1498Szrj    * <table border=1 cellpadding=10 cellspacing=0>
4542*38fd1498Szrj    * <caption align=top>Distribution Statistics</caption>
4543*38fd1498Szrj    * <tr><td>Mean</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
4544*38fd1498Szrj    * <tr><td>Median</td><td>@f$\frac{\ln 2}{\lambda}@f$</td></tr>
4545*38fd1498Szrj    * <tr><td>Mode</td><td>@f$zero@f$</td></tr>
4546*38fd1498Szrj    * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
4547*38fd1498Szrj    * <tr><td>Standard Deviation</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
4548*38fd1498Szrj    * </table>
4549*38fd1498Szrj    */
4550*38fd1498Szrj   template<typename _RealType = double>
4551*38fd1498Szrj     class exponential_distribution
4552*38fd1498Szrj     {
4553*38fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
4554*38fd1498Szrj 		    "result_type must be a floating point type");
4555*38fd1498Szrj 
4556*38fd1498Szrj     public:
4557*38fd1498Szrj       /** The type of the range of the distribution. */
4558*38fd1498Szrj       typedef _RealType result_type;
4559*38fd1498Szrj 
4560*38fd1498Szrj       /** Parameter type. */
4561*38fd1498Szrj       struct param_type
4562*38fd1498Szrj       {
4563*38fd1498Szrj 	typedef exponential_distribution<_RealType> distribution_type;
4564*38fd1498Szrj 
4565*38fd1498Szrj 	explicit
4566*38fd1498Szrj 	param_type(_RealType __lambda = _RealType(1))
4567*38fd1498Szrj 	: _M_lambda(__lambda)
4568*38fd1498Szrj 	{
4569*38fd1498Szrj 	  __glibcxx_assert(_M_lambda > _RealType(0));
4570*38fd1498Szrj 	}
4571*38fd1498Szrj 
4572*38fd1498Szrj 	_RealType
4573*38fd1498Szrj 	lambda() const
4574*38fd1498Szrj 	{ return _M_lambda; }
4575*38fd1498Szrj 
4576*38fd1498Szrj 	friend bool
4577*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
4578*38fd1498Szrj 	{ return __p1._M_lambda == __p2._M_lambda; }
4579*38fd1498Szrj 
4580*38fd1498Szrj 	friend bool
4581*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
4582*38fd1498Szrj 	{ return !(__p1 == __p2); }
4583*38fd1498Szrj 
4584*38fd1498Szrj       private:
4585*38fd1498Szrj 	_RealType _M_lambda;
4586*38fd1498Szrj       };
4587*38fd1498Szrj 
4588*38fd1498Szrj     public:
4589*38fd1498Szrj       /**
4590*38fd1498Szrj        * @brief Constructs an exponential distribution with inverse scale
4591*38fd1498Szrj        *        parameter @f$\lambda@f$.
4592*38fd1498Szrj        */
4593*38fd1498Szrj       explicit
4594*38fd1498Szrj       exponential_distribution(const result_type& __lambda = result_type(1))
4595*38fd1498Szrj       : _M_param(__lambda)
4596*38fd1498Szrj       { }
4597*38fd1498Szrj 
4598*38fd1498Szrj       explicit
4599*38fd1498Szrj       exponential_distribution(const param_type& __p)
4600*38fd1498Szrj       : _M_param(__p)
4601*38fd1498Szrj       { }
4602*38fd1498Szrj 
4603*38fd1498Szrj       /**
4604*38fd1498Szrj        * @brief Resets the distribution state.
4605*38fd1498Szrj        *
4606*38fd1498Szrj        * Has no effect on exponential distributions.
4607*38fd1498Szrj        */
4608*38fd1498Szrj       void
4609*38fd1498Szrj       reset() { }
4610*38fd1498Szrj 
4611*38fd1498Szrj       /**
4612*38fd1498Szrj        * @brief Returns the inverse scale parameter of the distribution.
4613*38fd1498Szrj        */
4614*38fd1498Szrj       _RealType
4615*38fd1498Szrj       lambda() const
4616*38fd1498Szrj       { return _M_param.lambda(); }
4617*38fd1498Szrj 
4618*38fd1498Szrj       /**
4619*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
4620*38fd1498Szrj        */
4621*38fd1498Szrj       param_type
4622*38fd1498Szrj       param() const
4623*38fd1498Szrj       { return _M_param; }
4624*38fd1498Szrj 
4625*38fd1498Szrj       /**
4626*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
4627*38fd1498Szrj        * @param __param The new parameter set of the distribution.
4628*38fd1498Szrj        */
4629*38fd1498Szrj       void
4630*38fd1498Szrj       param(const param_type& __param)
4631*38fd1498Szrj       { _M_param = __param; }
4632*38fd1498Szrj 
4633*38fd1498Szrj       /**
4634*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
4635*38fd1498Szrj        */
4636*38fd1498Szrj       result_type
4637*38fd1498Szrj       min() const
4638*38fd1498Szrj       { return result_type(0); }
4639*38fd1498Szrj 
4640*38fd1498Szrj       /**
4641*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
4642*38fd1498Szrj        */
4643*38fd1498Szrj       result_type
4644*38fd1498Szrj       max() const
4645*38fd1498Szrj       { return std::numeric_limits<result_type>::max(); }
4646*38fd1498Szrj 
4647*38fd1498Szrj       /**
4648*38fd1498Szrj        * @brief Generating functions.
4649*38fd1498Szrj        */
4650*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4651*38fd1498Szrj 	result_type
4652*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
4653*38fd1498Szrj         { return this->operator()(__urng, _M_param); }
4654*38fd1498Szrj 
4655*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4656*38fd1498Szrj 	result_type
4657*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
4658*38fd1498Szrj 		   const param_type& __p)
4659*38fd1498Szrj 	{
4660*38fd1498Szrj 	  __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
4661*38fd1498Szrj 	    __aurng(__urng);
4662*38fd1498Szrj 	  return -std::log(result_type(1) - __aurng()) / __p.lambda();
4663*38fd1498Szrj 	}
4664*38fd1498Szrj 
4665*38fd1498Szrj       template<typename _ForwardIterator,
4666*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4667*38fd1498Szrj 	void
4668*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
4669*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
4670*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
4671*38fd1498Szrj 
4672*38fd1498Szrj       template<typename _ForwardIterator,
4673*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4674*38fd1498Szrj 	void
4675*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
4676*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
4677*38fd1498Szrj 		   const param_type& __p)
4678*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
4679*38fd1498Szrj 
4680*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4681*38fd1498Szrj 	void
4682*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
4683*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
4684*38fd1498Szrj 		   const param_type& __p)
4685*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
4686*38fd1498Szrj 
4687*38fd1498Szrj       /**
4688*38fd1498Szrj        * @brief Return true if two exponential distributions have the same
4689*38fd1498Szrj        *        parameters.
4690*38fd1498Szrj        */
4691*38fd1498Szrj       friend bool
4692*38fd1498Szrj       operator==(const exponential_distribution& __d1,
4693*38fd1498Szrj 		 const exponential_distribution& __d2)
4694*38fd1498Szrj       { return __d1._M_param == __d2._M_param; }
4695*38fd1498Szrj 
4696*38fd1498Szrj     private:
4697*38fd1498Szrj       template<typename _ForwardIterator,
4698*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4699*38fd1498Szrj 	void
4700*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4701*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
4702*38fd1498Szrj 			const param_type& __p);
4703*38fd1498Szrj 
4704*38fd1498Szrj       param_type _M_param;
4705*38fd1498Szrj     };
4706*38fd1498Szrj 
4707*38fd1498Szrj   /**
4708*38fd1498Szrj    * @brief Return true if two exponential distributions have different
4709*38fd1498Szrj    *        parameters.
4710*38fd1498Szrj    */
4711*38fd1498Szrj   template<typename _RealType>
4712*38fd1498Szrj     inline bool
4713*38fd1498Szrj     operator!=(const std::exponential_distribution<_RealType>& __d1,
4714*38fd1498Szrj 	       const std::exponential_distribution<_RealType>& __d2)
4715*38fd1498Szrj     { return !(__d1 == __d2); }
4716*38fd1498Szrj 
4717*38fd1498Szrj   /**
4718*38fd1498Szrj    * @brief Inserts a %exponential_distribution random number distribution
4719*38fd1498Szrj    * @p __x into the output stream @p __os.
4720*38fd1498Szrj    *
4721*38fd1498Szrj    * @param __os An output stream.
4722*38fd1498Szrj    * @param __x  A %exponential_distribution random number distribution.
4723*38fd1498Szrj    *
4724*38fd1498Szrj    * @returns The output stream with the state of @p __x inserted or in
4725*38fd1498Szrj    * an error state.
4726*38fd1498Szrj    */
4727*38fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
4728*38fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
4729*38fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4730*38fd1498Szrj 	       const std::exponential_distribution<_RealType>& __x);
4731*38fd1498Szrj 
4732*38fd1498Szrj   /**
4733*38fd1498Szrj    * @brief Extracts a %exponential_distribution random number distribution
4734*38fd1498Szrj    * @p __x from the input stream @p __is.
4735*38fd1498Szrj    *
4736*38fd1498Szrj    * @param __is An input stream.
4737*38fd1498Szrj    * @param __x A %exponential_distribution random number
4738*38fd1498Szrj    *            generator engine.
4739*38fd1498Szrj    *
4740*38fd1498Szrj    * @returns The input stream with @p __x extracted or in an error state.
4741*38fd1498Szrj    */
4742*38fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
4743*38fd1498Szrj     std::basic_istream<_CharT, _Traits>&
4744*38fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
4745*38fd1498Szrj 	       std::exponential_distribution<_RealType>& __x);
4746*38fd1498Szrj 
4747*38fd1498Szrj 
4748*38fd1498Szrj   /**
4749*38fd1498Szrj    * @brief A weibull_distribution random number distribution.
4750*38fd1498Szrj    *
4751*38fd1498Szrj    * The formula for the normal probability density function is:
4752*38fd1498Szrj    * @f[
4753*38fd1498Szrj    *     p(x|\alpha,\beta) = \frac{\alpha}{\beta} (\frac{x}{\beta})^{\alpha-1}
4754*38fd1498Szrj    *                         \exp{(-(\frac{x}{\beta})^\alpha)}
4755*38fd1498Szrj    * @f]
4756*38fd1498Szrj    */
4757*38fd1498Szrj   template<typename _RealType = double>
4758*38fd1498Szrj     class weibull_distribution
4759*38fd1498Szrj     {
4760*38fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
4761*38fd1498Szrj 		    "result_type must be a floating point type");
4762*38fd1498Szrj 
4763*38fd1498Szrj     public:
4764*38fd1498Szrj       /** The type of the range of the distribution. */
4765*38fd1498Szrj       typedef _RealType result_type;
4766*38fd1498Szrj 
4767*38fd1498Szrj       /** Parameter type. */
4768*38fd1498Szrj       struct param_type
4769*38fd1498Szrj       {
4770*38fd1498Szrj 	typedef weibull_distribution<_RealType> distribution_type;
4771*38fd1498Szrj 
4772*38fd1498Szrj 	explicit
4773*38fd1498Szrj 	param_type(_RealType __a = _RealType(1),
4774*38fd1498Szrj 		   _RealType __b = _RealType(1))
4775*38fd1498Szrj 	: _M_a(__a), _M_b(__b)
4776*38fd1498Szrj 	{ }
4777*38fd1498Szrj 
4778*38fd1498Szrj 	_RealType
4779*38fd1498Szrj 	a() const
4780*38fd1498Szrj 	{ return _M_a; }
4781*38fd1498Szrj 
4782*38fd1498Szrj 	_RealType
4783*38fd1498Szrj 	b() const
4784*38fd1498Szrj 	{ return _M_b; }
4785*38fd1498Szrj 
4786*38fd1498Szrj 	friend bool
4787*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
4788*38fd1498Szrj 	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
4789*38fd1498Szrj 
4790*38fd1498Szrj 	friend bool
4791*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
4792*38fd1498Szrj 	{ return !(__p1 == __p2); }
4793*38fd1498Szrj 
4794*38fd1498Szrj       private:
4795*38fd1498Szrj 	_RealType _M_a;
4796*38fd1498Szrj 	_RealType _M_b;
4797*38fd1498Szrj       };
4798*38fd1498Szrj 
4799*38fd1498Szrj       explicit
4800*38fd1498Szrj       weibull_distribution(_RealType __a = _RealType(1),
4801*38fd1498Szrj 			   _RealType __b = _RealType(1))
4802*38fd1498Szrj       : _M_param(__a, __b)
4803*38fd1498Szrj       { }
4804*38fd1498Szrj 
4805*38fd1498Szrj       explicit
4806*38fd1498Szrj       weibull_distribution(const param_type& __p)
4807*38fd1498Szrj       : _M_param(__p)
4808*38fd1498Szrj       { }
4809*38fd1498Szrj 
4810*38fd1498Szrj       /**
4811*38fd1498Szrj        * @brief Resets the distribution state.
4812*38fd1498Szrj        */
4813*38fd1498Szrj       void
4814*38fd1498Szrj       reset()
4815*38fd1498Szrj       { }
4816*38fd1498Szrj 
4817*38fd1498Szrj       /**
4818*38fd1498Szrj        * @brief Return the @f$a@f$ parameter of the distribution.
4819*38fd1498Szrj        */
4820*38fd1498Szrj       _RealType
4821*38fd1498Szrj       a() const
4822*38fd1498Szrj       { return _M_param.a(); }
4823*38fd1498Szrj 
4824*38fd1498Szrj       /**
4825*38fd1498Szrj        * @brief Return the @f$b@f$ parameter of the distribution.
4826*38fd1498Szrj        */
4827*38fd1498Szrj       _RealType
4828*38fd1498Szrj       b() const
4829*38fd1498Szrj       { return _M_param.b(); }
4830*38fd1498Szrj 
4831*38fd1498Szrj       /**
4832*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
4833*38fd1498Szrj        */
4834*38fd1498Szrj       param_type
4835*38fd1498Szrj       param() const
4836*38fd1498Szrj       { return _M_param; }
4837*38fd1498Szrj 
4838*38fd1498Szrj       /**
4839*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
4840*38fd1498Szrj        * @param __param The new parameter set of the distribution.
4841*38fd1498Szrj        */
4842*38fd1498Szrj       void
4843*38fd1498Szrj       param(const param_type& __param)
4844*38fd1498Szrj       { _M_param = __param; }
4845*38fd1498Szrj 
4846*38fd1498Szrj       /**
4847*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
4848*38fd1498Szrj        */
4849*38fd1498Szrj       result_type
4850*38fd1498Szrj       min() const
4851*38fd1498Szrj       { return result_type(0); }
4852*38fd1498Szrj 
4853*38fd1498Szrj       /**
4854*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
4855*38fd1498Szrj        */
4856*38fd1498Szrj       result_type
4857*38fd1498Szrj       max() const
4858*38fd1498Szrj       { return std::numeric_limits<result_type>::max(); }
4859*38fd1498Szrj 
4860*38fd1498Szrj       /**
4861*38fd1498Szrj        * @brief Generating functions.
4862*38fd1498Szrj        */
4863*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4864*38fd1498Szrj 	result_type
4865*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
4866*38fd1498Szrj 	{ return this->operator()(__urng, _M_param); }
4867*38fd1498Szrj 
4868*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4869*38fd1498Szrj 	result_type
4870*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
4871*38fd1498Szrj 		   const param_type& __p);
4872*38fd1498Szrj 
4873*38fd1498Szrj       template<typename _ForwardIterator,
4874*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4875*38fd1498Szrj 	void
4876*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
4877*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
4878*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
4879*38fd1498Szrj 
4880*38fd1498Szrj       template<typename _ForwardIterator,
4881*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4882*38fd1498Szrj 	void
4883*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
4884*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
4885*38fd1498Szrj 		   const param_type& __p)
4886*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
4887*38fd1498Szrj 
4888*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
4889*38fd1498Szrj 	void
4890*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
4891*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
4892*38fd1498Szrj 		   const param_type& __p)
4893*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
4894*38fd1498Szrj 
4895*38fd1498Szrj       /**
4896*38fd1498Szrj        * @brief Return true if two Weibull distributions have the same
4897*38fd1498Szrj        *        parameters.
4898*38fd1498Szrj        */
4899*38fd1498Szrj       friend bool
4900*38fd1498Szrj       operator==(const weibull_distribution& __d1,
4901*38fd1498Szrj 		 const weibull_distribution& __d2)
4902*38fd1498Szrj       { return __d1._M_param == __d2._M_param; }
4903*38fd1498Szrj 
4904*38fd1498Szrj     private:
4905*38fd1498Szrj       template<typename _ForwardIterator,
4906*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
4907*38fd1498Szrj 	void
4908*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
4909*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
4910*38fd1498Szrj 			const param_type& __p);
4911*38fd1498Szrj 
4912*38fd1498Szrj       param_type _M_param;
4913*38fd1498Szrj     };
4914*38fd1498Szrj 
4915*38fd1498Szrj    /**
4916*38fd1498Szrj     * @brief Return true if two Weibull distributions have different
4917*38fd1498Szrj     *        parameters.
4918*38fd1498Szrj     */
4919*38fd1498Szrj   template<typename _RealType>
4920*38fd1498Szrj     inline bool
4921*38fd1498Szrj     operator!=(const std::weibull_distribution<_RealType>& __d1,
4922*38fd1498Szrj 	       const std::weibull_distribution<_RealType>& __d2)
4923*38fd1498Szrj     { return !(__d1 == __d2); }
4924*38fd1498Szrj 
4925*38fd1498Szrj   /**
4926*38fd1498Szrj    * @brief Inserts a %weibull_distribution random number distribution
4927*38fd1498Szrj    * @p __x into the output stream @p __os.
4928*38fd1498Szrj    *
4929*38fd1498Szrj    * @param __os An output stream.
4930*38fd1498Szrj    * @param __x  A %weibull_distribution random number distribution.
4931*38fd1498Szrj    *
4932*38fd1498Szrj    * @returns The output stream with the state of @p __x inserted or in
4933*38fd1498Szrj    * an error state.
4934*38fd1498Szrj    */
4935*38fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
4936*38fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
4937*38fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4938*38fd1498Szrj 	       const std::weibull_distribution<_RealType>& __x);
4939*38fd1498Szrj 
4940*38fd1498Szrj   /**
4941*38fd1498Szrj    * @brief Extracts a %weibull_distribution random number distribution
4942*38fd1498Szrj    * @p __x from the input stream @p __is.
4943*38fd1498Szrj    *
4944*38fd1498Szrj    * @param __is An input stream.
4945*38fd1498Szrj    * @param __x A %weibull_distribution random number
4946*38fd1498Szrj    *            generator engine.
4947*38fd1498Szrj    *
4948*38fd1498Szrj    * @returns The input stream with @p __x extracted or in an error state.
4949*38fd1498Szrj    */
4950*38fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
4951*38fd1498Szrj     std::basic_istream<_CharT, _Traits>&
4952*38fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
4953*38fd1498Szrj 	       std::weibull_distribution<_RealType>& __x);
4954*38fd1498Szrj 
4955*38fd1498Szrj 
4956*38fd1498Szrj   /**
4957*38fd1498Szrj    * @brief A extreme_value_distribution random number distribution.
4958*38fd1498Szrj    *
4959*38fd1498Szrj    * The formula for the normal probability mass function is
4960*38fd1498Szrj    * @f[
4961*38fd1498Szrj    *     p(x|a,b) = \frac{1}{b}
4962*38fd1498Szrj    *                \exp( \frac{a-x}{b} - \exp(\frac{a-x}{b}))
4963*38fd1498Szrj    * @f]
4964*38fd1498Szrj    */
4965*38fd1498Szrj   template<typename _RealType = double>
4966*38fd1498Szrj     class extreme_value_distribution
4967*38fd1498Szrj     {
4968*38fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
4969*38fd1498Szrj 		    "result_type must be a floating point type");
4970*38fd1498Szrj 
4971*38fd1498Szrj     public:
4972*38fd1498Szrj       /** The type of the range of the distribution. */
4973*38fd1498Szrj       typedef _RealType result_type;
4974*38fd1498Szrj 
4975*38fd1498Szrj       /** Parameter type. */
4976*38fd1498Szrj       struct param_type
4977*38fd1498Szrj       {
4978*38fd1498Szrj 	typedef extreme_value_distribution<_RealType> distribution_type;
4979*38fd1498Szrj 
4980*38fd1498Szrj 	explicit
4981*38fd1498Szrj 	param_type(_RealType __a = _RealType(0),
4982*38fd1498Szrj 		   _RealType __b = _RealType(1))
4983*38fd1498Szrj 	: _M_a(__a), _M_b(__b)
4984*38fd1498Szrj 	{ }
4985*38fd1498Szrj 
4986*38fd1498Szrj 	_RealType
4987*38fd1498Szrj 	a() const
4988*38fd1498Szrj 	{ return _M_a; }
4989*38fd1498Szrj 
4990*38fd1498Szrj 	_RealType
4991*38fd1498Szrj 	b() const
4992*38fd1498Szrj 	{ return _M_b; }
4993*38fd1498Szrj 
4994*38fd1498Szrj 	friend bool
4995*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
4996*38fd1498Szrj 	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
4997*38fd1498Szrj 
4998*38fd1498Szrj 	friend bool
4999*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
5000*38fd1498Szrj 	{ return !(__p1 == __p2); }
5001*38fd1498Szrj 
5002*38fd1498Szrj       private:
5003*38fd1498Szrj 	_RealType _M_a;
5004*38fd1498Szrj 	_RealType _M_b;
5005*38fd1498Szrj       };
5006*38fd1498Szrj 
5007*38fd1498Szrj       explicit
5008*38fd1498Szrj       extreme_value_distribution(_RealType __a = _RealType(0),
5009*38fd1498Szrj 				 _RealType __b = _RealType(1))
5010*38fd1498Szrj       : _M_param(__a, __b)
5011*38fd1498Szrj       { }
5012*38fd1498Szrj 
5013*38fd1498Szrj       explicit
5014*38fd1498Szrj       extreme_value_distribution(const param_type& __p)
5015*38fd1498Szrj       : _M_param(__p)
5016*38fd1498Szrj       { }
5017*38fd1498Szrj 
5018*38fd1498Szrj       /**
5019*38fd1498Szrj        * @brief Resets the distribution state.
5020*38fd1498Szrj        */
5021*38fd1498Szrj       void
5022*38fd1498Szrj       reset()
5023*38fd1498Szrj       { }
5024*38fd1498Szrj 
5025*38fd1498Szrj       /**
5026*38fd1498Szrj        * @brief Return the @f$a@f$ parameter of the distribution.
5027*38fd1498Szrj        */
5028*38fd1498Szrj       _RealType
5029*38fd1498Szrj       a() const
5030*38fd1498Szrj       { return _M_param.a(); }
5031*38fd1498Szrj 
5032*38fd1498Szrj       /**
5033*38fd1498Szrj        * @brief Return the @f$b@f$ parameter of the distribution.
5034*38fd1498Szrj        */
5035*38fd1498Szrj       _RealType
5036*38fd1498Szrj       b() const
5037*38fd1498Szrj       { return _M_param.b(); }
5038*38fd1498Szrj 
5039*38fd1498Szrj       /**
5040*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
5041*38fd1498Szrj        */
5042*38fd1498Szrj       param_type
5043*38fd1498Szrj       param() const
5044*38fd1498Szrj       { return _M_param; }
5045*38fd1498Szrj 
5046*38fd1498Szrj       /**
5047*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
5048*38fd1498Szrj        * @param __param The new parameter set of the distribution.
5049*38fd1498Szrj        */
5050*38fd1498Szrj       void
5051*38fd1498Szrj       param(const param_type& __param)
5052*38fd1498Szrj       { _M_param = __param; }
5053*38fd1498Szrj 
5054*38fd1498Szrj       /**
5055*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
5056*38fd1498Szrj        */
5057*38fd1498Szrj       result_type
5058*38fd1498Szrj       min() const
5059*38fd1498Szrj       { return std::numeric_limits<result_type>::lowest(); }
5060*38fd1498Szrj 
5061*38fd1498Szrj       /**
5062*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
5063*38fd1498Szrj        */
5064*38fd1498Szrj       result_type
5065*38fd1498Szrj       max() const
5066*38fd1498Szrj       { return std::numeric_limits<result_type>::max(); }
5067*38fd1498Szrj 
5068*38fd1498Szrj       /**
5069*38fd1498Szrj        * @brief Generating functions.
5070*38fd1498Szrj        */
5071*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
5072*38fd1498Szrj 	result_type
5073*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
5074*38fd1498Szrj 	{ return this->operator()(__urng, _M_param); }
5075*38fd1498Szrj 
5076*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
5077*38fd1498Szrj 	result_type
5078*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
5079*38fd1498Szrj 		   const param_type& __p);
5080*38fd1498Szrj 
5081*38fd1498Szrj       template<typename _ForwardIterator,
5082*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
5083*38fd1498Szrj 	void
5084*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
5085*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
5086*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
5087*38fd1498Szrj 
5088*38fd1498Szrj       template<typename _ForwardIterator,
5089*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
5090*38fd1498Szrj 	void
5091*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
5092*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
5093*38fd1498Szrj 		   const param_type& __p)
5094*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
5095*38fd1498Szrj 
5096*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
5097*38fd1498Szrj 	void
5098*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
5099*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
5100*38fd1498Szrj 		   const param_type& __p)
5101*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
5102*38fd1498Szrj 
5103*38fd1498Szrj       /**
5104*38fd1498Szrj        * @brief Return true if two extreme value distributions have the same
5105*38fd1498Szrj        *        parameters.
5106*38fd1498Szrj        */
5107*38fd1498Szrj       friend bool
5108*38fd1498Szrj       operator==(const extreme_value_distribution& __d1,
5109*38fd1498Szrj 		 const extreme_value_distribution& __d2)
5110*38fd1498Szrj       { return __d1._M_param == __d2._M_param; }
5111*38fd1498Szrj 
5112*38fd1498Szrj     private:
5113*38fd1498Szrj       template<typename _ForwardIterator,
5114*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
5115*38fd1498Szrj 	void
5116*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
5117*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
5118*38fd1498Szrj 			const param_type& __p);
5119*38fd1498Szrj 
5120*38fd1498Szrj       param_type _M_param;
5121*38fd1498Szrj     };
5122*38fd1498Szrj 
5123*38fd1498Szrj   /**
5124*38fd1498Szrj     * @brief Return true if two extreme value distributions have different
5125*38fd1498Szrj     *        parameters.
5126*38fd1498Szrj    */
5127*38fd1498Szrj   template<typename _RealType>
5128*38fd1498Szrj     inline bool
5129*38fd1498Szrj     operator!=(const std::extreme_value_distribution<_RealType>& __d1,
5130*38fd1498Szrj 	       const std::extreme_value_distribution<_RealType>& __d2)
5131*38fd1498Szrj     { return !(__d1 == __d2); }
5132*38fd1498Szrj 
5133*38fd1498Szrj   /**
5134*38fd1498Szrj    * @brief Inserts a %extreme_value_distribution random number distribution
5135*38fd1498Szrj    * @p __x into the output stream @p __os.
5136*38fd1498Szrj    *
5137*38fd1498Szrj    * @param __os An output stream.
5138*38fd1498Szrj    * @param __x  A %extreme_value_distribution random number distribution.
5139*38fd1498Szrj    *
5140*38fd1498Szrj    * @returns The output stream with the state of @p __x inserted or in
5141*38fd1498Szrj    * an error state.
5142*38fd1498Szrj    */
5143*38fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
5144*38fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
5145*38fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5146*38fd1498Szrj 	       const std::extreme_value_distribution<_RealType>& __x);
5147*38fd1498Szrj 
5148*38fd1498Szrj   /**
5149*38fd1498Szrj    * @brief Extracts a %extreme_value_distribution random number
5150*38fd1498Szrj    *        distribution @p __x from the input stream @p __is.
5151*38fd1498Szrj    *
5152*38fd1498Szrj    * @param __is An input stream.
5153*38fd1498Szrj    * @param __x A %extreme_value_distribution random number
5154*38fd1498Szrj    *            generator engine.
5155*38fd1498Szrj    *
5156*38fd1498Szrj    * @returns The input stream with @p __x extracted or in an error state.
5157*38fd1498Szrj    */
5158*38fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
5159*38fd1498Szrj     std::basic_istream<_CharT, _Traits>&
5160*38fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
5161*38fd1498Szrj 	       std::extreme_value_distribution<_RealType>& __x);
5162*38fd1498Szrj 
5163*38fd1498Szrj 
5164*38fd1498Szrj   /**
5165*38fd1498Szrj    * @brief A discrete_distribution random number distribution.
5166*38fd1498Szrj    *
5167*38fd1498Szrj    * The formula for the discrete probability mass function is
5168*38fd1498Szrj    *
5169*38fd1498Szrj    */
5170*38fd1498Szrj   template<typename _IntType = int>
5171*38fd1498Szrj     class discrete_distribution
5172*38fd1498Szrj     {
5173*38fd1498Szrj       static_assert(std::is_integral<_IntType>::value,
5174*38fd1498Szrj 		    "result_type must be an integral type");
5175*38fd1498Szrj 
5176*38fd1498Szrj     public:
5177*38fd1498Szrj       /** The type of the range of the distribution. */
5178*38fd1498Szrj       typedef _IntType result_type;
5179*38fd1498Szrj 
5180*38fd1498Szrj       /** Parameter type. */
5181*38fd1498Szrj       struct param_type
5182*38fd1498Szrj       {
5183*38fd1498Szrj 	typedef discrete_distribution<_IntType> distribution_type;
5184*38fd1498Szrj 	friend class discrete_distribution<_IntType>;
5185*38fd1498Szrj 
5186*38fd1498Szrj 	param_type()
5187*38fd1498Szrj 	: _M_prob(), _M_cp()
5188*38fd1498Szrj 	{ }
5189*38fd1498Szrj 
5190*38fd1498Szrj 	template<typename _InputIterator>
5191*38fd1498Szrj 	  param_type(_InputIterator __wbegin,
5192*38fd1498Szrj 		     _InputIterator __wend)
5193*38fd1498Szrj 	  : _M_prob(__wbegin, __wend), _M_cp()
5194*38fd1498Szrj 	  { _M_initialize(); }
5195*38fd1498Szrj 
5196*38fd1498Szrj 	param_type(initializer_list<double> __wil)
5197*38fd1498Szrj 	: _M_prob(__wil.begin(), __wil.end()), _M_cp()
5198*38fd1498Szrj 	{ _M_initialize(); }
5199*38fd1498Szrj 
5200*38fd1498Szrj 	template<typename _Func>
5201*38fd1498Szrj 	  param_type(size_t __nw, double __xmin, double __xmax,
5202*38fd1498Szrj 		     _Func __fw);
5203*38fd1498Szrj 
5204*38fd1498Szrj 	// See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
5205*38fd1498Szrj 	param_type(const param_type&) = default;
5206*38fd1498Szrj 	param_type& operator=(const param_type&) = default;
5207*38fd1498Szrj 
5208*38fd1498Szrj 	std::vector<double>
5209*38fd1498Szrj 	probabilities() const
5210*38fd1498Szrj 	{ return _M_prob.empty() ? std::vector<double>(1, 1.0) : _M_prob; }
5211*38fd1498Szrj 
5212*38fd1498Szrj 	friend bool
5213*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
5214*38fd1498Szrj 	{ return __p1._M_prob == __p2._M_prob; }
5215*38fd1498Szrj 
5216*38fd1498Szrj 	friend bool
5217*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
5218*38fd1498Szrj 	{ return !(__p1 == __p2); }
5219*38fd1498Szrj 
5220*38fd1498Szrj       private:
5221*38fd1498Szrj 	void
5222*38fd1498Szrj 	_M_initialize();
5223*38fd1498Szrj 
5224*38fd1498Szrj 	std::vector<double> _M_prob;
5225*38fd1498Szrj 	std::vector<double> _M_cp;
5226*38fd1498Szrj       };
5227*38fd1498Szrj 
5228*38fd1498Szrj       discrete_distribution()
5229*38fd1498Szrj       : _M_param()
5230*38fd1498Szrj       { }
5231*38fd1498Szrj 
5232*38fd1498Szrj       template<typename _InputIterator>
5233*38fd1498Szrj 	discrete_distribution(_InputIterator __wbegin,
5234*38fd1498Szrj 			      _InputIterator __wend)
5235*38fd1498Szrj 	: _M_param(__wbegin, __wend)
5236*38fd1498Szrj 	{ }
5237*38fd1498Szrj 
5238*38fd1498Szrj       discrete_distribution(initializer_list<double> __wl)
5239*38fd1498Szrj       : _M_param(__wl)
5240*38fd1498Szrj       { }
5241*38fd1498Szrj 
5242*38fd1498Szrj       template<typename _Func>
5243*38fd1498Szrj 	discrete_distribution(size_t __nw, double __xmin, double __xmax,
5244*38fd1498Szrj 			      _Func __fw)
5245*38fd1498Szrj 	: _M_param(__nw, __xmin, __xmax, __fw)
5246*38fd1498Szrj 	{ }
5247*38fd1498Szrj 
5248*38fd1498Szrj       explicit
5249*38fd1498Szrj       discrete_distribution(const param_type& __p)
5250*38fd1498Szrj       : _M_param(__p)
5251*38fd1498Szrj       { }
5252*38fd1498Szrj 
5253*38fd1498Szrj       /**
5254*38fd1498Szrj        * @brief Resets the distribution state.
5255*38fd1498Szrj        */
5256*38fd1498Szrj       void
5257*38fd1498Szrj       reset()
5258*38fd1498Szrj       { }
5259*38fd1498Szrj 
5260*38fd1498Szrj       /**
5261*38fd1498Szrj        * @brief Returns the probabilities of the distribution.
5262*38fd1498Szrj        */
5263*38fd1498Szrj       std::vector<double>
5264*38fd1498Szrj       probabilities() const
5265*38fd1498Szrj       {
5266*38fd1498Szrj 	return _M_param._M_prob.empty()
5267*38fd1498Szrj 	  ? std::vector<double>(1, 1.0) : _M_param._M_prob;
5268*38fd1498Szrj       }
5269*38fd1498Szrj 
5270*38fd1498Szrj       /**
5271*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
5272*38fd1498Szrj        */
5273*38fd1498Szrj       param_type
5274*38fd1498Szrj       param() const
5275*38fd1498Szrj       { return _M_param; }
5276*38fd1498Szrj 
5277*38fd1498Szrj       /**
5278*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
5279*38fd1498Szrj        * @param __param The new parameter set of the distribution.
5280*38fd1498Szrj        */
5281*38fd1498Szrj       void
5282*38fd1498Szrj       param(const param_type& __param)
5283*38fd1498Szrj       { _M_param = __param; }
5284*38fd1498Szrj 
5285*38fd1498Szrj       /**
5286*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
5287*38fd1498Szrj        */
5288*38fd1498Szrj       result_type
5289*38fd1498Szrj       min() const
5290*38fd1498Szrj       { return result_type(0); }
5291*38fd1498Szrj 
5292*38fd1498Szrj       /**
5293*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
5294*38fd1498Szrj        */
5295*38fd1498Szrj       result_type
5296*38fd1498Szrj       max() const
5297*38fd1498Szrj       {
5298*38fd1498Szrj 	return _M_param._M_prob.empty()
5299*38fd1498Szrj 	  ? result_type(0) : result_type(_M_param._M_prob.size() - 1);
5300*38fd1498Szrj       }
5301*38fd1498Szrj 
5302*38fd1498Szrj       /**
5303*38fd1498Szrj        * @brief Generating functions.
5304*38fd1498Szrj        */
5305*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
5306*38fd1498Szrj 	result_type
5307*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
5308*38fd1498Szrj 	{ return this->operator()(__urng, _M_param); }
5309*38fd1498Szrj 
5310*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
5311*38fd1498Szrj 	result_type
5312*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
5313*38fd1498Szrj 		   const param_type& __p);
5314*38fd1498Szrj 
5315*38fd1498Szrj       template<typename _ForwardIterator,
5316*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
5317*38fd1498Szrj 	void
5318*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
5319*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
5320*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
5321*38fd1498Szrj 
5322*38fd1498Szrj       template<typename _ForwardIterator,
5323*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
5324*38fd1498Szrj 	void
5325*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
5326*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
5327*38fd1498Szrj 		   const param_type& __p)
5328*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
5329*38fd1498Szrj 
5330*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
5331*38fd1498Szrj 	void
5332*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
5333*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
5334*38fd1498Szrj 		   const param_type& __p)
5335*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
5336*38fd1498Szrj 
5337*38fd1498Szrj       /**
5338*38fd1498Szrj        * @brief Return true if two discrete distributions have the same
5339*38fd1498Szrj        *        parameters.
5340*38fd1498Szrj        */
5341*38fd1498Szrj       friend bool
5342*38fd1498Szrj       operator==(const discrete_distribution& __d1,
5343*38fd1498Szrj 		 const discrete_distribution& __d2)
5344*38fd1498Szrj       { return __d1._M_param == __d2._M_param; }
5345*38fd1498Szrj 
5346*38fd1498Szrj       /**
5347*38fd1498Szrj        * @brief Inserts a %discrete_distribution random number distribution
5348*38fd1498Szrj        * @p __x into the output stream @p __os.
5349*38fd1498Szrj        *
5350*38fd1498Szrj        * @param __os An output stream.
5351*38fd1498Szrj        * @param __x  A %discrete_distribution random number distribution.
5352*38fd1498Szrj        *
5353*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
5354*38fd1498Szrj        * an error state.
5355*38fd1498Szrj        */
5356*38fd1498Szrj       template<typename _IntType1, typename _CharT, typename _Traits>
5357*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
5358*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5359*38fd1498Szrj 		   const std::discrete_distribution<_IntType1>& __x);
5360*38fd1498Szrj 
5361*38fd1498Szrj       /**
5362*38fd1498Szrj        * @brief Extracts a %discrete_distribution random number distribution
5363*38fd1498Szrj        * @p __x from the input stream @p __is.
5364*38fd1498Szrj        *
5365*38fd1498Szrj        * @param __is An input stream.
5366*38fd1498Szrj        * @param __x A %discrete_distribution random number
5367*38fd1498Szrj        *            generator engine.
5368*38fd1498Szrj        *
5369*38fd1498Szrj        * @returns The input stream with @p __x extracted or in an error
5370*38fd1498Szrj        *          state.
5371*38fd1498Szrj        */
5372*38fd1498Szrj       template<typename _IntType1, typename _CharT, typename _Traits>
5373*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
5374*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
5375*38fd1498Szrj 		   std::discrete_distribution<_IntType1>& __x);
5376*38fd1498Szrj 
5377*38fd1498Szrj     private:
5378*38fd1498Szrj       template<typename _ForwardIterator,
5379*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
5380*38fd1498Szrj 	void
5381*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
5382*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
5383*38fd1498Szrj 			const param_type& __p);
5384*38fd1498Szrj 
5385*38fd1498Szrj       param_type _M_param;
5386*38fd1498Szrj     };
5387*38fd1498Szrj 
5388*38fd1498Szrj   /**
5389*38fd1498Szrj     * @brief Return true if two discrete distributions have different
5390*38fd1498Szrj     *        parameters.
5391*38fd1498Szrj     */
5392*38fd1498Szrj   template<typename _IntType>
5393*38fd1498Szrj     inline bool
5394*38fd1498Szrj     operator!=(const std::discrete_distribution<_IntType>& __d1,
5395*38fd1498Szrj 	       const std::discrete_distribution<_IntType>& __d2)
5396*38fd1498Szrj     { return !(__d1 == __d2); }
5397*38fd1498Szrj 
5398*38fd1498Szrj 
5399*38fd1498Szrj   /**
5400*38fd1498Szrj    * @brief A piecewise_constant_distribution random number distribution.
5401*38fd1498Szrj    *
5402*38fd1498Szrj    * The formula for the piecewise constant probability mass function is
5403*38fd1498Szrj    *
5404*38fd1498Szrj    */
5405*38fd1498Szrj   template<typename _RealType = double>
5406*38fd1498Szrj     class piecewise_constant_distribution
5407*38fd1498Szrj     {
5408*38fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
5409*38fd1498Szrj 		    "result_type must be a floating point type");
5410*38fd1498Szrj 
5411*38fd1498Szrj     public:
5412*38fd1498Szrj       /** The type of the range of the distribution. */
5413*38fd1498Szrj       typedef _RealType result_type;
5414*38fd1498Szrj 
5415*38fd1498Szrj       /** Parameter type. */
5416*38fd1498Szrj       struct param_type
5417*38fd1498Szrj       {
5418*38fd1498Szrj 	typedef piecewise_constant_distribution<_RealType> distribution_type;
5419*38fd1498Szrj 	friend class piecewise_constant_distribution<_RealType>;
5420*38fd1498Szrj 
5421*38fd1498Szrj 	param_type()
5422*38fd1498Szrj 	: _M_int(), _M_den(), _M_cp()
5423*38fd1498Szrj 	{ }
5424*38fd1498Szrj 
5425*38fd1498Szrj 	template<typename _InputIteratorB, typename _InputIteratorW>
5426*38fd1498Szrj 	  param_type(_InputIteratorB __bfirst,
5427*38fd1498Szrj 		     _InputIteratorB __bend,
5428*38fd1498Szrj 		     _InputIteratorW __wbegin);
5429*38fd1498Szrj 
5430*38fd1498Szrj 	template<typename _Func>
5431*38fd1498Szrj 	  param_type(initializer_list<_RealType> __bi, _Func __fw);
5432*38fd1498Szrj 
5433*38fd1498Szrj 	template<typename _Func>
5434*38fd1498Szrj 	  param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
5435*38fd1498Szrj 		     _Func __fw);
5436*38fd1498Szrj 
5437*38fd1498Szrj 	// See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
5438*38fd1498Szrj 	param_type(const param_type&) = default;
5439*38fd1498Szrj 	param_type& operator=(const param_type&) = default;
5440*38fd1498Szrj 
5441*38fd1498Szrj 	std::vector<_RealType>
5442*38fd1498Szrj 	intervals() const
5443*38fd1498Szrj 	{
5444*38fd1498Szrj 	  if (_M_int.empty())
5445*38fd1498Szrj 	    {
5446*38fd1498Szrj 	      std::vector<_RealType> __tmp(2);
5447*38fd1498Szrj 	      __tmp[1] = _RealType(1);
5448*38fd1498Szrj 	      return __tmp;
5449*38fd1498Szrj 	    }
5450*38fd1498Szrj 	  else
5451*38fd1498Szrj 	    return _M_int;
5452*38fd1498Szrj 	}
5453*38fd1498Szrj 
5454*38fd1498Szrj 	std::vector<double>
5455*38fd1498Szrj 	densities() const
5456*38fd1498Szrj 	{ return _M_den.empty() ? std::vector<double>(1, 1.0) : _M_den; }
5457*38fd1498Szrj 
5458*38fd1498Szrj 	friend bool
5459*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
5460*38fd1498Szrj 	{ return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; }
5461*38fd1498Szrj 
5462*38fd1498Szrj 	friend bool
5463*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
5464*38fd1498Szrj 	{ return !(__p1 == __p2); }
5465*38fd1498Szrj 
5466*38fd1498Szrj       private:
5467*38fd1498Szrj 	void
5468*38fd1498Szrj 	_M_initialize();
5469*38fd1498Szrj 
5470*38fd1498Szrj 	std::vector<_RealType> _M_int;
5471*38fd1498Szrj 	std::vector<double> _M_den;
5472*38fd1498Szrj 	std::vector<double> _M_cp;
5473*38fd1498Szrj       };
5474*38fd1498Szrj 
5475*38fd1498Szrj       explicit
5476*38fd1498Szrj       piecewise_constant_distribution()
5477*38fd1498Szrj       : _M_param()
5478*38fd1498Szrj       { }
5479*38fd1498Szrj 
5480*38fd1498Szrj       template<typename _InputIteratorB, typename _InputIteratorW>
5481*38fd1498Szrj 	piecewise_constant_distribution(_InputIteratorB __bfirst,
5482*38fd1498Szrj 					_InputIteratorB __bend,
5483*38fd1498Szrj 					_InputIteratorW __wbegin)
5484*38fd1498Szrj 	: _M_param(__bfirst, __bend, __wbegin)
5485*38fd1498Szrj 	{ }
5486*38fd1498Szrj 
5487*38fd1498Szrj       template<typename _Func>
5488*38fd1498Szrj 	piecewise_constant_distribution(initializer_list<_RealType> __bl,
5489*38fd1498Szrj 					_Func __fw)
5490*38fd1498Szrj 	: _M_param(__bl, __fw)
5491*38fd1498Szrj 	{ }
5492*38fd1498Szrj 
5493*38fd1498Szrj       template<typename _Func>
5494*38fd1498Szrj 	piecewise_constant_distribution(size_t __nw,
5495*38fd1498Szrj 					_RealType __xmin, _RealType __xmax,
5496*38fd1498Szrj 					_Func __fw)
5497*38fd1498Szrj 	: _M_param(__nw, __xmin, __xmax, __fw)
5498*38fd1498Szrj 	{ }
5499*38fd1498Szrj 
5500*38fd1498Szrj       explicit
5501*38fd1498Szrj       piecewise_constant_distribution(const param_type& __p)
5502*38fd1498Szrj       : _M_param(__p)
5503*38fd1498Szrj       { }
5504*38fd1498Szrj 
5505*38fd1498Szrj       /**
5506*38fd1498Szrj        * @brief Resets the distribution state.
5507*38fd1498Szrj        */
5508*38fd1498Szrj       void
5509*38fd1498Szrj       reset()
5510*38fd1498Szrj       { }
5511*38fd1498Szrj 
5512*38fd1498Szrj       /**
5513*38fd1498Szrj        * @brief Returns a vector of the intervals.
5514*38fd1498Szrj        */
5515*38fd1498Szrj       std::vector<_RealType>
5516*38fd1498Szrj       intervals() const
5517*38fd1498Szrj       {
5518*38fd1498Szrj 	if (_M_param._M_int.empty())
5519*38fd1498Szrj 	  {
5520*38fd1498Szrj 	    std::vector<_RealType> __tmp(2);
5521*38fd1498Szrj 	    __tmp[1] = _RealType(1);
5522*38fd1498Szrj 	    return __tmp;
5523*38fd1498Szrj 	  }
5524*38fd1498Szrj 	else
5525*38fd1498Szrj 	  return _M_param._M_int;
5526*38fd1498Szrj       }
5527*38fd1498Szrj 
5528*38fd1498Szrj       /**
5529*38fd1498Szrj        * @brief Returns a vector of the probability densities.
5530*38fd1498Szrj        */
5531*38fd1498Szrj       std::vector<double>
5532*38fd1498Szrj       densities() const
5533*38fd1498Szrj       {
5534*38fd1498Szrj 	return _M_param._M_den.empty()
5535*38fd1498Szrj 	  ? std::vector<double>(1, 1.0) : _M_param._M_den;
5536*38fd1498Szrj       }
5537*38fd1498Szrj 
5538*38fd1498Szrj       /**
5539*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
5540*38fd1498Szrj        */
5541*38fd1498Szrj       param_type
5542*38fd1498Szrj       param() const
5543*38fd1498Szrj       { return _M_param; }
5544*38fd1498Szrj 
5545*38fd1498Szrj       /**
5546*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
5547*38fd1498Szrj        * @param __param The new parameter set of the distribution.
5548*38fd1498Szrj        */
5549*38fd1498Szrj       void
5550*38fd1498Szrj       param(const param_type& __param)
5551*38fd1498Szrj       { _M_param = __param; }
5552*38fd1498Szrj 
5553*38fd1498Szrj       /**
5554*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
5555*38fd1498Szrj        */
5556*38fd1498Szrj       result_type
5557*38fd1498Szrj       min() const
5558*38fd1498Szrj       {
5559*38fd1498Szrj 	return _M_param._M_int.empty()
5560*38fd1498Szrj 	  ? result_type(0) : _M_param._M_int.front();
5561*38fd1498Szrj       }
5562*38fd1498Szrj 
5563*38fd1498Szrj       /**
5564*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
5565*38fd1498Szrj        */
5566*38fd1498Szrj       result_type
5567*38fd1498Szrj       max() const
5568*38fd1498Szrj       {
5569*38fd1498Szrj 	return _M_param._M_int.empty()
5570*38fd1498Szrj 	  ? result_type(1) : _M_param._M_int.back();
5571*38fd1498Szrj       }
5572*38fd1498Szrj 
5573*38fd1498Szrj       /**
5574*38fd1498Szrj        * @brief Generating functions.
5575*38fd1498Szrj        */
5576*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
5577*38fd1498Szrj 	result_type
5578*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
5579*38fd1498Szrj 	{ return this->operator()(__urng, _M_param); }
5580*38fd1498Szrj 
5581*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
5582*38fd1498Szrj 	result_type
5583*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
5584*38fd1498Szrj 		   const param_type& __p);
5585*38fd1498Szrj 
5586*38fd1498Szrj       template<typename _ForwardIterator,
5587*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
5588*38fd1498Szrj 	void
5589*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
5590*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
5591*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
5592*38fd1498Szrj 
5593*38fd1498Szrj       template<typename _ForwardIterator,
5594*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
5595*38fd1498Szrj 	void
5596*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
5597*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
5598*38fd1498Szrj 		   const param_type& __p)
5599*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
5600*38fd1498Szrj 
5601*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
5602*38fd1498Szrj 	void
5603*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
5604*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
5605*38fd1498Szrj 		   const param_type& __p)
5606*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
5607*38fd1498Szrj 
5608*38fd1498Szrj       /**
5609*38fd1498Szrj        * @brief Return true if two piecewise constant distributions have the
5610*38fd1498Szrj        *        same parameters.
5611*38fd1498Szrj        */
5612*38fd1498Szrj       friend bool
5613*38fd1498Szrj       operator==(const piecewise_constant_distribution& __d1,
5614*38fd1498Szrj 		 const piecewise_constant_distribution& __d2)
5615*38fd1498Szrj       { return __d1._M_param == __d2._M_param; }
5616*38fd1498Szrj 
5617*38fd1498Szrj       /**
5618*38fd1498Szrj        * @brief Inserts a %piecewise_constant_distribution random
5619*38fd1498Szrj        *        number distribution @p __x into the output stream @p __os.
5620*38fd1498Szrj        *
5621*38fd1498Szrj        * @param __os An output stream.
5622*38fd1498Szrj        * @param __x  A %piecewise_constant_distribution random number
5623*38fd1498Szrj        *             distribution.
5624*38fd1498Szrj        *
5625*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
5626*38fd1498Szrj        * an error state.
5627*38fd1498Szrj        */
5628*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
5629*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
5630*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5631*38fd1498Szrj 		   const std::piecewise_constant_distribution<_RealType1>& __x);
5632*38fd1498Szrj 
5633*38fd1498Szrj       /**
5634*38fd1498Szrj        * @brief Extracts a %piecewise_constant_distribution random
5635*38fd1498Szrj        *        number distribution @p __x from the input stream @p __is.
5636*38fd1498Szrj        *
5637*38fd1498Szrj        * @param __is An input stream.
5638*38fd1498Szrj        * @param __x A %piecewise_constant_distribution random number
5639*38fd1498Szrj        *            generator engine.
5640*38fd1498Szrj        *
5641*38fd1498Szrj        * @returns The input stream with @p __x extracted or in an error
5642*38fd1498Szrj        *          state.
5643*38fd1498Szrj        */
5644*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
5645*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
5646*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
5647*38fd1498Szrj 		   std::piecewise_constant_distribution<_RealType1>& __x);
5648*38fd1498Szrj 
5649*38fd1498Szrj     private:
5650*38fd1498Szrj       template<typename _ForwardIterator,
5651*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
5652*38fd1498Szrj 	void
5653*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
5654*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
5655*38fd1498Szrj 			const param_type& __p);
5656*38fd1498Szrj 
5657*38fd1498Szrj       param_type _M_param;
5658*38fd1498Szrj     };
5659*38fd1498Szrj 
5660*38fd1498Szrj   /**
5661*38fd1498Szrj     * @brief Return true if two piecewise constant distributions have
5662*38fd1498Szrj     *        different parameters.
5663*38fd1498Szrj    */
5664*38fd1498Szrj   template<typename _RealType>
5665*38fd1498Szrj     inline bool
5666*38fd1498Szrj     operator!=(const std::piecewise_constant_distribution<_RealType>& __d1,
5667*38fd1498Szrj 	       const std::piecewise_constant_distribution<_RealType>& __d2)
5668*38fd1498Szrj     { return !(__d1 == __d2); }
5669*38fd1498Szrj 
5670*38fd1498Szrj 
5671*38fd1498Szrj   /**
5672*38fd1498Szrj    * @brief A piecewise_linear_distribution random number distribution.
5673*38fd1498Szrj    *
5674*38fd1498Szrj    * The formula for the piecewise linear probability mass function is
5675*38fd1498Szrj    *
5676*38fd1498Szrj    */
5677*38fd1498Szrj   template<typename _RealType = double>
5678*38fd1498Szrj     class piecewise_linear_distribution
5679*38fd1498Szrj     {
5680*38fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
5681*38fd1498Szrj 		    "result_type must be a floating point type");
5682*38fd1498Szrj 
5683*38fd1498Szrj     public:
5684*38fd1498Szrj       /** The type of the range of the distribution. */
5685*38fd1498Szrj       typedef _RealType result_type;
5686*38fd1498Szrj 
5687*38fd1498Szrj       /** Parameter type. */
5688*38fd1498Szrj       struct param_type
5689*38fd1498Szrj       {
5690*38fd1498Szrj 	typedef piecewise_linear_distribution<_RealType> distribution_type;
5691*38fd1498Szrj 	friend class piecewise_linear_distribution<_RealType>;
5692*38fd1498Szrj 
5693*38fd1498Szrj 	param_type()
5694*38fd1498Szrj 	: _M_int(), _M_den(), _M_cp(), _M_m()
5695*38fd1498Szrj 	{ }
5696*38fd1498Szrj 
5697*38fd1498Szrj 	template<typename _InputIteratorB, typename _InputIteratorW>
5698*38fd1498Szrj 	  param_type(_InputIteratorB __bfirst,
5699*38fd1498Szrj 		     _InputIteratorB __bend,
5700*38fd1498Szrj 		     _InputIteratorW __wbegin);
5701*38fd1498Szrj 
5702*38fd1498Szrj 	template<typename _Func>
5703*38fd1498Szrj 	  param_type(initializer_list<_RealType> __bl, _Func __fw);
5704*38fd1498Szrj 
5705*38fd1498Szrj 	template<typename _Func>
5706*38fd1498Szrj 	  param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
5707*38fd1498Szrj 		     _Func __fw);
5708*38fd1498Szrj 
5709*38fd1498Szrj 	// See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
5710*38fd1498Szrj 	param_type(const param_type&) = default;
5711*38fd1498Szrj 	param_type& operator=(const param_type&) = default;
5712*38fd1498Szrj 
5713*38fd1498Szrj 	std::vector<_RealType>
5714*38fd1498Szrj 	intervals() const
5715*38fd1498Szrj 	{
5716*38fd1498Szrj 	  if (_M_int.empty())
5717*38fd1498Szrj 	    {
5718*38fd1498Szrj 	      std::vector<_RealType> __tmp(2);
5719*38fd1498Szrj 	      __tmp[1] = _RealType(1);
5720*38fd1498Szrj 	      return __tmp;
5721*38fd1498Szrj 	    }
5722*38fd1498Szrj 	  else
5723*38fd1498Szrj 	    return _M_int;
5724*38fd1498Szrj 	}
5725*38fd1498Szrj 
5726*38fd1498Szrj 	std::vector<double>
5727*38fd1498Szrj 	densities() const
5728*38fd1498Szrj 	{ return _M_den.empty() ? std::vector<double>(2, 1.0) : _M_den; }
5729*38fd1498Szrj 
5730*38fd1498Szrj 	friend bool
5731*38fd1498Szrj 	operator==(const param_type& __p1, const param_type& __p2)
5732*38fd1498Szrj 	{ return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; }
5733*38fd1498Szrj 
5734*38fd1498Szrj 	friend bool
5735*38fd1498Szrj 	operator!=(const param_type& __p1, const param_type& __p2)
5736*38fd1498Szrj 	{ return !(__p1 == __p2); }
5737*38fd1498Szrj 
5738*38fd1498Szrj       private:
5739*38fd1498Szrj 	void
5740*38fd1498Szrj 	_M_initialize();
5741*38fd1498Szrj 
5742*38fd1498Szrj 	std::vector<_RealType> _M_int;
5743*38fd1498Szrj 	std::vector<double> _M_den;
5744*38fd1498Szrj 	std::vector<double> _M_cp;
5745*38fd1498Szrj 	std::vector<double> _M_m;
5746*38fd1498Szrj       };
5747*38fd1498Szrj 
5748*38fd1498Szrj       explicit
5749*38fd1498Szrj       piecewise_linear_distribution()
5750*38fd1498Szrj       : _M_param()
5751*38fd1498Szrj       { }
5752*38fd1498Szrj 
5753*38fd1498Szrj       template<typename _InputIteratorB, typename _InputIteratorW>
5754*38fd1498Szrj 	piecewise_linear_distribution(_InputIteratorB __bfirst,
5755*38fd1498Szrj 				      _InputIteratorB __bend,
5756*38fd1498Szrj 				      _InputIteratorW __wbegin)
5757*38fd1498Szrj 	: _M_param(__bfirst, __bend, __wbegin)
5758*38fd1498Szrj 	{ }
5759*38fd1498Szrj 
5760*38fd1498Szrj       template<typename _Func>
5761*38fd1498Szrj 	piecewise_linear_distribution(initializer_list<_RealType> __bl,
5762*38fd1498Szrj 				      _Func __fw)
5763*38fd1498Szrj 	: _M_param(__bl, __fw)
5764*38fd1498Szrj 	{ }
5765*38fd1498Szrj 
5766*38fd1498Szrj       template<typename _Func>
5767*38fd1498Szrj 	piecewise_linear_distribution(size_t __nw,
5768*38fd1498Szrj 				      _RealType __xmin, _RealType __xmax,
5769*38fd1498Szrj 				      _Func __fw)
5770*38fd1498Szrj 	: _M_param(__nw, __xmin, __xmax, __fw)
5771*38fd1498Szrj 	{ }
5772*38fd1498Szrj 
5773*38fd1498Szrj       explicit
5774*38fd1498Szrj       piecewise_linear_distribution(const param_type& __p)
5775*38fd1498Szrj       : _M_param(__p)
5776*38fd1498Szrj       { }
5777*38fd1498Szrj 
5778*38fd1498Szrj       /**
5779*38fd1498Szrj        * Resets the distribution state.
5780*38fd1498Szrj        */
5781*38fd1498Szrj       void
5782*38fd1498Szrj       reset()
5783*38fd1498Szrj       { }
5784*38fd1498Szrj 
5785*38fd1498Szrj       /**
5786*38fd1498Szrj        * @brief Return the intervals of the distribution.
5787*38fd1498Szrj        */
5788*38fd1498Szrj       std::vector<_RealType>
5789*38fd1498Szrj       intervals() const
5790*38fd1498Szrj       {
5791*38fd1498Szrj 	if (_M_param._M_int.empty())
5792*38fd1498Szrj 	  {
5793*38fd1498Szrj 	    std::vector<_RealType> __tmp(2);
5794*38fd1498Szrj 	    __tmp[1] = _RealType(1);
5795*38fd1498Szrj 	    return __tmp;
5796*38fd1498Szrj 	  }
5797*38fd1498Szrj 	else
5798*38fd1498Szrj 	  return _M_param._M_int;
5799*38fd1498Szrj       }
5800*38fd1498Szrj 
5801*38fd1498Szrj       /**
5802*38fd1498Szrj        * @brief Return a vector of the probability densities of the
5803*38fd1498Szrj        *        distribution.
5804*38fd1498Szrj        */
5805*38fd1498Szrj       std::vector<double>
5806*38fd1498Szrj       densities() const
5807*38fd1498Szrj       {
5808*38fd1498Szrj 	return _M_param._M_den.empty()
5809*38fd1498Szrj 	  ? std::vector<double>(2, 1.0) : _M_param._M_den;
5810*38fd1498Szrj       }
5811*38fd1498Szrj 
5812*38fd1498Szrj       /**
5813*38fd1498Szrj        * @brief Returns the parameter set of the distribution.
5814*38fd1498Szrj        */
5815*38fd1498Szrj       param_type
5816*38fd1498Szrj       param() const
5817*38fd1498Szrj       { return _M_param; }
5818*38fd1498Szrj 
5819*38fd1498Szrj       /**
5820*38fd1498Szrj        * @brief Sets the parameter set of the distribution.
5821*38fd1498Szrj        * @param __param The new parameter set of the distribution.
5822*38fd1498Szrj        */
5823*38fd1498Szrj       void
5824*38fd1498Szrj       param(const param_type& __param)
5825*38fd1498Szrj       { _M_param = __param; }
5826*38fd1498Szrj 
5827*38fd1498Szrj       /**
5828*38fd1498Szrj        * @brief Returns the greatest lower bound value of the distribution.
5829*38fd1498Szrj        */
5830*38fd1498Szrj       result_type
5831*38fd1498Szrj       min() const
5832*38fd1498Szrj       {
5833*38fd1498Szrj 	return _M_param._M_int.empty()
5834*38fd1498Szrj 	  ? result_type(0) : _M_param._M_int.front();
5835*38fd1498Szrj       }
5836*38fd1498Szrj 
5837*38fd1498Szrj       /**
5838*38fd1498Szrj        * @brief Returns the least upper bound value of the distribution.
5839*38fd1498Szrj        */
5840*38fd1498Szrj       result_type
5841*38fd1498Szrj       max() const
5842*38fd1498Szrj       {
5843*38fd1498Szrj 	return _M_param._M_int.empty()
5844*38fd1498Szrj 	  ? result_type(1) : _M_param._M_int.back();
5845*38fd1498Szrj       }
5846*38fd1498Szrj 
5847*38fd1498Szrj       /**
5848*38fd1498Szrj        * @brief Generating functions.
5849*38fd1498Szrj        */
5850*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
5851*38fd1498Szrj 	result_type
5852*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng)
5853*38fd1498Szrj 	{ return this->operator()(__urng, _M_param); }
5854*38fd1498Szrj 
5855*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
5856*38fd1498Szrj 	result_type
5857*38fd1498Szrj 	operator()(_UniformRandomNumberGenerator& __urng,
5858*38fd1498Szrj 		   const param_type& __p);
5859*38fd1498Szrj 
5860*38fd1498Szrj       template<typename _ForwardIterator,
5861*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
5862*38fd1498Szrj 	void
5863*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
5864*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng)
5865*38fd1498Szrj 	{ this->__generate(__f, __t, __urng, _M_param); }
5866*38fd1498Szrj 
5867*38fd1498Szrj       template<typename _ForwardIterator,
5868*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
5869*38fd1498Szrj 	void
5870*38fd1498Szrj 	__generate(_ForwardIterator __f, _ForwardIterator __t,
5871*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
5872*38fd1498Szrj 		   const param_type& __p)
5873*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
5874*38fd1498Szrj 
5875*38fd1498Szrj       template<typename _UniformRandomNumberGenerator>
5876*38fd1498Szrj 	void
5877*38fd1498Szrj 	__generate(result_type* __f, result_type* __t,
5878*38fd1498Szrj 		   _UniformRandomNumberGenerator& __urng,
5879*38fd1498Szrj 		   const param_type& __p)
5880*38fd1498Szrj 	{ this->__generate_impl(__f, __t, __urng, __p); }
5881*38fd1498Szrj 
5882*38fd1498Szrj       /**
5883*38fd1498Szrj        * @brief Return true if two piecewise linear distributions have the
5884*38fd1498Szrj        *        same parameters.
5885*38fd1498Szrj        */
5886*38fd1498Szrj       friend bool
5887*38fd1498Szrj       operator==(const piecewise_linear_distribution& __d1,
5888*38fd1498Szrj 		 const piecewise_linear_distribution& __d2)
5889*38fd1498Szrj       { return __d1._M_param == __d2._M_param; }
5890*38fd1498Szrj 
5891*38fd1498Szrj       /**
5892*38fd1498Szrj        * @brief Inserts a %piecewise_linear_distribution random number
5893*38fd1498Szrj        *        distribution @p __x into the output stream @p __os.
5894*38fd1498Szrj        *
5895*38fd1498Szrj        * @param __os An output stream.
5896*38fd1498Szrj        * @param __x  A %piecewise_linear_distribution random number
5897*38fd1498Szrj        *             distribution.
5898*38fd1498Szrj        *
5899*38fd1498Szrj        * @returns The output stream with the state of @p __x inserted or in
5900*38fd1498Szrj        *          an error state.
5901*38fd1498Szrj        */
5902*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
5903*38fd1498Szrj 	friend std::basic_ostream<_CharT, _Traits>&
5904*38fd1498Szrj 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5905*38fd1498Szrj 		   const std::piecewise_linear_distribution<_RealType1>& __x);
5906*38fd1498Szrj 
5907*38fd1498Szrj       /**
5908*38fd1498Szrj        * @brief Extracts a %piecewise_linear_distribution random number
5909*38fd1498Szrj        *        distribution @p __x from the input stream @p __is.
5910*38fd1498Szrj        *
5911*38fd1498Szrj        * @param __is An input stream.
5912*38fd1498Szrj        * @param __x  A %piecewise_linear_distribution random number
5913*38fd1498Szrj        *             generator engine.
5914*38fd1498Szrj        *
5915*38fd1498Szrj        * @returns The input stream with @p __x extracted or in an error
5916*38fd1498Szrj        *          state.
5917*38fd1498Szrj        */
5918*38fd1498Szrj       template<typename _RealType1, typename _CharT, typename _Traits>
5919*38fd1498Szrj 	friend std::basic_istream<_CharT, _Traits>&
5920*38fd1498Szrj 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
5921*38fd1498Szrj 		   std::piecewise_linear_distribution<_RealType1>& __x);
5922*38fd1498Szrj 
5923*38fd1498Szrj     private:
5924*38fd1498Szrj       template<typename _ForwardIterator,
5925*38fd1498Szrj 	       typename _UniformRandomNumberGenerator>
5926*38fd1498Szrj 	void
5927*38fd1498Szrj 	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
5928*38fd1498Szrj 			_UniformRandomNumberGenerator& __urng,
5929*38fd1498Szrj 			const param_type& __p);
5930*38fd1498Szrj 
5931*38fd1498Szrj       param_type _M_param;
5932*38fd1498Szrj     };
5933*38fd1498Szrj 
5934*38fd1498Szrj   /**
5935*38fd1498Szrj     * @brief Return true if two piecewise linear distributions have
5936*38fd1498Szrj     *        different parameters.
5937*38fd1498Szrj    */
5938*38fd1498Szrj   template<typename _RealType>
5939*38fd1498Szrj     inline bool
5940*38fd1498Szrj     operator!=(const std::piecewise_linear_distribution<_RealType>& __d1,
5941*38fd1498Szrj 	       const std::piecewise_linear_distribution<_RealType>& __d2)
5942*38fd1498Szrj     { return !(__d1 == __d2); }
5943*38fd1498Szrj 
5944*38fd1498Szrj 
5945*38fd1498Szrj   /* @} */ // group random_distributions_poisson
5946*38fd1498Szrj 
5947*38fd1498Szrj   /* @} */ // group random_distributions
5948*38fd1498Szrj 
5949*38fd1498Szrj   /**
5950*38fd1498Szrj    * @addtogroup random_utilities Random Number Utilities
5951*38fd1498Szrj    * @ingroup random
5952*38fd1498Szrj    * @{
5953*38fd1498Szrj    */
5954*38fd1498Szrj 
5955*38fd1498Szrj   /**
5956*38fd1498Szrj    * @brief The seed_seq class generates sequences of seeds for random
5957*38fd1498Szrj    *        number generators.
5958*38fd1498Szrj    */
5959*38fd1498Szrj   class seed_seq
5960*38fd1498Szrj   {
5961*38fd1498Szrj   public:
5962*38fd1498Szrj     /** The type of the seed vales. */
5963*38fd1498Szrj     typedef uint_least32_t result_type;
5964*38fd1498Szrj 
5965*38fd1498Szrj     /** Default constructor. */
5966*38fd1498Szrj     seed_seq() noexcept
5967*38fd1498Szrj     : _M_v()
5968*38fd1498Szrj     { }
5969*38fd1498Szrj 
5970*38fd1498Szrj     template<typename _IntType>
5971*38fd1498Szrj       seed_seq(std::initializer_list<_IntType> il);
5972*38fd1498Szrj 
5973*38fd1498Szrj     template<typename _InputIterator>
5974*38fd1498Szrj       seed_seq(_InputIterator __begin, _InputIterator __end);
5975*38fd1498Szrj 
5976*38fd1498Szrj     // generating functions
5977*38fd1498Szrj     template<typename _RandomAccessIterator>
5978*38fd1498Szrj       void
5979*38fd1498Szrj       generate(_RandomAccessIterator __begin, _RandomAccessIterator __end);
5980*38fd1498Szrj 
5981*38fd1498Szrj     // property functions
5982*38fd1498Szrj     size_t size() const noexcept
5983*38fd1498Szrj     { return _M_v.size(); }
5984*38fd1498Szrj 
5985*38fd1498Szrj     template<typename OutputIterator>
5986*38fd1498Szrj       void
5987*38fd1498Szrj       param(OutputIterator __dest) const
5988*38fd1498Szrj       { std::copy(_M_v.begin(), _M_v.end(), __dest); }
5989*38fd1498Szrj 
5990*38fd1498Szrj     // no copy functions
5991*38fd1498Szrj     seed_seq(const seed_seq&) = delete;
5992*38fd1498Szrj     seed_seq& operator=(const seed_seq&) = delete;
5993*38fd1498Szrj 
5994*38fd1498Szrj   private:
5995*38fd1498Szrj     std::vector<result_type> _M_v;
5996*38fd1498Szrj   };
5997*38fd1498Szrj 
5998*38fd1498Szrj   /* @} */ // group random_utilities
5999*38fd1498Szrj 
6000*38fd1498Szrj   /* @} */ // group random
6001*38fd1498Szrj 
6002*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
6003*38fd1498Szrj } // namespace std
6004*38fd1498Szrj 
6005*38fd1498Szrj #endif
6006