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