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