LCOV - code coverage report
Current view: top level - usr/include/c++/8/bits - random.h (source / functions) Hit Total Coverage
Test: Coverage example Lines: 29 29 100.0 %
Date: 2021-12-02 17:21:05 Functions: 17 17 100.0 %

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

Generated by: LCOV version 1.14