libstdc++

random.h

Go to the documentation of this file.
00001 // random number generation -*- C++ -*-
00002 
00003 // Copyright (C) 2009-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, _M_param); }
01723 
01724       template<typename _UniformRandomNumberGenerator>
01725     result_type
01726     operator()(_UniformRandomNumberGenerator& __urng,
01727            const param_type& __p);
01728 
01729       /**
01730        * @brief Return true if two uniform integer distributions have
01731        *        the same parameters.
01732        */
01733       friend bool
01734       operator==(const uniform_int_distribution& __d1,
01735          const uniform_int_distribution& __d2)
01736       { return __d1._M_param == __d2._M_param; }
01737 
01738     private:
01739       param_type _M_param;
01740     };
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, _M_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       /**
01910        * @brief Return true if two uniform real distributions have
01911        *        the same parameters.
01912        */
01913       friend bool
01914       operator==(const uniform_real_distribution& __d1,
01915          const uniform_real_distribution& __d2)
01916       { return __d1._M_param == __d2._M_param; }
01917 
01918     private:
01919       param_type _M_param;
01920     };
01921 
01922   /**
01923    * @brief Return true if two uniform real distributions have
01924    *        different parameters.
01925    */
01926   template<typename _IntType>
01927     inline bool
01928     operator!=(const std::uniform_real_distribution<_IntType>& __d1,
01929            const std::uniform_real_distribution<_IntType>& __d2)
01930     { return !(__d1 == __d2); }
01931 
01932   /**
01933    * @brief Inserts a %uniform_real_distribution random number
01934    *        distribution @p __x into the output stream @p __os.
01935    *
01936    * @param __os An output stream.
01937    * @param __x  A %uniform_real_distribution random number distribution.
01938    *
01939    * @returns The output stream with the state of @p __x inserted or in
01940    *          an error state.
01941    */
01942   template<typename _RealType, typename _CharT, typename _Traits>
01943     std::basic_ostream<_CharT, _Traits>&
01944     operator<<(std::basic_ostream<_CharT, _Traits>&,
01945            const std::uniform_real_distribution<_RealType>&);
01946 
01947   /**
01948    * @brief Extracts a %uniform_real_distribution random number distribution
01949    * @p __x from the input stream @p __is.
01950    *
01951    * @param __is An input stream.
01952    * @param __x  A %uniform_real_distribution random number generator engine.
01953    *
01954    * @returns The input stream with @p __x extracted or in an error state.
01955    */
01956   template<typename _RealType, typename _CharT, typename _Traits>
01957     std::basic_istream<_CharT, _Traits>&
01958     operator>>(std::basic_istream<_CharT, _Traits>&,
01959            std::uniform_real_distribution<_RealType>&);
01960 
01961   /* @} */ // group random_distributions_uniform
01962 
01963   /**
01964    * @addtogroup random_distributions_normal Normal Distributions
01965    * @ingroup random_distributions
01966    * @{
01967    */
01968 
01969   /**
01970    * @brief A normal continuous distribution for random numbers.
01971    *
01972    * The formula for the normal probability density function is
01973    * @f[
01974    *     p(x|\mu,\sigma) = \frac{1}{\sigma \sqrt{2 \pi}}
01975    *            e^{- \frac{{x - \mu}^ {2}}{2 \sigma ^ {2}} } 
01976    * @f]
01977    */
01978   template<typename _RealType = double>
01979     class normal_distribution
01980     {
01981       static_assert(std::is_floating_point<_RealType>::value,
01982             "template argument not a floating point type");
01983 
01984     public:
01985       /** The type of the range of the distribution. */
01986       typedef _RealType result_type;
01987       /** Parameter type. */
01988       struct param_type
01989       {
01990     typedef normal_distribution<_RealType> distribution_type;
01991 
01992     explicit
01993     param_type(_RealType __mean = _RealType(0),
01994            _RealType __stddev = _RealType(1))
01995     : _M_mean(__mean), _M_stddev(__stddev)
01996     {
01997       _GLIBCXX_DEBUG_ASSERT(_M_stddev > _RealType(0));
01998     }
01999 
02000     _RealType
02001     mean() const
02002     { return _M_mean; }
02003 
02004     _RealType
02005     stddev() const
02006     { return _M_stddev; }
02007 
02008     friend bool
02009     operator==(const param_type& __p1, const param_type& __p2)
02010     { return (__p1._M_mean == __p2._M_mean
02011           && __p1._M_stddev == __p2._M_stddev); }
02012 
02013       private:
02014     _RealType _M_mean;
02015     _RealType _M_stddev;
02016       };
02017 
02018     public:
02019       /**
02020        * Constructs a normal distribution with parameters @f$mean@f$ and
02021        * standard deviation.
02022        */
02023       explicit
02024       normal_distribution(result_type __mean = result_type(0),
02025               result_type __stddev = result_type(1))
02026       : _M_param(__mean, __stddev), _M_saved_available(false)
02027       { }
02028 
02029       explicit
02030       normal_distribution(const param_type& __p)
02031       : _M_param(__p), _M_saved_available(false)
02032       { }
02033 
02034       /**
02035        * @brief Resets the distribution state.
02036        */
02037       void
02038       reset()
02039       { _M_saved_available = false; }
02040 
02041       /**
02042        * @brief Returns the mean of the distribution.
02043        */
02044       _RealType
02045       mean() const
02046       { return _M_param.mean(); }
02047 
02048       /**
02049        * @brief Returns the standard deviation of the distribution.
02050        */
02051       _RealType
02052       stddev() const
02053       { return _M_param.stddev(); }
02054 
02055       /**
02056        * @brief Returns the parameter set of the distribution.
02057        */
02058       param_type
02059       param() const
02060       { return _M_param; }
02061 
02062       /**
02063        * @brief Sets the parameter set of the distribution.
02064        * @param __param The new parameter set of the distribution.
02065        */
02066       void
02067       param(const param_type& __param)
02068       { _M_param = __param; }
02069 
02070       /**
02071        * @brief Returns the greatest lower bound value of the distribution.
02072        */
02073       result_type
02074       min() const
02075       { return std::numeric_limits<result_type>::min(); }
02076 
02077       /**
02078        * @brief Returns the least upper bound value of the distribution.
02079        */
02080       result_type
02081       max() const
02082       { return std::numeric_limits<result_type>::max(); }
02083 
02084       /**
02085        * @brief Generating functions.
02086        */
02087       template<typename _UniformRandomNumberGenerator>
02088     result_type
02089     operator()(_UniformRandomNumberGenerator& __urng)
02090     { return this->operator()(__urng, _M_param); }
02091 
02092       template<typename _UniformRandomNumberGenerator>
02093     result_type
02094     operator()(_UniformRandomNumberGenerator& __urng,
02095            const param_type& __p);
02096 
02097       /**
02098        * @brief Return true if two normal distributions have
02099        *        the same parameters and the sequences that would
02100        *        be generated are equal.
02101        */
02102       template<typename _RealType1>
02103     friend bool
02104         operator==(const std::normal_distribution<_RealType1>& __d1,
02105            const std::normal_distribution<_RealType1>& __d2);
02106 
02107       /**
02108        * @brief Inserts a %normal_distribution random number distribution
02109        * @p __x into the output stream @p __os.
02110        *
02111        * @param __os An output stream.
02112        * @param __x  A %normal_distribution random number distribution.
02113        *
02114        * @returns The output stream with the state of @p __x inserted or in
02115        * an error state.
02116        */
02117       template<typename _RealType1, typename _CharT, typename _Traits>
02118     friend std::basic_ostream<_CharT, _Traits>&
02119     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02120            const std::normal_distribution<_RealType1>& __x);
02121 
02122       /**
02123        * @brief Extracts a %normal_distribution random number distribution
02124        * @p __x from the input stream @p __is.
02125        *
02126        * @param __is An input stream.
02127        * @param __x  A %normal_distribution random number generator engine.
02128        *
02129        * @returns The input stream with @p __x extracted or in an error
02130        *          state.
02131        */
02132       template<typename _RealType1, typename _CharT, typename _Traits>
02133     friend std::basic_istream<_CharT, _Traits>&
02134     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02135            std::normal_distribution<_RealType1>& __x);
02136 
02137     private:
02138       param_type  _M_param;
02139       result_type _M_saved;
02140       bool        _M_saved_available;
02141     };
02142 
02143   /**
02144    * @brief Return true if two normal distributions are different.
02145    */
02146   template<typename _RealType>
02147     inline bool
02148     operator!=(const std::normal_distribution<_RealType>& __d1,
02149            const std::normal_distribution<_RealType>& __d2)
02150     { return !(__d1 == __d2); }
02151 
02152 
02153   /**
02154    * @brief A lognormal_distribution random number distribution.
02155    *
02156    * The formula for the normal probability mass function is
02157    * @f[
02158    *     p(x|m,s) = \frac{1}{sx\sqrt{2\pi}}
02159    *                \exp{-\frac{(\ln{x} - m)^2}{2s^2}} 
02160    * @f]
02161    */
02162   template<typename _RealType = double>
02163     class lognormal_distribution
02164     {
02165       static_assert(std::is_floating_point<_RealType>::value,
02166             "template argument not a floating point type");
02167 
02168     public:
02169       /** The type of the range of the distribution. */
02170       typedef _RealType result_type;
02171       /** Parameter type. */
02172       struct param_type
02173       {
02174     typedef lognormal_distribution<_RealType> distribution_type;
02175 
02176     explicit
02177     param_type(_RealType __m = _RealType(0),
02178            _RealType __s = _RealType(1))
02179     : _M_m(__m), _M_s(__s)
02180     { }
02181 
02182     _RealType
02183     m() const
02184     { return _M_m; }
02185 
02186     _RealType
02187     s() const
02188     { return _M_s; }
02189 
02190     friend bool
02191     operator==(const param_type& __p1, const param_type& __p2)
02192     { return __p1._M_m == __p2._M_m && __p1._M_s == __p2._M_s; }
02193 
02194       private:
02195     _RealType _M_m;
02196     _RealType _M_s;
02197       };
02198 
02199       explicit
02200       lognormal_distribution(_RealType __m = _RealType(0),
02201                  _RealType __s = _RealType(1))
02202       : _M_param(__m, __s), _M_nd()
02203       { }
02204 
02205       explicit
02206       lognormal_distribution(const param_type& __p)
02207       : _M_param(__p), _M_nd()
02208       { }
02209 
02210       /**
02211        * Resets the distribution state.
02212        */
02213       void
02214       reset()
02215       { _M_nd.reset(); }
02216 
02217       /**
02218        *
02219        */
02220       _RealType
02221       m() const
02222       { return _M_param.m(); }
02223 
02224       _RealType
02225       s() const
02226       { return _M_param.s(); }
02227 
02228       /**
02229        * @brief Returns the parameter set of the distribution.
02230        */
02231       param_type
02232       param() const
02233       { return _M_param; }
02234 
02235       /**
02236        * @brief Sets the parameter set of the distribution.
02237        * @param __param The new parameter set of the distribution.
02238        */
02239       void
02240       param(const param_type& __param)
02241       { _M_param = __param; }
02242 
02243       /**
02244        * @brief Returns the greatest lower bound value of the distribution.
02245        */
02246       result_type
02247       min() const
02248       { return result_type(0); }
02249 
02250       /**
02251        * @brief Returns the least upper bound value of the distribution.
02252        */
02253       result_type
02254       max() const
02255       { return std::numeric_limits<result_type>::max(); }
02256 
02257       /**
02258        * @brief Generating functions.
02259        */
02260       template<typename _UniformRandomNumberGenerator>
02261     result_type
02262     operator()(_UniformRandomNumberGenerator& __urng)
02263     { return this->operator()(__urng, _M_param); }
02264 
02265       template<typename _UniformRandomNumberGenerator>
02266     result_type
02267     operator()(_UniformRandomNumberGenerator& __urng,
02268            const param_type& __p)
02269         { return std::exp(__p.s() * _M_nd(__urng) + __p.m()); }
02270 
02271       /**
02272        * @brief Return true if two lognormal distributions have
02273        *        the same parameters and the sequences that would
02274        *        be generated are equal.
02275        */
02276       friend bool
02277       operator==(const lognormal_distribution& __d1,
02278          const lognormal_distribution& __d2)
02279       { return (__d1._M_param == __d2._M_param
02280         && __d1._M_nd == __d2._M_nd); }
02281 
02282       /**
02283        * @brief Inserts a %lognormal_distribution random number distribution
02284        * @p __x into the output stream @p __os.
02285        *
02286        * @param __os An output stream.
02287        * @param __x  A %lognormal_distribution random number distribution.
02288        *
02289        * @returns The output stream with the state of @p __x inserted or in
02290        * an error state.
02291        */
02292       template<typename _RealType1, typename _CharT, typename _Traits>
02293     friend std::basic_ostream<_CharT, _Traits>&
02294     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02295            const std::lognormal_distribution<_RealType1>& __x);
02296 
02297       /**
02298        * @brief Extracts a %lognormal_distribution random number distribution
02299        * @p __x from the input stream @p __is.
02300        *
02301        * @param __is An input stream.
02302        * @param __x A %lognormal_distribution random number
02303        *            generator engine.
02304        *
02305        * @returns The input stream with @p __x extracted or in an error state.
02306        */
02307       template<typename _RealType1, typename _CharT, typename _Traits>
02308     friend std::basic_istream<_CharT, _Traits>&
02309     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02310            std::lognormal_distribution<_RealType1>& __x);
02311 
02312     private:
02313       param_type _M_param;
02314 
02315       std::normal_distribution<result_type> _M_nd;
02316     };
02317 
02318   /**
02319    * @brief Return true if two lognormal distributions are different.
02320    */
02321   template<typename _RealType>
02322     inline bool
02323     operator!=(const std::lognormal_distribution<_RealType>& __d1,
02324            const std::lognormal_distribution<_RealType>& __d2)
02325     { return !(__d1 == __d2); }
02326 
02327 
02328   /**
02329    * @brief A gamma continuous distribution for random numbers.
02330    *
02331    * The formula for the gamma probability density function is:
02332    * @f[
02333    *     p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
02334    *                         (x/\beta)^{\alpha - 1} e^{-x/\beta} 
02335    * @f]
02336    */
02337   template<typename _RealType = double>
02338     class gamma_distribution
02339     {
02340       static_assert(std::is_floating_point<_RealType>::value,
02341             "template argument not a floating point type");
02342 
02343     public:
02344       /** The type of the range of the distribution. */
02345       typedef _RealType result_type;
02346       /** Parameter type. */
02347       struct param_type
02348       {
02349     typedef gamma_distribution<_RealType> distribution_type;
02350     friend class gamma_distribution<_RealType>;
02351 
02352     explicit
02353     param_type(_RealType __alpha_val = _RealType(1),
02354            _RealType __beta_val = _RealType(1))
02355     : _M_alpha(__alpha_val), _M_beta(__beta_val)
02356     {
02357       _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0));
02358       _M_initialize();
02359     }
02360 
02361     _RealType
02362     alpha() const
02363     { return _M_alpha; }
02364 
02365     _RealType
02366     beta() const
02367     { return _M_beta; }
02368 
02369     friend bool
02370     operator==(const param_type& __p1, const param_type& __p2)
02371     { return (__p1._M_alpha == __p2._M_alpha
02372           && __p1._M_beta == __p2._M_beta); }
02373 
02374       private:
02375     void
02376     _M_initialize();
02377 
02378     _RealType _M_alpha;
02379     _RealType _M_beta;
02380 
02381     _RealType _M_malpha, _M_a2;
02382       };
02383 
02384     public:
02385       /**
02386        * @brief Constructs a gamma distribution with parameters
02387        * @f$\alpha@f$ and @f$\beta@f$.
02388        */
02389       explicit
02390       gamma_distribution(_RealType __alpha_val = _RealType(1),
02391              _RealType __beta_val = _RealType(1))
02392       : _M_param(__alpha_val, __beta_val), _M_nd()
02393       { }
02394 
02395       explicit
02396       gamma_distribution(const param_type& __p)
02397       : _M_param(__p), _M_nd()
02398       { }
02399 
02400       /**
02401        * @brief Resets the distribution state.
02402        */
02403       void
02404       reset()
02405       { _M_nd.reset(); }
02406 
02407       /**
02408        * @brief Returns the @f$\alpha@f$ of the distribution.
02409        */
02410       _RealType
02411       alpha() const
02412       { return _M_param.alpha(); }
02413 
02414       /**
02415        * @brief Returns the @f$\beta@f$ of the distribution.
02416        */
02417       _RealType
02418       beta() const
02419       { return _M_param.beta(); }
02420 
02421       /**
02422        * @brief Returns the parameter set of the distribution.
02423        */
02424       param_type
02425       param() const
02426       { return _M_param; }
02427 
02428       /**
02429        * @brief Sets the parameter set of the distribution.
02430        * @param __param The new parameter set of the distribution.
02431        */
02432       void
02433       param(const param_type& __param)
02434       { _M_param = __param; }
02435 
02436       /**
02437        * @brief Returns the greatest lower bound value of the distribution.
02438        */
02439       result_type
02440       min() const
02441       { return result_type(0); }
02442 
02443       /**
02444        * @brief Returns the least upper bound value of the distribution.
02445        */
02446       result_type
02447       max() const
02448       { return std::numeric_limits<result_type>::max(); }
02449 
02450       /**
02451        * @brief Generating functions.
02452        */
02453       template<typename _UniformRandomNumberGenerator>
02454     result_type
02455     operator()(_UniformRandomNumberGenerator& __urng)
02456     { return this->operator()(__urng, _M_param); }
02457 
02458       template<typename _UniformRandomNumberGenerator>
02459     result_type
02460     operator()(_UniformRandomNumberGenerator& __urng,
02461            const param_type& __p);
02462 
02463       /**
02464        * @brief Return true if two gamma distributions have the same
02465        *        parameters and the sequences that would be generated
02466        *        are equal.
02467        */
02468       friend bool
02469       operator==(const gamma_distribution& __d1,
02470          const gamma_distribution& __d2)
02471       { return (__d1._M_param == __d2._M_param
02472         && __d1._M_nd == __d2._M_nd); }
02473 
02474       /**
02475        * @brief Inserts a %gamma_distribution random number distribution
02476        * @p __x into the output stream @p __os.
02477        *
02478        * @param __os An output stream.
02479        * @param __x  A %gamma_distribution random number distribution.
02480        *
02481        * @returns The output stream with the state of @p __x inserted or in
02482        * an error state.
02483        */
02484       template<typename _RealType1, typename _CharT, typename _Traits>
02485     friend std::basic_ostream<_CharT, _Traits>&
02486     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02487            const std::gamma_distribution<_RealType1>& __x);
02488 
02489       /**
02490        * @brief Extracts a %gamma_distribution random number distribution
02491        * @p __x from the input stream @p __is.
02492        *
02493        * @param __is An input stream.
02494        * @param __x  A %gamma_distribution random number generator engine.
02495        *
02496        * @returns The input stream with @p __x extracted or in an error state.
02497        */
02498       template<typename _RealType1, typename _CharT, typename _Traits>
02499     friend std::basic_istream<_CharT, _Traits>&
02500     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02501            std::gamma_distribution<_RealType1>& __x);
02502 
02503     private:
02504       param_type _M_param;
02505 
02506       std::normal_distribution<result_type> _M_nd;
02507     };
02508 
02509   /**
02510    * @brief Return true if two gamma distributions are different.
02511    */
02512    template<typename _RealType>
02513     inline bool
02514      operator!=(const std::gamma_distribution<_RealType>& __d1,
02515         const std::gamma_distribution<_RealType>& __d2)
02516     { return !(__d1 == __d2); }
02517 
02518 
02519   /**
02520    * @brief A chi_squared_distribution random number distribution.
02521    *
02522    * The formula for the normal probability mass function is
02523    * @f$p(x|n) = \frac{x^{(n/2) - 1}e^{-x/2}}{\Gamma(n/2) 2^{n/2}}@f$
02524    */
02525   template<typename _RealType = double>
02526     class chi_squared_distribution
02527     {
02528       static_assert(std::is_floating_point<_RealType>::value,
02529             "template argument not a floating point type");
02530 
02531     public:
02532       /** The type of the range of the distribution. */
02533       typedef _RealType result_type;
02534       /** Parameter type. */
02535       struct param_type
02536       {
02537     typedef chi_squared_distribution<_RealType> distribution_type;
02538 
02539     explicit
02540     param_type(_RealType __n = _RealType(1))
02541     : _M_n(__n)
02542     { }
02543 
02544     _RealType
02545     n() const
02546     { return _M_n; }
02547 
02548     friend bool
02549     operator==(const param_type& __p1, const param_type& __p2)
02550     { return __p1._M_n == __p2._M_n; }
02551 
02552       private:
02553     _RealType _M_n;
02554       };
02555 
02556       explicit
02557       chi_squared_distribution(_RealType __n = _RealType(1))
02558       : _M_param(__n), _M_gd(__n / 2)
02559       { }
02560 
02561       explicit
02562       chi_squared_distribution(const param_type& __p)
02563       : _M_param(__p), _M_gd(__p.n() / 2)
02564       { }
02565 
02566       /**
02567        * @brief Resets the distribution state.
02568        */
02569       void
02570       reset()
02571       { _M_gd.reset(); }
02572 
02573       /**
02574        *
02575        */
02576       _RealType
02577       n() const
02578       { return _M_param.n(); }
02579 
02580       /**
02581        * @brief Returns the parameter set of the distribution.
02582        */
02583       param_type
02584       param() const
02585       { return _M_param; }
02586 
02587       /**
02588        * @brief Sets the parameter set of the distribution.
02589        * @param __param The new parameter set of the distribution.
02590        */
02591       void
02592       param(const param_type& __param)
02593       { _M_param = __param; }
02594 
02595       /**
02596        * @brief Returns the greatest lower bound value of the distribution.
02597        */
02598       result_type
02599       min() const
02600       { return result_type(0); }
02601 
02602       /**
02603        * @brief Returns the least upper bound value of the distribution.
02604        */
02605       result_type
02606       max() const
02607       { return std::numeric_limits<result_type>::max(); }
02608 
02609       /**
02610        * @brief Generating functions.
02611        */
02612       template<typename _UniformRandomNumberGenerator>
02613     result_type
02614     operator()(_UniformRandomNumberGenerator& __urng)
02615     { return 2 * _M_gd(__urng); }
02616 
02617       template<typename _UniformRandomNumberGenerator>
02618     result_type
02619     operator()(_UniformRandomNumberGenerator& __urng,
02620            const param_type& __p)
02621         {
02622       typedef typename std::gamma_distribution<result_type>::param_type
02623         param_type;
02624       return 2 * _M_gd(__urng, param_type(__p.n() / 2));
02625     }
02626 
02627       /**
02628        * @brief Return true if two Chi-squared distributions have
02629        *        the same parameters and the sequences that would be
02630        *        generated are equal.
02631        */
02632       friend bool
02633       operator==(const chi_squared_distribution& __d1,
02634          const chi_squared_distribution& __d2)
02635       { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; }
02636 
02637       /**
02638        * @brief Inserts a %chi_squared_distribution random number distribution
02639        * @p __x into the output stream @p __os.
02640        *
02641        * @param __os An output stream.
02642        * @param __x  A %chi_squared_distribution random number distribution.
02643        *
02644        * @returns The output stream with the state of @p __x inserted or in
02645        * an error state.
02646        */
02647       template<typename _RealType1, typename _CharT, typename _Traits>
02648     friend std::basic_ostream<_CharT, _Traits>&
02649     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02650            const std::chi_squared_distribution<_RealType1>& __x);
02651 
02652       /**
02653        * @brief Extracts a %chi_squared_distribution random number distribution
02654        * @p __x from the input stream @p __is.
02655        *
02656        * @param __is An input stream.
02657        * @param __x A %chi_squared_distribution random number
02658        *            generator engine.
02659        *
02660        * @returns The input stream with @p __x extracted or in an error state.
02661        */
02662       template<typename _RealType1, typename _CharT, typename _Traits>
02663     friend std::basic_istream<_CharT, _Traits>&
02664     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02665            std::chi_squared_distribution<_RealType1>& __x);
02666 
02667     private:
02668       param_type _M_param;
02669 
02670       std::gamma_distribution<result_type> _M_gd;
02671     };
02672 
02673   /**
02674    * @brief Return true if two Chi-squared distributions are different.
02675    */
02676   template<typename _RealType>
02677     inline bool
02678     operator!=(const std::chi_squared_distribution<_RealType>& __d1,
02679            const std::chi_squared_distribution<_RealType>& __d2)
02680     { return !(__d1 == __d2); }
02681 
02682 
02683   /**
02684    * @brief A cauchy_distribution random number distribution.
02685    *
02686    * The formula for the normal probability mass function is
02687    * @f$p(x|a,b) = (\pi b (1 + (\frac{x-a}{b})^2))^{-1}@f$
02688    */
02689   template<typename _RealType = double>
02690     class cauchy_distribution
02691     {
02692       static_assert(std::is_floating_point<_RealType>::value,
02693             "template argument not a floating point type");
02694 
02695     public:
02696       /** The type of the range of the distribution. */
02697       typedef _RealType result_type;
02698       /** Parameter type. */
02699       struct param_type
02700       {
02701     typedef cauchy_distribution<_RealType> distribution_type;
02702 
02703     explicit
02704     param_type(_RealType __a = _RealType(0),
02705            _RealType __b = _RealType(1))
02706     : _M_a(__a), _M_b(__b)
02707     { }
02708 
02709     _RealType
02710     a() const
02711     { return _M_a; }
02712 
02713     _RealType
02714     b() const
02715     { return _M_b; }
02716 
02717     friend bool
02718     operator==(const param_type& __p1, const param_type& __p2)
02719     { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
02720 
02721       private:
02722     _RealType _M_a;
02723     _RealType _M_b;
02724       };
02725 
02726       explicit
02727       cauchy_distribution(_RealType __a = _RealType(0),
02728               _RealType __b = _RealType(1))
02729       : _M_param(__a, __b)
02730       { }
02731 
02732       explicit
02733       cauchy_distribution(const param_type& __p)
02734       : _M_param(__p)
02735       { }
02736 
02737       /**
02738        * @brief Resets the distribution state.
02739        */
02740       void
02741       reset()
02742       { }
02743 
02744       /**
02745        *
02746        */
02747       _RealType
02748       a() const
02749       { return _M_param.a(); }
02750 
02751       _RealType
02752       b() const
02753       { return _M_param.b(); }
02754 
02755       /**
02756        * @brief Returns the parameter set of the distribution.
02757        */
02758       param_type
02759       param() const
02760       { return _M_param; }
02761 
02762       /**
02763        * @brief Sets the parameter set of the distribution.
02764        * @param __param The new parameter set of the distribution.
02765        */
02766       void
02767       param(const param_type& __param)
02768       { _M_param = __param; }
02769 
02770       /**
02771        * @brief Returns the greatest lower bound value of the distribution.
02772        */
02773       result_type
02774       min() const
02775       { return std::numeric_limits<result_type>::min(); }
02776 
02777       /**
02778        * @brief Returns the least upper bound value of the distribution.
02779        */
02780       result_type
02781       max() const
02782       { return std::numeric_limits<result_type>::max(); }
02783 
02784       /**
02785        * @brief Generating functions.
02786        */
02787       template<typename _UniformRandomNumberGenerator>
02788     result_type
02789     operator()(_UniformRandomNumberGenerator& __urng)
02790     { return this->operator()(__urng, _M_param); }
02791 
02792       template<typename _UniformRandomNumberGenerator>
02793     result_type
02794     operator()(_UniformRandomNumberGenerator& __urng,
02795            const param_type& __p);
02796 
02797       /**
02798        * @brief Return true if two Cauchy distributions have
02799        *        the same parameters.
02800        */
02801       friend bool
02802       operator==(const cauchy_distribution& __d1,
02803          const cauchy_distribution& __d2)
02804       { return __d1._M_param == __d2._M_param; }
02805 
02806     private:
02807       param_type _M_param;
02808     };
02809 
02810   /**
02811    * @brief Return true if two Cauchy distributions have
02812    *        different parameters.
02813    */
02814   template<typename _RealType>
02815     inline bool
02816     operator!=(const std::cauchy_distribution<_RealType>& __d1,
02817            const std::cauchy_distribution<_RealType>& __d2)
02818     { return !(__d1 == __d2); }
02819 
02820   /**
02821    * @brief Inserts a %cauchy_distribution random number distribution
02822    * @p __x into the output stream @p __os.
02823    *
02824    * @param __os An output stream.
02825    * @param __x  A %cauchy_distribution random number distribution.
02826    *
02827    * @returns The output stream with the state of @p __x inserted or in
02828    * an error state.
02829    */
02830   template<typename _RealType, typename _CharT, typename _Traits>
02831     std::basic_ostream<_CharT, _Traits>&
02832     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
02833            const std::cauchy_distribution<_RealType>& __x);
02834 
02835   /**
02836    * @brief Extracts a %cauchy_distribution random number distribution
02837    * @p __x from the input stream @p __is.
02838    *
02839    * @param __is An input stream.
02840    * @param __x A %cauchy_distribution random number
02841    *            generator engine.
02842    *
02843    * @returns The input stream with @p __x extracted or in an error state.
02844    */
02845   template<typename _RealType, typename _CharT, typename _Traits>
02846     std::basic_istream<_CharT, _Traits>&
02847     operator>>(std::basic_istream<_CharT, _Traits>& __is,
02848            std::cauchy_distribution<_RealType>& __x);
02849 
02850 
02851   /**
02852    * @brief A fisher_f_distribution random number distribution.
02853    *
02854    * The formula for the normal probability mass function is
02855    * @f[
02856    *     p(x|m,n) = \frac{\Gamma((m+n)/2)}{\Gamma(m/2)\Gamma(n/2)}
02857    *                (\frac{m}{n})^{m/2} x^{(m/2)-1}
02858    *                (1 + \frac{mx}{n})^{-(m+n)/2} 
02859    * @f]
02860    */
02861   template<typename _RealType = double>
02862     class fisher_f_distribution
02863     {
02864       static_assert(std::is_floating_point<_RealType>::value,
02865             "template argument not a floating point type");
02866 
02867     public:
02868       /** The type of the range of the distribution. */
02869       typedef _RealType result_type;
02870       /** Parameter type. */
02871       struct param_type
02872       {
02873     typedef fisher_f_distribution<_RealType> distribution_type;
02874 
02875     explicit
02876     param_type(_RealType __m = _RealType(1),
02877            _RealType __n = _RealType(1))
02878     : _M_m(__m), _M_n(__n)
02879     { }
02880 
02881     _RealType
02882     m() const
02883     { return _M_m; }
02884 
02885     _RealType
02886     n() const
02887     { return _M_n; }
02888 
02889     friend bool
02890     operator==(const param_type& __p1, const param_type& __p2)
02891     { return __p1._M_m == __p2._M_m && __p1._M_n == __p2._M_n; }
02892 
02893       private:
02894     _RealType _M_m;
02895     _RealType _M_n;
02896       };
02897 
02898       explicit
02899       fisher_f_distribution(_RealType __m = _RealType(1),
02900                 _RealType __n = _RealType(1))
02901       : _M_param(__m, __n), _M_gd_x(__m / 2), _M_gd_y(__n / 2)
02902       { }
02903 
02904       explicit
02905       fisher_f_distribution(const param_type& __p)
02906       : _M_param(__p), _M_gd_x(__p.m() / 2), _M_gd_y(__p.n() / 2)
02907       { }
02908 
02909       /**
02910        * @brief Resets the distribution state.
02911        */
02912       void
02913       reset()
02914       {
02915     _M_gd_x.reset();
02916     _M_gd_y.reset();
02917       }
02918 
02919       /**
02920        *
02921        */
02922       _RealType
02923       m() const
02924       { return _M_param.m(); }
02925 
02926       _RealType
02927       n() const
02928       { return _M_param.n(); }
02929 
02930       /**
02931        * @brief Returns the parameter set of the distribution.
02932        */
02933       param_type
02934       param() const
02935       { return _M_param; }
02936 
02937       /**
02938        * @brief Sets the parameter set of the distribution.
02939        * @param __param The new parameter set of the distribution.
02940        */
02941       void
02942       param(const param_type& __param)
02943       { _M_param = __param; }
02944 
02945       /**
02946        * @brief Returns the greatest lower bound value of the distribution.
02947        */
02948       result_type
02949       min() const
02950       { return result_type(0); }
02951 
02952       /**
02953        * @brief Returns the least upper bound value of the distribution.
02954        */
02955       result_type
02956       max() const
02957       { return std::numeric_limits<result_type>::max(); }
02958 
02959       /**
02960        * @brief Generating functions.
02961        */
02962       template<typename _UniformRandomNumberGenerator>
02963     result_type
02964     operator()(_UniformRandomNumberGenerator& __urng)
02965     { return (_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()); }
02966 
02967       template<typename _UniformRandomNumberGenerator>
02968     result_type
02969     operator()(_UniformRandomNumberGenerator& __urng,
02970            const param_type& __p)
02971         {
02972       typedef typename std::gamma_distribution<result_type>::param_type
02973         param_type;
02974       return ((_M_gd_x(__urng, param_type(__p.m() / 2)) * n())
02975           / (_M_gd_y(__urng, param_type(__p.n() / 2)) * m()));
02976     }
02977 
02978       /**
02979        * @brief Return true if two Fisher f distributions have
02980        *        the same parameters and the sequences that would
02981        *        be generated are equal.
02982        */
02983       friend bool
02984       operator==(const fisher_f_distribution& __d1,
02985          const fisher_f_distribution& __d2)
02986       { return (__d1._M_param == __d2._M_param
02987         && __d1._M_gd_x == __d2._M_gd_x
02988         && __d1._M_gd_y == __d2._M_gd_y); }
02989 
02990       /**
02991        * @brief Inserts a %fisher_f_distribution random number distribution
02992        * @p __x into the output stream @p __os.
02993        *
02994        * @param __os An output stream.
02995        * @param __x  A %fisher_f_distribution random number distribution.
02996        *
02997        * @returns The output stream with the state of @p __x inserted or in
02998        * an error state.
02999        */
03000       template<typename _RealType1, typename _CharT, typename _Traits>
03001     friend std::basic_ostream<_CharT, _Traits>&
03002     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03003            const std::fisher_f_distribution<_RealType1>& __x);
03004 
03005       /**
03006        * @brief Extracts a %fisher_f_distribution random number distribution
03007        * @p __x from the input stream @p __is.
03008        *
03009        * @param __is An input stream.
03010        * @param __x A %fisher_f_distribution random number
03011        *            generator engine.
03012        *
03013        * @returns The input stream with @p __x extracted or in an error state.
03014        */
03015       template<typename _RealType1, typename _CharT, typename _Traits>
03016     friend std::basic_istream<_CharT, _Traits>&
03017     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03018            std::fisher_f_distribution<_RealType1>& __x);
03019 
03020     private:
03021       param_type _M_param;
03022 
03023       std::gamma_distribution<result_type> _M_gd_x, _M_gd_y;
03024     };
03025 
03026   /**
03027    * @brief Return true if two Fisher f distributions are diferent.
03028    */
03029   template<typename _RealType>
03030     inline bool
03031     operator!=(const std::fisher_f_distribution<_RealType>& __d1,
03032            const std::fisher_f_distribution<_RealType>& __d2)
03033     { return !(__d1 == __d2); }
03034 
03035   /**
03036    * @brief A student_t_distribution random number distribution.
03037    *
03038    * The formula for the normal probability mass function is:
03039    * @f[
03040    *     p(x|n) = \frac{1}{\sqrt(n\pi)} \frac{\Gamma((n+1)/2)}{\Gamma(n/2)}
03041    *              (1 + \frac{x^2}{n}) ^{-(n+1)/2} 
03042    * @f]
03043    */
03044   template<typename _RealType = double>
03045     class student_t_distribution
03046     {
03047       static_assert(std::is_floating_point<_RealType>::value,
03048             "template argument not a floating point type");
03049 
03050     public:
03051       /** The type of the range of the distribution. */
03052       typedef _RealType result_type;
03053       /** Parameter type. */
03054       struct param_type
03055       {
03056     typedef student_t_distribution<_RealType> distribution_type;
03057 
03058     explicit
03059     param_type(_RealType __n = _RealType(1))
03060     : _M_n(__n)
03061     { }
03062 
03063     _RealType
03064     n() const
03065     { return _M_n; }
03066 
03067     friend bool
03068     operator==(const param_type& __p1, const param_type& __p2)
03069     { return __p1._M_n == __p2._M_n; }
03070 
03071       private:
03072     _RealType _M_n;
03073       };
03074 
03075       explicit
03076       student_t_distribution(_RealType __n = _RealType(1))
03077       : _M_param(__n), _M_nd(), _M_gd(__n / 2, 2)
03078       { }
03079 
03080       explicit
03081       student_t_distribution(const param_type& __p)
03082       : _M_param(__p), _M_nd(), _M_gd(__p.n() / 2, 2)
03083       { }
03084 
03085       /**
03086        * @brief Resets the distribution state.
03087        */
03088       void
03089       reset()
03090       {
03091     _M_nd.reset();
03092     _M_gd.reset();
03093       }
03094 
03095       /**
03096        *
03097        */
03098       _RealType
03099       n() const
03100       { return _M_param.n(); }
03101 
03102       /**
03103        * @brief Returns the parameter set of the distribution.
03104        */
03105       param_type
03106       param() const
03107       { return _M_param; }
03108 
03109       /**
03110        * @brief Sets the parameter set of the distribution.
03111        * @param __param The new parameter set of the distribution.
03112        */
03113       void
03114       param(const param_type& __param)
03115       { _M_param = __param; }
03116 
03117       /**
03118        * @brief Returns the greatest lower bound value of the distribution.
03119        */
03120       result_type
03121       min() const
03122       { return std::numeric_limits<result_type>::min(); }
03123 
03124       /**
03125        * @brief Returns the least upper bound value of the distribution.
03126        */
03127       result_type
03128       max() const
03129       { return std::numeric_limits<result_type>::max(); }
03130 
03131       /**
03132        * @brief Generating functions.
03133        */
03134       template<typename _UniformRandomNumberGenerator>
03135     result_type
03136         operator()(_UniformRandomNumberGenerator& __urng)
03137         { return _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); }
03138 
03139       template<typename _UniformRandomNumberGenerator>
03140     result_type
03141     operator()(_UniformRandomNumberGenerator& __urng,
03142            const param_type& __p)
03143         {
03144       typedef typename std::gamma_distribution<result_type>::param_type
03145         param_type;
03146     
03147       const result_type __g = _M_gd(__urng, param_type(__p.n() / 2, 2));
03148       return _M_nd(__urng) * std::sqrt(__p.n() / __g);
03149         }
03150 
03151       /**
03152        * @brief Return true if two Student t distributions have
03153        *        the same parameters and the sequences that would
03154        *        be generated are equal.
03155        */
03156       friend bool
03157       operator==(const student_t_distribution& __d1,
03158          const student_t_distribution& __d2)
03159       { return (__d1._M_param == __d2._M_param
03160         && __d1._M_nd == __d2._M_nd && __d1._M_gd == __d2._M_gd); }
03161 
03162       /**
03163        * @brief Inserts a %student_t_distribution random number distribution
03164        * @p __x into the output stream @p __os.
03165        *
03166        * @param __os An output stream.
03167        * @param __x  A %student_t_distribution random number distribution.
03168        *
03169        * @returns The output stream with the state of @p __x inserted or in
03170        * an error state.
03171        */
03172       template<typename _RealType1, typename _CharT, typename _Traits>
03173     friend std::basic_ostream<_CharT, _Traits>&
03174     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03175            const std::student_t_distribution<_RealType1>& __x);
03176 
03177       /**
03178        * @brief Extracts a %student_t_distribution random number distribution
03179        * @p __x from the input stream @p __is.
03180        *
03181        * @param __is An input stream.
03182        * @param __x A %student_t_distribution random number
03183        *            generator engine.
03184        *
03185        * @returns The input stream with @p __x extracted or in an error state.
03186        */
03187       template<typename _RealType1, typename _CharT, typename _Traits>
03188     friend std::basic_istream<_CharT, _Traits>&
03189     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03190            std::student_t_distribution<_RealType1>& __x);
03191 
03192     private:
03193       param_type _M_param;
03194 
03195       std::normal_distribution<result_type> _M_nd;
03196       std::gamma_distribution<result_type> _M_gd;
03197     };
03198 
03199   /**
03200    * @brief Return true if two Student t distributions are different.
03201    */
03202   template<typename _RealType>
03203     inline bool
03204     operator!=(const std::student_t_distribution<_RealType>& __d1,
03205            const std::student_t_distribution<_RealType>& __d2)
03206     { return !(__d1 == __d2); }
03207 
03208 
03209   /* @} */ // group random_distributions_normal
03210 
03211   /**
03212    * @addtogroup random_distributions_bernoulli Bernoulli Distributions
03213    * @ingroup random_distributions
03214    * @{
03215    */
03216 
03217   /**
03218    * @brief A Bernoulli random number distribution.
03219    *
03220    * Generates a sequence of true and false values with likelihood @f$p@f$
03221    * that true will come up and @f$(1 - p)@f$ that false will appear.
03222    */
03223   class bernoulli_distribution
03224   {
03225   public:
03226     /** The type of the range of the distribution. */
03227     typedef bool result_type;
03228     /** Parameter type. */
03229     struct param_type
03230     {
03231       typedef bernoulli_distribution distribution_type;
03232 
03233       explicit
03234       param_type(double __p = 0.5)
03235       : _M_p(__p)
03236       {
03237     _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
03238       }
03239 
03240       double
03241       p() const
03242       { return _M_p; }
03243 
03244       friend bool
03245       operator==(const param_type& __p1, const param_type& __p2)
03246       { return __p1._M_p == __p2._M_p; }
03247 
03248     private:
03249       double _M_p;
03250     };
03251 
03252   public:
03253     /**
03254      * @brief Constructs a Bernoulli distribution with likelihood @p p.
03255      *
03256      * @param __p  [IN]  The likelihood of a true result being returned.
03257      *                   Must be in the interval @f$[0, 1]@f$.
03258      */
03259     explicit
03260     bernoulli_distribution(double __p = 0.5)
03261     : _M_param(__p)
03262     { }
03263 
03264     explicit
03265     bernoulli_distribution(const param_type& __p)
03266     : _M_param(__p)
03267     { }
03268 
03269     /**
03270      * @brief Resets the distribution state.
03271      *
03272      * Does nothing for a Bernoulli distribution.
03273      */
03274     void
03275     reset() { }
03276 
03277     /**
03278      * @brief Returns the @p p parameter of the distribution.
03279      */
03280     double
03281     p() const
03282     { return _M_param.p(); }
03283 
03284     /**
03285      * @brief Returns the parameter set of the distribution.
03286      */
03287     param_type
03288     param() const
03289     { return _M_param; }
03290 
03291     /**
03292      * @brief Sets the parameter set of the distribution.
03293      * @param __param The new parameter set of the distribution.
03294      */
03295     void
03296     param(const param_type& __param)
03297     { _M_param = __param; }
03298 
03299     /**
03300      * @brief Returns the greatest lower bound value of the distribution.
03301      */
03302     result_type
03303     min() const
03304     { return std::numeric_limits<result_type>::min(); }
03305 
03306     /**
03307      * @brief Returns the least upper bound value of the distribution.
03308      */
03309     result_type
03310     max() const
03311     { return std::numeric_limits<result_type>::max(); }
03312 
03313     /**
03314      * @brief Generating functions.
03315      */
03316     template<typename _UniformRandomNumberGenerator>
03317       result_type
03318       operator()(_UniformRandomNumberGenerator& __urng)
03319       { return this->operator()(__urng, _M_param); }
03320 
03321     template<typename _UniformRandomNumberGenerator>
03322       result_type
03323       operator()(_UniformRandomNumberGenerator& __urng,
03324          const param_type& __p)
03325       {
03326     __detail::_Adaptor<_UniformRandomNumberGenerator, double>
03327       __aurng(__urng);
03328     if ((__aurng() - __aurng.min())
03329          < __p.p() * (__aurng.max() - __aurng.min()))
03330       return true;
03331     return false;
03332       }
03333 
03334     /**
03335      * @brief Return true if two Bernoulli distributions have
03336      *        the same parameters.
03337      */
03338     friend bool
03339     operator==(const bernoulli_distribution& __d1,
03340            const bernoulli_distribution& __d2)
03341     { return __d1._M_param == __d2._M_param; }
03342 
03343   private:
03344     param_type _M_param;
03345   };
03346 
03347   /**
03348    * @brief Return true if two Bernoulli distributions have
03349    *        different parameters.
03350    */
03351   inline bool
03352   operator!=(const std::bernoulli_distribution& __d1,
03353          const std::bernoulli_distribution& __d2)
03354   { return !(__d1 == __d2); }
03355 
03356   /**
03357    * @brief Inserts a %bernoulli_distribution random number distribution
03358    * @p __x into the output stream @p __os.
03359    *
03360    * @param __os An output stream.
03361    * @param __x  A %bernoulli_distribution random number distribution.
03362    *
03363    * @returns The output stream with the state of @p __x inserted or in
03364    * an error state.
03365    */
03366   template<typename _CharT, typename _Traits>
03367     std::basic_ostream<_CharT, _Traits>&
03368     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03369            const std::bernoulli_distribution& __x);
03370 
03371   /**
03372    * @brief Extracts a %bernoulli_distribution random number distribution
03373    * @p __x from the input stream @p __is.
03374    *
03375    * @param __is An input stream.
03376    * @param __x  A %bernoulli_distribution random number generator engine.
03377    *
03378    * @returns The input stream with @p __x extracted or in an error state.
03379    */
03380   template<typename _CharT, typename _Traits>
03381     std::basic_istream<_CharT, _Traits>&
03382     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03383            std::bernoulli_distribution& __x)
03384     {
03385       double __p;
03386       __is >> __p;
03387       __x.param(bernoulli_distribution::param_type(__p));
03388       return __is;
03389     }
03390 
03391 
03392   /**
03393    * @brief A discrete binomial random number distribution.
03394    *
03395    * The formula for the binomial probability density function is
03396    * @f$p(i|t,p) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
03397    * and @f$p@f$ are the parameters of the distribution.
03398    */
03399   template<typename _IntType = int>
03400     class binomial_distribution
03401     {
03402       static_assert(std::is_integral<_IntType>::value,
03403             "template argument not an integral type");
03404 
03405     public:
03406       /** The type of the range of the distribution. */
03407       typedef _IntType result_type;
03408       /** Parameter type. */
03409       struct param_type
03410       {
03411     typedef binomial_distribution<_IntType> distribution_type;
03412     friend class binomial_distribution<_IntType>;
03413 
03414     explicit
03415     param_type(_IntType __t = _IntType(1), double __p = 0.5)
03416     : _M_t(__t), _M_p(__p)
03417     {
03418       _GLIBCXX_DEBUG_ASSERT((_M_t >= _IntType(0))
03419                 && (_M_p >= 0.0)
03420                 && (_M_p <= 1.0));
03421       _M_initialize();
03422     }
03423 
03424     _IntType
03425     t() const
03426     { return _M_t; }
03427 
03428     double
03429     p() const
03430     { return _M_p; }
03431 
03432     friend bool
03433     operator==(const param_type& __p1, const param_type& __p2)
03434     { return __p1._M_t == __p2._M_t && __p1._M_p == __p2._M_p; }
03435 
03436       private:
03437     void
03438     _M_initialize();
03439 
03440     _IntType _M_t;
03441     double _M_p;
03442 
03443     double _M_q;
03444 #if _GLIBCXX_USE_C99_MATH_TR1
03445     double _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
03446            _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
03447 #endif
03448     bool   _M_easy;
03449       };
03450 
03451       // constructors and member function
03452       explicit
03453       binomial_distribution(_IntType __t = _IntType(1),
03454                 double __p = 0.5)
03455       : _M_param(__t, __p), _M_nd()
03456       { }
03457 
03458       explicit
03459       binomial_distribution(const param_type& __p)
03460       : _M_param(__p), _M_nd()
03461       { }
03462 
03463       /**
03464        * @brief Resets the distribution state.
03465        */
03466       void
03467       reset()
03468       { _M_nd.reset(); }
03469 
03470       /**
03471        * @brief Returns the distribution @p t parameter.
03472        */
03473       _IntType
03474       t() const
03475       { return _M_param.t(); }
03476 
03477       /**
03478        * @brief Returns the distribution @p p parameter.
03479        */
03480       double
03481       p() const
03482       { return _M_param.p(); }
03483 
03484       /**
03485        * @brief Returns the parameter set of the distribution.
03486        */
03487       param_type
03488       param() const
03489       { return _M_param; }
03490 
03491       /**
03492        * @brief Sets the parameter set of the distribution.
03493        * @param __param The new parameter set of the distribution.
03494        */
03495       void
03496       param(const param_type& __param)
03497       { _M_param = __param; }
03498 
03499       /**
03500        * @brief Returns the greatest lower bound value of the distribution.
03501        */
03502       result_type
03503       min() const
03504       { return 0; }
03505 
03506       /**
03507        * @brief Returns the least upper bound value of the distribution.
03508        */
03509       result_type
03510       max() const
03511       { return _M_param.t(); }
03512 
03513       /**
03514        * @brief Generating functions.
03515        */
03516       template<typename _UniformRandomNumberGenerator>
03517     result_type
03518     operator()(_UniformRandomNumberGenerator& __urng)
03519     { return this->operator()(__urng, _M_param); }
03520 
03521       template<typename _UniformRandomNumberGenerator>
03522     result_type
03523     operator()(_UniformRandomNumberGenerator& __urng,
03524            const param_type& __p);
03525 
03526       /**
03527        * @brief Return true if two binomial distributions have
03528        *        the same parameters and the sequences that would
03529        *        be generated are equal.
03530        */
03531     friend bool
03532         operator==(const binomial_distribution& __d1,
03533            const binomial_distribution& __d2)
03534 #ifdef _GLIBCXX_USE_C99_MATH_TR1
03535     { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; }
03536 #else
03537         { return __d1._M_param == __d2._M_param; }
03538 #endif
03539 
03540       /**
03541        * @brief Inserts a %binomial_distribution random number distribution
03542        * @p __x into the output stream @p __os.
03543        *
03544        * @param __os An output stream.
03545        * @param __x  A %binomial_distribution random number distribution.
03546        *
03547        * @returns The output stream with the state of @p __x inserted or in
03548        * an error state.
03549        */
03550       template<typename _IntType1,
03551            typename _CharT, typename _Traits>
03552     friend std::basic_ostream<_CharT, _Traits>&
03553     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03554            const std::binomial_distribution<_IntType1>& __x);
03555 
03556       /**
03557        * @brief Extracts a %binomial_distribution random number distribution
03558        * @p __x from the input stream @p __is.
03559        *
03560        * @param __is An input stream.
03561        * @param __x  A %binomial_distribution random number generator engine.
03562        *
03563        * @returns The input stream with @p __x extracted or in an error
03564        *          state.
03565        */
03566       template<typename _IntType1,
03567            typename _CharT, typename _Traits>
03568     friend std::basic_istream<_CharT, _Traits>&
03569     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03570            std::binomial_distribution<_IntType1>& __x);
03571 
03572     private:
03573       template<typename _UniformRandomNumberGenerator>
03574     result_type
03575     _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);
03576 
03577       param_type _M_param;
03578 
03579       // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
03580       std::normal_distribution<double> _M_nd;
03581     };
03582 
03583   /**
03584    * @brief Return true if two binomial distributions are different.
03585    */
03586   template<typename _IntType>
03587     inline bool
03588     operator!=(const std::binomial_distribution<_IntType>& __d1,
03589            const std::binomial_distribution<_IntType>& __d2)
03590     { return !(__d1 == __d2); }
03591 
03592 
03593   /**
03594    * @brief A discrete geometric random number distribution.
03595    *
03596    * The formula for the geometric probability density function is
03597    * @f$p(i|p) = p(1 - p)^{i}@f$ where @f$p@f$ is the parameter of the
03598    * distribution.
03599    */
03600   template<typename _IntType = int>
03601     class geometric_distribution
03602     {
03603       static_assert(std::is_integral<_IntType>::value,
03604             "template argument not an integral type");
03605 
03606     public:
03607       /** The type of the range of the distribution. */
03608       typedef _IntType  result_type;
03609       /** Parameter type. */
03610       struct param_type
03611       {
03612     typedef geometric_distribution<_IntType> distribution_type;
03613     friend class geometric_distribution<_IntType>;
03614 
03615     explicit
03616     param_type(double __p = 0.5)
03617     : _M_p(__p)
03618     {
03619       _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
03620       _M_initialize();
03621     }
03622 
03623     double
03624     p() const
03625     { return _M_p; }
03626 
03627     friend bool
03628     operator==(const param_type& __p1, const param_type& __p2)
03629     { return __p1._M_p == __p2._M_p; }
03630 
03631       private:
03632     void
03633     _M_initialize()
03634     { _M_log_1_p = std::log(1.0 - _M_p); }
03635 
03636     double _M_p;
03637 
03638     double _M_log_1_p;
03639       };
03640 
03641       // constructors and member function
03642       explicit
03643       geometric_distribution(double __p = 0.5)
03644       : _M_param(__p)
03645       { }
03646 
03647       explicit
03648       geometric_distribution(const param_type& __p)
03649       : _M_param(__p)
03650       { }
03651 
03652       /**
03653        * @brief Resets the distribution state.
03654        *
03655        * Does nothing for the geometric distribution.
03656        */
03657       void
03658       reset() { }
03659 
03660       /**
03661        * @brief Returns the distribution parameter @p p.
03662        */
03663       double
03664       p() const
03665       { return _M_param.p(); }
03666 
03667       /**
03668        * @brief Returns the parameter set of the distribution.
03669        */
03670       param_type
03671       param() const
03672       { return _M_param; }
03673 
03674       /**
03675        * @brief Sets the parameter set of the distribution.
03676        * @param __param The new parameter set of the distribution.
03677        */
03678       void
03679       param(const param_type& __param)
03680       { _M_param = __param; }
03681 
03682       /**
03683        * @brief Returns the greatest lower bound value of the distribution.
03684        */
03685       result_type
03686       min() const
03687       { return 0; }
03688 
03689       /**
03690        * @brief Returns the least upper bound value of the distribution.
03691        */
03692       result_type
03693       max() const
03694       { return std::numeric_limits<result_type>::max(); }
03695 
03696       /**
03697        * @brief Generating functions.
03698        */
03699       template<typename _UniformRandomNumberGenerator>
03700     result_type
03701     operator()(_UniformRandomNumberGenerator& __urng)
03702     { return this->operator()(__urng, _M_param); }
03703 
03704       template<typename _UniformRandomNumberGenerator>
03705     result_type
03706     operator()(_UniformRandomNumberGenerator& __urng,
03707            const param_type& __p);
03708 
03709       /**
03710        * @brief Return true if two geometric distributions have
03711        *        the same parameters.
03712        */
03713       friend bool
03714       operator==(const geometric_distribution& __d1,
03715          const geometric_distribution& __d2)
03716       { return __d1._M_param == __d2._M_param; }
03717 
03718     private:
03719       param_type _M_param;
03720     };
03721 
03722   /**
03723    * @brief Return true if two geometric distributions have
03724    *        different parameters.
03725    */
03726   template<typename _IntType>
03727     inline bool
03728     operator!=(const std::geometric_distribution<_IntType>& __d1,
03729            const std::geometric_distribution<_IntType>& __d2)
03730     { return !(__d1 == __d2); }
03731 
03732   /**
03733    * @brief Inserts a %geometric_distribution random number distribution
03734    * @p __x into the output stream @p __os.
03735    *
03736    * @param __os An output stream.
03737    * @param __x  A %geometric_distribution random number distribution.
03738    *
03739    * @returns The output stream with the state of @p __x inserted or in
03740    * an error state.
03741    */
03742   template<typename _IntType,
03743        typename _CharT, typename _Traits>
03744     std::basic_ostream<_CharT, _Traits>&
03745     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03746            const std::geometric_distribution<_IntType>& __x);
03747 
03748   /**
03749    * @brief Extracts a %geometric_distribution random number distribution
03750    * @p __x from the input stream @p __is.
03751    *
03752    * @param __is An input stream.
03753    * @param __x  A %geometric_distribution random number generator engine.
03754    *
03755    * @returns The input stream with @p __x extracted or in an error state.
03756    */
03757   template<typename _IntType,
03758        typename _CharT, typename _Traits>
03759     std::basic_istream<_CharT, _Traits>&
03760     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03761            std::geometric_distribution<_IntType>& __x);
03762 
03763 
03764   /**
03765    * @brief A negative_binomial_distribution random number distribution.
03766    *
03767    * The formula for the negative binomial probability mass function is
03768    * @f$p(i) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
03769    * and @f$p@f$ are the parameters of the distribution.
03770    */
03771   template<typename _IntType = int>
03772     class negative_binomial_distribution
03773     {
03774       static_assert(std::is_integral<_IntType>::value,
03775             "template argument not an integral type");
03776 
03777     public:
03778       /** The type of the range of the distribution. */
03779       typedef _IntType result_type;
03780       /** Parameter type. */
03781       struct param_type
03782       {
03783     typedef negative_binomial_distribution<_IntType> distribution_type;
03784 
03785     explicit
03786     param_type(_IntType __k = 1, double __p = 0.5)
03787     : _M_k(__k), _M_p(__p)
03788     {
03789       _GLIBCXX_DEBUG_ASSERT((_M_k > 0) && (_M_p > 0.0) && (_M_p <= 1.0));
03790     }
03791 
03792     _IntType
03793     k() const
03794     { return _M_k; }
03795 
03796     double
03797     p() const
03798     { return _M_p; }
03799 
03800     friend bool
03801     operator==(const param_type& __p1, const param_type& __p2)
03802     { return __p1._M_k == __p2._M_k && __p1._M_p == __p2._M_p; }
03803 
03804       private:
03805     _IntType _M_k;
03806     double _M_p;
03807       };
03808 
03809       explicit
03810       negative_binomial_distribution(_IntType __k = 1, double __p = 0.5)
03811       : _M_param(__k, __p), _M_gd(__k, (1.0 - __p) / __p)
03812       { }
03813 
03814       explicit
03815       negative_binomial_distribution(const param_type& __p)
03816       : _M_param(__p), _M_gd(__p.k(), (1.0 - __p.p()) / __p.p())
03817       { }
03818 
03819       /**
03820        * @brief Resets the distribution state.
03821        */
03822       void
03823       reset()
03824       { _M_gd.reset(); }
03825 
03826       /**
03827        * @brief Return the @f$k@f$ parameter of the distribution.
03828        */
03829       _IntType
03830       k() const
03831       { return _M_param.k(); }
03832 
03833       /**
03834        * @brief Return the @f$p@f$ parameter of the distribution.
03835        */
03836       double
03837       p() const
03838       { return _M_param.p(); }
03839 
03840       /**
03841        * @brief Returns the parameter set of the distribution.
03842        */
03843       param_type
03844       param() const
03845       { return _M_param; }
03846 
03847       /**
03848        * @brief Sets the parameter set of the distribution.
03849        * @param __param The new parameter set of the distribution.
03850        */
03851       void
03852       param(const param_type& __param)
03853       { _M_param = __param; }
03854 
03855       /**
03856        * @brief Returns the greatest lower bound value of the distribution.
03857        */
03858       result_type
03859       min() const
03860       { return result_type(0); }
03861 
03862       /**
03863        * @brief Returns the least upper bound value of the distribution.
03864        */
03865       result_type
03866       max() const
03867       { return std::numeric_limits<result_type>::max(); }
03868 
03869       /**
03870        * @brief Generating functions.
03871        */
03872       template<typename _UniformRandomNumberGenerator>
03873     result_type
03874         operator()(_UniformRandomNumberGenerator& __urng);
03875 
03876       template<typename _UniformRandomNumberGenerator>
03877     result_type
03878     operator()(_UniformRandomNumberGenerator& __urng,
03879            const param_type& __p);
03880 
03881       /**
03882        * @brief Return true if two negative binomial distributions have
03883        *        the same parameters and the sequences that would be
03884        *        generated are equal.
03885        */
03886       friend bool
03887       operator==(const negative_binomial_distribution& __d1,
03888          const negative_binomial_distribution& __d2)
03889       { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; }
03890 
03891       /**
03892        * @brief Inserts a %negative_binomial_distribution random
03893        *        number distribution @p __x into the output stream @p __os.
03894        *
03895        * @param __os An output stream.
03896        * @param __x  A %negative_binomial_distribution random number
03897        *             distribution.
03898        *
03899        * @returns The output stream with the state of @p __x inserted or in
03900        *          an error state.
03901        */
03902       template<typename _IntType1, typename _CharT, typename _Traits>
03903     friend std::basic_ostream<_CharT, _Traits>&
03904     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
03905            const std::negative_binomial_distribution<_IntType1>& __x);
03906 
03907       /**
03908        * @brief Extracts a %negative_binomial_distribution random number
03909        *        distribution @p __x from the input stream @p __is.
03910        *
03911        * @param __is An input stream.
03912        * @param __x A %negative_binomial_distribution random number
03913        *            generator engine.
03914        *
03915        * @returns The input stream with @p __x extracted or in an error state.
03916        */
03917       template<typename _IntType1, typename _CharT, typename _Traits>
03918     friend std::basic_istream<_CharT, _Traits>&
03919     operator>>(std::basic_istream<_CharT, _Traits>& __is,
03920            std::negative_binomial_distribution<_IntType1>& __x);
03921 
03922     private:
03923       param_type _M_param;
03924 
03925       std::gamma_distribution<double> _M_gd;
03926     };
03927 
03928   /**
03929    * @brief Return true if two negative binomial distributions are different.
03930    */
03931   template<typename _IntType>
03932     inline bool
03933     operator!=(const std::negative_binomial_distribution<_IntType>& __d1,
03934            const std::negative_binomial_distribution<_IntType>& __d2)
03935     { return !(__d1 == __d2); }
03936 
03937 
03938   /* @} */ // group random_distributions_bernoulli
03939 
03940   /**
03941    * @addtogroup random_distributions_poisson Poisson Distributions
03942    * @ingroup random_distributions
03943    * @{
03944    */
03945 
03946   /**
03947    * @brief A discrete Poisson random number distribution.
03948    *
03949    * The formula for the Poisson probability density function is
03950    * @f$p(i|\mu) = \frac{\mu^i}{i!} e^{-\mu}@f$ where @f$\mu@f$ is the
03951    * parameter of the distribution.
03952    */
03953   template<typename _IntType = int>
03954     class poisson_distribution
03955     {
03956       static_assert(std::is_integral<_IntType>::value,
03957             "template argument not an integral type");
03958 
03959     public:
03960       /** The type of the range of the distribution. */
03961       typedef _IntType  result_type;
03962       /** Parameter type. */
03963       struct param_type
03964       {
03965     typedef poisson_distribution<_IntType> distribution_type;
03966     friend class poisson_distribution<_IntType>;
03967 
03968     explicit
03969     param_type(double __mean = 1.0)
03970     : _M_mean(__mean)
03971     {
03972       _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
03973       _M_initialize();
03974     }
03975 
03976     double
03977     mean() const
03978     { return _M_mean; }
03979 
03980     friend bool
03981     operator==(const param_type& __p1, const param_type& __p2)
03982     { return __p1._M_mean == __p2._M_mean; }
03983 
03984       private:
03985     // Hosts either log(mean) or the threshold of the simple method.
03986     void
03987     _M_initialize();
03988 
03989     double _M_mean;
03990 
03991     double _M_lm_thr;
03992 #if _GLIBCXX_USE_C99_MATH_TR1
03993     double _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
03994 #endif
03995       };
03996 
03997       // constructors and member function
03998       explicit
03999       poisson_distribution(double __mean = 1.0)
04000       : _M_param(__mean), _M_nd()
04001       { }
04002 
04003       explicit
04004       poisson_distribution(const param_type& __p)
04005       : _M_param(__p), _M_nd()
04006       { }
04007 
04008       /**
04009        * @brief Resets the distribution state.
04010        */
04011       void
04012       reset()
04013       { _M_nd.reset(); }
04014 
04015       /**
04016        * @brief Returns the distribution parameter @p mean.
04017        */
04018       double
04019       mean() const
04020       { return _M_param.mean(); }
04021 
04022       /**
04023        * @brief Returns the parameter set of the distribution.
04024        */
04025       param_type
04026       param() const
04027       { return _M_param; }
04028 
04029       /**
04030        * @brief Sets the parameter set of the distribution.
04031        * @param __param The new parameter set of the distribution.
04032        */
04033       void
04034       param(const param_type& __param)
04035       { _M_param = __param; }
04036 
04037       /**
04038        * @brief Returns the greatest lower bound value of the distribution.
04039        */
04040       result_type
04041       min() const
04042       { return 0; }
04043 
04044       /**
04045        * @brief Returns the least upper bound value of the distribution.
04046        */
04047       result_type
04048       max() const
04049       { return std::numeric_limits<result_type>::max(); }
04050 
04051       /**
04052        * @brief Generating functions.
04053        */
04054       template<typename _UniformRandomNumberGenerator>
04055     result_type
04056     operator()(_UniformRandomNumberGenerator& __urng)
04057     { return this->operator()(__urng, _M_param); }
04058 
04059       template<typename _UniformRandomNumberGenerator>
04060     result_type
04061     operator()(_UniformRandomNumberGenerator& __urng,
04062            const param_type& __p);
04063 
04064        /**
04065     * @brief Return true if two Poisson distributions have the same
04066     *        parameters and the sequences that would be generated
04067     *        are equal.
04068     */
04069       friend bool
04070       operator==(const poisson_distribution& __d1,
04071          const poisson_distribution& __d2)
04072 #ifdef _GLIBCXX_USE_C99_MATH_TR1
04073       { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; }
04074 #else
04075       { return __d1._M_param == __d2._M_param; }
04076 #endif
04077 
04078       /**
04079        * @brief Inserts a %poisson_distribution random number distribution
04080        * @p __x into the output stream @p __os.
04081        *
04082        * @param __os An output stream.
04083        * @param __x  A %poisson_distribution random number distribution.
04084        *
04085        * @returns The output stream with the state of @p __x inserted or in
04086        * an error state.
04087        */
04088       template<typename _IntType1, typename _CharT, typename _Traits>
04089     friend std::basic_ostream<_CharT, _Traits>&
04090     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04091            const std::poisson_distribution<_IntType1>& __x);
04092 
04093       /**
04094        * @brief Extracts a %poisson_distribution random number distribution
04095        * @p __x from the input stream @p __is.
04096        *
04097        * @param __is An input stream.
04098        * @param __x  A %poisson_distribution random number generator engine.
04099        *
04100        * @returns The input stream with @p __x extracted or in an error
04101        *          state.
04102        */
04103       template<typename _IntType1, typename _CharT, typename _Traits>
04104     friend std::basic_istream<_CharT, _Traits>&
04105     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04106            std::poisson_distribution<_IntType1>& __x);
04107 
04108     private:
04109       param_type _M_param;
04110 
04111       // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
04112       std::normal_distribution<double> _M_nd;
04113     };
04114 
04115   /**
04116    * @brief Return true if two Poisson distributions are different.
04117    */
04118   template<typename _IntType>
04119     inline bool
04120     operator!=(const std::poisson_distribution<_IntType>& __d1,
04121            const std::poisson_distribution<_IntType>& __d2)
04122     { return !(__d1 == __d2); }
04123 
04124 
04125   /**
04126    * @brief An exponential continuous distribution for random numbers.
04127    *
04128    * The formula for the exponential probability density function is
04129    * @f$p(x|\lambda) = \lambda e^{-\lambda x}@f$.
04130    *
04131    * <table border=1 cellpadding=10 cellspacing=0>
04132    * <caption align=top>Distribution Statistics</caption>
04133    * <tr><td>Mean</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
04134    * <tr><td>Median</td><td>@f$\frac{\ln 2}{\lambda}@f$</td></tr>
04135    * <tr><td>Mode</td><td>@f$zero@f$</td></tr>
04136    * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
04137    * <tr><td>Standard Deviation</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
04138    * </table>
04139    */
04140   template<typename _RealType = double>
04141     class exponential_distribution
04142     {
04143       static_assert(std::is_floating_point<_RealType>::value,
04144             "template argument not a floating point type");
04145 
04146     public:
04147       /** The type of the range of the distribution. */
04148       typedef _RealType result_type;
04149       /** Parameter type. */
04150       struct param_type
04151       {
04152     typedef exponential_distribution<_RealType> distribution_type;
04153 
04154     explicit
04155     param_type(_RealType __lambda = _RealType(1))
04156     : _M_lambda(__lambda)
04157     {
04158       _GLIBCXX_DEBUG_ASSERT(_M_lambda > _RealType(0));
04159     }
04160 
04161     _RealType
04162     lambda() const
04163     { return _M_lambda; }
04164 
04165     friend bool
04166     operator==(const param_type& __p1, const param_type& __p2)
04167     { return __p1._M_lambda == __p2._M_lambda; }
04168 
04169       private:
04170     _RealType _M_lambda;
04171       };
04172 
04173     public:
04174       /**
04175        * @brief Constructs an exponential distribution with inverse scale
04176        *        parameter @f$\lambda@f$.
04177        */
04178       explicit
04179       exponential_distribution(const result_type& __lambda = result_type(1))
04180       : _M_param(__lambda)
04181       { }
04182 
04183       explicit
04184       exponential_distribution(const param_type& __p)
04185       : _M_param(__p)
04186       { }
04187 
04188       /**
04189        * @brief Resets the distribution state.
04190        *
04191        * Has no effect on exponential distributions.
04192        */
04193       void
04194       reset() { }
04195 
04196       /**
04197        * @brief Returns the inverse scale parameter of the distribution.
04198        */
04199       _RealType
04200       lambda() const
04201       { return _M_param.lambda(); }
04202 
04203       /**
04204        * @brief Returns the parameter set of the distribution.
04205        */
04206       param_type
04207       param() const
04208       { return _M_param; }
04209 
04210       /**
04211        * @brief Sets the parameter set of the distribution.
04212        * @param __param The new parameter set of the distribution.
04213        */
04214       void
04215       param(const param_type& __param)
04216       { _M_param = __param; }
04217 
04218       /**
04219        * @brief Returns the greatest lower bound value of the distribution.
04220        */
04221       result_type
04222       min() const
04223       { return result_type(0); }
04224 
04225       /**
04226        * @brief Returns the least upper bound value of the distribution.
04227        */
04228       result_type
04229       max() const
04230       { return std::numeric_limits<result_type>::max(); }
04231 
04232       /**
04233        * @brief Generating functions.
04234        */
04235       template<typename _UniformRandomNumberGenerator>
04236     result_type
04237     operator()(_UniformRandomNumberGenerator& __urng)
04238         { return this->operator()(__urng, _M_param); }
04239 
04240       template<typename _UniformRandomNumberGenerator>
04241     result_type
04242     operator()(_UniformRandomNumberGenerator& __urng,
04243            const param_type& __p)
04244     {
04245       __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
04246         __aurng(__urng);
04247       return -std::log(result_type(1) - __aurng()) / __p.lambda();
04248     }
04249 
04250       /**
04251        * @brief Return true if two exponential distributions have the same
04252        *        parameters.
04253        */
04254       friend bool
04255       operator==(const exponential_distribution& __d1,
04256          const exponential_distribution& __d2)
04257       { return __d1._M_param == __d2._M_param; }
04258 
04259     private:
04260       param_type _M_param;
04261     };
04262 
04263   /**
04264    * @brief Return true if two exponential distributions have different
04265    *        parameters.
04266    */
04267   template<typename _RealType>
04268     inline bool
04269     operator!=(const std::exponential_distribution<_RealType>& __d1,
04270            const std::exponential_distribution<_RealType>& __d2)
04271     { return !(__d1 == __d2); }
04272 
04273   /**
04274    * @brief Inserts a %exponential_distribution random number distribution
04275    * @p __x into the output stream @p __os.
04276    *
04277    * @param __os An output stream.
04278    * @param __x  A %exponential_distribution random number distribution.
04279    *
04280    * @returns The output stream with the state of @p __x inserted or in
04281    * an error state.
04282    */
04283   template<typename _RealType, typename _CharT, typename _Traits>
04284     std::basic_ostream<_CharT, _Traits>&
04285     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04286            const std::exponential_distribution<_RealType>& __x);
04287 
04288   /**
04289    * @brief Extracts a %exponential_distribution random number distribution
04290    * @p __x from the input stream @p __is.
04291    *
04292    * @param __is An input stream.
04293    * @param __x A %exponential_distribution random number
04294    *            generator engine.
04295    *
04296    * @returns The input stream with @p __x extracted or in an error state.
04297    */
04298   template<typename _RealType, typename _CharT, typename _Traits>
04299     std::basic_istream<_CharT, _Traits>&
04300     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04301            std::exponential_distribution<_RealType>& __x);
04302 
04303 
04304   /**
04305    * @brief A weibull_distribution random number distribution.
04306    *
04307    * The formula for the normal probability density function is:
04308    * @f[
04309    *     p(x|\alpha,\beta) = \frac{\alpha}{\beta} (\frac{x}{\beta})^{\alpha-1}
04310    *                         \exp{(-(\frac{x}{\beta})^\alpha)} 
04311    * @f]
04312    */
04313   template<typename _RealType = double>
04314     class weibull_distribution
04315     {
04316       static_assert(std::is_floating_point<_RealType>::value,
04317             "template argument not a floating point type");
04318 
04319     public:
04320       /** The type of the range of the distribution. */
04321       typedef _RealType result_type;
04322       /** Parameter type. */
04323       struct param_type
04324       {
04325     typedef weibull_distribution<_RealType> distribution_type;
04326 
04327     explicit
04328     param_type(_RealType __a = _RealType(1),
04329            _RealType __b = _RealType(1))
04330     : _M_a(__a), _M_b(__b)
04331     { }
04332 
04333     _RealType
04334     a() const
04335     { return _M_a; }
04336 
04337     _RealType
04338     b() const
04339     { return _M_b; }
04340 
04341     friend bool
04342     operator==(const param_type& __p1, const param_type& __p2)
04343     { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
04344 
04345       private:
04346     _RealType _M_a;
04347     _RealType _M_b;
04348       };
04349 
04350       explicit
04351       weibull_distribution(_RealType __a = _RealType(1),
04352                _RealType __b = _RealType(1))
04353       : _M_param(__a, __b)
04354       { }
04355 
04356       explicit
04357       weibull_distribution(const param_type& __p)
04358       : _M_param(__p)
04359       { }
04360 
04361       /**
04362        * @brief Resets the distribution state.
04363        */
04364       void
04365       reset()
04366       { }
04367 
04368       /**
04369        * @brief Return the @f$a@f$ parameter of the distribution.
04370        */
04371       _RealType
04372       a() const
04373       { return _M_param.a(); }
04374 
04375       /**
04376        * @brief Return the @f$b@f$ parameter of the distribution.
04377        */
04378       _RealType
04379       b() const
04380       { return _M_param.b(); }
04381 
04382       /**
04383        * @brief Returns the parameter set of the distribution.
04384        */
04385       param_type
04386       param() const
04387       { return _M_param; }
04388 
04389       /**
04390        * @brief Sets the parameter set of the distribution.
04391        * @param __param The new parameter set of the distribution.
04392        */
04393       void
04394       param(const param_type& __param)
04395       { _M_param = __param; }
04396 
04397       /**
04398        * @brief Returns the greatest lower bound value of the distribution.
04399        */
04400       result_type
04401       min() const
04402       { return result_type(0); }
04403 
04404       /**
04405        * @brief Returns the least upper bound value of the distribution.
04406        */
04407       result_type
04408       max() const
04409       { return std::numeric_limits<result_type>::max(); }
04410 
04411       /**
04412        * @brief Generating functions.
04413        */
04414       template<typename _UniformRandomNumberGenerator>
04415     result_type
04416     operator()(_UniformRandomNumberGenerator& __urng)
04417     { return this->operator()(__urng, _M_param); }
04418 
04419       template<typename _UniformRandomNumberGenerator>
04420     result_type
04421     operator()(_UniformRandomNumberGenerator& __urng,
04422            const param_type& __p);
04423 
04424       /**
04425        * @brief Return true if two Weibull distributions have the same
04426        *        parameters.
04427        */
04428       friend bool
04429       operator==(const weibull_distribution& __d1,
04430          const weibull_distribution& __d2)
04431       { return __d1._M_param == __d2._M_param; }
04432 
04433     private:
04434       param_type _M_param;
04435     };
04436 
04437    /**
04438     * @brief Return true if two Weibull distributions have different
04439     *        parameters.
04440     */
04441   template<typename _RealType>
04442     inline bool
04443     operator!=(const std::weibull_distribution<_RealType>& __d1,
04444            const std::weibull_distribution<_RealType>& __d2)
04445     { return !(__d1 == __d2); }
04446 
04447   /**
04448    * @brief Inserts a %weibull_distribution random number distribution
04449    * @p __x into the output stream @p __os.
04450    *
04451    * @param __os An output stream.
04452    * @param __x  A %weibull_distribution random number distribution.
04453    *
04454    * @returns The output stream with the state of @p __x inserted or in
04455    * an error state.
04456    */
04457   template<typename _RealType, typename _CharT, typename _Traits>
04458     std::basic_ostream<_CharT, _Traits>&
04459     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04460            const std::weibull_distribution<_RealType>& __x);
04461 
04462   /**
04463    * @brief Extracts a %weibull_distribution random number distribution
04464    * @p __x from the input stream @p __is.
04465    *
04466    * @param __is An input stream.
04467    * @param __x A %weibull_distribution random number
04468    *            generator engine.
04469    *
04470    * @returns The input stream with @p __x extracted or in an error state.
04471    */
04472   template<typename _RealType, typename _CharT, typename _Traits>
04473     std::basic_istream<_CharT, _Traits>&
04474     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04475            std::weibull_distribution<_RealType>& __x);
04476 
04477 
04478   /**
04479    * @brief A extreme_value_distribution random number distribution.
04480    *
04481    * The formula for the normal probability mass function is
04482    * @f[
04483    *     p(x|a,b) = \frac{1}{b}
04484    *                \exp( \frac{a-x}{b} - \exp(\frac{a-x}{b})) 
04485    * @f]
04486    */
04487   template<typename _RealType = double>
04488     class extreme_value_distribution
04489     {
04490       static_assert(std::is_floating_point<_RealType>::value,
04491             "template argument not a floating point type");
04492 
04493     public:
04494       /** The type of the range of the distribution. */
04495       typedef _RealType result_type;
04496       /** Parameter type. */
04497       struct param_type
04498       {
04499     typedef extreme_value_distribution<_RealType> distribution_type;
04500 
04501     explicit
04502     param_type(_RealType __a = _RealType(0),
04503            _RealType __b = _RealType(1))
04504     : _M_a(__a), _M_b(__b)
04505     { }
04506 
04507     _RealType
04508     a() const
04509     { return _M_a; }
04510 
04511     _RealType
04512     b() const
04513     { return _M_b; }
04514 
04515     friend bool
04516     operator==(const param_type& __p1, const param_type& __p2)
04517     { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
04518 
04519       private:
04520     _RealType _M_a;
04521     _RealType _M_b;
04522       };
04523 
04524       explicit
04525       extreme_value_distribution(_RealType __a = _RealType(0),
04526                  _RealType __b = _RealType(1))
04527       : _M_param(__a, __b)
04528       { }
04529 
04530       explicit
04531       extreme_value_distribution(const param_type& __p)
04532       : _M_param(__p)
04533       { }
04534 
04535       /**
04536        * @brief Resets the distribution state.
04537        */
04538       void
04539       reset()
04540       { }
04541 
04542       /**
04543        * @brief Return the @f$a@f$ parameter of the distribution.
04544        */
04545       _RealType
04546       a() const
04547       { return _M_param.a(); }
04548 
04549       /**
04550        * @brief Return the @f$b@f$ parameter of the distribution.
04551        */
04552       _RealType
04553       b() const
04554       { return _M_param.b(); }
04555 
04556       /**
04557        * @brief Returns the parameter set of the distribution.
04558        */
04559       param_type
04560       param() const
04561       { return _M_param; }
04562 
04563       /**
04564        * @brief Sets the parameter set of the distribution.
04565        * @param __param The new parameter set of the distribution.
04566        */
04567       void
04568       param(const param_type& __param)
04569       { _M_param = __param; }
04570 
04571       /**
04572        * @brief Returns the greatest lower bound value of the distribution.
04573        */
04574       result_type
04575       min() const
04576       { return std::numeric_limits<result_type>::min(); }
04577 
04578       /**
04579        * @brief Returns the least upper bound value of the distribution.
04580        */
04581       result_type
04582       max() const
04583       { return std::numeric_limits<result_type>::max(); }
04584 
04585       /**
04586        * @brief Generating functions.
04587        */
04588       template<typename _UniformRandomNumberGenerator>
04589     result_type
04590     operator()(_UniformRandomNumberGenerator& __urng)
04591     { return this->operator()(__urng, _M_param); }
04592 
04593       template<typename _UniformRandomNumberGenerator>
04594     result_type
04595     operator()(_UniformRandomNumberGenerator& __urng,
04596            const param_type& __p);
04597 
04598       /**
04599        * @brief Return true if two extreme value distributions have the same
04600        *        parameters.
04601        */
04602       friend bool
04603       operator==(const extreme_value_distribution& __d1,
04604          const extreme_value_distribution& __d2)
04605       { return __d1._M_param == __d2._M_param; }
04606 
04607     private:
04608       param_type _M_param;
04609     };
04610 
04611   /**
04612     * @brief Return true if two extreme value distributions have different
04613     *        parameters.
04614    */
04615   template<typename _RealType>
04616     inline bool
04617     operator!=(const std::extreme_value_distribution<_RealType>& __d1,
04618            const std::extreme_value_distribution<_RealType>& __d2)
04619     { return !(__d1 == __d2); }
04620 
04621   /**
04622    * @brief Inserts a %extreme_value_distribution random number distribution
04623    * @p __x into the output stream @p __os.
04624    *
04625    * @param __os An output stream.
04626    * @param __x  A %extreme_value_distribution random number distribution.
04627    *
04628    * @returns The output stream with the state of @p __x inserted or in
04629    * an error state.
04630    */
04631   template<typename _RealType, typename _CharT, typename _Traits>
04632     std::basic_ostream<_CharT, _Traits>&
04633     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04634            const std::extreme_value_distribution<_RealType>& __x);
04635 
04636   /**
04637    * @brief Extracts a %extreme_value_distribution random number
04638    *        distribution @p __x from the input stream @p __is.
04639    *
04640    * @param __is An input stream.
04641    * @param __x A %extreme_value_distribution random number
04642    *            generator engine.
04643    *
04644    * @returns The input stream with @p __x extracted or in an error state.
04645    */
04646   template<typename _RealType, typename _CharT, typename _Traits>
04647     std::basic_istream<_CharT, _Traits>&
04648     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04649            std::extreme_value_distribution<_RealType>& __x);
04650 
04651 
04652   /**
04653    * @brief A discrete_distribution random number distribution.
04654    *
04655    * The formula for the discrete probability mass function is
04656    *
04657    */
04658   template<typename _IntType = int>
04659     class discrete_distribution
04660     {
04661       static_assert(std::is_integral<_IntType>::value,
04662             "template argument not an integral type");
04663 
04664     public:
04665       /** The type of the range of the distribution. */
04666       typedef _IntType result_type;
04667       /** Parameter type. */
04668       struct param_type
04669       {
04670     typedef discrete_distribution<_IntType> distribution_type;
04671     friend class discrete_distribution<_IntType>;
04672 
04673     param_type()
04674     : _M_prob(), _M_cp()
04675     { }
04676 
04677     template<typename _InputIterator>
04678       param_type(_InputIterator __wbegin,
04679              _InputIterator __wend)
04680       : _M_prob(__wbegin, __wend), _M_cp()
04681       { _M_initialize(); }
04682 
04683     param_type(initializer_list<double> __wil)
04684     : _M_prob(__wil.begin(), __wil.end()), _M_cp()
04685     { _M_initialize(); }
04686 
04687     template<typename _Func>
04688       param_type(size_t __nw, double __xmin, double __xmax,
04689              _Func __fw);
04690 
04691     // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
04692     param_type(const param_type&) = default;
04693     param_type& operator=(const param_type&) = default;
04694 
04695     std::vector<double>
04696     probabilities() const
04697     { return _M_prob.empty() ? std::vector<double>(1, 1.0) : _M_prob; }
04698 
04699     friend bool
04700     operator==(const param_type& __p1, const param_type& __p2)
04701     { return __p1._M_prob == __p2._M_prob; }
04702 
04703       private:
04704     void
04705     _M_initialize();
04706 
04707     std::vector<double> _M_prob;
04708     std::vector<double> _M_cp;
04709       };
04710 
04711       discrete_distribution()
04712       : _M_param()
04713       { }
04714 
04715       template<typename _InputIterator>
04716     discrete_distribution(_InputIterator __wbegin,
04717                   _InputIterator __wend)
04718     : _M_param(__wbegin, __wend)
04719     { }
04720 
04721       discrete_distribution(initializer_list<double> __wl)
04722       : _M_param(__wl)
04723       { }
04724 
04725       template<typename _Func>
04726     discrete_distribution(size_t __nw, double __xmin, double __xmax,
04727                   _Func __fw)
04728     : _M_param(__nw, __xmin, __xmax, __fw)
04729     { }
04730 
04731       explicit
04732       discrete_distribution(const param_type& __p)
04733       : _M_param(__p)
04734       { }
04735 
04736       /**
04737        * @brief Resets the distribution state.
04738        */
04739       void
04740       reset()
04741       { }
04742 
04743       /**
04744        * @brief Returns the probabilities of the distribution.
04745        */
04746       std::vector<double>
04747       probabilities() const
04748       {
04749     return _M_param._M_prob.empty()
04750       ? std::vector<double>(1, 1.0) : _M_param._M_prob;
04751       }
04752 
04753       /**
04754        * @brief Returns the parameter set of the distribution.
04755        */
04756       param_type
04757       param() const
04758       { return _M_param; }
04759 
04760       /**
04761        * @brief Sets the parameter set of the distribution.
04762        * @param __param The new parameter set of the distribution.
04763        */
04764       void
04765       param(const param_type& __param)
04766       { _M_param = __param; }
04767 
04768       /**
04769        * @brief Returns the greatest lower bound value of the distribution.
04770        */
04771       result_type
04772       min() const
04773       { return result_type(0); }
04774 
04775       /**
04776        * @brief Returns the least upper bound value of the distribution.
04777        */
04778       result_type
04779       max() const
04780       {
04781     return _M_param._M_prob.empty()
04782       ? result_type(0) : result_type(_M_param._M_prob.size() - 1);
04783       }
04784 
04785       /**
04786        * @brief Generating functions.
04787        */
04788       template<typename _UniformRandomNumberGenerator>
04789     result_type
04790     operator()(_UniformRandomNumberGenerator& __urng)
04791     { return this->operator()(__urng, _M_param); }
04792 
04793       template<typename _UniformRandomNumberGenerator>
04794     result_type
04795     operator()(_UniformRandomNumberGenerator& __urng,
04796            const param_type& __p);
04797 
04798       /**
04799        * @brief Return true if two discrete distributions have the same
04800        *        parameters.
04801        */
04802       friend bool
04803       operator==(const discrete_distribution& __d1,
04804          const discrete_distribution& __d2)
04805       { return __d1._M_param == __d2._M_param; }
04806 
04807       /**
04808        * @brief Inserts a %discrete_distribution random number distribution
04809        * @p __x into the output stream @p __os.
04810        *
04811        * @param __os An output stream.
04812        * @param __x  A %discrete_distribution random number distribution.
04813        *
04814        * @returns The output stream with the state of @p __x inserted or in
04815        * an error state.
04816        */
04817       template<typename _IntType1, typename _CharT, typename _Traits>
04818     friend std::basic_ostream<_CharT, _Traits>&
04819     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
04820            const std::discrete_distribution<_IntType1>& __x);
04821 
04822       /**
04823        * @brief Extracts a %discrete_distribution random number distribution
04824        * @p __x from the input stream @p __is.
04825        *
04826        * @param __is An input stream.
04827        * @param __x A %discrete_distribution random number
04828        *            generator engine.
04829        *
04830        * @returns The input stream with @p __x extracted or in an error
04831        *          state.
04832        */
04833       template<typename _IntType1, typename _CharT, typename _Traits>
04834     friend std::basic_istream<_CharT, _Traits>&
04835     operator>>(std::basic_istream<_CharT, _Traits>& __is,
04836            std::discrete_distribution<_IntType1>& __x);
04837 
04838     private:
04839       param_type _M_param;
04840     };
04841 
04842   /**
04843     * @brief Return true if two discrete distributions have different
04844     *        parameters.
04845     */
04846   template<typename _IntType>
04847     inline bool
04848     operator!=(const std::discrete_distribution<_IntType>& __d1,
04849            const std::discrete_distribution<_IntType>& __d2)
04850     { return !(__d1 == __d2); }
04851 
04852 
04853   /**
04854    * @brief A piecewise_constant_distribution random number distribution.
04855    *
04856    * The formula for the piecewise constant probability mass function is
04857    *
04858    */
04859   template<typename _RealType = double>
04860     class piecewise_constant_distribution
04861     {
04862       static_assert(std::is_floating_point<_RealType>::value,
04863             "template argument not a floating point type");
04864 
04865     public:
04866       /** The type of the range of the distribution. */
04867       typedef _RealType result_type;
04868       /** Parameter type. */
04869       struct param_type
04870       {
04871     typedef piecewise_constant_distribution<_RealType> distribution_type;
04872     friend class piecewise_constant_distribution<_RealType>;
04873 
04874     param_type()
04875     : _M_int(), _M_den(), _M_cp()
04876     { }
04877 
04878     template<typename _InputIteratorB, typename _InputIteratorW>
04879       param_type(_InputIteratorB __bfirst,
04880              _InputIteratorB __bend,
04881              _InputIteratorW __wbegin);
04882 
04883     template<typename _Func>
04884       param_type(initializer_list<_RealType> __bi, _Func __fw);
04885 
04886     template<typename _Func>
04887       param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
04888              _Func __fw);
04889 
04890     // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
04891     param_type(const param_type&) = default;
04892     param_type& operator=(const param_type&) = default;
04893 
04894     std::vector<_RealType>
04895     intervals() const
04896     {
04897       if (_M_int.empty())
04898         {
04899           std::vector<_RealType> __tmp(2);
04900           __tmp[1] = _RealType(1);
04901           return __tmp;
04902         }
04903       else
04904         return _M_int;
04905     }
04906 
04907     std::vector<double>
04908     densities() const
04909     { return _M_den.empty() ? std::vector<double>(1, 1.0) : _M_den; }
04910 
04911     friend bool
04912     operator==(const param_type& __p1, const param_type& __p2)
04913     { return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; }
04914 
04915       private:
04916     void
04917     _M_initialize();
04918 
04919     std::vector<_RealType> _M_int;
04920     std::vector<double> _M_den;
04921     std::vector<double> _M_cp;
04922       };
04923 
04924       explicit
04925       piecewise_constant_distribution()
04926       : _M_param()
04927       { }
04928 
04929       template<typename _InputIteratorB, typename _InputIteratorW>
04930     piecewise_constant_distribution(_InputIteratorB __bfirst,
04931                     _InputIteratorB __bend,
04932                     _InputIteratorW __wbegin)
04933     : _M_param(__bfirst, __bend, __wbegin)
04934     { }
04935 
04936       template<typename _Func>
04937     piecewise_constant_distribution(initializer_list<_RealType> __bl,
04938                     _Func __fw)
04939     : _M_param(__bl, __fw)
04940     { }
04941 
04942       template<typename _Func>
04943     piecewise_constant_distribution(size_t __nw,
04944                     _RealType __xmin, _RealType __xmax,
04945                     _Func __fw)
04946     : _M_param(__nw, __xmin, __xmax, __fw)
04947     { }
04948 
04949       explicit
04950       piecewise_constant_distribution(const param_type& __p)
04951       : _M_param(__p)
04952       { }
04953 
04954       /**
04955        * @brief Resets the distribution state.
04956        */
04957       void
04958       reset()
04959       { }
04960 
04961       /**
04962        * @brief Returns a vector of the intervals.
04963        */
04964       std::vector<_RealType>
04965       intervals() const
04966       {
04967     if (_M_param._M_int.empty())
04968       {
04969         std::vector<_RealType> __tmp(2);
04970         __tmp[1] = _RealType(1);
04971         return __tmp;
04972       }
04973     else
04974       return _M_param._M_int;
04975       }
04976 
04977       /**
04978        * @brief Returns a vector of the probability densities.
04979        */
04980       std::vector<double>
04981       densities() const
04982       {
04983     return _M_param._M_den.empty()
04984       ? std::vector<double>(1, 1.0) : _M_param._M_den;
04985       }
04986 
04987       /**
04988        * @brief Returns the parameter set of the distribution.
04989        */
04990       param_type
04991       param() const
04992       { return _M_param; }
04993 
04994       /**
04995        * @brief Sets the parameter set of the distribution.
04996        * @param __param The new parameter set of the distribution.
04997        */
04998       void
04999       param(const param_type& __param)
05000       { _M_param = __param; }
05001 
05002       /**
05003        * @brief Returns the greatest lower bound value of the distribution.
05004        */
05005       result_type
05006       min() const
05007       {
05008     return _M_param._M_int.empty()
05009       ? result_type(0) : _M_param._M_int.front();
05010       }
05011 
05012       /**
05013        * @brief Returns the least upper bound value of the distribution.
05014        */
05015       result_type
05016       max() const
05017       {
05018     return _M_param._M_int.empty()
05019       ? result_type(1) : _M_param._M_int.back();
05020       }
05021 
05022       /**
05023        * @brief Generating functions.
05024        */
05025       template<typename _UniformRandomNumberGenerator>
05026     result_type
05027     operator()(_UniformRandomNumberGenerator& __urng)
05028     { return this->operator()(__urng, _M_param); }
05029 
05030       template<typename _UniformRandomNumberGenerator>
05031     result_type
05032     operator()(_UniformRandomNumberGenerator& __urng,
05033            const param_type& __p);
05034 
05035       /**
05036        * @brief Return true if two piecewise constant distributions have the
05037        *        same parameters.
05038        */
05039       friend bool
05040       operator==(const piecewise_constant_distribution& __d1,
05041          const piecewise_constant_distribution& __d2)
05042       { return __d1._M_param == __d2._M_param; }
05043 
05044       /**
05045        * @brief Inserts a %piecewise_constan_distribution random
05046        *        number distribution @p __x into the output stream @p __os.
05047        *
05048        * @param __os An output stream.
05049        * @param __x  A %piecewise_constan_distribution random number
05050        *             distribution.
05051        *
05052        * @returns The output stream with the state of @p __x inserted or in
05053        * an error state.
05054        */
05055       template<typename _RealType1, typename _CharT, typename _Traits>
05056     friend std::basic_ostream<_CharT, _Traits>&
05057     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
05058            const std::piecewise_constant_distribution<_RealType1>& __x);
05059 
05060       /**
05061        * @brief Extracts a %piecewise_constan_distribution random
05062        *        number distribution @p __x from the input stream @p __is.
05063        *
05064        * @param __is An input stream.
05065        * @param __x A %piecewise_constan_distribution random number
05066        *            generator engine.
05067        *
05068        * @returns The input stream with @p __x extracted or in an error
05069        *          state.
05070        */
05071       template<typename _RealType1, typename _CharT, typename _Traits>
05072     friend std::basic_istream<_CharT, _Traits>&
05073     operator>>(std::basic_istream<_CharT, _Traits>& __is,
05074            std::piecewise_constant_distribution<_RealType1>& __x);
05075 
05076     private:
05077       param_type _M_param;
05078     };
05079 
05080   /**
05081     * @brief Return true if two piecewise constant distributions have 
05082     *        different parameters.
05083    */
05084   template<typename _RealType>
05085     inline bool
05086     operator!=(const std::piecewise_constant_distribution<_RealType>& __d1,
05087            const std::piecewise_constant_distribution<_RealType>& __d2)
05088     { return !(__d1 == __d2); }
05089 
05090 
05091   /**
05092    * @brief A piecewise_linear_distribution random number distribution.
05093    *
05094    * The formula for the piecewise linear probability mass function is
05095    *
05096    */
05097   template<typename _RealType = double>
05098     class piecewise_linear_distribution
05099     {
05100       static_assert(std::is_floating_point<_RealType>::value,
05101             "template argument not a floating point type");
05102 
05103     public:
05104       /** The type of the range of the distribution. */
05105       typedef _RealType result_type;
05106       /** Parameter type. */
05107       struct param_type
05108       {
05109     typedef piecewise_linear_distribution<_RealType> distribution_type;
05110     friend class piecewise_linear_distribution<_RealType>;
05111 
05112     param_type()
05113     : _M_int(), _M_den(), _M_cp(), _M_m()
05114     { }
05115 
05116     template<typename _InputIteratorB, typename _InputIteratorW>
05117       param_type(_InputIteratorB __bfirst,
05118              _InputIteratorB __bend,
05119              _InputIteratorW __wbegin);
05120 
05121     template<typename _Func>
05122       param_type(initializer_list<_RealType> __bl, _Func __fw);
05123 
05124     template<typename _Func>
05125       param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
05126              _Func __fw);
05127 
05128     // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
05129     param_type(const param_type&) = default;
05130     param_type& operator=(const param_type&) = default;
05131 
05132     std::vector<_RealType>
05133     intervals() const
05134     {
05135       if (_M_int.empty())
05136         {
05137           std::vector<_RealType> __tmp(2);
05138           __tmp[1] = _RealType(1);
05139           return __tmp;
05140         }
05141       else
05142         return _M_int;
05143     }
05144 
05145     std::vector<double>
05146     densities() const
05147     { return _M_den.empty() ? std::vector<double>(2, 1.0) : _M_den; }
05148 
05149     friend bool
05150     operator==(const param_type& __p1, const param_type& __p2)
05151     { return (__p1._M_int == __p2._M_int
05152           && __p1._M_den == __p2._M_den); }
05153 
05154       private:
05155     void
05156     _M_initialize();
05157 
05158     std::vector<_RealType> _M_int;
05159     std::vector<double> _M_den;
05160     std::vector<double> _M_cp;
05161     std::vector<double> _M_m;
05162       };
05163 
05164       explicit
05165       piecewise_linear_distribution()
05166       : _M_param()
05167       { }
05168 
05169       template<typename _InputIteratorB, typename _InputIteratorW>
05170     piecewise_linear_distribution(_InputIteratorB __bfirst,
05171                       _InputIteratorB __bend,
05172                       _InputIteratorW __wbegin)
05173     : _M_param(__bfirst, __bend, __wbegin)
05174     { }
05175 
05176       template<typename _Func>
05177     piecewise_linear_distribution(initializer_list<_RealType> __bl,
05178                       _Func __fw)
05179     : _M_param(__bl, __fw)
05180     { }
05181 
05182       template<typename _Func>
05183     piecewise_linear_distribution(size_t __nw,
05184                       _RealType __xmin, _RealType __xmax,
05185                       _Func __fw)
05186     : _M_param(__nw, __xmin, __xmax, __fw)
05187     { }
05188 
05189       explicit
05190       piecewise_linear_distribution(const param_type& __p)
05191       : _M_param(__p)
05192       { }
05193 
05194       /**
05195        * Resets the distribution state.
05196        */
05197       void
05198       reset()
05199       { }
05200 
05201       /**
05202        * @brief Return the intervals of the distribution.
05203        */
05204       std::vector<_RealType>
05205       intervals() const
05206       {
05207     if (_M_param._M_int.empty())
05208       {
05209         std::vector<_RealType> __tmp(2);
05210         __tmp[1] = _RealType(1);
05211         return __tmp;
05212       }
05213     else
05214       return _M_param._M_int;
05215       }
05216 
05217       /**
05218        * @brief Return a vector of the probability densities of the
05219        *        distribution.
05220        */
05221       std::vector<double>
05222       densities() const
05223       {
05224     return _M_param._M_den.empty()
05225       ? std::vector<double>(2, 1.0) : _M_param._M_den;
05226       }
05227 
05228       /**
05229        * @brief Returns the parameter set of the distribution.
05230        */
05231       param_type
05232       param() const
05233       { return _M_param; }
05234 
05235       /**
05236        * @brief Sets the parameter set of the distribution.
05237        * @param __param The new parameter set of the distribution.
05238        */
05239       void
05240       param(const param_type& __param)
05241       { _M_param = __param; }
05242 
05243       /**
05244        * @brief Returns the greatest lower bound value of the distribution.
05245        */
05246       result_type
05247       min() const
05248       {
05249     return _M_param._M_int.empty()
05250       ? result_type(0) : _M_param._M_int.front();
05251       }
05252 
05253       /**
05254        * @brief Returns the least upper bound value of the distribution.
05255        */
05256       result_type
05257       max() const
05258       {
05259     return _M_param._M_int.empty()
05260       ? result_type(1) : _M_param._M_int.back();
05261       }
05262 
05263       /**
05264        * @brief Generating functions.
05265        */
05266       template<typename _UniformRandomNumberGenerator>
05267     result_type
05268     operator()(_UniformRandomNumberGenerator& __urng)
05269     { return this->operator()(__urng, _M_param); }
05270 
05271       template<typename _UniformRandomNumberGenerator>
05272     result_type
05273     operator()(_UniformRandomNumberGenerator& __urng,
05274            const param_type& __p);
05275 
05276       /**
05277        * @brief Return true if two piecewise linear distributions have the
05278        *        same parameters.
05279        */
05280       friend bool
05281       operator==(const piecewise_linear_distribution& __d1,
05282          const piecewise_linear_distribution& __d2)
05283       { return __d1._M_param == __d2._M_param; }
05284 
05285       /**
05286        * @brief Inserts a %piecewise_linear_distribution random number
05287        *        distribution @p __x into the output stream @p __os.
05288        *
05289        * @param __os An output stream.
05290        * @param __x  A %piecewise_linear_distribution random number
05291        *             distribution.
05292        *
05293        * @returns The output stream with the state of @p __x inserted or in
05294        *          an error state.
05295        */
05296       template<typename _RealType1, typename _CharT, typename _Traits>
05297     friend std::basic_ostream<_CharT, _Traits>&
05298     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
05299            const std::piecewise_linear_distribution<_RealType1>& __x);
05300 
05301       /**
05302        * @brief Extracts a %piecewise_linear_distribution random number
05303        *        distribution @p __x from the input stream @p __is.
05304        *
05305        * @param __is An input stream.
05306        * @param __x  A %piecewise_linear_distribution random number
05307        *             generator engine.
05308        *
05309        * @returns The input stream with @p __x extracted or in an error
05310        *          state.
05311        */
05312       template<typename _RealType1, typename _CharT, typename _Traits>
05313     friend std::basic_istream<_CharT, _Traits>&
05314     operator>>(std::basic_istream<_CharT, _Traits>& __is,
05315            std::piecewise_linear_distribution<_RealType1>& __x);
05316 
05317     private:
05318       param_type _M_param;
05319     };
05320 
05321   /**
05322     * @brief Return true if two piecewise linear distributions have
05323     *        different parameters.
05324    */
05325   template<typename _RealType>
05326     inline bool
05327     operator!=(const std::piecewise_linear_distribution<_RealType>& __d1,
05328            const std::piecewise_linear_distribution<_RealType>& __d2)
05329     { return !(__d1 == __d2); }
05330 
05331 
05332   /* @} */ // group random_distributions_poisson
05333 
05334   /* @} */ // group random_distributions
05335 
05336   /**
05337    * @addtogroup random_utilities Random Number Utilities
05338    * @ingroup random
05339    * @{
05340    */
05341 
05342   /**
05343    * @brief The seed_seq class generates sequences of seeds for random
05344    *        number generators.
05345    */
05346   class seed_seq
05347   {
05348 
05349   public:
05350     /** The type of the seed vales. */
05351     typedef uint_least32_t result_type;
05352 
05353     /** Default constructor. */
05354     seed_seq()
05355     : _M_v()
05356     { }
05357 
05358     template<typename _IntType>
05359       seed_seq(std::initializer_list<_IntType> il);
05360 
05361     template<typename _InputIterator>
05362       seed_seq(_InputIterator __begin, _InputIterator __end);
05363 
05364     // generating functions
05365     template<typename _RandomAccessIterator>
05366       void
05367       generate(_RandomAccessIterator __begin, _RandomAccessIterator __end);
05368 
05369     // property functions
05370     size_t size() const
05371     { return _M_v.size(); }
05372 
05373     template<typename OutputIterator>
05374       void
05375       param(OutputIterator __dest) const
05376       { std::copy(_M_v.begin(), _M_v.end(), __dest); }
05377 
05378   private:
05379     ///
05380     std::vector<result_type> _M_v;
05381   };
05382 
05383   /* @} */ // group random_utilities
05384 
05385   /* @} */ // group random
05386 
05387 _GLIBCXX_END_NAMESPACE_VERSION
05388 } // namespace std
05389 
05390 #endif