libstdc++
random.h
Go to the documentation of this file.
00001 // random number generation -*- C++ -*-
00002 
00003 // Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /**
00026  * @file bits/random.h
00027  *  This is an internal header file, included by other library headers.
00028  *  Do not attempt to use it directly. @headername{random}
00029  */
00030 
00031 #ifndef _RANDOM_H
00032 #define _RANDOM_H 1
00033 
00034 #include <vector>
00035 
00036 namespace std _GLIBCXX_VISIBILITY(default)
00037 {
00038 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00039 
00040   // [26.4] Random number generation
00041 
00042   /**
00043    * @defgroup random Random Number Generation
00044    * @ingroup numerics
00045    *
00046    * A facility for generating random numbers on selected distributions.
00047    * @{
00048    */
00049 
00050   /**
00051    * @brief A function template for converting the output of a (integral)
00052    * uniform random number generator to a floatng point result in the range
00053    * [0-1).
00054    */
00055   template<typename _RealType, size_t __bits,
00056        typename _UniformRandomNumberGenerator>
00057     _RealType
00058     generate_canonical(_UniformRandomNumberGenerator& __g);
00059 
00060 _GLIBCXX_END_NAMESPACE_VERSION
00061 
00062   /*
00063    * Implementation-space details.
00064    */
00065   namespace __detail
00066   {
00067   _GLIBCXX_BEGIN_NAMESPACE_VERSION
00068 
00069     template<typename _UIntType, size_t __w,
00070          bool = __w < static_cast<size_t>
00071               (std::numeric_limits<_UIntType>::digits)>
00072       struct _Shift
00073       { static const _UIntType __value = 0; };
00074 
00075     template<typename _UIntType, size_t __w>
00076       struct _Shift<_UIntType, __w, true>
00077       { static const _UIntType __value = _UIntType(1) << __w; };
00078 
00079     template<typename _Tp, _Tp __m, _Tp __a, _Tp __c, bool>
00080       struct _Mod;
00081 
00082     // Dispatch based on modulus value to prevent divide-by-zero compile-time
00083     // errors when m == 0.
00084     template<typename _Tp, _Tp __m, _Tp __a = 1, _Tp __c = 0>
00085       inline _Tp
00086       __mod(_Tp __x)
00087       { return _Mod<_Tp, __m, __a, __c, __m == 0>::__calc(__x); }
00088 
00089     /*
00090      * An adaptor class for converting the output of any Generator into
00091      * the input for a specific Distribution.
00092      */
00093     template<typename _Engine, typename _DInputType>
00094       struct _Adaptor
00095       {
00096 
00097       public:
00098     _Adaptor(_Engine& __g)
00099     : _M_g(__g) { }
00100 
00101     _DInputType
00102     min() const
00103     { return _DInputType(0); }
00104 
00105     _DInputType
00106     max() const
00107     { return _DInputType(1); }
00108 
00109     /*
00110      * Converts a value generated by the adapted random number generator
00111      * into a value in the input domain for the dependent random number
00112      * distribution.
00113      */
00114     _DInputType
00115     operator()()
00116     {
00117       return std::generate_canonical<_DInputType,
00118                                 std::numeric_limits<_DInputType>::digits,
00119                                 _Engine>(_M_g);
00120     }
00121 
00122       private:
00123     _Engine& _M_g;
00124       };
00125 
00126   _GLIBCXX_END_NAMESPACE_VERSION
00127   } // namespace __detail
00128 
00129 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00130 
00131   /**
00132    * @addtogroup random_generators Random Number Generators
00133    * @ingroup random
00134    *
00135    * These classes define objects which provide random or pseudorandom
00136    * numbers, either from a discrete or a continuous interval.  The
00137    * random number generator supplied as a part of this library are
00138    * all uniform random number generators which provide a sequence of
00139    * random number uniformly distributed over their range.
00140    *
00141    * A number generator is a function object with an operator() that
00142    * takes zero arguments and returns a number.
00143    *
00144    * A compliant random number generator must satisfy the following
00145    * requirements.  <table border=1 cellpadding=10 cellspacing=0>
00146    * <caption align=top>Random Number Generator Requirements</caption>
00147    * <tr><td>To be documented.</td></tr> </table>
00148    *
00149    * @{
00150    */
00151 
00152   /**
00153    * @brief A model of a linear congruential random number generator.
00154    *
00155    * A random number generator that produces pseudorandom numbers via
00156    * linear function:
00157    * @f[
00158    *     x_{i+1}\leftarrow(ax_{i} + c) \bmod m 
00159    * @f]
00160    *
00161    * The template parameter @p _UIntType must be an unsigned integral type
00162    * large enough to store values up to (__m-1). If the template parameter
00163    * @p __m is 0, the modulus @p __m used is
00164    * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
00165    * parameters @p __a and @p __c must be less than @p __m.
00166    *
00167    * The size of the state is @f$1@f$.
00168    */
00169   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
00170     class linear_congruential_engine
00171     {
00172       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
00173             "substituting _UIntType not an unsigned integral type");
00174       static_assert(__m == 0u || (__a < __m && __c < __m),
00175             "template argument substituting __m out of bounds");
00176 
00177       // XXX FIXME:
00178       // _Mod::__calc should handle correctly __m % __a >= __m / __a too.
00179       static_assert(__m % __a < __m / __a,
00180             "sorry, not implemented yet: try a smaller 'a' constant");
00181 
00182     public:
00183       /** The type of the generated random value. */
00184       typedef _UIntType result_type;
00185 
00186       /** The multiplier. */
00187       static constexpr result_type multiplier   = __a;
00188       /** An increment. */
00189       static constexpr result_type increment    = __c;
00190       /** The modulus. */
00191       static constexpr result_type modulus      = __m;
00192       static constexpr result_type default_seed = 1u;
00193 
00194       /**
00195        * @brief Constructs a %linear_congruential_engine random number
00196        *        generator engine with seed @p __s.  The default seed value
00197        *        is 1.
00198        *
00199        * @param __s The initial seed value.
00200        */
00201       explicit
00202       linear_congruential_engine(result_type __s = default_seed)
00203       { seed(__s); }
00204 
00205       /**
00206        * @brief Constructs a %linear_congruential_engine random number
00207        *        generator engine seeded from the seed sequence @p __q.
00208        *
00209        * @param __q the seed sequence.
00210        */
00211       template<typename _Sseq, typename = typename
00212     std::enable_if<!std::is_same<_Sseq, linear_congruential_engine>::value>
00213            ::type>
00214         explicit
00215         linear_congruential_engine(_Sseq& __q)
00216         { seed(__q); }
00217 
00218       /**
00219        * @brief Reseeds the %linear_congruential_engine random number generator
00220        *        engine sequence to the seed @p __s.
00221        *
00222        * @param __s The new seed.
00223        */
00224       void
00225       seed(result_type __s = default_seed);
00226 
00227       /**
00228        * @brief Reseeds the %linear_congruential_engine random number generator
00229        *        engine
00230        * sequence using values from the seed sequence @p __q.
00231        *
00232        * @param __q the seed sequence.
00233        */
00234       template<typename _Sseq>
00235         typename std::enable_if<std::is_class<_Sseq>::value>::type
00236         seed(_Sseq& __q);
00237 
00238       /**
00239        * @brief Gets the smallest possible value in the output range.
00240        *
00241        * The minimum depends on the @p __c parameter: if it is zero, the
00242        * minimum generated must be > 0, otherwise 0 is allowed.
00243        */
00244       static constexpr result_type
00245       min()
00246       { return __c == 0u ? 1u : 0u; }
00247 
00248       /**
00249        * @brief Gets the largest possible value in the output range.
00250        */
00251       static constexpr result_type
00252       max()
00253       { return __m - 1u; }
00254 
00255       /**
00256        * @brief Discard a sequence of random numbers.
00257        */
00258       void
00259       discard(unsigned long long __z)
00260       {
00261     for (; __z != 0ULL; --__z)
00262       (*this)();
00263       }
00264 
00265       /**
00266        * @brief Gets the next random number in the sequence.
00267        */
00268       result_type
00269       operator()()
00270       {
00271     _M_x = __detail::__mod<_UIntType, __m, __a, __c>(_M_x);
00272     return _M_x;
00273       }
00274 
00275       /**
00276        * @brief Compares two linear congruential random number generator
00277        * objects of the same type for equality.
00278        *
00279        * @param __lhs A linear congruential random number generator object.
00280        * @param __rhs Another linear congruential random number generator
00281        *              object.
00282        *
00283        * @returns true if the infinite sequences of generated values
00284        *          would be equal, false otherwise.
00285        */
00286       friend bool
00287       operator==(const linear_congruential_engine& __lhs,
00288          const linear_congruential_engine& __rhs)
00289       { return __lhs._M_x == __rhs._M_x; }
00290 
00291       /**
00292        * @brief Writes the textual representation of the state x(i) of x to
00293        *        @p __os.
00294        *
00295        * @param __os  The output stream.
00296        * @param __lcr A % linear_congruential_engine random number generator.
00297        * @returns __os.
00298        */
00299       template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
00300            _UIntType1 __m1, typename _CharT, typename _Traits>
00301     friend std::basic_ostream<_CharT, _Traits>&
00302     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00303            const std::linear_congruential_engine<_UIntType1,
00304            __a1, __c1, __m1>& __lcr);
00305 
00306       /**
00307        * @brief Sets the state of the engine by reading its textual
00308        *        representation from @p __is.
00309        *
00310        * The textual representation must have been previously written using
00311        * an output stream whose imbued locale and whose type's template
00312        * specialization arguments _CharT and _Traits were the same as those
00313        * of @p __is.
00314        *
00315        * @param __is  The input stream.
00316        * @param __lcr A % linear_congruential_engine random number generator.
00317        * @returns __is.
00318        */
00319       template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
00320            _UIntType1 __m1, typename _CharT, typename _Traits>
00321     friend std::basic_istream<_CharT, _Traits>&
00322     operator>>(std::basic_istream<_CharT, _Traits>& __is,
00323            std::linear_congruential_engine<_UIntType1, __a1,
00324            __c1, __m1>& __lcr);
00325 
00326     private:
00327       _UIntType _M_x;
00328     };
00329 
00330   /**
00331    * @brief Compares two linear congruential random number generator
00332    * objects of the same type for inequality.
00333    *
00334    * @param __lhs A linear congruential random number generator object.
00335    * @param __rhs Another linear congruential random number generator
00336    *              object.
00337    *
00338    * @returns true if the infinite sequences of generated values
00339    *          would be different, false otherwise.
00340    */
00341   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
00342     inline bool
00343     operator!=(const std::linear_congruential_engine<_UIntType, __a,
00344            __c, __m>& __lhs,
00345            const std::linear_congruential_engine<_UIntType, __a,
00346            __c, __m>& __rhs)
00347     { return !(__lhs == __rhs); }
00348 
00349 
00350   /**
00351    * A generalized feedback shift register discrete random number generator.
00352    *
00353    * This algorithm avoids multiplication and division and is designed to be
00354    * friendly to a pipelined architecture.  If the parameters are chosen
00355    * correctly, this generator will produce numbers with a very long period and
00356    * fairly good apparent entropy, although still not cryptographically strong.
00357    *
00358    * The best way to use this generator is with the predefined mt19937 class.
00359    *
00360    * This algorithm was originally invented by Makoto Matsumoto and
00361    * Takuji Nishimura.
00362    *
00363    * @tparam __w  Word size, the number of bits in each element of 
00364    *              the state vector.
00365    * @tparam __n  The degree of recursion.
00366    * @tparam __m  The period parameter.
00367    * @tparam __r  The separation point bit index.
00368    * @tparam __a  The last row of the twist matrix.
00369    * @tparam __u  The first right-shift tempering matrix parameter.
00370    * @tparam __d  The first right-shift tempering matrix mask.
00371    * @tparam __s  The first left-shift tempering matrix parameter.
00372    * @tparam __b  The first left-shift tempering matrix mask.
00373    * @tparam __t  The second left-shift tempering matrix parameter.
00374    * @tparam __c  The second left-shift tempering matrix mask.
00375    * @tparam __l  The second right-shift tempering matrix parameter.
00376    * @tparam __f  Initialization multiplier.
00377    */
00378   template<typename _UIntType, size_t __w,
00379        size_t __n, size_t __m, size_t __r,
00380        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00381        _UIntType __b, size_t __t,
00382        _UIntType __c, size_t __l, _UIntType __f>
00383     class mersenne_twister_engine
00384     {
00385       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
00386             "substituting _UIntType not an unsigned integral type");
00387       static_assert(1u <= __m && __m <= __n,
00388             "template argument substituting __m out of bounds");
00389       static_assert(__r <= __w, "template argument substituting "
00390             "__r out of bound");
00391       static_assert(__u <= __w, "template argument substituting "
00392             "__u out of bound");
00393       static_assert(__s <= __w, "template argument substituting "
00394             "__s out of bound");
00395       static_assert(__t <= __w, "template argument substituting "
00396             "__t out of bound");
00397       static_assert(__l <= __w, "template argument substituting "
00398             "__l out of bound");
00399       static_assert(__w <= std::numeric_limits<_UIntType>::digits,
00400             "template argument substituting __w out of bound");
00401       static_assert(__a <= (__detail::_Shift<_UIntType, __w>::__value - 1),
00402             "template argument substituting __a out of bound");
00403       static_assert(__b <= (__detail::_Shift<_UIntType, __w>::__value - 1),
00404             "template argument substituting __b out of bound");
00405       static_assert(__c <= (__detail::_Shift<_UIntType, __w>::__value - 1),
00406             "template argument substituting __c out of bound");
00407       static_assert(__d <= (__detail::_Shift<_UIntType, __w>::__value - 1),
00408             "template argument substituting __d out of bound");
00409       static_assert(__f <= (__detail::_Shift<_UIntType, __w>::__value - 1),
00410             "template argument substituting __f out of bound");
00411 
00412     public:
00413       /** The type of the generated random value. */
00414       typedef _UIntType result_type;
00415 
00416       // parameter values
00417       static constexpr size_t      word_size                 = __w;
00418       static constexpr size_t      state_size                = __n;
00419       static constexpr size_t      shift_size                = __m;
00420       static constexpr size_t      mask_bits                 = __r;
00421       static constexpr result_type xor_mask                  = __a;
00422       static constexpr size_t      tempering_u               = __u;
00423       static constexpr result_type tempering_d               = __d;
00424       static constexpr size_t      tempering_s               = __s;
00425       static constexpr result_type tempering_b               = __b;
00426       static constexpr size_t      tempering_t               = __t;
00427       static constexpr result_type tempering_c               = __c;
00428       static constexpr size_t      tempering_l               = __l;
00429       static constexpr result_type initialization_multiplier = __f;
00430       static constexpr result_type default_seed = 5489u;
00431 
00432       // constructors and member function
00433       explicit
00434       mersenne_twister_engine(result_type __sd = default_seed)
00435       { seed(__sd); }
00436 
00437       /**
00438        * @brief Constructs a %mersenne_twister_engine random number generator
00439        *        engine seeded from the seed sequence @p __q.
00440        *
00441        * @param __q the seed sequence.
00442        */
00443       template<typename _Sseq, typename = typename
00444         std::enable_if<!std::is_same<_Sseq, mersenne_twister_engine>::value>
00445            ::type>
00446         explicit
00447         mersenne_twister_engine(_Sseq& __q)
00448         { seed(__q); }
00449 
00450       void
00451       seed(result_type __sd = default_seed);
00452 
00453       template<typename _Sseq>
00454     typename std::enable_if<std::is_class<_Sseq>::value>::type
00455         seed(_Sseq& __q);
00456 
00457       /**
00458        * @brief Gets the smallest possible value in the output range.
00459        */
00460       static constexpr result_type
00461       min()
00462       { return 0; };
00463 
00464       /**
00465        * @brief Gets the largest possible value in the output range.
00466        */
00467       static constexpr result_type
00468       max()
00469       { return __detail::_Shift<_UIntType, __w>::__value - 1; }
00470 
00471       /**
00472        * @brief Discard a sequence of random numbers.
00473        */
00474       void
00475       discard(unsigned long long __z)
00476       {
00477     for (; __z != 0ULL; --__z)
00478       (*this)();
00479       }
00480 
00481       result_type
00482       operator()();
00483 
00484       /**
00485        * @brief Compares two % mersenne_twister_engine random number generator
00486        *        objects of the same type for equality.
00487        *
00488        * @param __lhs A % mersenne_twister_engine random number generator
00489        *              object.
00490        * @param __rhs Another % mersenne_twister_engine random number
00491        *              generator object.
00492        *
00493        * @returns true if the infinite sequences of generated values
00494        *          would be equal, false otherwise.
00495        */
00496       friend bool
00497       operator==(const mersenne_twister_engine& __lhs,
00498          const mersenne_twister_engine& __rhs)
00499       { return (std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x)
00500         && __lhs._M_p == __rhs._M_p); }
00501 
00502       /**
00503        * @brief Inserts the current state of a % mersenne_twister_engine
00504        *        random number generator engine @p __x into the output stream
00505        *        @p __os.
00506        *
00507        * @param __os An output stream.
00508        * @param __x  A % mersenne_twister_engine random number generator
00509        *             engine.
00510        *
00511        * @returns The output stream with the state of @p __x inserted or in
00512        * an error state.
00513        */
00514       template<typename _UIntType1,
00515            size_t __w1, size_t __n1,
00516            size_t __m1, size_t __r1,
00517            _UIntType1 __a1, size_t __u1,
00518            _UIntType1 __d1, size_t __s1,
00519            _UIntType1 __b1, size_t __t1,
00520            _UIntType1 __c1, size_t __l1, _UIntType1 __f1,
00521            typename _CharT, typename _Traits>
00522     friend std::basic_ostream<_CharT, _Traits>&
00523     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00524            const std::mersenne_twister_engine<_UIntType1, __w1, __n1,
00525            __m1, __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
00526            __l1, __f1>& __x);
00527 
00528       /**
00529        * @brief Extracts the current state of a % mersenne_twister_engine
00530        *        random number generator engine @p __x from the input stream
00531        *        @p __is.
00532        *
00533        * @param __is An input stream.
00534        * @param __x  A % mersenne_twister_engine random number generator
00535        *             engine.
00536        *
00537        * @returns The input stream with the state of @p __x extracted or in
00538        * an error state.
00539        */
00540       template<typename _UIntType1,
00541            size_t __w1, size_t __n1,
00542            size_t __m1, size_t __r1,
00543            _UIntType1 __a1, size_t __u1,
00544            _UIntType1 __d1, size_t __s1,
00545            _UIntType1 __b1, size_t __t1,
00546            _UIntType1 __c1, size_t __l1, _UIntType1 __f1,
00547            typename _CharT, typename _Traits>
00548     friend std::basic_istream<_CharT, _Traits>&
00549     operator>>(std::basic_istream<_CharT, _Traits>& __is,
00550            std::mersenne_twister_engine<_UIntType1, __w1, __n1, __m1,
00551            __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
00552            __l1, __f1>& __x);
00553 
00554     private:
00555       _UIntType _M_x[state_size];
00556       size_t    _M_p;
00557     };
00558 
00559   /**
00560    * @brief Compares two % mersenne_twister_engine random number generator
00561    *        objects of the same type for inequality.
00562    *
00563    * @param __lhs A % mersenne_twister_engine random number generator
00564    *              object.
00565    * @param __rhs Another % mersenne_twister_engine random number
00566    *              generator object.
00567    *
00568    * @returns true if the infinite sequences of generated values
00569    *          would be different, false otherwise.
00570    */
00571   template<typename _UIntType, size_t __w,
00572        size_t __n, size_t __m, size_t __r,
00573        _UIntType __a, size_t __u, _UIntType __d, size_t __s,
00574        _UIntType __b, size_t __t,
00575        _UIntType __c, size_t __l, _UIntType __f>
00576     inline bool
00577     operator!=(const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
00578            __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __lhs,
00579            const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
00580            __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __rhs)
00581     { return !(__lhs == __rhs); }
00582 
00583 
00584   /**
00585    * @brief The Marsaglia-Zaman generator.
00586    *
00587    * This is a model of a Generalized Fibonacci discrete random number
00588    * generator, sometimes referred to as the SWC generator.
00589    *
00590    * A discrete random number generator that produces pseudorandom
00591    * numbers using:
00592    * @f[
00593    *     x_{i}\leftarrow(x_{i - s} - x_{i - r} - carry_{i-1}) \bmod m 
00594    * @f]
00595    *
00596    * The size of the state is @f$r@f$
00597    * and the maximum period of the generator is @f$(m^r - m^s - 1)@f$.
00598    *
00599    * @var _M_x     The state of the generator.  This is a ring buffer.
00600    * @var _M_carry The carry.
00601    * @var _M_p     Current index of x(i - r).
00602    */
00603   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
00604     class subtract_with_carry_engine
00605     {
00606       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
00607             "substituting _UIntType not an unsigned integral type");
00608       static_assert(0u < __s && __s < __r,
00609             "template argument substituting __s out of bounds");
00610       static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
00611             "template argument substituting __w out of bounds");
00612 
00613     public:
00614       /** The type of the generated random value. */
00615       typedef _UIntType result_type;
00616 
00617       // parameter values
00618       static constexpr size_t      word_size    = __w;
00619       static constexpr size_t      short_lag    = __s;
00620       static constexpr size_t      long_lag     = __r;
00621       static constexpr result_type default_seed = 19780503u;
00622 
00623       /**
00624        * @brief Constructs an explicitly seeded % subtract_with_carry_engine
00625        *        random number generator.
00626        */
00627       explicit
00628       subtract_with_carry_engine(result_type __sd = default_seed)
00629       { seed(__sd); }
00630 
00631       /**
00632        * @brief Constructs a %subtract_with_carry_engine random number engine
00633        *        seeded from the seed sequence @p __q.
00634        *
00635        * @param __q the seed sequence.
00636        */
00637       template<typename _Sseq, typename = typename
00638         std::enable_if<!std::is_same<_Sseq, subtract_with_carry_engine>::value>
00639            ::type>
00640         explicit
00641         subtract_with_carry_engine(_Sseq& __q)
00642         { seed(__q); }
00643 
00644       /**
00645        * @brief Seeds the initial state @f$x_0@f$ of the random number
00646        *        generator.
00647        *
00648        * N1688[4.19] modifies this as follows.  If @p __value == 0,
00649        * sets value to 19780503.  In any case, with a linear
00650        * congruential generator lcg(i) having parameters @f$ m_{lcg} =
00651        * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
00652        * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
00653        * \dots lcg(r) \bmod m @f$ respectively.  If @f$ x_{-1} = 0 @f$
00654        * set carry to 1, otherwise sets carry to 0.
00655        */
00656       void
00657       seed(result_type __sd = default_seed);
00658 
00659       /**
00660        * @brief Seeds the initial state @f$x_0@f$ of the
00661        * % subtract_with_carry_engine random number generator.
00662        */
00663       template<typename _Sseq>
00664     typename std::enable_if<std::is_class<_Sseq>::value>::type
00665         seed(_Sseq& __q);
00666 
00667       /**
00668        * @brief Gets the inclusive minimum value of the range of random
00669        * integers returned by this generator.
00670        */
00671       static constexpr result_type
00672       min()
00673       { return 0; }
00674 
00675       /**
00676        * @brief Gets the inclusive maximum value of the range of random
00677        * integers returned by this generator.
00678        */
00679       static constexpr result_type
00680       max()
00681       { return __detail::_Shift<_UIntType, __w>::__value - 1; }
00682 
00683       /**
00684        * @brief Discard a sequence of random numbers.
00685        */
00686       void
00687       discard(unsigned long long __z)
00688       {
00689     for (; __z != 0ULL; --__z)
00690       (*this)();
00691       }
00692 
00693       /**
00694        * @brief Gets the next random number in the sequence.
00695        */
00696       result_type
00697       operator()();
00698 
00699       /**
00700        * @brief Compares two % subtract_with_carry_engine random number
00701        *        generator objects of the same type for equality.
00702        *
00703        * @param __lhs A % subtract_with_carry_engine random number generator
00704        *              object.
00705        * @param __rhs Another % subtract_with_carry_engine random number
00706        *              generator object.
00707        *
00708        * @returns true if the infinite sequences of generated values
00709        *          would be equal, false otherwise.
00710       */
00711       friend bool
00712       operator==(const subtract_with_carry_engine& __lhs,
00713          const subtract_with_carry_engine& __rhs)
00714       { return (std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x)
00715         && __lhs._M_carry == __rhs._M_carry
00716         && __lhs._M_p == __rhs._M_p); }
00717 
00718       /**
00719        * @brief Inserts the current state of a % subtract_with_carry_engine
00720        *        random number generator engine @p __x into the output stream
00721        *        @p __os.
00722        *
00723        * @param __os An output stream.
00724        * @param __x  A % subtract_with_carry_engine random number generator
00725        *             engine.
00726        *
00727        * @returns The output stream with the state of @p __x inserted or in
00728        * an error state.
00729        */
00730       template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1,
00731            typename _CharT, typename _Traits>
00732     friend std::basic_ostream<_CharT, _Traits>&
00733     operator<<(std::basic_ostream<_CharT, _Traits>&,
00734            const std::subtract_with_carry_engine<_UIntType1, __w1,
00735            __s1, __r1>&);
00736 
00737       /**
00738        * @brief Extracts the current state of a % subtract_with_carry_engine
00739        *        random number generator engine @p __x from the input stream
00740        *        @p __is.
00741        *
00742        * @param __is An input stream.
00743        * @param __x  A % subtract_with_carry_engine random number generator
00744        *             engine.
00745        *
00746        * @returns The input stream with the state of @p __x extracted or in
00747        * an error state.
00748        */
00749       template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1,
00750            typename _CharT, typename _Traits>
00751     friend std::basic_istream<_CharT, _Traits>&
00752     operator>>(std::basic_istream<_CharT, _Traits>&,
00753            std::subtract_with_carry_engine<_UIntType1, __w1,
00754            __s1, __r1>&);
00755 
00756     private:
00757       _UIntType  _M_x[long_lag];
00758       _UIntType  _M_carry;
00759       size_t     _M_p;
00760     };
00761 
00762   /**
00763    * @brief Compares two % subtract_with_carry_engine random number
00764    *        generator objects of the same type for inequality.
00765    *
00766    * @param __lhs A % subtract_with_carry_engine random number generator
00767    *              object.
00768    * @param __rhs Another % subtract_with_carry_engine random number
00769    *              generator object.
00770    *
00771    * @returns true if the infinite sequences of generated values
00772    *          would be different, false otherwise.
00773    */
00774   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
00775     inline bool
00776     operator!=(const std::subtract_with_carry_engine<_UIntType, __w,
00777            __s, __r>& __lhs,
00778            const std::subtract_with_carry_engine<_UIntType, __w,
00779            __s, __r>& __rhs)
00780     { return !(__lhs == __rhs); }
00781 
00782 
00783   /**
00784    * Produces random numbers from some base engine by discarding blocks of
00785    * data.
00786    *
00787    * 0 <= @p __r <= @p __p
00788    */
00789   template<typename _RandomNumberEngine, size_t __p, size_t __r>
00790     class discard_block_engine
00791     {
00792       static_assert(1 <= __r && __r <= __p,
00793             "template argument substituting __r out of bounds");
00794 
00795     public:
00796       /** The type of the generated random value. */
00797       typedef typename _RandomNumberEngine::result_type result_type;
00798 
00799       // parameter values
00800       static constexpr size_t block_size = __p;
00801       static constexpr size_t used_block = __r;
00802 
00803       /**
00804        * @brief Constructs a default %discard_block_engine engine.
00805        *
00806        * The underlying engine is default constructed as well.
00807        */
00808       discard_block_engine()
00809       : _M_b(), _M_n(0) { }
00810 
00811       /**
00812        * @brief Copy constructs a %discard_block_engine engine.
00813        *
00814        * Copies an existing base class random number generator.
00815        * @param __rng An existing (base class) engine object.
00816        */
00817       explicit
00818       discard_block_engine(const _RandomNumberEngine& __rng)
00819       : _M_b(__rng), _M_n(0) { }
00820 
00821       /**
00822        * @brief Move constructs a %discard_block_engine engine.
00823        *
00824        * Copies an existing base class random number generator.
00825        * @param __rng An existing (base class) engine object.
00826        */
00827       explicit
00828       discard_block_engine(_RandomNumberEngine&& __rng)
00829       : _M_b(std::move(__rng)), _M_n(0) { }
00830 
00831       /**
00832        * @brief Seed constructs a %discard_block_engine engine.
00833        *
00834        * Constructs the underlying generator engine seeded with @p __s.
00835        * @param __s A seed value for the base class engine.
00836        */
00837       explicit
00838       discard_block_engine(result_type __s)
00839       : _M_b(__s), _M_n(0) { }
00840 
00841       /**
00842        * @brief Generator construct a %discard_block_engine engine.
00843        *
00844        * @param __q A seed sequence.
00845        */
00846       template<typename _Sseq, typename = typename
00847     std::enable_if<!std::is_same<_Sseq, discard_block_engine>::value
00848                && !std::is_same<_Sseq, _RandomNumberEngine>::value>
00849            ::type>
00850         explicit
00851         discard_block_engine(_Sseq& __q)
00852     : _M_b(__q), _M_n(0)
00853         { }
00854 
00855       /**
00856        * @brief Reseeds the %discard_block_engine object with the default
00857        *        seed for the underlying base class generator engine.
00858        */
00859       void
00860       seed()
00861       {
00862     _M_b.seed();
00863     _M_n = 0;
00864       }
00865 
00866       /**
00867        * @brief Reseeds the %discard_block_engine object with the default
00868        *        seed for the underlying base class generator engine.
00869        */
00870       void
00871       seed(result_type __s)
00872       {
00873     _M_b.seed(__s);
00874     _M_n = 0;
00875       }
00876 
00877       /**
00878        * @brief Reseeds the %discard_block_engine object with the given seed
00879        *        sequence.
00880        * @param __q A seed generator function.
00881        */
00882       template<typename _Sseq>
00883         void
00884         seed(_Sseq& __q)
00885         {
00886       _M_b.seed(__q);
00887       _M_n = 0;
00888     }
00889 
00890       /**
00891        * @brief Gets a const reference to the underlying generator engine
00892        *        object.
00893        */
00894       const _RandomNumberEngine&
00895       base() const noexcept
00896       { return _M_b; }
00897 
00898       /**
00899        * @brief Gets the minimum value in the generated random number range.
00900        */
00901       static constexpr result_type
00902       min()
00903       { return _RandomNumberEngine::min(); }
00904 
00905       /**
00906        * @brief Gets the maximum value in the generated random number range.
00907        */
00908       static constexpr result_type
00909       max()
00910       { return _RandomNumberEngine::max(); }
00911 
00912       /**
00913        * @brief Discard a sequence of random numbers.
00914        */
00915       void
00916       discard(unsigned long long __z)
00917       {
00918     for (; __z != 0ULL; --__z)
00919       (*this)();
00920       }
00921 
00922       /**
00923        * @brief Gets the next value in the generated random number sequence.
00924        */
00925       result_type
00926       operator()();
00927 
00928       /**
00929        * @brief Compares two %discard_block_engine random number generator
00930        *        objects of the same type for equality.
00931        *
00932        * @param __lhs A %discard_block_engine random number generator object.
00933        * @param __rhs Another %discard_block_engine random number generator
00934        *              object.
00935        *
00936        * @returns true if the infinite sequences of generated values
00937        *          would be equal, false otherwise.
00938        */
00939       friend bool
00940       operator==(const discard_block_engine& __lhs,
00941          const discard_block_engine& __rhs)
00942       { return __lhs._M_b == __rhs._M_b && __lhs._M_n == __rhs._M_n; }
00943 
00944       /**
00945        * @brief Inserts the current state of a %discard_block_engine random
00946        *        number generator engine @p __x into the output stream
00947        *        @p __os.
00948        *
00949        * @param __os An output stream.
00950        * @param __x  A %discard_block_engine random number generator engine.
00951        *
00952        * @returns The output stream with the state of @p __x inserted or in
00953        * an error state.
00954        */
00955       template<typename _RandomNumberEngine1, size_t __p1, size_t __r1,
00956            typename _CharT, typename _Traits>
00957     friend std::basic_ostream<_CharT, _Traits>&
00958     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
00959            const std::discard_block_engine<_RandomNumberEngine1,
00960            __p1, __r1>& __x);
00961 
00962       /**
00963        * @brief Extracts the current state of a % subtract_with_carry_engine
00964        *        random number generator engine @p __x from the input stream
00965        *        @p __is.
00966        *
00967        * @param __is An input stream.
00968        * @param __x  A %discard_block_engine random number generator engine.
00969        *
00970        * @returns The input stream with the state of @p __x extracted or in
00971        * an error state.
00972        */
00973       template<typename _RandomNumberEngine1, size_t __p1, size_t __r1,
00974            typename _CharT, typename _Traits>
00975     friend std::basic_istream<_CharT, _Traits>&
00976     operator>>(std::basic_istream<_CharT, _Traits>& __is,
00977            std::discard_block_engine<_RandomNumberEngine1,
00978            __p1, __r1>& __x);
00979 
00980     private:
00981       _RandomNumberEngine _M_b;
00982       size_t _M_n;
00983     };
00984 
00985   /**
00986    * @brief Compares two %discard_block_engine random number generator
00987    *        objects of the same type for inequality.
00988    *
00989    * @param __lhs A %discard_block_engine random number generator object.
00990    * @param __rhs Another %discard_block_engine random number generator
00991    *              object.
00992    *
00993    * @returns true if the infinite sequences of generated values
00994    *          would be different, false otherwise.
00995    */
00996   template<typename _RandomNumberEngine, size_t __p, size_t __r>
00997     inline bool
00998     operator!=(const std::discard_block_engine<_RandomNumberEngine, __p,
00999            __r>& __lhs,
01000            const std::discard_block_engine<_RandomNumberEngine, __p,
01001            __r>& __rhs)
01002     { return !(__lhs == __rhs); }
01003 
01004 
01005   /**
01006    * Produces random numbers by combining random numbers from some base
01007    * engine to produce random numbers with a specifies number of bits @p __w.
01008    */
01009   template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
01010     class independent_bits_engine
01011     {
01012       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
01013             "substituting _UIntType not an unsigned integral type");
01014       static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
01015             "template argument substituting __w out of bounds");
01016 
01017     public:
01018       /** The type of the generated random value. */
01019       typedef _UIntType result_type;
01020 
01021       /**
01022        * @brief Constructs a default %independent_bits_engine engine.
01023        *
01024        * The underlying engine is default constructed as well.
01025        */
01026       independent_bits_engine()
01027       : _M_b() { }
01028 
01029       /**
01030        * @brief Copy constructs a %independent_bits_engine engine.
01031        *
01032        * Copies an existing base class random number generator.
01033        * @param __rng An existing (base class) engine object.
01034        */
01035       explicit
01036       independent_bits_engine(const _RandomNumberEngine& __rng)
01037       : _M_b(__rng) { }
01038 
01039       /**
01040        * @brief Move constructs a %independent_bits_engine engine.
01041        *
01042        * Copies an existing base class random number generator.
01043        * @param __rng An existing (base class) engine object.
01044        */
01045       explicit
01046       independent_bits_engine(_RandomNumberEngine&& __rng)
01047       : _M_b(std::move(__rng)) { }
01048 
01049       /**
01050        * @brief Seed constructs a %independent_bits_engine engine.
01051        *
01052        * Constructs the underlying generator engine seeded with @p __s.
01053        * @param __s A seed value for the base class engine.
01054        */
01055       explicit
01056       independent_bits_engine(result_type __s)
01057       : _M_b(__s) { }
01058 
01059       /**
01060        * @brief Generator construct a %independent_bits_engine engine.
01061        *
01062        * @param __q A seed sequence.
01063        */
01064       template<typename _Sseq, typename = typename
01065     std::enable_if<!std::is_same<_Sseq, independent_bits_engine>::value
01066                && !std::is_same<_Sseq, _RandomNumberEngine>::value>
01067                ::type>
01068         explicit
01069         independent_bits_engine(_Sseq& __q)
01070         : _M_b(__q)
01071         { }
01072 
01073       /**
01074        * @brief Reseeds the %independent_bits_engine object with the default
01075        *        seed for the underlying base class generator engine.
01076        */
01077       void
01078       seed()
01079       { _M_b.seed(); }
01080 
01081       /**
01082        * @brief Reseeds the %independent_bits_engine object with the default
01083        *        seed for the underlying base class generator engine.
01084        */
01085       void
01086       seed(result_type __s)
01087       { _M_b.seed(__s); }
01088 
01089       /**
01090        * @brief Reseeds the %independent_bits_engine object with the given
01091        *        seed sequence.
01092        * @param __q A seed generator function.
01093        */
01094       template<typename _Sseq>
01095         void
01096         seed(_Sseq& __q)
01097         { _M_b.seed(__q); }
01098 
01099       /**
01100        * @brief Gets a const reference to the underlying generator engine
01101        *        object.
01102        */
01103       const _RandomNumberEngine&
01104       base() const noexcept
01105       { return _M_b; }
01106 
01107       /**
01108        * @brief Gets the minimum value in the generated random number range.
01109        */
01110       static constexpr result_type
01111       min()
01112       { return 0U; }
01113 
01114       /**
01115        * @brief Gets the maximum value in the generated random number range.
01116        */
01117       static constexpr result_type
01118       max()
01119       { return __detail::_Shift<_UIntType, __w>::__value - 1; }
01120 
01121       /**
01122        * @brief Discard a sequence of random numbers.
01123        */
01124       void
01125       discard(unsigned long long __z)
01126       {
01127     for (; __z != 0ULL; --__z)
01128       (*this)();
01129       }
01130 
01131       /**
01132        * @brief Gets the next value in the generated random number sequence.
01133        */
01134       result_type
01135       operator()();
01136 
01137       /**
01138        * @brief Compares two %independent_bits_engine random number generator
01139        * objects of the same type for equality.
01140        *
01141        * @param __lhs A %independent_bits_engine random number generator
01142        *              object.
01143        * @param __rhs Another %independent_bits_engine random number generator
01144        *              object.
01145        *
01146        * @returns true if the infinite sequences of generated values
01147        *          would be equal, false otherwise.
01148        */
01149       friend bool
01150       operator==(const independent_bits_engine& __lhs,
01151          const independent_bits_engine& __rhs)
01152       { return __lhs._M_b == __rhs._M_b; }
01153 
01154       /**
01155        * @brief Extracts the current state of a % subtract_with_carry_engine
01156        *        random number generator engine @p __x from the input stream
01157        *        @p __is.
01158        *
01159        * @param __is An input stream.
01160        * @param __x  A %independent_bits_engine random number generator
01161        *             engine.
01162        *
01163        * @returns The input stream with the state of @p __x extracted or in
01164        *          an error state.
01165        */
01166       template<typename _CharT, typename _Traits>
01167     friend std::basic_istream<_CharT, _Traits>&
01168     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01169            std::independent_bits_engine<_RandomNumberEngine,
01170            __w, _UIntType>& __x)
01171     {
01172       __is >> __x._M_b;
01173       return __is;
01174     }
01175 
01176     private:
01177       _RandomNumberEngine _M_b;
01178     };
01179 
01180   /**
01181    * @brief Compares two %independent_bits_engine random number generator
01182    * objects of the same type for inequality.
01183    *
01184    * @param __lhs A %independent_bits_engine random number generator
01185    *              object.
01186    * @param __rhs Another %independent_bits_engine random number generator
01187    *              object.
01188    *
01189    * @returns true if the infinite sequences of generated values
01190    *          would be different, false otherwise.
01191    */
01192   template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
01193     inline bool
01194     operator!=(const std::independent_bits_engine<_RandomNumberEngine, __w,
01195            _UIntType>& __lhs,
01196            const std::independent_bits_engine<_RandomNumberEngine, __w,
01197            _UIntType>& __rhs)
01198     { return !(__lhs == __rhs); }
01199 
01200   /**
01201    * @brief Inserts the current state of a %independent_bits_engine random
01202    *        number generator engine @p __x into the output stream @p __os.
01203    *
01204    * @param __os An output stream.
01205    * @param __x  A %independent_bits_engine random number generator engine.
01206    *
01207    * @returns The output stream with the state of @p __x inserted or in
01208    *          an error state.
01209    */
01210   template<typename _RandomNumberEngine, size_t __w, typename _UIntType,
01211        typename _CharT, typename _Traits>
01212     std::basic_ostream<_CharT, _Traits>&
01213     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01214            const std::independent_bits_engine<_RandomNumberEngine,
01215            __w, _UIntType>& __x)
01216     {
01217       __os << __x.base();
01218       return __os;
01219     }
01220 
01221 
01222   /**
01223    * @brief Produces random numbers by combining random numbers from some
01224    * base engine to produce random numbers with a specifies number of bits
01225    * @p __w.
01226    */
01227   template<typename _RandomNumberEngine, size_t __k>
01228     class shuffle_order_engine
01229     {
01230       static_assert(1u <= __k, "template argument substituting "
01231             "__k out of bound");
01232 
01233     public:
01234       /** The type of the generated random value. */
01235       typedef typename _RandomNumberEngine::result_type result_type;
01236 
01237       static constexpr size_t table_size = __k;
01238 
01239       /**
01240        * @brief Constructs a default %shuffle_order_engine engine.
01241        *
01242        * The underlying engine is default constructed as well.
01243        */
01244       shuffle_order_engine()
01245       : _M_b()
01246       { _M_initialize(); }
01247 
01248       /**
01249        * @brief Copy constructs a %shuffle_order_engine engine.
01250        *
01251        * Copies an existing base class random number generator.
01252        * @param __rng An existing (base class) engine object.
01253        */
01254       explicit
01255       shuffle_order_engine(const _RandomNumberEngine& __rng)
01256       : _M_b(__rng)
01257       { _M_initialize(); }
01258 
01259       /**
01260        * @brief Move constructs a %shuffle_order_engine engine.
01261        *
01262        * Copies an existing base class random number generator.
01263        * @param __rng An existing (base class) engine object.
01264        */
01265       explicit
01266       shuffle_order_engine(_RandomNumberEngine&& __rng)
01267       : _M_b(std::move(__rng))
01268       { _M_initialize(); }
01269 
01270       /**
01271        * @brief Seed constructs a %shuffle_order_engine engine.
01272        *
01273        * Constructs the underlying generator engine seeded with @p __s.
01274        * @param __s A seed value for the base class engine.
01275        */
01276       explicit
01277       shuffle_order_engine(result_type __s)
01278       : _M_b(__s)
01279       { _M_initialize(); }
01280 
01281       /**
01282        * @brief Generator construct a %shuffle_order_engine engine.
01283        *
01284        * @param __q A seed sequence.
01285        */
01286       template<typename _Sseq, typename = typename
01287     std::enable_if<!std::is_same<_Sseq, shuffle_order_engine>::value
01288                && !std::is_same<_Sseq, _RandomNumberEngine>::value>
01289            ::type>
01290         explicit
01291         shuffle_order_engine(_Sseq& __q)
01292         : _M_b(__q)
01293         { _M_initialize(); }
01294 
01295       /**
01296        * @brief Reseeds the %shuffle_order_engine object with the default seed
01297                 for the underlying base class generator engine.
01298        */
01299       void
01300       seed()
01301       {
01302     _M_b.seed();
01303     _M_initialize();
01304       }
01305 
01306       /**
01307        * @brief Reseeds the %shuffle_order_engine object with the default seed
01308        *        for the underlying base class generator engine.
01309        */
01310       void
01311       seed(result_type __s)
01312       {
01313     _M_b.seed(__s);
01314     _M_initialize();
01315       }
01316 
01317       /**
01318        * @brief Reseeds the %shuffle_order_engine object with the given seed
01319        *        sequence.
01320        * @param __q A seed generator function.
01321        */
01322       template<typename _Sseq>
01323         void
01324         seed(_Sseq& __q)
01325         {
01326       _M_b.seed(__q);
01327       _M_initialize();
01328     }
01329 
01330       /**
01331        * Gets a const reference to the underlying generator engine object.
01332        */
01333       const _RandomNumberEngine&
01334       base() const noexcept
01335       { return _M_b; }
01336 
01337       /**
01338        * Gets the minimum value in the generated random number range.
01339        */
01340       static constexpr result_type
01341       min()
01342       { return _RandomNumberEngine::min(); }
01343 
01344       /**
01345        * Gets the maximum value in the generated random number range.
01346        */
01347       static constexpr result_type
01348       max()
01349       { return _RandomNumberEngine::max(); }
01350 
01351       /**
01352        * Discard a sequence of random numbers.
01353        */
01354       void
01355       discard(unsigned long long __z)
01356       {
01357     for (; __z != 0ULL; --__z)
01358       (*this)();
01359       }
01360 
01361       /**
01362        * Gets the next value in the generated random number sequence.
01363        */
01364       result_type
01365       operator()();
01366 
01367       /**
01368        * Compares two %shuffle_order_engine random number generator objects
01369        * of the same type for equality.
01370        *
01371        * @param __lhs A %shuffle_order_engine random number generator object.
01372        * @param __rhs Another %shuffle_order_engine random number generator
01373        *              object.
01374        *
01375        * @returns true if the infinite sequences of generated values
01376        *          would be equal, false otherwise.
01377       */
01378       friend bool
01379       operator==(const shuffle_order_engine& __lhs,
01380          const shuffle_order_engine& __rhs)
01381       { return (__lhs._M_b == __rhs._M_b
01382         && std::equal(__lhs._M_v, __lhs._M_v + __k, __rhs._M_v)
01383         && __lhs._M_y == __rhs._M_y); }
01384 
01385       /**
01386        * @brief Inserts the current state of a %shuffle_order_engine random
01387        *        number generator engine @p __x into the output stream
01388     @p __os.
01389        *
01390        * @param __os An output stream.
01391        * @param __x  A %shuffle_order_engine random number generator engine.
01392        *
01393        * @returns The output stream with the state of @p __x inserted or in
01394        * an error state.
01395        */
01396       template<typename _RandomNumberEngine1, size_t __k1,
01397            typename _CharT, typename _Traits>
01398     friend std::basic_ostream<_CharT, _Traits>&
01399     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01400            const std::shuffle_order_engine<_RandomNumberEngine1,
01401            __k1>& __x);
01402 
01403       /**
01404        * @brief Extracts the current state of a % subtract_with_carry_engine
01405        *        random number generator engine @p __x from the input stream
01406        *        @p __is.
01407        *
01408        * @param __is An input stream.
01409        * @param __x  A %shuffle_order_engine random number generator engine.
01410        *
01411        * @returns The input stream with the state of @p __x extracted or in
01412        * an error state.
01413        */
01414       template<typename _RandomNumberEngine1, size_t __k1,
01415            typename _CharT, typename _Traits>
01416     friend std::basic_istream<_CharT, _Traits>&
01417     operator>>(std::basic_istream<_CharT, _Traits>& __is,
01418            std::shuffle_order_engine<_RandomNumberEngine1, __k1>& __x);
01419 
01420     private:
01421       void _M_initialize()
01422       {
01423     for (size_t __i = 0; __i < __k; ++__i)
01424       _M_v[__i] = _M_b();
01425     _M_y = _M_b();
01426       }
01427 
01428       _RandomNumberEngine _M_b;
01429       result_type _M_v[__k];
01430       result_type _M_y;
01431     };
01432 
01433   /**
01434    * Compares two %shuffle_order_engine random number generator objects
01435    * of the same type for inequality.
01436    *
01437    * @param __lhs A %shuffle_order_engine random number generator object.
01438    * @param __rhs Another %shuffle_order_engine random number generator
01439    *              object.
01440    *
01441    * @returns true if the infinite sequences of generated values
01442    *          would be different, false otherwise.
01443    */
01444   template<typename _RandomNumberEngine, size_t __k>
01445     inline bool
01446     operator!=(const std::shuffle_order_engine<_RandomNumberEngine,
01447            __k>& __lhs,
01448            const std::shuffle_order_engine<_RandomNumberEngine,
01449            __k>& __rhs)
01450     { return !(__lhs == __rhs); }
01451 
01452 
01453   /**
01454    * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
01455    */
01456   typedef linear_congruential_engine<uint_fast32_t, 16807UL, 0UL, 2147483647UL>
01457   minstd_rand0;
01458 
01459   /**
01460    * An alternative LCR (Lehmer Generator function).
01461    */
01462   typedef linear_congruential_engine<uint_fast32_t, 48271UL, 0UL, 2147483647UL>
01463   minstd_rand;
01464 
01465   /**
01466    * The classic Mersenne Twister.
01467    *
01468    * Reference:
01469    * M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally
01470    * Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions
01471    * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
01472    */
01473   typedef mersenne_twister_engine<
01474     uint_fast32_t,
01475     32, 624, 397, 31,
01476     0x9908b0dfUL, 11,
01477     0xffffffffUL, 7,
01478     0x9d2c5680UL, 15,
01479     0xefc60000UL, 18, 1812433253UL> mt19937;
01480 
01481   /**
01482    * An alternative Mersenne Twister.
01483    */
01484   typedef mersenne_twister_engine<
01485     uint_fast64_t,
01486     64, 312, 156, 31,
01487     0xb5026f5aa96619e9ULL, 29,
01488     0x5555555555555555ULL, 17,
01489     0x71d67fffeda60000ULL, 37,
01490     0xfff7eee000000000ULL, 43,
01491     6364136223846793005ULL> mt19937_64;
01492 
01493   typedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>
01494     ranlux24_base;
01495 
01496   typedef subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>
01497     ranlux48_base;
01498 
01499   typedef discard_block_engine<ranlux24_base, 223, 23> ranlux24;
01500 
01501   typedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;
01502 
01503   typedef shuffle_order_engine<minstd_rand0, 256> knuth_b;
01504 
01505   typedef minstd_rand0 default_random_engine;
01506 
01507   /**
01508    * A standard interface to a platform-specific non-deterministic
01509    * random number generator (if any are available).
01510    */
01511   class random_device
01512   {
01513   public:
01514     /** The type of the generated random value. */
01515     typedef unsigned int result_type;
01516 
01517     // constructors, destructors and member functions
01518 
01519 #ifdef _GLIBCXX_USE_RANDOM_TR1
01520 
01521     explicit
01522     random_device(const std::string& __token = "/dev/urandom")
01523     {
01524       if ((__token != "/dev/urandom" && __token != "/dev/random")
01525       || !(_M_file = std::fopen(__token.c_str(), "rb")))
01526     std::__throw_runtime_error(__N("random_device::"
01527                        "random_device(const std::string&)"));
01528     }
01529 
01530     ~random_device()
01531     { std::fclose(_M_file); }
01532 
01533 #else
01534 
01535     explicit
01536     random_device(const std::string& __token = "mt19937")
01537     : _M_mt(_M_strtoul(__token)) { }
01538 
01539   private:
01540     static unsigned long
01541     _M_strtoul(const std::string& __str)
01542     {
01543       unsigned long __ret = 5489UL;
01544       if (__str != "mt19937")
01545     {
01546       const char* __nptr = __str.c_str();
01547       char* __endptr;
01548       __ret = std::strtoul(__nptr, &__endptr, 0);
01549       if (*__nptr == '\0' || *__endptr != '\0')
01550         std::__throw_runtime_error(__N("random_device::_M_strtoul"
01551                        "(const std::string&)"));
01552     }
01553       return __ret;
01554     }
01555 
01556   public:
01557 
01558 #endif
01559 
01560     static constexpr result_type
01561     min()
01562     { return std::numeric_limits<result_type>::min(); }
01563 
01564     static constexpr result_type
01565     max()
01566     { return std::numeric_limits<result_type>::max(); }
01567 
01568     double
01569     entropy() const noexcept
01570     { return 0.0; }
01571 
01572     result_type
01573     operator()()
01574     {
01575 #ifdef _GLIBCXX_USE_RANDOM_TR1
01576       result_type __ret;
01577       std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type),
01578          1, _M_file);
01579       return __ret;
01580 #else
01581       return _M_mt();
01582 #endif
01583     }
01584 
01585     // No copy functions.
01586     random_device(const random_device&) = delete;
01587     void operator=(const random_device&) = delete;
01588 
01589   private:
01590 
01591 #ifdef _GLIBCXX_USE_RANDOM_TR1
01592     FILE*        _M_file;
01593 #else
01594     mt19937      _M_mt;
01595 #endif
01596   };
01597 
01598   /* @} */ // group random_generators
01599 
01600   /**
01601    * @addtogroup random_distributions Random Number Distributions
01602    * @ingroup random
01603    * @{
01604    */
01605 
01606   /**
01607    * @addtogroup random_distributions_uniform Uniform Distributions
01608    * @ingroup random_distributions
01609    * @{
01610    */
01611 
01612   /**
01613    * @brief Uniform discrete distribution for random numbers.
01614    * A discrete random distribution on the range @f$[min, max]@f$ with equal
01615    * probability throughout the range.
01616    */
01617   template<typename _IntType = int>
01618     class uniform_int_distribution
01619     {
01620       static_assert(std::is_integral<_IntType>::value,
01621             "template argument not an integral type");
01622 
01623     public:
01624       /** The type of the range of the distribution. */
01625       typedef _IntType result_type;
01626       /** Parameter type. */
01627       struct param_type
01628       {
01629     typedef uniform_int_distribution<_IntType> distribution_type;
01630 
01631     explicit
01632     param_type(_IntType __a = 0,
01633            _IntType __b = std::numeric_limits<_IntType>::max())
01634     : _M_a(__a), _M_b(__b)
01635     {
01636       _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
01637     }
01638 
01639     result_type
01640     a() const
01641     { return _M_a; }
01642 
01643     result_type
01644     b() const
01645     { return _M_b; }
01646 
01647     friend bool
01648     operator==(const param_type& __p1, const param_type& __p2)
01649     { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
01650 
01651       private:
01652     _IntType _M_a;
01653     _IntType _M_b;
01654       };
01655 
01656     public:
01657       /**
01658        * @brief Constructs a uniform distribution object.
01659        */
01660       explicit
01661       uniform_int_distribution(_IntType __a = 0,
01662                _IntType __b = std::numeric_limits<_IntType>::max())
01663       : _M_param(__a, __b)
01664       { }
01665 
01666       explicit
01667       uniform_int_distribution(const param_type& __p)
01668       : _M_param(__p)
01669       { }
01670 
01671       /**
01672        * @brief Resets the distribution state.
01673        *
01674        * Does nothing for the uniform integer distribution.
01675        */
01676       void
01677       reset() { }
01678 
01679       result_type
01680       a() const
01681       { return _M_param.a(); }
01682 
01683       result_type
01684       b() const
01685       { return _M_param.b(); }
01686 
01687       /**
01688        * @brief Returns the parameter set of the distribution.
01689        */
01690       param_type
01691       param() const
01692       { return _M_param; }
01693 
01694       /**
01695        * @brief Sets the parameter set of the distribution.
01696        * @param __param The new parameter set of the distribution.
01697        */
01698       void
01699       param(const param_type& __param)
01700       { _M_param = __param; }
01701 
01702       /**
01703        * @brief Returns the inclusive lower bound of the distribution range.
01704        */
01705       result_type
01706       min() const
01707       { return this->a(); }
01708 
01709       /**
01710        * @brief Returns the inclusive upper bound of the distribution range.
01711        */
01712       result_type
01713       max() const
01714       { return this->b(); }
01715 
01716       /**
01717        * @brief Generating functions.
01718        */
01719       template<typename _UniformRandomNumberGenerator>
01720     result_type
01721     operator()(_UniformRandomNumberGenerator& __urng)
01722         { return this->operator()(__urng, this->param()); }
01723 
01724       template<typename _UniformRandomNumberGenerator>
01725     result_type
01726     operator()(_UniformRandomNumberGenerator& __urng,
01727            const param_type& __p);
01728 
01729       param_type _M_param;
01730     };
01731 
01732   /**
01733    * @brief Return true if two uniform integer distributions have
01734    *        the same parameters.
01735    */
01736   template<typename _IntType>
01737     inline bool
01738     operator==(const std::uniform_int_distribution<_IntType>& __d1,
01739            const std::uniform_int_distribution<_IntType>& __d2)
01740     { return __d1.param() == __d2.param(); }
01741 
01742   /**
01743    * @brief Return true if two uniform integer distributions have
01744    *        different parameters.
01745    */
01746   template<typename _IntType>
01747     inline bool
01748     operator!=(const std::uniform_int_distribution<_IntType>& __d1,
01749            const std::uniform_int_distribution<_IntType>& __d2)
01750     { return !(__d1 == __d2); }
01751 
01752   /**
01753    * @brief Inserts a %uniform_int_distribution random number
01754    *        distribution @p __x into the output stream @p os.
01755    *
01756    * @param __os An output stream.
01757    * @param __x  A %uniform_int_distribution random number distribution.
01758    *
01759    * @returns The output stream with the state of @p __x inserted or in
01760    * an error state.
01761    */
01762   template<typename _IntType, typename _CharT, typename _Traits>
01763     std::basic_ostream<_CharT, _Traits>&
01764     operator<<(std::basic_ostream<_CharT, _Traits>&,
01765            const std::uniform_int_distribution<_IntType>&);
01766 
01767   /**
01768    * @brief Extracts a %uniform_int_distribution random number distribution
01769    * @p __x from the input stream @p __is.
01770    *
01771    * @param __is An input stream.
01772    * @param __x  A %uniform_int_distribution random number generator engine.
01773    *
01774    * @returns The input stream with @p __x extracted or in an error state.
01775    */
01776   template<typename _IntType, typename _CharT, typename _Traits>
01777     std::basic_istream<_CharT, _Traits>&
01778     operator>>(std::basic_istream<_CharT, _Traits>&,
01779            std::uniform_int_distribution<_IntType>&);
01780 
01781 
01782   /**
01783    * @brief Uniform continuous distribution for random numbers.
01784    *
01785    * A continuous random distribution on the range [min, max) with equal
01786    * probability throughout the range.  The URNG should be real-valued and
01787    * deliver number in the range [0, 1).
01788    */
01789   template<typename _RealType = double>
01790     class uniform_real_distribution
01791     {
01792       static_assert(std::is_floating_point<_RealType>::value,
01793             "template argument not a floating point type");
01794 
01795     public:
01796       /** The type of the range of the distribution. */
01797       typedef _RealType result_type;
01798       /** Parameter type. */
01799       struct param_type
01800       {
01801     typedef uniform_real_distribution<_RealType> distribution_type;
01802 
01803     explicit
01804     param_type(_RealType __a = _RealType(0),
01805            _RealType __b = _RealType(1))
01806     : _M_a(__a), _M_b(__b)
01807     {
01808       _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
01809     }
01810 
01811     result_type
01812     a() const
01813     { return _M_a; }
01814 
01815     result_type
01816     b() const
01817     { return _M_b; }
01818 
01819     friend bool
01820     operator==(const param_type& __p1, const param_type& __p2)
01821     { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
01822 
01823       private:
01824     _RealType _M_a;
01825     _RealType _M_b;
01826       };
01827 
01828     public:
01829       /**
01830        * @brief Constructs a uniform_real_distribution object.
01831        *
01832        * @param __a [IN]  The lower bound of the distribution.
01833        * @param __b [IN]  The upper bound of the distribution.
01834        */
01835       explicit
01836       uniform_real_distribution(_RealType __a = _RealType(0),
01837                 _RealType __b = _RealType(1))
01838       : _M_param(__a, __b)
01839       { }
01840 
01841       explicit
01842       uniform_real_distribution(const param_type& __p)
01843       : _M_param(__p)
01844       { }
01845 
01846       /**
01847        * @brief Resets the distribution state.
01848        *
01849        * Does nothing for the uniform real distribution.
01850        */
01851       void
01852       reset() { }
01853 
01854       result_type
01855       a() const
01856       { return _M_param.a(); }
01857 
01858       result_type
01859       b() const
01860       { return _M_param.b(); }
01861 
01862       /**
01863        * @brief Returns the parameter set of the distribution.
01864        */
01865       param_type
01866       param() const
01867       { return _M_param; }
01868 
01869       /**
01870        * @brief Sets the parameter set of the distribution.
01871        * @param __param The new parameter set of the distribution.
01872        */
01873       void
01874       param(const param_type& __param)
01875       { _M_param = __param; }
01876 
01877       /**
01878        * @brief Returns the inclusive lower bound of the distribution range.
01879        */
01880       result_type
01881       min() const
01882       { return this->a(); }
01883 
01884       /**
01885        * @brief Returns the inclusive upper bound of the distribution range.
01886        */
01887       result_type
01888       max() const
01889       { return this->b(); }
01890 
01891       /**
01892        * @brief Generating functions.
01893        */
01894       template<typename _UniformRandomNumberGenerator>
01895     result_type
01896     operator()(_UniformRandomNumberGenerator& __urng)
01897         { return this->operator()(__urng, this->param()); }
01898 
01899       template<typename _UniformRandomNumberGenerator>
01900     result_type
01901     operator()(_UniformRandomNumberGenerator& __urng,
01902            const param_type& __p)
01903     {
01904       __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
01905         __aurng(__urng);
01906       return (__aurng() * (__p.b() - __p.a())) + __p.a();
01907     }
01908 
01909     private:
01910       param_type _M_param;
01911     };
01912 
01913   /**
01914    * @brief Return true if two uniform real distributions have
01915    *        the same parameters.
01916    */
01917   template<typename _IntType>
01918     inline bool
01919     operator==(const std::uniform_real_distribution<_IntType>& __d1,
01920            const std::uniform_real_distribution<_IntType>& __d2)
01921     { return __d1.param() == __d2.param(); }
01922 
01923   /**
01924    * @brief Return true if two uniform real distributions have
01925    *        different parameters.
01926    */
01927   template<typename _IntType>
01928     inline bool
01929     operator!=(const std::uniform_real_distribution<_IntType>& __d1,
01930            const std::uniform_real_distribution<_IntType>& __d2)
01931     { return !(__d1 == __d2); }
01932 
01933   /**
01934    * @brief Inserts a %uniform_real_distribution random number
01935    *        distribution @p __x into the output stream @p __os.
01936    *
01937    * @param __os An output stream.
01938    * @param __x  A %uniform_real_distribution random number distribution.
01939    *
01940    * @returns The output stream with the state of @p __x inserted or in
01941    *          an error state.
01942    */
01943   template<typename _RealType, typename _CharT, typename _Traits>
01944     std::basic_ostream<_CharT, _Traits>&
01945     operator<<(std::basic_ostream<_CharT, _Traits>&,
01946            const std::uniform_real_distribution<_RealType>&);
01947 
01948   /**
01949    * @brief Extracts a %uniform_real_distribution random number distribution
01950    * @p __x from the input stream @p __is.
01951    *
01952    * @param __is An input stream.
01953    * @param __x  A %uniform_real_distribution random number generator engine.
01954    *
01955    * @returns The input stream with @p __x extracted or in an error state.
01956    */
01957   template<typename _RealType, typename _CharT, typename _Traits>
01958     std::basic_istream<_CharT, _Traits>&
01959     operator>>(std::basic_istream<_CharT, _Traits>&,
01960            std::uniform_real_distribution<_RealType>&);
01961 
01962   /* @} */ // group random_distributions_uniform
01963 
01964   /**
01965    * @addtogroup random_distributions_normal Normal Distributions
01966    * @ingroup random_distributions
01967    * @{
01968    */
01969 
01970   /**
01971    * @brief A normal continuous distribution for random numbers.
01972    *
01973    * The formula for the normal probability density function is
01974    * @f[
01975    *     p(x|\mu,\sigma) = \frac{1}{\sigma \sqrt{2 \pi}}
01976    *            e^{- \frac{{x - \mu}^ {2}}{2 \sigma ^ {2}} } 
01977    * @f]
01978    */
01979   template<typename _RealType = double>
01980     class normal_distribution
01981     {
01982       static_assert(std::is_floating_point<_RealType>::value,
01983             "template argument not a floating point type");
01984 
01985     public:
01986       /** The type of the range of the distribution. */
01987       typedef _RealType result_type;
01988       /** Parameter type. */
01989       struct param_type
01990       {
01991     typedef normal_distribution<_RealType> distribution_type;
01992 
01993     explicit
01994     param_type(_RealType __mean = _RealType(0),
01995            _RealType __stddev = _RealType(1))
01996     : _M_mean(__mean), _M_stddev(__stddev)
01997     {
01998       _GLIBCXX_DEBUG_ASSERT(_M_stddev > _RealType(0));
01999     }
02000 
02001     _RealType
02002     mean() const
02003     { return _M_mean; }
02004 
02005     _RealType
02006     stddev() const
02007     { return _M_stddev; }
02008 
02009     friend bool
02010     operator==(const param_type& __p1, const param_type& __p2)
02011     { return (__p1._M_mean == __p2._M_mean
02012           && __p1._M_stddev == __p2._M_stddev); }
02013 
02014       private:
02015     _RealType _M_mean;
02016     _RealType _M_stddev;
02017       };
02018 
02019     public:
02020       /**
02021        * Constructs a normal distribution with parameters @f$mean@f$ and
02022        * standard deviation.
02023        */
02024       explicit
02025       normal_distribution(result_type __mean = result_type(0),
02026               result_type __stddev = result_type(1))
02027       : _M_param(__mean, __stddev), _M_saved_available(false)
02028       { }
02029 
02030       explicit
02031       normal_distribution(const param_type& __p)
02032       : _M_param(__p), _M_saved_available(false)
02033       { }
02034 
02035       /**
02036        * @brief Resets the distribution state.
02037        */
02038       void
02039       reset()
02040       { _M_saved_available = false; }
02041 
02042       /**
02043        * @brief Returns the mean of the distribution.
02044        */
02045       _RealType
02046       mean() const
02047       { return _M_param.mean(); }
02048 
02049       /**
02050        * @brief Returns the standard deviation of the distribution.
02051        */
02052       _RealType
02053       stddev() const
02054       { return _M_param.stddev(); }
02055 
02056       /**
02057        * @brief Returns the parameter set of the distribution.
02058        */
02059       param_type
02060       param() const
02061       { return _M_param; }
02062 
02063       /**
02064        * @brief Sets the parameter set of the distribution.
02065        * @param __param The new parameter set of the distribution.
02066        */
02067       void
02068       param(const param_type& __param)
02069       { _M_param = __param; }
02070 
02071       /**
02072        * @brief Returns the greatest lower bound value of the distribution.
02073        */
02074       result_type
02075       min() const
02076       { return std::numeric_limits<result_type>::min(); }
02077 
02078       /**
02079        * @brief Returns the least upper bound value of the distribution.
02080        */
02081       result_type
02082       max() const
02083       { return std::numeric_limits<result_type>::max(); }
02084 
02085       /**
02086        * @brief Generating functions.
02087        */
02088       template<typename _UniformRandomNumberGenerator>
02089     result_type
02090     operator()(_UniformRandomNumberGenerator& __urng)
02091     { return this->operator()(__urng, this->param()); }
02092 
02093       template<typename _UniformRandomNumberGenerator>
02094     result_type
02095     operator()(_UniformRandomNumberGenerator& __urng,
02096            const param_type& __p);
02097 
02098       /**
02099        * @brief Return true if two normal distributions have
02100        *        the same parameters and the sequences that would
02101        *        be generated are equal.
02102        */
02103       template<typename _RealType1>
02104     friend bool
02105         operator==(const std::normal_distribution<_RealType1>& __d1,
02106            const std::normal_distribution<_RealType1>& __d2);
02107 
02108       /**
02109        * @brief Inserts a %normal_distribution random number distribution
02110        * @p __x into the output stream @p __os.
02111        *
02112        * @param __os An output stream.
02113        * @param __x  A %normal_distribution random number distribution.
02114        *
02115        * @returns The output stream with the state of @p __x inserted or in
02116        * an error state.
02117        */
02118       template<typename _RealType1, typename _CharT, typename _Traits>
02119     friend std::basic_ostream<_CharT, _Traits>&
02120     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02121            const std::normal_distribution<_RealType1>& __x);
02122 
02123       /**
02124        * @brief Extracts a %normal_distribution random number distribution
02125        * @p __x from the input stream @p __is.
02126        *
02127        * @param __is An input stream.
02128        * @param __x  A %normal_distribution random number generator engine.
02129        *
02130        * @returns The input stream with @p __x extracted or in an error
02131        *          state.
02132        */
02133       template<typename _RealType1, typename _CharT, typename _Traits>
02134     friend std::basic_istream<_CharT, _Traits>&
02135     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02136            std::normal_distribution<_RealType1>& __x);
02137 
02138     private:
02139       param_type  _M_param;
02140       result_type _M_saved;
02141       bool        _M_saved_available;
02142     };
02143 
02144   /**
02145    * @brief Return true if two normal distributions are different.
02146    */
02147   template<typename _RealType>
02148     inline bool
02149     operator!=(const std::normal_distribution<_RealType>& __d1,
02150            const std::normal_distribution<_RealType>& __d2)
02151     { return !(__d1 == __d2); }
02152 
02153 
02154   /**
02155    * @brief A lognormal_distribution random number distribution.
02156    *
02157    * The formula for the normal probability mass function is
02158    * @f[
02159    *     p(x|m,s) = \frac{1}{sx\sqrt{2\pi}}
02160    *                \exp{-\frac{(\ln{x} - m)^2}{2s^2}} 
02161    * @f]
02162    */
02163   template<typename _RealType = double>
02164     class lognormal_distribution
02165     {
02166       static_assert(std::is_floating_point<_RealType>::value,
02167             "template argument not a floating point type");
02168 
02169     public:
02170       /** The type of the range of the distribution. */
02171       typedef _RealType result_type;
02172       /** Parameter type. */
02173       struct param_type
02174       {
02175     typedef lognormal_distribution<_RealType> distribution_type;
02176 
02177     explicit
02178     param_type(_RealType __m = _RealType(0),
02179            _RealType __s = _RealType(1))
02180     : _M_m(__m), _M_s(__s)
02181     { }
02182 
02183     _RealType
02184     m() const
02185     { return _M_m; }
02186 
02187     _RealType
02188     s() const
02189     { return _M_s; }
02190 
02191     friend bool
02192     operator==(const param_type& __p1, const param_type& __p2)
02193     { return __p1._M_m == __p2._M_m && __p1._M_s == __p2._M_s; }
02194 
02195       private:
02196     _RealType _M_m;
02197     _RealType _M_s;
02198       };
02199 
02200       explicit
02201       lognormal_distribution(_RealType __m = _RealType(0),
02202                  _RealType __s = _RealType(1))
02203       : _M_param(__m, __s), _M_nd()
02204       { }
02205 
02206       explicit
02207       lognormal_distribution(const param_type& __p)
02208       : _M_param(__p), _M_nd()
02209       { }
02210 
02211       /**
02212        * Resets the distribution state.
02213        */
02214       void
02215       reset()
02216       { _M_nd.reset(); }
02217 
02218       /**
02219        *
02220        */
02221       _RealType
02222       m() const
02223       { return _M_param.m(); }
02224 
02225       _RealType
02226       s() const
02227       { return _M_param.s(); }
02228 
02229       /**
02230        * @brief Returns the parameter set of the distribution.
02231        */
02232       param_type
02233       param() const
02234       { return _M_param; }
02235 
02236       /**
02237        * @brief Sets the parameter set of the distribution.
02238        * @param __param The new parameter set of the distribution.
02239        */
02240       void
02241       param(const param_type& __param)
02242       { _M_param = __param; }
02243 
02244       /**
02245        * @brief Returns the greatest lower bound value of the distribution.
02246        */
02247       result_type
02248       min() const
02249       { return result_type(0); }
02250 
02251       /**
02252        * @brief Returns the least upper bound value of the distribution.
02253        */
02254       result_type
02255       max() const
02256       { return std::numeric_limits<result_type>::max(); }
02257 
02258       /**
02259        * @brief Generating functions.
02260        */
02261       template<typename _UniformRandomNumberGenerator>
02262     result_type
02263     operator()(_UniformRandomNumberGenerator& __urng)
02264     { return this->operator()(__urng, this->param()); }
02265 
02266       template<typename _UniformRandomNumberGenerator>
02267     result_type
02268     operator()(_UniformRandomNumberGenerator& __urng,
02269            const param_type& __p)
02270         { return std::exp(__p.s() * _M_nd(__urng) + __p.m()); }
02271 
02272       /**
02273        * @brief Return true if two lognormal distributions have
02274        *        the same parameters and the sequences that would
02275        *        be generated are equal.
02276        */
02277       template<typename _RealType1>
02278         friend bool
02279         operator==(const std::lognormal_distribution<_RealType1>& __d1,
02280            const std::lognormal_distribution<_RealType1>& __d2)
02281         { return (__d1.param() == __d2.param()
02282           && __d1._M_nd == __d2._M_nd); }
02283 
02284       /**
02285        * @brief Inserts a %lognormal_distribution random number distribution
02286        * @p __x into the output stream @p __os.
02287        *
02288        * @param __os An output stream.
02289        * @param __x  A %lognormal_distribution random number distribution.
02290        *
02291        * @returns The output stream with the state of @p __x inserted or in
02292        * an error state.
02293        */
02294       template<typename _RealType1, typename _CharT, typename _Traits>
02295     friend std::basic_ostream<_CharT, _Traits>&
02296     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02297            const std::lognormal_distribution<_RealType1>& __x);
02298 
02299       /**
02300        * @brief Extracts a %lognormal_distribution random number distribution
02301        * @p __x from the input stream @p __is.
02302        *
02303        * @param __is An input stream.
02304        * @param __x A %lognormal_distribution random number
02305        *            generator engine.
02306        *
02307        * @returns The input stream with @p __x extracted or in an error state.
02308        */
02309       template<typename _RealType1, typename _CharT, typename _Traits>
02310     friend std::basic_istream<_CharT, _Traits>&
02311     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02312            std::lognormal_distribution<_RealType1>& __x);
02313 
02314     private:
02315       param_type _M_param;
02316 
02317       std::normal_distribution<result_type> _M_nd;
02318     };
02319 
02320   /**
02321    * @brief Return true if two lognormal distributions are different.
02322    */
02323   template<typename _RealType>
02324     inline bool
02325     operator!=(const std::lognormal_distribution<_RealType>& __d1,
02326            const std::lognormal_distribution<_RealType>& __d2)
02327     { return !(__d1 == __d2); }
02328 
02329 
02330   /**
02331    * @brief A gamma continuous distribution for random numbers.
02332    *
02333    * The formula for the gamma probability density function is:
02334    * @f[
02335    *     p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
02336    *                         (x/\beta)^{\alpha - 1} e^{-x/\beta} 
02337    * @f]
02338    */
02339   template<typename _RealType = double>
02340     class gamma_distribution
02341     {
02342       static_assert(std::is_floating_point<_RealType>::value,
02343             "template argument not a floating point type");
02344 
02345     public:
02346       /** The type of the range of the distribution. */
02347       typedef _RealType result_type;
02348       /** Parameter type. */
02349       struct param_type
02350       {
02351     typedef gamma_distribution<_RealType> distribution_type;
02352     friend class gamma_distribution<_RealType>;
02353 
02354     explicit
02355     param_type(_RealType __alpha_val = _RealType(1),
02356            _RealType __beta_val = _RealType(1))
02357     : _M_alpha(__alpha_val), _M_beta(__beta_val)
02358     {
02359       _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0));
02360       _M_initialize();
02361     }
02362 
02363     _RealType
02364     alpha() const
02365     { return _M_alpha; }
02366 
02367     _RealType
02368     beta() const
02369     { return _M_beta; }
02370 
02371     friend bool
02372     operator==(const param_type& __p1, const param_type& __p2)
02373     { return (__p1._M_alpha == __p2._M_alpha
02374           && __p1._M_beta == __p2._M_beta); }
02375 
02376       private:
02377     void
02378     _M_initialize();
02379 
02380     _RealType _M_alpha;
02381     _RealType _M_beta;
02382 
02383     _RealType _M_malpha, _M_a2;
02384       };
02385 
02386     public:
02387       /**
02388        * @brief Constructs a gamma distribution with parameters
02389        * @f$\alpha@f$ and @f$\beta@f$.
02390        */
02391       explicit
02392       gamma_distribution(_RealType __alpha_val = _RealType(1),
02393              _RealType __beta_val = _RealType(1))
02394       : _M_param(__alpha_val, __beta_val), _M_nd()
02395       { }
02396 
02397       explicit
02398       gamma_distribution(const param_type& __p)
02399       : _M_param(__p), _M_nd()
02400       { }
02401 
02402       /**
02403        * @brief Resets the distribution state.
02404        */
02405       void
02406       reset()
02407       { _M_nd.reset(); }
02408 
02409       /**
02410        * @brief Returns the @f$\alpha@f$ of the distribution.
02411        */
02412       _RealType
02413       alpha() const
02414       { return _M_param.alpha(); }
02415 
02416       /**
02417        * @brief Returns the @f$\beta@f$ of the distribution.
02418        */
02419       _RealType
02420       beta() const
02421       { return _M_param.beta(); }
02422 
02423       /**
02424        * @brief Returns the parameter set of the distribution.
02425        */
02426       param_type
02427       param() const
02428       { return _M_param; }
02429 
02430       /**
02431        * @brief Sets the parameter set of the distribution.
02432        * @param __param The new parameter set of the distribution.
02433        */
02434       void
02435       param(const param_type& __param)
02436       { _M_param = __param; }
02437 
02438       /**
02439        * @brief Returns the greatest lower bound value of the distribution.
02440        */
02441       result_type
02442       min() const
02443       { return result_type(0); }
02444 
02445       /**
02446        * @brief Returns the least upper bound value of the distribution.
02447        */
02448       result_type
02449       max() const
02450       { return std::numeric_limits<result_type>::max(); }
02451 
02452       /**
02453        * @brief Generating functions.
02454        */
02455       template<typename _UniformRandomNumberGenerator>
02456     result_type
02457     operator()(_UniformRandomNumberGenerator& __urng)
02458     { return this->operator()(__urng, this->param()); }
02459 
02460       template<typename _UniformRandomNumberGenerator>
02461     result_type
02462     operator()(_UniformRandomNumberGenerator& __urng,
02463            const param_type& __p);
02464 
02465       /**
02466        * @brief Return true if two gamma distributions have the same
02467        *        parameters and the sequences that would be generated
02468        *        are equal.
02469        */
02470       template<typename _RealType1>
02471         friend bool
02472         operator==(const std::gamma_distribution<_RealType1>& __d1,
02473            const std::gamma_distribution<_RealType1>& __d2)
02474         { return (__d1.param() == __d2.param()
02475           && __d1._M_nd == __d2._M_nd); }
02476 
02477       /**
02478        * @brief Inserts a %gamma_distribution random number distribution
02479        * @p __x into the output stream @p __os.
02480        *
02481        * @param __os An output stream.
02482        * @param __x  A %gamma_distribution random number distribution.
02483        *
02484        * @returns The output stream with the state of @p __x inserted or in
02485        * an error state.
02486        */
02487       template<typename _RealType1, typename _CharT, typename _Traits>
02488     friend std::basic_ostream<_CharT, _Traits>&
02489     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02490            const std::gamma_distribution<_RealType1>& __x);
02491 
02492       /**
02493        * @brief Extracts a %gamma_distribution random number distribution
02494        * @p __x from the input stream @p __is.
02495        *
02496        * @param __is An input stream.
02497        * @param __x  A %gamma_distribution random number generator engine.
02498        *
02499        * @returns The input stream with @p __x extracted or in an error state.
02500        */
02501       template<typename _RealType1, typename _CharT, typename _Traits>
02502     friend std::basic_istream<_CharT, _Traits>&
02503     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02504            std::gamma_distribution<_RealType1>& __x);
02505 
02506     private:
02507       param_type _M_param;
02508 
02509       std::normal_distribution<result_type> _M_nd;
02510     };
02511 
02512   /**
02513    * @brief Return true if two gamma distributions are different.
02514    */
02515    template<typename _RealType>
02516     inline bool
02517      operator!=(const std::gamma_distribution<_RealType>& __d1,
02518         const std::gamma_distribution<_RealType>& __d2)
02519     { return !(__d1 == __d2); }
02520 
02521 
02522   /**
02523    * @brief A chi_squared_distribution random number distribution.
02524    *
02525    * The formula for the normal probability mass function is
02526    * @f$p(x|n) = \frac{x^{(n/2) - 1}e^{-x/2}}{\Gamma(n/2) 2^{n/2}}@f$
02527    */
02528   template<typename _RealType = double>
02529     class chi_squared_distribution
02530     {
02531       static_assert(std::is_floating_point<_RealType>::value,
02532             "template argument not a floating point type");
02533 
02534     public:
02535       /** The type of the range of the distribution. */
02536       typedef _RealType result_type;
02537       /** Parameter type. */
02538       struct param_type
02539       {
02540     typedef chi_squared_distribution<_RealType> distribution_type;
02541 
02542     explicit
02543     param_type(_RealType __n = _RealType(1))
02544     : _M_n(__n)
02545     { }
02546 
02547     _RealType
02548     n() const
02549     { return _M_n; }
02550 
02551     friend bool
02552     operator==(const param_type& __p1, const param_type& __p2)
02553     { return __p1._M_n == __p2._M_n; }
02554 
02555       private:
02556     _RealType _M_n;
02557       };
02558 
02559       explicit
02560       chi_squared_distribution(_RealType __n = _RealType(1))
02561       : _M_param(__n), _M_gd(__n / 2)
02562       { }
02563 
02564       explicit
02565       chi_squared_distribution(const param_type& __p)
02566       : _M_param(__p), _M_gd(__p.n() / 2)
02567       { }
02568 
02569       /**
02570        * @brief Resets the distribution state.
02571        */
02572       void
02573       reset()
02574       { _M_gd.reset(); }
02575 
02576       /**
02577        *
02578        */
02579       _RealType
02580       n() const
02581       { return _M_param.n(); }
02582 
02583       /**
02584        * @brief Returns the parameter set of the distribution.
02585        */
02586       param_type
02587       param() const
02588       { return _M_param; }
02589 
02590       /**
02591        * @brief Sets the parameter set of the distribution.
02592        * @param __param The new parameter set of the distribution.
02593        */
02594       void
02595       param(const param_type& __param)
02596       { _M_param = __param; }
02597 
02598       /**
02599        * @brief Returns the greatest lower bound value of the distribution.
02600        */
02601       result_type
02602       min() const
02603       { return result_type(0); }
02604 
02605       /**
02606        * @brief Returns the least upper bound value of the distribution.
02607        */
02608       result_type
02609       max() const
02610       { return std::numeric_limits<result_type>::max(); }
02611 
02612       /**
02613        * @brief Generating functions.
02614        */
02615       template<typename _UniformRandomNumberGenerator>
02616     result_type
02617     operator()(_UniformRandomNumberGenerator& __urng)
02618     { return 2 * _M_gd(__urng); }
02619 
02620       template<typename _UniformRandomNumberGenerator>
02621     result_type
02622     operator()(_UniformRandomNumberGenerator& __urng,
02623            const param_type& __p)
02624         {
02625       typedef typename std::gamma_distribution<result_type>::param_type
02626         param_type;
02627       return 2 * _M_gd(__urng, param_type(__p.n() / 2));
02628     }
02629 
02630       /**
02631        * @brief Return true if two Chi-squared distributions have
02632        *        the same parameters and the sequences that would be
02633        *        generated are equal.
02634        */
02635       template<typename _RealType1>
02636         friend bool
02637         operator==(const std::chi_squared_distribution<_RealType1>& __d1,
02638            const std::chi_squared_distribution<_RealType1>& __d2)
02639         { return __d1.param() == __d2.param() && __d1._M_gd == __d2._M_gd; }
02640 
02641       /**
02642        * @brief Inserts a %chi_squared_distribution random number distribution
02643        * @p __x into the output stream @p __os.
02644        *
02645        * @param __os An output stream.
02646        * @param __x  A %chi_squared_distribution random number distribution.
02647        *
02648        * @returns The output stream with the state of @p __x inserted or in
02649        * an error state.
02650        */
02651       template<typename _RealType1, typename _CharT, typename _Traits>
02652     friend std::basic_ostream<_CharT, _Traits>&
02653     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02654            const std::chi_squared_distribution<_RealType1>& __x);
02655 
02656       /**
02657        * @brief Extracts a %chi_squared_distribution random number distribution
02658        * @p __x from the input stream @p __is.
02659        *
02660        * @param __is An input stream.
02661        * @param __x A %chi_squared_distribution random number
02662        *            generator engine.
02663        *
02664        * @returns The input stream with @p __x extracted or in an error state.
02665        */
02666       template<typename _RealType1, typename _CharT, typename _Traits>
02667     friend std::basic_istream<_CharT, _Traits>&
02668     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02669            std::chi_squared_distribution<_RealType1>& __x);
02670 
02671     private:
02672       param_type _M_param;
02673 
02674       std::gamma_distribution<result_type> _M_gd;
02675     };
02676 
02677   /**
02678    * @brief Return true if two Chi-squared distributions are different.
02679    */
02680   template<typename _RealType>
02681     inline bool
02682     operator!=(const std::chi_squared_distribution<_RealType>& __d1,
02683            const std::chi_squared_distribution<_RealType>& __d2)
02684     { return !(__d1 == __d2); }
02685 
02686 
02687   /**
02688    * @brief A cauchy_distribution random number distribution.
02689    *
02690    * The formula for the normal probability mass function is
02691    * @f$p(x|a,b) = (\pi b (1 + (\frac{x-a}{b})^2))^{-1}@f$
02692    */
02693   template<typename _RealType = double>
02694     class cauchy_distribution
02695     {
02696       static_assert(std::is_floating_point<_RealType>::value,
02697             "template argument not a floating point type");
02698 
02699     public:
02700       /** The type of the range of the distribution. */
02701       typedef _RealType result_type;
02702       /** Parameter type. */
02703       struct param_type
02704       {
02705     typedef cauchy_distribution<_RealType> distribution_type;
02706 
02707     explicit
02708     param_type(_RealType __a = _RealType(0),
02709            _RealType __b = _RealType(1))
02710     : _M_a(__a), _M_b(__b)
02711     { }
02712 
02713     _RealType
02714     a() const
02715     { return _M_a; }
02716 
02717     _RealType
02718     b() const
02719     { return _M_b; }
02720 
02721     friend bool
02722     operator==(const param_type& __p1, const param_type& __p2)
02723     { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
02724 
02725       private:
02726     _RealType _M_a;
02727     _RealType _M_b;
02728       };
02729 
02730       explicit
02731       cauchy_distribution(_RealType __a = _RealType(0),
02732               _RealType __b = _RealType(1))
02733       : _M_param(__a, __b)
02734       { }
02735 
02736       explicit
02737       cauchy_distribution(const param_type& __p)
02738       : _M_param(__p)
02739       { }
02740 
02741       /**
02742        * @brief Resets the distribution state.
02743        */
02744       void
02745       reset()
02746       { }
02747 
02748       /**
02749        *
02750        */
02751       _RealType
02752       a() const
02753       { return _M_param.a(); }
02754 
02755       _RealType
02756       b() const
02757       { return _M_param.b(); }
02758 
02759       /**
02760        * @brief Returns the parameter set of the distribution.
02761        */
02762       param_type
02763       param() const
02764       { return _M_param; }
02765 
02766       /**
02767        * @brief Sets the parameter set of the distribution.
02768        * @param __param The new parameter set of the distribution.
02769        */
02770       void
02771       param(const param_type& __param)
02772       { _M_param = __param; }
02773 
02774       /**
02775        * @brief Returns the greatest lower bound value of the distribution.
02776        */
02777       result_type
02778       min() const
02779       { return std::numeric_limits<result_type>::min(); }
02780 
02781       /**
02782        * @brief Returns the least upper bound value of the distribution.
02783        */
02784       result_type
02785       max() const
02786       { return std::numeric_limits<result_type>::max(); }
02787 
02788       /**
02789        * @brief Generating functions.
02790        */
02791       template<typename _UniformRandomNumberGenerator>
02792     result_type
02793     operator()(_UniformRandomNumberGenerator& __urng)
02794     { return this->operator()(__urng, this->param()); }
02795 
02796       template<typename _UniformRandomNumberGenerator>
02797     result_type
02798     operator()(_UniformRandomNumberGenerator& __urng,
02799            const param_type& __p);
02800 
02801     private:
02802       param_type _M_param;
02803     };
02804 
02805   /**
02806    * @brief Return true if two Cauchy distributions have
02807    *        the same parameters.
02808    */
02809   template<typename _RealType>
02810     inline bool
02811     operator==(const std::cauchy_distribution<_RealType>& __d1,
02812            const std::cauchy_distribution<_RealType>& __d2)
02813     { return __d1.param() == __d2.param(); }
02814 
02815   /**
02816    * @brief Return true if two Cauchy distributions have
02817    *        different parameters.
02818    */
02819   template<typename _RealType>
02820     inline bool
02821     operator!=(const std::cauchy_distribution<_RealType>& __d1,
02822            const std::cauchy_distribution<_RealType>& __d2)
02823     { return !(__d1 == __d2); }
02824 
02825   /**
02826    * @brief Inserts a %cauchy_distribution random number distribution
02827    * @p __x into the output stream @p __os.
02828    *
02829    * @param __os An output stream.
02830    * @param __x  A %cauchy_distribution random number distribution.
02831    *
02832    * @returns The output stream with the state of @p __x inserted or in
02833    * an error state.
02834    */
02835   template<typename _RealType, typename _CharT, typename _Traits>
02836     std::basic_ostream<_CharT, _Traits>&
02837     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02838            const std::cauchy_distribution<_RealType>& __x);
02839 
02840   /**
02841    * @brief Extracts a %cauchy_distribution random number distribution
02842    * @p __x from the input stream @p __is.
02843    *
02844    * @param __is An input stream.
02845    * @param __x A %cauchy_distribution random number
02846    *            generator engine.
02847    *
02848    * @returns The input stream with @p __x extracted or in an error state.
02849    */
02850   template<typename _RealType, typename _CharT, typename _Traits>
02851     std::basic_istream<_CharT, _Traits>&
02852     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02853            std::cauchy_distribution<_RealType>& __x);
02854 
02855 
02856   /**
02857    * @brief A fisher_f_distribution random number distribution.
02858    *
02859    * The formula for the normal probability mass function is
02860    * @f[
02861    *     p(x|m,n) = \frac{\Gamma((m+n)/2)}{\Gamma(m/2)\Gamma(n/2)}
02862    *                (\frac{m}{n})^{m/2} x^{(m/2)-1}
02863    *                (1 + \frac{mx}{n})^{-(m+n)/2} 
02864    * @f]
02865    */
02866   template<typename _RealType = double>
02867     class fisher_f_distribution
02868     {
02869       static_assert(std::is_floating_point<_RealType>::value,
02870             "template argument not a floating point type");
02871 
02872     public:
02873       /** The type of the range of the distribution. */
02874       typedef _RealType result_type;
02875       /** Parameter type. */
02876       struct param_type
02877       {
02878     typedef fisher_f_distribution<_RealType> distribution_type;
02879 
02880     explicit
02881     param_type(_RealType __m = _RealType(1),
02882            _RealType __n = _RealType(1))
02883     : _M_m(__m), _M_n(__n)
02884     { }
02885 
02886     _RealType
02887     m() const
02888     { return _M_m; }
02889 
02890     _RealType
02891     n() const
02892     { return _M_n; }
02893 
02894     friend bool
02895     operator==(const param_type& __p1, const param_type& __p2)
02896     { return __p1._M_m == __p2._M_m && __p1._M_n == __p2._M_n; }
02897 
02898       private:
02899     _RealType _M_m;
02900     _RealType _M_n;
02901       };
02902 
02903       explicit
02904       fisher_f_distribution(_RealType __m = _RealType(1),
02905                 _RealType __n = _RealType(1))
02906       : _M_param(__m, __n), _M_gd_x(__m / 2), _M_gd_y(__n / 2)
02907       { }
02908 
02909       explicit
02910       fisher_f_distribution(const param_type& __p)
02911       : _M_param(__p), _M_gd_x(__p.m() / 2), _M_gd_y(__p.n() / 2)
02912       { }
02913 
02914       /**
02915        * @brief Resets the distribution state.
02916        */
02917       void
02918       reset()
02919       {
02920     _M_gd_x.reset();
02921     _M_gd_y.reset();
02922       }
02923 
02924       /**
02925        *
02926        */
02927       _RealType
02928       m() const
02929       { return _M_param.m(); }
02930 
02931       _RealType
02932       n() const
02933       { return _M_param.n(); }
02934 
02935       /**
02936        * @brief Returns the parameter set of the distribution.
02937        */
02938       param_type
02939       param() const
02940       { return _M_param; }
02941 
02942       /**
02943        * @brief Sets the parameter set of the distribution.
02944        * @param __param The new parameter set of the distribution.
02945        */
02946       void
02947       param(const param_type& __param)
02948       { _M_param = __param; }
02949 
02950       /**
02951        * @brief Returns the greatest lower bound value of the distribution.
02952        */
02953       result_type
02954       min() const
02955       { return result_type(0); }
02956 
02957       /**
02958        * @brief Returns the least upper bound value of the distribution.
02959        */
02960       result_type
02961       max() const
02962       { return std::numeric_limits<result_type>::max(); }
02963 
02964       /**
02965        * @brief Generating functions.
02966        */
02967       template<typename _UniformRandomNumberGenerator>
02968     result_type
02969     operator()(_UniformRandomNumberGenerator& __urng)
02970     { return (_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()); }
02971 
02972       template<typename _UniformRandomNumberGenerator>
02973     result_type
02974     operator()(_UniformRandomNumberGenerator& __urng,
02975            const param_type& __p)
02976         {
02977       typedef typename std::gamma_distribution<result_type>::param_type
02978         param_type;
02979       return ((_M_gd_x(__urng, param_type(__p.m() / 2)) * n())
02980           / (_M_gd_y(__urng, param_type(__p.n() / 2)) * m()));
02981     }
02982 
02983       /**
02984        * @brief Return true if two Fisher f distributions have
02985        *        the same parameters and the sequences that would
02986        *        be generated are equal.
02987        */
02988       template<typename _RealType1>
02989         friend bool
02990         operator==(const std::fisher_f_distribution<_RealType1>& __d1,
02991            const std::fisher_f_distribution<_RealType1>& __d2)
02992         { return (__d1.param() == __d2.param()
02993           && __d1._M_gd_x == __d2._M_gd_x
02994           && __d1._M_gd_y == __d2._M_gd_y); }
02995 
02996       /**
02997        * @brief Inserts a %fisher_f_distribution random number distribution
02998        * @p __x into the output stream @p __os.
02999        *
03000        * @param __os An output stream.
03001        * @param __x  A %fisher_f_distribution random number distribution.
03002        *
03003        * @returns The output stream with the state of @p __x inserted or in
03004        * an error state.
03005        */
03006       template<typename _RealType1, typename _CharT, typename _Traits>
03007     friend std::basic_ostream<_CharT, _Traits>&
03008     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03009            const std::fisher_f_distribution<_RealType1>& __x);
03010 
03011       /**
03012        * @brief Extracts a %fisher_f_distribution random number distribution
03013        * @p __x from the input stream @p __is.
03014        *
03015        * @param __is An input stream.
03016        * @param __x A %fisher_f_distribution random number
03017        *            generator engine.
03018        *
03019        * @returns The input stream with @p __x extracted or in an error state.
03020        */
03021       template<typename _RealType1, typename _CharT, typename _Traits>
03022     friend std::basic_istream<_CharT, _Traits>&
03023     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03024            std::fisher_f_distribution<_RealType1>& __x);
03025 
03026     private:
03027       param_type _M_param;
03028 
03029       std::gamma_distribution<result_type> _M_gd_x, _M_gd_y;
03030     };
03031 
03032   /**
03033    * @brief Return true if two Fisher f distributions are diferent.
03034    */
03035   template<typename _RealType>
03036     inline bool
03037     operator!=(const std::fisher_f_distribution<_RealType>& __d1,
03038            const std::fisher_f_distribution<_RealType>& __d2)
03039     { return !(__d1 == __d2); }
03040 
03041   /**
03042    * @brief A student_t_distribution random number distribution.
03043    *
03044    * The formula for the normal probability mass function is:
03045    * @f[
03046    *     p(x|n) = \frac{1}{\sqrt(n\pi)} \frac{\Gamma((n+1)/2)}{\Gamma(n/2)}
03047    *              (1 + \frac{x^2}{n}) ^{-(n+1)/2} 
03048    * @f]
03049    */
03050   template<typename _RealType = double>
03051     class student_t_distribution
03052     {
03053       static_assert(std::is_floating_point<_RealType>::value,
03054             "template argument not a floating point type");
03055 
03056     public:
03057       /** The type of the range of the distribution. */
03058       typedef _RealType result_type;
03059       /** Parameter type. */
03060       struct param_type
03061       {
03062     typedef student_t_distribution<_RealType> distribution_type;
03063 
03064     explicit
03065     param_type(_RealType __n = _RealType(1))
03066     : _M_n(__n)
03067     { }
03068 
03069     _RealType
03070     n() const
03071     { return _M_n; }
03072 
03073     friend bool
03074     operator==(const param_type& __p1, const param_type& __p2)
03075     { return __p1._M_n == __p2._M_n; }
03076 
03077       private:
03078     _RealType _M_n;
03079       };
03080 
03081       explicit
03082       student_t_distribution(_RealType __n = _RealType(1))
03083       : _M_param(__n), _M_nd(), _M_gd(__n / 2, 2)
03084       { }
03085 
03086       explicit
03087       student_t_distribution(const param_type& __p)
03088       : _M_param(__p), _M_nd(), _M_gd(__p.n() / 2, 2)
03089       { }
03090 
03091       /**
03092        * @brief Resets the distribution state.
03093        */
03094       void
03095       reset()
03096       {
03097     _M_nd.reset();
03098     _M_gd.reset();
03099       }
03100 
03101       /**
03102        *
03103        */
03104       _RealType
03105       n() const
03106       { return _M_param.n(); }
03107 
03108       /**
03109        * @brief Returns the parameter set of the distribution.
03110        */
03111       param_type
03112       param() const
03113       { return _M_param; }
03114 
03115       /**
03116        * @brief Sets the parameter set of the distribution.
03117        * @param __param The new parameter set of the distribution.
03118        */
03119       void
03120       param(const param_type& __param)
03121       { _M_param = __param; }
03122 
03123       /**
03124        * @brief Returns the greatest lower bound value of the distribution.
03125        */
03126       result_type
03127       min() const
03128       { return std::numeric_limits<result_type>::min(); }
03129 
03130       /**
03131        * @brief Returns the least upper bound value of the distribution.
03132        */
03133       result_type
03134       max() const
03135       { return std::numeric_limits<result_type>::max(); }
03136 
03137       /**
03138        * @brief Generating functions.
03139        */
03140       template<typename _UniformRandomNumberGenerator>
03141     result_type
03142         operator()(_UniformRandomNumberGenerator& __urng)
03143         { return _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); }
03144 
03145       template<typename _UniformRandomNumberGenerator>
03146     result_type
03147     operator()(_UniformRandomNumberGenerator& __urng,
03148            const param_type& __p)
03149         {
03150       typedef typename std::gamma_distribution<result_type>::param_type
03151         param_type;
03152     
03153       const result_type __g = _M_gd(__urng, param_type(__p.n() / 2, 2));
03154       return _M_nd(__urng) * std::sqrt(__p.n() / __g);
03155         }
03156 
03157       /**
03158        * @brief Return true if two Student t distributions have
03159        *        the same parameters and the sequences that would
03160        *        be generated are equal.
03161        */
03162       template<typename _RealType1>
03163         friend bool
03164         operator==(const std::student_t_distribution<_RealType1>& __d1,
03165            const std::student_t_distribution<_RealType1>& __d2)
03166         { return (__d1.param() == __d2.param()
03167           && __d1._M_nd == __d2._M_nd && __d1._M_gd == __d2._M_gd); }
03168 
03169       /**
03170        * @brief Inserts a %student_t_distribution random number distribution
03171        * @p __x into the output stream @p __os.
03172        *
03173        * @param __os An output stream.
03174        * @param __x  A %student_t_distribution random number distribution.
03175        *
03176        * @returns The output stream with the state of @p __x inserted or in
03177        * an error state.
03178        */
03179       template<typename _RealType1, typename _CharT, typename _Traits>
03180     friend std::basic_ostream<_CharT, _Traits>&
03181     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03182            const std::student_t_distribution<_RealType1>& __x);
03183 
03184       /**
03185        * @brief Extracts a %student_t_distribution random number distribution
03186        * @p __x from the input stream @p __is.
03187        *
03188        * @param __is An input stream.
03189        * @param __x A %student_t_distribution random number
03190        *            generator engine.
03191        *
03192        * @returns The input stream with @p __x extracted or in an error state.
03193        */
03194       template<typename _RealType1, typename _CharT, typename _Traits>
03195     friend std::basic_istream<_CharT, _Traits>&
03196     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03197            std::student_t_distribution<_RealType1>& __x);
03198 
03199     private:
03200       param_type _M_param;
03201 
03202       std::normal_distribution<result_type> _M_nd;
03203       std::gamma_distribution<result_type> _M_gd;
03204     };
03205 
03206   /**
03207    * @brief Return true if two Student t distributions are different.
03208    */
03209   template<typename _RealType>
03210     inline bool
03211     operator!=(const std::student_t_distribution<_RealType>& __d1,
03212            const std::student_t_distribution<_RealType>& __d2)
03213     { return !(__d1 == __d2); }
03214 
03215 
03216   /* @} */ // group random_distributions_normal
03217 
03218   /**
03219    * @addtogroup random_distributions_bernoulli Bernoulli Distributions
03220    * @ingroup random_distributions
03221    * @{
03222    */
03223 
03224   /**
03225    * @brief A Bernoulli random number distribution.
03226    *
03227    * Generates a sequence of true and false values with likelihood @f$p@f$
03228    * that true will come up and @f$(1 - p)@f$ that false will appear.
03229    */
03230   class bernoulli_distribution
03231   {
03232   public:
03233     /** The type of the range of the distribution. */
03234     typedef bool result_type;
03235     /** Parameter type. */
03236     struct param_type
03237     {
03238       typedef bernoulli_distribution distribution_type;
03239 
03240       explicit
03241       param_type(double __p = 0.5)
03242       : _M_p(__p)
03243       {
03244     _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
03245       }
03246 
03247       double
03248       p() const
03249       { return _M_p; }
03250 
03251       friend bool
03252       operator==(const param_type& __p1, const param_type& __p2)
03253       { return __p1._M_p == __p2._M_p; }
03254 
03255     private:
03256       double _M_p;
03257     };
03258 
03259   public:
03260     /**
03261      * @brief Constructs a Bernoulli distribution with likelihood @p p.
03262      *
03263      * @param __p  [IN]  The likelihood of a true result being returned.
03264      *                   Must be in the interval @f$[0, 1]@f$.
03265      */
03266     explicit
03267     bernoulli_distribution(double __p = 0.5)
03268     : _M_param(__p)
03269     { }
03270 
03271     explicit
03272     bernoulli_distribution(const param_type& __p)
03273     : _M_param(__p)
03274     { }
03275 
03276     /**
03277      * @brief Resets the distribution state.
03278      *
03279      * Does nothing for a Bernoulli distribution.
03280      */
03281     void
03282     reset() { }
03283 
03284     /**
03285      * @brief Returns the @p p parameter of the distribution.
03286      */
03287     double
03288     p() const
03289     { return _M_param.p(); }
03290 
03291     /**
03292      * @brief Returns the parameter set of the distribution.
03293      */
03294     param_type
03295     param() const
03296     { return _M_param; }
03297 
03298     /**
03299      * @brief Sets the parameter set of the distribution.
03300      * @param __param The new parameter set of the distribution.
03301      */
03302     void
03303     param(const param_type& __param)
03304     { _M_param = __param; }
03305 
03306     /**
03307      * @brief Returns the greatest lower bound value of the distribution.
03308      */
03309     result_type
03310     min() const
03311     { return std::numeric_limits<result_type>::min(); }
03312 
03313     /**
03314      * @brief Returns the least upper bound value of the distribution.
03315      */
03316     result_type
03317     max() const
03318     { return std::numeric_limits<result_type>::max(); }
03319 
03320     /**
03321      * @brief Generating functions.
03322      */
03323     template<typename _UniformRandomNumberGenerator>
03324       result_type
03325       operator()(_UniformRandomNumberGenerator& __urng)
03326       { return this->operator()(__urng, this->param()); }
03327 
03328     template<typename _UniformRandomNumberGenerator>
03329       result_type
03330       operator()(_UniformRandomNumberGenerator& __urng,
03331          const param_type& __p)
03332       {
03333     __detail::_Adaptor<_UniformRandomNumberGenerator, double>
03334       __aurng(__urng);
03335     if ((__aurng() - __aurng.min())
03336          < __p.p() * (__aurng.max() - __aurng.min()))
03337       return true;
03338     return false;
03339       }
03340 
03341   private:
03342     param_type _M_param;
03343   };
03344 
03345   /**
03346    * @brief Return true if two Bernoulli distributions have
03347    *        the same parameters.
03348    */
03349   inline bool
03350   operator==(const std::bernoulli_distribution& __d1,
03351          const std::bernoulli_distribution& __d2)
03352   { return __d1.param() == __d2.param(); }
03353 
03354   /**
03355    * @brief Return true if two Bernoulli distributions have
03356    *        different parameters.
03357    */
03358   inline bool
03359   operator!=(const std::bernoulli_distribution& __d1,
03360          const std::bernoulli_distribution& __d2)
03361   { return !(__d1 == __d2); }
03362 
03363   /**
03364    * @brief Inserts a %bernoulli_distribution random number distribution
03365    * @p __x into the output stream @p __os.
03366    *
03367    * @param __os An output stream.
03368    * @param __x  A %bernoulli_distribution random number distribution.
03369    *
03370    * @returns The output stream with the state of @p __x inserted or in
03371    * an error state.
03372    */
03373   template<typename _CharT, typename _Traits>
03374     std::basic_ostream<_CharT, _Traits>&
03375     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03376            const std::bernoulli_distribution& __x);
03377 
03378   /**
03379    * @brief Extracts a %bernoulli_distribution random number distribution
03380    * @p __x from the input stream @p __is.
03381    *
03382    * @param __is An input stream.
03383    * @param __x  A %bernoulli_distribution random number generator engine.
03384    *
03385    * @returns The input stream with @p __x extracted or in an error state.
03386    */
03387   template<typename _CharT, typename _Traits>
03388     std::basic_istream<_CharT, _Traits>&
03389     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03390            std::bernoulli_distribution& __x)
03391     {
03392       double __p;
03393       __is >> __p;
03394       __x.param(bernoulli_distribution::param_type(__p));
03395       return __is;
03396     }
03397 
03398 
03399   /**
03400    * @brief A discrete binomial random number distribution.
03401    *
03402    * The formula for the binomial probability density function is
03403    * @f$p(i|t,p) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
03404    * and @f$p@f$ are the parameters of the distribution.
03405    */
03406   template<typename _IntType = int>
03407     class binomial_distribution
03408     {
03409       static_assert(std::is_integral<_IntType>::value,
03410             "template argument not an integral type");
03411 
03412     public:
03413       /** The type of the range of the distribution. */
03414       typedef _IntType result_type;
03415       /** Parameter type. */
03416       struct param_type
03417       {
03418     typedef binomial_distribution<_IntType> distribution_type;
03419     friend class binomial_distribution<_IntType>;
03420 
03421     explicit
03422     param_type(_IntType __t = _IntType(1), double __p = 0.5)
03423     : _M_t(__t), _M_p(__p)
03424     {
03425       _GLIBCXX_DEBUG_ASSERT((_M_t >= _IntType(0))
03426                 && (_M_p >= 0.0)
03427                 && (_M_p <= 1.0));
03428       _M_initialize();
03429     }
03430 
03431     _IntType
03432     t() const
03433     { return _M_t; }
03434 
03435     double
03436     p() const
03437     { return _M_p; }
03438 
03439     friend bool
03440     operator==(const param_type& __p1, const param_type& __p2)
03441     { return __p1._M_t == __p2._M_t && __p1._M_p == __p2._M_p; }
03442 
03443       private:
03444     void
03445     _M_initialize();
03446 
03447     _IntType _M_t;
03448     double _M_p;
03449 
03450     double _M_q;
03451 #if _GLIBCXX_USE_C99_MATH_TR1
03452     double _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
03453            _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
03454 #endif
03455     bool   _M_easy;
03456       };
03457 
03458       // constructors and member function
03459       explicit
03460       binomial_distribution(_IntType __t = _IntType(1),
03461                 double __p = 0.5)
03462       : _M_param(__t, __p), _M_nd()
03463       { }
03464 
03465       explicit
03466       binomial_distribution(const param_type& __p)
03467       : _M_param(__p), _M_nd()
03468       { }
03469 
03470       /**
03471        * @brief Resets the distribution state.
03472        */
03473       void
03474       reset()
03475       { _M_nd.reset(); }
03476 
03477       /**
03478        * @brief Returns the distribution @p t parameter.
03479        */
03480       _IntType
03481       t() const
03482       { return _M_param.t(); }
03483 
03484       /**
03485        * @brief Returns the distribution @p p parameter.
03486        */
03487       double
03488       p() const
03489       { return _M_param.p(); }
03490 
03491       /**
03492        * @brief Returns the parameter set of the distribution.
03493        */
03494       param_type
03495       param() const
03496       { return _M_param; }
03497 
03498       /**
03499        * @brief Sets the parameter set of the distribution.
03500        * @param __param The new parameter set of the distribution.
03501        */
03502       void
03503       param(const param_type& __param)
03504       { _M_param = __param; }
03505 
03506       /**
03507        * @brief Returns the greatest lower bound value of the distribution.
03508        */
03509       result_type
03510       min() const
03511       { return 0; }
03512 
03513       /**
03514        * @brief Returns the least upper bound value of the distribution.
03515        */
03516       result_type
03517       max() const
03518       { return _M_param.t(); }
03519 
03520       /**
03521        * @brief Generating functions.
03522        */
03523       template<typename _UniformRandomNumberGenerator>
03524     result_type
03525     operator()(_UniformRandomNumberGenerator& __urng)
03526     { return this->operator()(__urng, this->param()); }
03527 
03528       template<typename _UniformRandomNumberGenerator>
03529     result_type
03530     operator()(_UniformRandomNumberGenerator& __urng,
03531            const param_type& __p);
03532 
03533       /**
03534        * @brief Return true if two binomial distributions have
03535        *        the same parameters and the sequences that would
03536        *        be generated are equal.
03537        */
03538       template<typename _IntType1>
03539     friend bool
03540         operator==(const std::binomial_distribution<_IntType1>& __d1,
03541            const std::binomial_distribution<_IntType1>& __d2)
03542 #ifdef _GLIBCXX_USE_C99_MATH_TR1
03543     { return __d1.param() == __d2.param() && __d1._M_nd == __d2._M_nd; }
03544 #else
03545         { return __d1.param() == __d2.param(); }
03546 #endif
03547 
03548       /**
03549        * @brief Inserts a %binomial_distribution random number distribution
03550        * @p __x into the output stream @p __os.
03551        *
03552        * @param __os An output stream.
03553        * @param __x  A %binomial_distribution random number distribution.
03554        *
03555        * @returns The output stream with the state of @p __x inserted or in
03556        * an error state.
03557        */
03558       template<typename _IntType1,
03559            typename _CharT, typename _Traits>
03560     friend std::basic_ostream<_CharT, _Traits>&
03561     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03562            const std::binomial_distribution<_IntType1>& __x);
03563 
03564       /**
03565        * @brief Extracts a %binomial_distribution random number distribution
03566        * @p __x from the input stream @p __is.
03567        *
03568        * @param __is An input stream.
03569        * @param __x  A %binomial_distribution random number generator engine.
03570        *
03571        * @returns The input stream with @p __x extracted or in an error
03572        *          state.
03573        */
03574       template<typename _IntType1,
03575            typename _CharT, typename _Traits>
03576     friend std::basic_istream<_CharT, _Traits>&
03577     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03578            std::binomial_distribution<_IntType1>& __x);
03579 
03580     private:
03581       template<typename _UniformRandomNumberGenerator>
03582     result_type
03583     _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);
03584 
03585       param_type _M_param;
03586 
03587       // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
03588       std::normal_distribution<double> _M_nd;
03589     };
03590 
03591   /**
03592    * @brief Return true if two binomial distributions are different.
03593    */
03594   template<typename _IntType>
03595     inline bool
03596     operator!=(const std::binomial_distribution<_IntType>& __d1,
03597            const std::binomial_distribution<_IntType>& __d2)
03598     { return !(__d1 == __d2); }
03599 
03600 
03601   /**
03602    * @brief A discrete geometric random number distribution.
03603    *
03604    * The formula for the geometric probability density function is
03605    * @f$p(i|p) = p(1 - p)^{i}@f$ where @f$p@f$ is the parameter of the
03606    * distribution.
03607    */
03608   template<typename _IntType = int>
03609     class geometric_distribution
03610     {
03611       static_assert(std::is_integral<_IntType>::value,
03612             "template argument not an integral type");
03613 
03614     public:
03615       /** The type of the range of the distribution. */
03616       typedef _IntType  result_type;
03617       /** Parameter type. */
03618       struct param_type
03619       {
03620     typedef geometric_distribution<_IntType> distribution_type;
03621     friend class geometric_distribution<_IntType>;
03622 
03623     explicit
03624     param_type(double __p = 0.5)
03625     : _M_p(__p)
03626     {
03627       _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
03628       _M_initialize();
03629     }
03630 
03631     double
03632     p() const
03633     { return _M_p; }
03634 
03635     friend bool
03636     operator==(const param_type& __p1, const param_type& __p2)
03637     { return __p1._M_p == __p2._M_p; }
03638 
03639       private:
03640     void
03641     _M_initialize()
03642     { _M_log_1_p = std::log(1.0 - _M_p); }
03643 
03644     double _M_p;
03645 
03646     double _M_log_1_p;
03647       };
03648 
03649       // constructors and member function
03650       explicit
03651       geometric_distribution(double __p = 0.5)
03652       : _M_param(__p)
03653       { }
03654 
03655       explicit
03656       geometric_distribution(const param_type& __p)
03657       : _M_param(__p)
03658       { }
03659 
03660       /**
03661        * @brief Resets the distribution state.
03662        *
03663        * Does nothing for the geometric distribution.
03664        */
03665       void
03666       reset() { }
03667 
03668       /**
03669        * @brief Returns the distribution parameter @p p.
03670        */
03671       double
03672       p() const
03673       { return _M_param.p(); }
03674 
03675       /**
03676        * @brief Returns the parameter set of the distribution.
03677        */
03678       param_type
03679       param() const
03680       { return _M_param; }
03681 
03682       /**
03683        * @brief Sets the parameter set of the distribution.
03684        * @param __param The new parameter set of the distribution.
03685        */
03686       void
03687       param(const param_type& __param)
03688       { _M_param = __param; }
03689 
03690       /**
03691        * @brief Returns the greatest lower bound value of the distribution.
03692        */
03693       result_type
03694       min() const
03695       { return 0; }
03696 
03697       /**
03698        * @brief Returns the least upper bound value of the distribution.
03699        */
03700       result_type
03701       max() const
03702       { return std::numeric_limits<result_type>::max(); }
03703 
03704       /**
03705        * @brief Generating functions.
03706        */
03707       template<typename _UniformRandomNumberGenerator>
03708     result_type
03709     operator()(_UniformRandomNumberGenerator& __urng)
03710     { return this->operator()(__urng, this->param()); }
03711 
03712       template<typename _UniformRandomNumberGenerator>
03713     result_type
03714     operator()(_UniformRandomNumberGenerator& __urng,
03715            const param_type& __p);
03716 
03717     private:
03718       param_type _M_param;
03719     };
03720 
03721   /**
03722    * @brief Return true if two geometric distributions have
03723    *        the same parameters.
03724    */
03725   template<typename _IntType>
03726     inline bool
03727     operator==(const std::geometric_distribution<_IntType>& __d1,
03728            const std::geometric_distribution<_IntType>& __d2)
03729     { return __d1.param() == __d2.param(); }
03730 
03731   /**
03732    * @brief Return true if two geometric distributions have
03733    *        different parameters.
03734    */
03735   template<typename _IntType>
03736     inline bool
03737     operator!=(const std::geometric_distribution<_IntType>& __d1,
03738            const std::geometric_distribution<_IntType>& __d2)
03739     { return !(__d1 == __d2); }
03740 
03741   /**
03742    * @brief Inserts a %geometric_distribution random number distribution
03743    * @p __x into the output stream @p __os.
03744    *
03745    * @param __os An output stream.
03746    * @param __x  A %geometric_distribution random number distribution.
03747    *
03748    * @returns The output stream with the state of @p __x inserted or in
03749    * an error state.
03750    */
03751   template<typename _IntType,
03752        typename _CharT, typename _Traits>
03753     std::basic_ostream<_CharT, _Traits>&
03754     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03755            const std::geometric_distribution<_IntType>& __x);
03756 
03757   /**
03758    * @brief Extracts a %geometric_distribution random number distribution
03759    * @p __x from the input stream @p __is.
03760    *
03761    * @param __is An input stream.
03762    * @param __x  A %geometric_distribution random number generator engine.
03763    *
03764    * @returns The input stream with @p __x extracted or in an error state.
03765    */
03766   template<typename _IntType,
03767        typename _CharT, typename _Traits>
03768     std::basic_istream<_CharT, _Traits>&
03769     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03770            std::geometric_distribution<_IntType>& __x);
03771 
03772 
03773   /**
03774    * @brief A negative_binomial_distribution random number distribution.
03775    *
03776    * The formula for the negative binomial probability mass function is
03777    * @f$p(i) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
03778    * and @f$p@f$ are the parameters of the distribution.
03779    */
03780   template<typename _IntType = int>
03781     class negative_binomial_distribution
03782     {
03783       static_assert(std::is_integral<_IntType>::value,
03784             "template argument not an integral type");
03785 
03786     public:
03787       /** The type of the range of the distribution. */
03788       typedef _IntType result_type;
03789       /** Parameter type. */
03790       struct param_type
03791       {
03792     typedef negative_binomial_distribution<_IntType> distribution_type;
03793 
03794     explicit
03795     param_type(_IntType __k = 1, double __p = 0.5)
03796     : _M_k(__k), _M_p(__p)
03797     {
03798       _GLIBCXX_DEBUG_ASSERT((_M_k > 0) && (_M_p > 0.0) && (_M_p <= 1.0));
03799     }
03800 
03801     _IntType
03802     k() const
03803     { return _M_k; }
03804 
03805     double
03806     p() const
03807     { return _M_p; }
03808 
03809     friend bool
03810     operator==(const param_type& __p1, const param_type& __p2)
03811     { return __p1._M_k == __p2._M_k && __p1._M_p == __p2._M_p; }
03812 
03813       private:
03814     _IntType _M_k;
03815     double _M_p;
03816       };
03817 
03818       explicit
03819       negative_binomial_distribution(_IntType __k = 1, double __p = 0.5)
03820       : _M_param(__k, __p), _M_gd(__k, (1.0 - __p) / __p)
03821       { }
03822 
03823       explicit
03824       negative_binomial_distribution(const param_type& __p)
03825       : _M_param(__p), _M_gd(__p.k(), (1.0 - __p.p()) / __p.p())
03826       { }
03827 
03828       /**
03829        * @brief Resets the distribution state.
03830        */
03831       void
03832       reset()
03833       { _M_gd.reset(); }
03834 
03835       /**
03836        * @brief Return the @f$k@f$ parameter of the distribution.
03837        */
03838       _IntType
03839       k() const
03840       { return _M_param.k(); }
03841 
03842       /**
03843        * @brief Return the @f$p@f$ parameter of the distribution.
03844        */
03845       double
03846       p() const
03847       { return _M_param.p(); }
03848 
03849       /**
03850        * @brief Returns the parameter set of the distribution.
03851        */
03852       param_type
03853       param() const
03854       { return _M_param; }
03855 
03856       /**
03857        * @brief Sets the parameter set of the distribution.
03858        * @param __param The new parameter set of the distribution.
03859        */
03860       void
03861       param(const param_type& __param)
03862       { _M_param = __param; }
03863 
03864       /**
03865        * @brief Returns the greatest lower bound value of the distribution.
03866        */
03867       result_type
03868       min() const
03869       { return result_type(0); }
03870 
03871       /**
03872        * @brief Returns the least upper bound value of the distribution.
03873        */
03874       result_type
03875       max() const
03876       { return std::numeric_limits<result_type>::max(); }
03877 
03878       /**
03879        * @brief Generating functions.
03880        */
03881       template<typename _UniformRandomNumberGenerator>
03882     result_type
03883         operator()(_UniformRandomNumberGenerator& __urng);
03884 
03885       template<typename _UniformRandomNumberGenerator>
03886     result_type
03887     operator()(_UniformRandomNumberGenerator& __urng,
03888            const param_type& __p);
03889 
03890       /**
03891        * @brief Return true if two negative binomial distributions have
03892        *        the same parameters and the sequences that would be
03893        *        generated are equal.
03894        */
03895       template<typename _IntType1>
03896         friend bool
03897         operator==(const std::negative_binomial_distribution<_IntType1>& __d1,
03898            const std::negative_binomial_distribution<_IntType1>& __d2)
03899         { return __d1.param() == __d2.param() && __d1._M_gd == __d2._M_gd; }
03900 
03901       /**
03902        * @brief Inserts a %negative_binomial_distribution random
03903        *        number distribution @p __x into the output stream @p __os.
03904        *
03905        * @param __os An output stream.
03906        * @param __x  A %negative_binomial_distribution random number
03907        *             distribution.
03908        *
03909        * @returns The output stream with the state of @p __x inserted or in
03910        *          an error state.
03911        */
03912       template<typename _IntType1, typename _CharT, typename _Traits>
03913     friend std::basic_ostream<_CharT, _Traits>&
03914     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03915            const std::negative_binomial_distribution<_IntType1>& __x);
03916 
03917       /**
03918        * @brief Extracts a %negative_binomial_distribution random number
03919        *        distribution @p __x from the input stream @p __is.
03920        *
03921        * @param __is An input stream.
03922        * @param __x A %negative_binomial_distribution random number
03923        *            generator engine.
03924        *
03925        * @returns The input stream with @p __x extracted or in an error state.
03926        */
03927       template<typename _IntType1, typename _CharT, typename _Traits>
03928     friend std::basic_istream<_CharT, _Traits>&
03929     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03930            std::negative_binomial_distribution<_IntType1>& __x);
03931 
03932     private:
03933       param_type _M_param;
03934 
03935       std::gamma_distribution<double> _M_gd;
03936     };
03937 
03938   /**
03939    * @brief Return true if two negative binomial distributions are different.
03940    */
03941   template<typename _IntType>
03942     inline bool
03943     operator!=(const std::negative_binomial_distribution<_IntType>& __d1,
03944            const std::negative_binomial_distribution<_IntType>& __d2)
03945     { return !(__d1 == __d2); }
03946 
03947 
03948   /* @} */ // group random_distributions_bernoulli
03949 
03950   /**
03951    * @addtogroup random_distributions_poisson Poisson Distributions
03952    * @ingroup random_distributions
03953    * @{
03954    */
03955 
03956   /**
03957    * @brief A discrete Poisson random number distribution.
03958    *
03959    * The formula for the Poisson probability density function is
03960    * @f$p(i|\mu) = \frac{\mu^i}{i!} e^{-\mu}@f$ where @f$\mu@f$ is the
03961    * parameter of the distribution.
03962    */
03963   template<typename _IntType = int>
03964     class poisson_distribution
03965     {
03966       static_assert(std::is_integral<_IntType>::value,
03967             "template argument not an integral type");
03968 
03969     public:
03970       /** The type of the range of the distribution. */
03971       typedef _IntType  result_type;
03972       /** Parameter type. */
03973       struct param_type
03974       {
03975     typedef poisson_distribution<_IntType> distribution_type;
03976     friend class poisson_distribution<_IntType>;
03977 
03978     explicit
03979     param_type(double __mean = 1.0)
03980     : _M_mean(__mean)
03981     {
03982       _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
03983       _M_initialize();
03984     }
03985 
03986     double
03987     mean() const
03988     { return _M_mean; }
03989 
03990     friend bool
03991     operator==(const param_type& __p1, const param_type& __p2)
03992     { return __p1._M_mean == __p2._M_mean; }
03993 
03994       private:
03995     // Hosts either log(mean) or the threshold of the simple method.
03996     void
03997     _M_initialize();
03998 
03999     double _M_mean;
04000 
04001     double _M_lm_thr;
04002 #if _GLIBCXX_USE_C99_MATH_TR1
04003     double _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
04004 #endif
04005       };
04006 
04007       // constructors and member function
04008       explicit
04009       poisson_distribution(double __mean = 1.0)
04010       : _M_param(__mean), _M_nd()
04011       { }
04012 
04013       explicit
04014       poisson_distribution(const param_type& __p)
04015       : _M_param(__p), _M_nd()
04016       { }
04017 
04018       /**
04019        * @brief Resets the distribution state.
04020        */
04021       void
04022       reset()
04023       { _M_nd.reset(); }
04024 
04025       /**
04026        * @brief Returns the distribution parameter @p mean.
04027        */
04028       double
04029       mean() const
04030       { return _M_param.mean(); }
04031 
04032       /**
04033        * @brief Returns the parameter set of the distribution.
04034        */
04035       param_type
04036       param() const
04037       { return _M_param; }
04038 
04039       /**
04040        * @brief Sets the parameter set of the distribution.
04041        * @param __param The new parameter set of the distribution.
04042        */
04043       void
04044       param(const param_type& __param)
04045       { _M_param = __param; }
04046 
04047       /**
04048        * @brief Returns the greatest lower bound value of the distribution.
04049        */
04050       result_type
04051       min() const
04052       { return 0; }
04053 
04054       /**
04055        * @brief Returns the least upper bound value of the distribution.
04056        */
04057       result_type
04058       max() const
04059       { return std::numeric_limits<result_type>::max(); }
04060 
04061       /**
04062        * @brief Generating functions.
04063        */
04064       template<typename _UniformRandomNumberGenerator>
04065     result_type
04066     operator()(_UniformRandomNumberGenerator& __urng)
04067     { return this->operator()(__urng, this->param()); }
04068 
04069       template<typename _UniformRandomNumberGenerator>
04070     result_type
04071     operator()(_UniformRandomNumberGenerator& __urng,
04072            const param_type& __p);
04073 
04074        /**
04075     * @brief Return true if two Poisson distributions have the same
04076     *        parameters and the sequences that would be generated
04077     *        are equal.
04078     */
04079       template<typename _IntType1>
04080         friend bool
04081         operator==(const std::poisson_distribution<_IntType1>& __d1,
04082            const std::poisson_distribution<_IntType1>& __d2)
04083 #ifdef _GLIBCXX_USE_C99_MATH_TR1
04084         { return __d1.param() == __d2.param() && __d1._M_nd == __d2._M_nd; }
04085 #else
04086         { return __d1.param() == __d2.param(); }
04087 #endif
04088 
04089       /**
04090        * @brief Inserts a %poisson_distribution random number distribution
04091        * @p __x into the output stream @p __os.
04092        *
04093        * @param __os An output stream.
04094        * @param __x  A %poisson_distribution random number distribution.
04095        *
04096        * @returns The output stream with the state of @p __x inserted or in
04097        * an error state.
04098        */
04099       template<typename _IntType1, typename _CharT, typename _Traits>
04100     friend std::basic_ostream<_CharT, _Traits>&
04101     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04102            const std::poisson_distribution<_IntType1>& __x);
04103 
04104       /**
04105        * @brief Extracts a %poisson_distribution random number distribution
04106        * @p __x from the input stream @p __is.
04107        *
04108        * @param __is An input stream.
04109        * @param __x  A %poisson_distribution random number generator engine.
04110        *
04111        * @returns The input stream with @p __x extracted or in an error
04112        *          state.
04113        */
04114       template<typename _IntType1, typename _CharT, typename _Traits>
04115     friend std::basic_istream<_CharT, _Traits>&
04116     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04117            std::poisson_distribution<_IntType1>& __x);
04118 
04119     private:
04120       param_type _M_param;
04121 
04122       // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
04123       std::normal_distribution<double> _M_nd;
04124     };
04125 
04126   /**
04127    * @brief Return true if two Poisson distributions are different.
04128    */
04129   template<typename _IntType>
04130     inline bool
04131     operator!=(const std::poisson_distribution<_IntType>& __d1,
04132            const std::poisson_distribution<_IntType>& __d2)
04133     { return !(__d1 == __d2); }
04134 
04135 
04136   /**
04137    * @brief An exponential continuous distribution for random numbers.
04138    *
04139    * The formula for the exponential probability density function is
04140    * @f$p(x|\lambda) = \lambda e^{-\lambda x}@f$.
04141    *
04142    * <table border=1 cellpadding=10 cellspacing=0>
04143    * <caption align=top>Distribution Statistics</caption>
04144    * <tr><td>Mean</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
04145    * <tr><td>Median</td><td>@f$\frac{\ln 2}{\lambda}@f$</td></tr>
04146    * <tr><td>Mode</td><td>@f$zero@f$</td></tr>
04147    * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
04148    * <tr><td>Standard Deviation</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
04149    * </table>
04150    */
04151   template<typename _RealType = double>
04152     class exponential_distribution
04153     {
04154       static_assert(std::is_floating_point<_RealType>::value,
04155             "template argument not a floating point type");
04156 
04157     public:
04158       /** The type of the range of the distribution. */
04159       typedef _RealType result_type;
04160       /** Parameter type. */
04161       struct param_type
04162       {
04163     typedef exponential_distribution<_RealType> distribution_type;
04164 
04165     explicit
04166     param_type(_RealType __lambda = _RealType(1))
04167     : _M_lambda(__lambda)
04168     {
04169       _GLIBCXX_DEBUG_ASSERT(_M_lambda > _RealType(0));
04170     }
04171 
04172     _RealType
04173     lambda() const
04174     { return _M_lambda; }
04175 
04176     friend bool
04177     operator==(const param_type& __p1, const param_type& __p2)
04178     { return __p1._M_lambda == __p2._M_lambda; }
04179 
04180       private:
04181     _RealType _M_lambda;
04182       };
04183 
04184     public:
04185       /**
04186        * @brief Constructs an exponential distribution with inverse scale
04187        *        parameter @f$\lambda@f$.
04188        */
04189       explicit
04190       exponential_distribution(const result_type& __lambda = result_type(1))
04191       : _M_param(__lambda)
04192       { }
04193 
04194       explicit
04195       exponential_distribution(const param_type& __p)
04196       : _M_param(__p)
04197       { }
04198 
04199       /**
04200        * @brief Resets the distribution state.
04201        *
04202        * Has no effect on exponential distributions.
04203        */
04204       void
04205       reset() { }
04206 
04207       /**
04208        * @brief Returns the inverse scale parameter of the distribution.
04209        */
04210       _RealType
04211       lambda() const
04212       { return _M_param.lambda(); }
04213 
04214       /**
04215        * @brief Returns the parameter set of the distribution.
04216        */
04217       param_type
04218       param() const
04219       { return _M_param; }
04220 
04221       /**
04222        * @brief Sets the parameter set of the distribution.
04223        * @param __param The new parameter set of the distribution.
04224        */
04225       void
04226       param(const param_type& __param)
04227       { _M_param = __param; }
04228 
04229       /**
04230        * @brief Returns the greatest lower bound value of the distribution.
04231        */
04232       result_type
04233       min() const
04234       { return result_type(0); }
04235 
04236       /**
04237        * @brief Returns the least upper bound value of the distribution.
04238        */
04239       result_type
04240       max() const
04241       { return std::numeric_limits<result_type>::max(); }
04242 
04243       /**
04244        * @brief Generating functions.
04245        */
04246       template<typename _UniformRandomNumberGenerator>
04247     result_type
04248     operator()(_UniformRandomNumberGenerator& __urng)
04249         { return this->operator()(__urng, this->param()); }
04250 
04251       template<typename _UniformRandomNumberGenerator>
04252     result_type
04253     operator()(_UniformRandomNumberGenerator& __urng,
04254            const param_type& __p)
04255     {
04256       __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
04257         __aurng(__urng);
04258       return -std::log(__aurng()) / __p.lambda();
04259     }
04260 
04261     private:
04262       param_type _M_param;
04263     };
04264 
04265   /**
04266    * @brief Return true if two exponential distributions have the same
04267    *        parameters.
04268    */
04269   template<typename _RealType>
04270     inline bool
04271     operator==(const std::exponential_distribution<_RealType>& __d1,
04272            const std::exponential_distribution<_RealType>& __d2)
04273     { return __d1.param() == __d2.param(); }
04274 
04275   /**
04276    * @brief Return true if two exponential distributions have different
04277    *        parameters.
04278    */
04279   template<typename _RealType>
04280     inline bool
04281     operator!=(const std::exponential_distribution<_RealType>& __d1,
04282            const std::exponential_distribution<_RealType>& __d2)
04283     { return !(__d1 == __d2); }
04284 
04285   /**
04286    * @brief Inserts a %exponential_distribution random number distribution
04287    * @p __x into the output stream @p __os.
04288    *
04289    * @param __os An output stream.
04290    * @param __x  A %exponential_distribution random number distribution.
04291    *
04292    * @returns The output stream with the state of @p __x inserted or in
04293    * an error state.
04294    */
04295   template<typename _RealType, typename _CharT, typename _Traits>
04296     std::basic_ostream<_CharT, _Traits>&
04297     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04298            const std::exponential_distribution<_RealType>& __x);
04299 
04300   /**
04301    * @brief Extracts a %exponential_distribution random number distribution
04302    * @p __x from the input stream @p __is.
04303    *
04304    * @param __is An input stream.
04305    * @param __x A %exponential_distribution random number
04306    *            generator engine.
04307    *
04308    * @returns The input stream with @p __x extracted or in an error state.
04309    */
04310   template<typename _RealType, typename _CharT, typename _Traits>
04311     std::basic_istream<_CharT, _Traits>&
04312     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04313            std::exponential_distribution<_RealType>& __x);
04314 
04315 
04316   /**
04317    * @brief A weibull_distribution random number distribution.
04318    *
04319    * The formula for the normal probability density function is:
04320    * @f[
04321    *     p(x|\alpha,\beta) = \frac{\alpha}{\beta} (\frac{x}{\beta})^{\alpha-1}
04322    *                         \exp{(-(\frac{x}{\beta})^\alpha)} 
04323    * @f]
04324    */
04325   template<typename _RealType = double>
04326     class weibull_distribution
04327     {
04328       static_assert(std::is_floating_point<_RealType>::value,
04329             "template argument not a floating point type");
04330 
04331     public:
04332       /** The type of the range of the distribution. */
04333       typedef _RealType result_type;
04334       /** Parameter type. */
04335       struct param_type
04336       {
04337     typedef weibull_distribution<_RealType> distribution_type;
04338 
04339     explicit
04340     param_type(_RealType __a = _RealType(1),
04341            _RealType __b = _RealType(1))
04342     : _M_a(__a), _M_b(__b)
04343     { }
04344 
04345     _RealType
04346     a() const
04347     { return _M_a; }
04348 
04349     _RealType
04350     b() const
04351     { return _M_b; }
04352 
04353     friend bool
04354     operator==(const param_type& __p1, const param_type& __p2)
04355     { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
04356 
04357       private:
04358     _RealType _M_a;
04359     _RealType _M_b;
04360       };
04361 
04362       explicit
04363       weibull_distribution(_RealType __a = _RealType(1),
04364                _RealType __b = _RealType(1))
04365       : _M_param(__a, __b)
04366       { }
04367 
04368       explicit
04369       weibull_distribution(const param_type& __p)
04370       : _M_param(__p)
04371       { }
04372 
04373       /**
04374        * @brief Resets the distribution state.
04375        */
04376       void
04377       reset()
04378       { }
04379 
04380       /**
04381        * @brief Return the @f$a@f$ parameter of the distribution.
04382        */
04383       _RealType
04384       a() const
04385       { return _M_param.a(); }
04386 
04387       /**
04388        * @brief Return the @f$b@f$ parameter of the distribution.
04389        */
04390       _RealType
04391       b() const
04392       { return _M_param.b(); }
04393 
04394       /**
04395        * @brief Returns the parameter set of the distribution.
04396        */
04397       param_type
04398       param() const
04399       { return _M_param; }
04400 
04401       /**
04402        * @brief Sets the parameter set of the distribution.
04403        * @param __param The new parameter set of the distribution.
04404        */
04405       void
04406       param(const param_type& __param)
04407       { _M_param = __param; }
04408 
04409       /**
04410        * @brief Returns the greatest lower bound value of the distribution.
04411        */
04412       result_type
04413       min() const
04414       { return result_type(0); }
04415 
04416       /**
04417        * @brief Returns the least upper bound value of the distribution.
04418        */
04419       result_type
04420       max() const
04421       { return std::numeric_limits<result_type>::max(); }
04422 
04423       /**
04424        * @brief Generating functions.
04425        */
04426       template<typename _UniformRandomNumberGenerator>
04427     result_type
04428     operator()(_UniformRandomNumberGenerator& __urng)
04429     { return this->operator()(__urng, this->param()); }
04430 
04431       template<typename _UniformRandomNumberGenerator>
04432     result_type
04433     operator()(_UniformRandomNumberGenerator& __urng,
04434            const param_type& __p);
04435 
04436     private:
04437       param_type _M_param;
04438     };
04439 
04440    /**
04441     * @brief Return true if two Weibull distributions have the same
04442     *        parameters.
04443     */
04444   template<typename _RealType>
04445     inline bool
04446     operator==(const std::weibull_distribution<_RealType>& __d1,
04447            const std::weibull_distribution<_RealType>& __d2)
04448     { return __d1.param() == __d2.param(); }
04449 
04450    /**
04451     * @brief Return true if two Weibull distributions have different
04452     *        parameters.
04453     */
04454   template<typename _RealType>
04455     inline bool
04456     operator!=(const std::weibull_distribution<_RealType>& __d1,
04457            const std::weibull_distribution<_RealType>& __d2)
04458     { return !(__d1 == __d2); }
04459 
04460   /**
04461    * @brief Inserts a %weibull_distribution random number distribution
04462    * @p __x into the output stream @p __os.
04463    *
04464    * @param __os An output stream.
04465    * @param __x  A %weibull_distribution random number distribution.
04466    *
04467    * @returns The output stream with the state of @p __x inserted or in
04468    * an error state.
04469    */
04470   template<typename _RealType, typename _CharT, typename _Traits>
04471     std::basic_ostream<_CharT, _Traits>&
04472     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04473            const std::weibull_distribution<_RealType>& __x);
04474 
04475   /**
04476    * @brief Extracts a %weibull_distribution random number distribution
04477    * @p __x from the input stream @p __is.
04478    *
04479    * @param __is An input stream.
04480    * @param __x A %weibull_distribution random number
04481    *            generator engine.
04482    *
04483    * @returns The input stream with @p __x extracted or in an error state.
04484    */
04485   template<typename _RealType, typename _CharT, typename _Traits>
04486     std::basic_istream<_CharT, _Traits>&
04487     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04488            std::weibull_distribution<_RealType>& __x);
04489 
04490 
04491   /**
04492    * @brief A extreme_value_distribution random number distribution.
04493    *
04494    * The formula for the normal probability mass function is
04495    * @f[
04496    *     p(x|a,b) = \frac{1}{b}
04497    *                \exp( \frac{a-x}{b} - \exp(\frac{a-x}{b})) 
04498    * @f]
04499    */
04500   template<typename _RealType = double>
04501     class extreme_value_distribution
04502     {
04503       static_assert(std::is_floating_point<_RealType>::value,
04504             "template argument not a floating point type");
04505 
04506     public:
04507       /** The type of the range of the distribution. */
04508       typedef _RealType result_type;
04509       /** Parameter type. */
04510       struct param_type
04511       {
04512     typedef extreme_value_distribution<_RealType> distribution_type;
04513 
04514     explicit
04515     param_type(_RealType __a = _RealType(0),
04516            _RealType __b = _RealType(1))
04517     : _M_a(__a), _M_b(__b)
04518     { }
04519 
04520     _RealType
04521     a() const
04522     { return _M_a; }
04523 
04524     _RealType
04525     b() const
04526     { return _M_b; }
04527 
04528     friend bool
04529     operator==(const param_type& __p1, const param_type& __p2)
04530     { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
04531 
04532       private:
04533     _RealType _M_a;
04534     _RealType _M_b;
04535       };
04536 
04537       explicit
04538       extreme_value_distribution(_RealType __a = _RealType(0),
04539                  _RealType __b = _RealType(1))
04540       : _M_param(__a, __b)
04541       { }
04542 
04543       explicit
04544       extreme_value_distribution(const param_type& __p)
04545       : _M_param(__p)
04546       { }
04547 
04548       /**
04549        * @brief Resets the distribution state.
04550        */
04551       void
04552       reset()
04553       { }
04554 
04555       /**
04556        * @brief Return the @f$a@f$ parameter of the distribution.
04557        */
04558       _RealType
04559       a() const
04560       { return _M_param.a(); }
04561 
04562       /**
04563        * @brief Return the @f$b@f$ parameter of the distribution.
04564        */
04565       _RealType
04566       b() const
04567       { return _M_param.b(); }
04568 
04569       /**
04570        * @brief Returns the parameter set of the distribution.
04571        */
04572       param_type
04573       param() const
04574       { return _M_param; }
04575 
04576       /**
04577        * @brief Sets the parameter set of the distribution.
04578        * @param __param The new parameter set of the distribution.
04579        */
04580       void
04581       param(const param_type& __param)
04582       { _M_param = __param; }
04583 
04584       /**
04585        * @brief Returns the greatest lower bound value of the distribution.
04586        */
04587       result_type
04588       min() const
04589       { return std::numeric_limits<result_type>::min(); }
04590 
04591       /**
04592        * @brief Returns the least upper bound value of the distribution.
04593        */
04594       result_type
04595       max() const
04596       { return std::numeric_limits<result_type>::max(); }
04597 
04598       /**
04599        * @brief Generating functions.
04600        */
04601       template<typename _UniformRandomNumberGenerator>
04602     result_type
04603     operator()(_UniformRandomNumberGenerator& __urng)
04604     { return this->operator()(__urng, this->param()); }
04605 
04606       template<typename _UniformRandomNumberGenerator>
04607     result_type
04608     operator()(_UniformRandomNumberGenerator& __urng,
04609            const param_type& __p);
04610 
04611     private:
04612       param_type _M_param;
04613     };
04614 
04615   /**
04616     * @brief Return true if two extreme value distributions have the same
04617     *        parameters.
04618    */
04619   template<typename _RealType>
04620     inline bool
04621     operator==(const std::extreme_value_distribution<_RealType>& __d1,
04622            const std::extreme_value_distribution<_RealType>& __d2)
04623     { return __d1.param() == __d2.param(); }
04624 
04625   /**
04626     * @brief Return true if two extreme value distributions have different
04627     *        parameters.
04628    */
04629   template<typename _RealType>
04630     inline bool
04631     operator!=(const std::extreme_value_distribution<_RealType>& __d1,
04632            const std::extreme_value_distribution<_RealType>& __d2)
04633     { return !(__d1 == __d2); }
04634 
04635   /**
04636    * @brief Inserts a %extreme_value_distribution random number distribution
04637    * @p __x into the output stream @p __os.
04638    *
04639    * @param __os An output stream.
04640    * @param __x  A %extreme_value_distribution random number distribution.
04641    *
04642    * @returns The output stream with the state of @p __x inserted or in
04643    * an error state.
04644    */
04645   template<typename _RealType, typename _CharT, typename _Traits>
04646     std::basic_ostream<_CharT, _Traits>&
04647     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04648            const std::extreme_value_distribution<_RealType>& __x);
04649 
04650   /**
04651    * @brief Extracts a %extreme_value_distribution random number
04652    *        distribution @p __x from the input stream @p __is.
04653    *
04654    * @param __is An input stream.
04655    * @param __x A %extreme_value_distribution random number
04656    *            generator engine.
04657    *
04658    * @returns The input stream with @p __x extracted or in an error state.
04659    */
04660   template<typename _RealType, typename _CharT, typename _Traits>
04661     std::basic_istream<_CharT, _Traits>&
04662     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04663            std::extreme_value_distribution<_RealType>& __x);
04664 
04665 
04666   /**
04667    * @brief A discrete_distribution random number distribution.
04668    *
04669    * The formula for the discrete probability mass function is
04670    *
04671    */
04672   template<typename _IntType = int>
04673     class discrete_distribution
04674     {
04675       static_assert(std::is_integral<_IntType>::value,
04676             "template argument not an integral type");
04677 
04678     public:
04679       /** The type of the range of the distribution. */
04680       typedef _IntType result_type;
04681       /** Parameter type. */
04682       struct param_type
04683       {
04684     typedef discrete_distribution<_IntType> distribution_type;
04685     friend class discrete_distribution<_IntType>;
04686 
04687     param_type()
04688     : _M_prob(), _M_cp()
04689     { }
04690 
04691     template<typename _InputIterator>
04692       param_type(_InputIterator __wbegin,
04693              _InputIterator __wend)
04694       : _M_prob(__wbegin, __wend), _M_cp()
04695       { _M_initialize(); }
04696 
04697     param_type(initializer_list<double> __wil)
04698     : _M_prob(__wil.begin(), __wil.end()), _M_cp()
04699     { _M_initialize(); }
04700 
04701     template<typename _Func>
04702       param_type(size_t __nw, double __xmin, double __xmax,
04703              _Func __fw);
04704 
04705     // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
04706     param_type(const param_type&) = default;
04707     param_type& operator=(const param_type&) = default;
04708 
04709     std::vector<double>
04710     probabilities() const
04711     { return _M_prob.empty() ? std::vector<double>(1, 1.0) : _M_prob; }
04712 
04713     friend bool
04714     operator==(const param_type& __p1, const param_type& __p2)
04715     { return __p1._M_prob == __p2._M_prob; }
04716 
04717       private:
04718     void
04719     _M_initialize();
04720 
04721     std::vector<double> _M_prob;
04722     std::vector<double> _M_cp;
04723       };
04724 
04725       discrete_distribution()
04726       : _M_param()
04727       { }
04728 
04729       template<typename _InputIterator>
04730     discrete_distribution(_InputIterator __wbegin,
04731                   _InputIterator __wend)
04732     : _M_param(__wbegin, __wend)
04733     { }
04734 
04735       discrete_distribution(initializer_list<double> __wl)
04736       : _M_param(__wl)
04737       { }
04738 
04739       template<typename _Func>
04740     discrete_distribution(size_t __nw, double __xmin, double __xmax,
04741                   _Func __fw)
04742     : _M_param(__nw, __xmin, __xmax, __fw)
04743     { }
04744 
04745       explicit
04746       discrete_distribution(const param_type& __p)
04747       : _M_param(__p)
04748       { }
04749 
04750       /**
04751        * @brief Resets the distribution state.
04752        */
04753       void
04754       reset()
04755       { }
04756 
04757       /**
04758        * @brief Returns the probabilities of the distribution.
04759        */
04760       std::vector<double>
04761       probabilities() const
04762       {
04763     return _M_param._M_prob.empty()
04764       ? std::vector<double>(1, 1.0) : _M_param._M_prob;
04765       }
04766 
04767       /**
04768        * @brief Returns the parameter set of the distribution.
04769        */
04770       param_type
04771       param() const
04772       { return _M_param; }
04773 
04774       /**
04775        * @brief Sets the parameter set of the distribution.
04776        * @param __param The new parameter set of the distribution.
04777        */
04778       void
04779       param(const param_type& __param)
04780       { _M_param = __param; }
04781 
04782       /**
04783        * @brief Returns the greatest lower bound value of the distribution.
04784        */
04785       result_type
04786       min() const
04787       { return result_type(0); }
04788 
04789       /**
04790        * @brief Returns the least upper bound value of the distribution.
04791        */
04792       result_type
04793       max() const
04794       {
04795     return _M_param._M_prob.empty()
04796       ? result_type(0) : result_type(_M_param._M_prob.size() - 1);
04797       }
04798 
04799       /**
04800        * @brief Generating functions.
04801        */
04802       template<typename _UniformRandomNumberGenerator>
04803     result_type
04804     operator()(_UniformRandomNumberGenerator& __urng)
04805     { return this->operator()(__urng, this->param()); }
04806 
04807       template<typename _UniformRandomNumberGenerator>
04808     result_type
04809     operator()(_UniformRandomNumberGenerator& __urng,
04810            const param_type& __p);
04811 
04812       /**
04813        * @brief Inserts a %discrete_distribution random number distribution
04814        * @p __x into the output stream @p __os.
04815        *
04816        * @param __os An output stream.
04817        * @param __x  A %discrete_distribution random number distribution.
04818        *
04819        * @returns The output stream with the state of @p __x inserted or in
04820        * an error state.
04821        */
04822       template<typename _IntType1, typename _CharT, typename _Traits>
04823     friend std::basic_ostream<_CharT, _Traits>&
04824     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04825            const std::discrete_distribution<_IntType1>& __x);
04826 
04827       /**
04828        * @brief Extracts a %discrete_distribution random number distribution
04829        * @p __x from the input stream @p __is.
04830        *
04831        * @param __is An input stream.
04832        * @param __x A %discrete_distribution random number
04833        *            generator engine.
04834        *
04835        * @returns The input stream with @p __x extracted or in an error
04836        *          state.
04837        */
04838       template<typename _IntType1, typename _CharT, typename _Traits>
04839     friend std::basic_istream<_CharT, _Traits>&
04840     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04841            std::discrete_distribution<_IntType1>& __x);
04842 
04843     private:
04844       param_type _M_param;
04845     };
04846 
04847   /**
04848     * @brief Return true if two discrete distributions have the same
04849     *        parameters.
04850     */
04851   template<typename _IntType>
04852     inline bool
04853     operator==(const std::discrete_distribution<_IntType>& __d1,
04854            const std::discrete_distribution<_IntType>& __d2)
04855     { return __d1.param() == __d2.param(); }
04856 
04857   /**
04858     * @brief Return true if two discrete distributions have different
04859     *        parameters.
04860     */
04861   template<typename _IntType>
04862     inline bool
04863     operator!=(const std::discrete_distribution<_IntType>& __d1,
04864            const std::discrete_distribution<_IntType>& __d2)
04865     { return !(__d1 == __d2); }
04866 
04867 
04868   /**
04869    * @brief A piecewise_constant_distribution random number distribution.
04870    *
04871    * The formula for the piecewise constant probability mass function is
04872    *
04873    */
04874   template<typename _RealType = double>
04875     class piecewise_constant_distribution
04876     {
04877       static_assert(std::is_floating_point<_RealType>::value,
04878             "template argument not a floating point type");
04879 
04880     public:
04881       /** The type of the range of the distribution. */
04882       typedef _RealType result_type;
04883       /** Parameter type. */
04884       struct param_type
04885       {
04886     typedef piecewise_constant_distribution<_RealType> distribution_type;
04887     friend class piecewise_constant_distribution<_RealType>;
04888 
04889     param_type()
04890     : _M_int(), _M_den(), _M_cp()
04891     { }
04892 
04893     template<typename _InputIteratorB, typename _InputIteratorW>
04894       param_type(_InputIteratorB __bfirst,
04895              _InputIteratorB __bend,
04896              _InputIteratorW __wbegin);
04897 
04898     template<typename _Func>
04899       param_type(initializer_list<_RealType> __bi, _Func __fw);
04900 
04901     template<typename _Func>
04902       param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
04903              _Func __fw);
04904 
04905     // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
04906     param_type(const param_type&) = default;
04907     param_type& operator=(const param_type&) = default;
04908 
04909     std::vector<_RealType>
04910     intervals() const
04911     {
04912       if (_M_int.empty())
04913         {
04914           std::vector<_RealType> __tmp(2);
04915           __tmp[1] = _RealType(1);
04916           return __tmp;
04917         }
04918       else
04919         return _M_int;
04920     }
04921 
04922     std::vector<double>
04923     densities() const
04924     { return _M_den.empty() ? std::vector<double>(1, 1.0) : _M_den; }
04925 
04926     friend bool
04927     operator==(const param_type& __p1, const param_type& __p2)
04928     { return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; }
04929 
04930       private:
04931     void
04932     _M_initialize();
04933 
04934     std::vector<_RealType> _M_int;
04935     std::vector<double> _M_den;
04936     std::vector<double> _M_cp;
04937       };
04938 
04939       explicit
04940       piecewise_constant_distribution()
04941       : _M_param()
04942       { }
04943 
04944       template<typename _InputIteratorB, typename _InputIteratorW>
04945     piecewise_constant_distribution(_InputIteratorB __bfirst,
04946                     _InputIteratorB __bend,
04947                     _InputIteratorW __wbegin)
04948     : _M_param(__bfirst, __bend, __wbegin)
04949     { }
04950 
04951       template<typename _Func>
04952     piecewise_constant_distribution(initializer_list<_RealType> __bl,
04953                     _Func __fw)
04954     : _M_param(__bl, __fw)
04955     { }
04956 
04957       template<typename _Func>
04958     piecewise_constant_distribution(size_t __nw,
04959                     _RealType __xmin, _RealType __xmax,
04960                     _Func __fw)
04961     : _M_param(__nw, __xmin, __xmax, __fw)
04962     { }
04963 
04964       explicit
04965       piecewise_constant_distribution(const param_type& __p)
04966       : _M_param(__p)
04967       { }
04968 
04969       /**
04970        * @brief Resets the distribution state.
04971        */
04972       void
04973       reset()
04974       { }
04975 
04976       /**
04977        * @brief Returns a vector of the intervals.
04978        */
04979       std::vector<_RealType>
04980       intervals() const
04981       {
04982     if (_M_param._M_int.empty())
04983       {
04984         std::vector<_RealType> __tmp(2);
04985         __tmp[1] = _RealType(1);
04986         return __tmp;
04987       }
04988     else
04989       return _M_param._M_int;
04990       }
04991 
04992       /**
04993        * @brief Returns a vector of the probability densities.
04994        */
04995       std::vector<double>
04996       densities() const
04997       {
04998     return _M_param._M_den.empty()
04999       ? std::vector<double>(1, 1.0) : _M_param._M_den;
05000       }
05001 
05002       /**
05003        * @brief Returns the parameter set of the distribution.
05004        */
05005       param_type
05006       param() const
05007       { return _M_param; }
05008 
05009       /**
05010        * @brief Sets the parameter set of the distribution.
05011        * @param __param The new parameter set of the distribution.
05012        */
05013       void
05014       param(const param_type& __param)
05015       { _M_param = __param; }
05016 
05017       /**
05018        * @brief Returns the greatest lower bound value of the distribution.
05019        */
05020       result_type
05021       min() const
05022       {
05023     return _M_param._M_int.empty()
05024       ? result_type(0) : _M_param._M_int.front();
05025       }
05026 
05027       /**
05028        * @brief Returns the least upper bound value of the distribution.
05029        */
05030       result_type
05031       max() const
05032       {
05033     return _M_param._M_int.empty()
05034       ? result_type(1) : _M_param._M_int.back();
05035       }
05036 
05037       /**
05038        * @brief Generating functions.
05039        */
05040       template<typename _UniformRandomNumberGenerator>
05041     result_type
05042     operator()(_UniformRandomNumberGenerator& __urng)
05043     { return this->operator()(__urng, this->param()); }
05044 
05045       template<typename _UniformRandomNumberGenerator>
05046     result_type
05047     operator()(_UniformRandomNumberGenerator& __urng,
05048            const param_type& __p);
05049 
05050       /**
05051        * @brief Inserts a %piecewise_constan_distribution random
05052        *        number distribution @p __x into the output stream @p __os.
05053        *
05054        * @param __os An output stream.
05055        * @param __x  A %piecewise_constan_distribution random number
05056        *             distribution.
05057        *
05058        * @returns The output stream with the state of @p __x inserted or in
05059        * an error state.
05060        */
05061       template<typename _RealType1, typename _CharT, typename _Traits>
05062     friend std::basic_ostream<_CharT, _Traits>&
05063     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
05064            const std::piecewise_constant_distribution<_RealType1>& __x);
05065 
05066       /**
05067        * @brief Extracts a %piecewise_constan_distribution random
05068        *        number distribution @p __x from the input stream @p __is.
05069        *
05070        * @param __is An input stream.
05071        * @param __x A %piecewise_constan_distribution random number
05072        *            generator engine.
05073        *
05074        * @returns The input stream with @p __x extracted or in an error
05075        *          state.
05076        */
05077       template<typename _RealType1, typename _CharT, typename _Traits>
05078     friend std::basic_istream<_CharT, _Traits>&
05079     operator>>(std::basic_istream<_CharT, _Traits>& __is,
05080            std::piecewise_constant_distribution<_RealType1>& __x);
05081 
05082     private:
05083       param_type _M_param;
05084     };
05085 
05086   /**
05087     * @brief Return true if two piecewise constant distributions have the
05088     *        same parameters.
05089    */
05090   template<typename _RealType>
05091     inline bool
05092     operator==(const std::piecewise_constant_distribution<_RealType>& __d1,
05093            const std::piecewise_constant_distribution<_RealType>& __d2)
05094     { return __d1.param() == __d2.param(); }
05095 
05096   /**
05097     * @brief Return true if two piecewise constant distributions have 
05098     *        different parameters.
05099    */
05100   template<typename _RealType>
05101     inline bool
05102     operator!=(const std::piecewise_constant_distribution<_RealType>& __d1,
05103            const std::piecewise_constant_distribution<_RealType>& __d2)
05104     { return !(__d1 == __d2); }
05105 
05106 
05107   /**
05108    * @brief A piecewise_linear_distribution random number distribution.
05109    *
05110    * The formula for the piecewise linear probability mass function is
05111    *
05112    */
05113   template<typename _RealType = double>
05114     class piecewise_linear_distribution
05115     {
05116       static_assert(std::is_floating_point<_RealType>::value,
05117             "template argument not a floating point type");
05118 
05119     public:
05120       /** The type of the range of the distribution. */
05121       typedef _RealType result_type;
05122       /** Parameter type. */
05123       struct param_type
05124       {
05125     typedef piecewise_linear_distribution<_RealType> distribution_type;
05126     friend class piecewise_linear_distribution<_RealType>;
05127 
05128     param_type()
05129     : _M_int(), _M_den(), _M_cp(), _M_m()
05130     { }
05131 
05132     template<typename _InputIteratorB, typename _InputIteratorW>
05133       param_type(_InputIteratorB __bfirst,
05134              _InputIteratorB __bend,
05135              _InputIteratorW __wbegin);
05136 
05137     template<typename _Func>
05138       param_type(initializer_list<_RealType> __bl, _Func __fw);
05139 
05140     template<typename _Func>
05141       param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
05142              _Func __fw);
05143 
05144     // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
05145     param_type(const param_type&) = default;
05146     param_type& operator=(const param_type&) = default;
05147 
05148     std::vector<_RealType>
05149     intervals() const
05150     {
05151       if (_M_int.empty())
05152         {
05153           std::vector<_RealType> __tmp(2);
05154           __tmp[1] = _RealType(1);
05155           return __tmp;
05156         }
05157       else
05158         return _M_int;
05159     }
05160 
05161     std::vector<double>
05162     densities() const
05163     { return _M_den.empty() ? std::vector<double>(2, 1.0) : _M_den; }
05164 
05165     friend bool
05166     operator==(const param_type& __p1, const param_type& __p2)
05167     { return (__p1._M_int == __p2._M_int
05168           && __p1._M_den == __p2._M_den); }
05169 
05170       private:
05171     void
05172     _M_initialize();
05173 
05174     std::vector<_RealType> _M_int;
05175     std::vector<double> _M_den;
05176     std::vector<double> _M_cp;
05177     std::vector<double> _M_m;
05178       };
05179 
05180       explicit
05181       piecewise_linear_distribution()
05182       : _M_param()
05183       { }
05184 
05185       template<typename _InputIteratorB, typename _InputIteratorW>
05186     piecewise_linear_distribution(_InputIteratorB __bfirst,
05187                       _InputIteratorB __bend,
05188                       _InputIteratorW __wbegin)
05189     : _M_param(__bfirst, __bend, __wbegin)
05190     { }
05191 
05192       template<typename _Func>
05193     piecewise_linear_distribution(initializer_list<_RealType> __bl,
05194                       _Func __fw)
05195     : _M_param(__bl, __fw)
05196     { }
05197 
05198       template<typename _Func>
05199     piecewise_linear_distribution(size_t __nw,
05200                       _RealType __xmin, _RealType __xmax,
05201                       _Func __fw)
05202     : _M_param(__nw, __xmin, __xmax, __fw)
05203     { }
05204 
05205       explicit
05206       piecewise_linear_distribution(const param_type& __p)
05207       : _M_param(__p)
05208       { }
05209 
05210       /**
05211        * Resets the distribution state.
05212        */
05213       void
05214       reset()
05215       { }
05216 
05217       /**
05218        * @brief Return the intervals of the distribution.
05219        */
05220       std::vector<_RealType>
05221       intervals() const
05222       {
05223     if (_M_param._M_int.empty())
05224       {
05225         std::vector<_RealType> __tmp(2);
05226         __tmp[1] = _RealType(1);
05227         return __tmp;
05228       }
05229     else
05230       return _M_param._M_int;
05231       }
05232 
05233       /**
05234        * @brief Return a vector of the probability densities of the
05235        *        distribution.
05236        */
05237       std::vector<double>
05238       densities() const
05239       {
05240     return _M_param._M_den.empty()
05241       ? std::vector<double>(2, 1.0) : _M_param._M_den;
05242       }
05243 
05244       /**
05245        * @brief Returns the parameter set of the distribution.
05246        */
05247       param_type
05248       param() const
05249       { return _M_param; }
05250 
05251       /**
05252        * @brief Sets the parameter set of the distribution.
05253        * @param __param The new parameter set of the distribution.
05254        */
05255       void
05256       param(const param_type& __param)
05257       { _M_param = __param; }
05258 
05259       /**
05260        * @brief Returns the greatest lower bound value of the distribution.
05261        */
05262       result_type
05263       min() const
05264       {
05265     return _M_param._M_int.empty()
05266       ? result_type(0) : _M_param._M_int.front();
05267       }
05268 
05269       /**
05270        * @brief Returns the least upper bound value of the distribution.
05271        */
05272       result_type
05273       max() const
05274       {
05275     return _M_param._M_int.empty()
05276       ? result_type(1) : _M_param._M_int.back();
05277       }
05278 
05279       /**
05280        * @brief Generating functions.
05281        */
05282       template<typename _UniformRandomNumberGenerator>
05283     result_type
05284     operator()(_UniformRandomNumberGenerator& __urng)
05285     { return this->operator()(__urng, this->param()); }
05286 
05287       template<typename _UniformRandomNumberGenerator>
05288     result_type
05289     operator()(_UniformRandomNumberGenerator& __urng,
05290            const param_type& __p);
05291 
05292       /**
05293        * @brief Inserts a %piecewise_linear_distribution random number
05294        *        distribution @p __x into the output stream @p __os.
05295        *
05296        * @param __os An output stream.
05297        * @param __x  A %piecewise_linear_distribution random number
05298        *             distribution.
05299        *
05300        * @returns The output stream with the state of @p __x inserted or in
05301        *          an error state.
05302        */
05303       template<typename _RealType1, typename _CharT, typename _Traits>
05304     friend std::basic_ostream<_CharT, _Traits>&
05305     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
05306            const std::piecewise_linear_distribution<_RealType1>& __x);
05307 
05308       /**
05309        * @brief Extracts a %piecewise_linear_distribution random number
05310        *        distribution @p __x from the input stream @p __is.
05311        *
05312        * @param __is An input stream.
05313        * @param __x  A %piecewise_linear_distribution random number
05314        *             generator engine.
05315        *
05316        * @returns The input stream with @p __x extracted or in an error
05317        *          state.
05318        */
05319       template<typename _RealType1, typename _CharT, typename _Traits>
05320     friend std::basic_istream<_CharT, _Traits>&
05321     operator>>(std::basic_istream<_CharT, _Traits>& __is,
05322            std::piecewise_linear_distribution<_RealType1>& __x);
05323 
05324     private:
05325       param_type _M_param;
05326     };
05327 
05328   /**
05329     * @brief Return true if two piecewise linear distributions have the
05330     *        same parameters.
05331    */
05332   template<typename _RealType>
05333     inline bool
05334     operator==(const std::piecewise_linear_distribution<_RealType>& __d1,
05335            const std::piecewise_linear_distribution<_RealType>& __d2)
05336     { return __d1.param() == __d2.param(); }
05337 
05338   /**
05339     * @brief Return true if two piecewise linear distributions have
05340     *        different parameters.
05341    */
05342   template<typename _RealType>
05343     inline bool
05344     operator!=(const std::piecewise_linear_distribution<_RealType>& __d1,
05345            const std::piecewise_linear_distribution<_RealType>& __d2)
05346     { return !(__d1 == __d2); }
05347 
05348 
05349   /* @} */ // group random_distributions_poisson
05350 
05351   /* @} */ // group random_distributions
05352 
05353   /**
05354    * @addtogroup random_utilities Random Number Utilities
05355    * @ingroup random
05356    * @{
05357    */
05358 
05359   /**
05360    * @brief The seed_seq class generates sequences of seeds for random
05361    *        number generators.
05362    */
05363   class seed_seq
05364   {
05365 
05366   public:
05367     /** The type of the seed vales. */
05368     typedef uint_least32_t result_type;
05369 
05370     /** Default constructor. */
05371     seed_seq()
05372     : _M_v()
05373     { }
05374 
05375     template<typename _IntType>
05376       seed_seq(std::initializer_list<_IntType> il);
05377 
05378     template<typename _InputIterator>
05379       seed_seq(_InputIterator __begin, _InputIterator __end);
05380 
05381     // generating functions
05382     template<typename _RandomAccessIterator>
05383       void
05384       generate(_RandomAccessIterator __begin, _RandomAccessIterator __end);
05385 
05386     // property functions
05387     size_t size() const
05388     { return _M_v.size(); }
05389 
05390     template<typename OutputIterator>
05391       void
05392       param(OutputIterator __dest) const
05393       { std::copy(_M_v.begin(), _M_v.end(), __dest); }
05394 
05395   private:
05396     ///
05397     std::vector<result_type> _M_v;
05398   };
05399 
05400   /* @} */ // group random_utilities
05401 
05402   /* @} */ // group random
05403 
05404 _GLIBCXX_END_NAMESPACE_VERSION
05405 } // namespace std
05406 
05407 #endif