Files
BayesNet/html/usr/include/c++/13/bits/random.h.gcov.html

677 KiB

<html lang="en"> <head> </head>
LCOV - code coverage report
Current view: top level - /usr/include/c++/13/bits - random.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 15 15
Test Date: 2024-04-30 13:17:26 Functions: 100.0 % 9 9

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

Generated by: LCOV version 2.0-1

</html>