random.h

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