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