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