LCOV - code coverage report
Current view: top level - 11/bits - random.h (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 14 14 100.0 %
Date: 2025-08-24 09:11:10 Functions: 11 11 100.0 %

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

Generated by: LCOV version 1.14