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