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