// random number generation -*- C++ -*-

// Copyright (C) 2009-2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/**
 * @file tr1/random.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{tr1/random}
 */

#ifndef _GLIBCXX_TR1_RANDOM_H
#define _GLIBCXX_TR1_RANDOM_H 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

namespace tr1
{
  // [5.1] Random number generation

  /**
   * @addtogroup tr1_random Random Number Generation
   * A facility for generating random numbers on selected distributions.
   * @{
   */

  /*
   * Implementation-space details.
   */
  namespace __detail
  {
    template<typename _UIntType, int __w,
	     bool = __w < std::numeric_limits<_UIntType>::digits>
      struct _Shift
      { static const _UIntType __value = 0; };

    template<typename _UIntType, int __w>
      struct _Shift<_UIntType, __w, true>
      { static const _UIntType __value = _UIntType(1) << __w; };

    template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
      struct _Mod;

    // Dispatch based on modulus value to prevent divide-by-zero compile-time
    // errors when m == 0.
    template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
      inline _Tp
      __mod(_Tp __x)
      { return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); }

    typedef __gnu_cxx::__conditional_type<(sizeof(unsigned) == 4),
		    unsigned, unsigned long>::__type _UInt32Type;

    /*
     * An adaptor class for converting the output of any Generator into
     * the input for a specific Distribution.
     */
    template<typename _Engine, typename _Distribution>
      struct _Adaptor
      {
	typedef typename _Engine::result_type           _Engine_result_type;
	typedef typename _Distribution::input_type      result_type;

      public:
	_Adaptor(const _Engine& __g)
	: _M_g(__g) { }

	result_type
	min() const
	{
	  result_type __return_value;
	  if (is_integral<_Engine_result_type>::value
	      && is_integral<result_type>::value)
	    __return_value = _M_g.min();
	  else
	    __return_value = result_type(0);
	  return __return_value;
	}

	result_type
	max() const
	{
	  result_type __return_value;
	  if (is_integral<_Engine_result_type>::value
	      && is_integral<result_type>::value)
	    __return_value = _M_g.max();
	  else if (!is_integral<result_type>::value)
	    __return_value = result_type(1);
	  else
	    __return_value = std::numeric_limits<result_type>::max() - 1;
	  return __return_value;
	}

	/*
	 * Converts a value generated by the adapted random number generator
	 * into a value in the input domain for the dependent random number
	 * distribution.
	 *
	 * Because the type traits are compile time constants only the
	 * appropriate clause of the if statements will actually be emitted
	 * by the compiler.
	 */
	result_type
	operator()()
	{
	  result_type __return_value;
	  if (is_integral<_Engine_result_type>::value
	      && is_integral<result_type>::value)
	    __return_value = _M_g();
	  else if (!is_integral<_Engine_result_type>::value
		   && !is_integral<result_type>::value)
	    __return_value = result_type(_M_g() - _M_g.min())
	      / result_type(_M_g.max() - _M_g.min());
	  else if (is_integral<_Engine_result_type>::value
		   && !is_integral<result_type>::value)
	    __return_value = result_type(_M_g() - _M_g.min())
	      / result_type(_M_g.max() - _M_g.min() + result_type(1));
	  else
	    __return_value = (((_M_g() - _M_g.min())
			       / (_M_g.max() - _M_g.min()))
			      * std::numeric_limits<result_type>::max());
	  return __return_value;
	}

	_Engine _M_g;
      };
  } // namespace __detail

  /**
   * Produces random numbers on a given distribution function using a
   * non-uniform random number generation engine.
   *
   * @todo the engine_value_type needs to be studied more carefully.
   */
  template<typename _Engine, typename _Dist>
    class variate_generator
    {
      template<typename _Eng>
	struct _Value
	{
	  typedef _Eng type;

	  static const _Eng&
	  _S_ref(const _Eng& __e) { return __e; }
	};

      template<typename _Eng>
	struct _Value<_Eng*>
	{
	  typedef _Eng type;

	  __attribute__((__nonnull__))
	  static const _Eng&
	  _S_ref(const _Eng* __e) { return *__e; }
	};

      template<typename _Eng>
	struct _Value<_Eng&>
	{
	  typedef _Eng type;

	  static const _Eng&
	  _S_ref(const _Eng& __e) { return __e; }
	};

    public:
      typedef _Engine                                engine_type;
      typedef typename _Value<_Engine>::type         engine_value_type;
      typedef _Dist                                  distribution_type;
      typedef typename _Dist::result_type            result_type;

      // Concept requirements.
      __glibcxx_class_requires(engine_value_type, _CopyConstructibleConcept)
      // __glibcxx_class_requires(_Engine, _EngineConcept)
      //  __glibcxx_class_requires(_Dist, _EngineConcept)

      // tr1:5.1.1 table 5.1 requirement
      typedef typename __gnu_cxx::__enable_if<
	is_arithmetic<result_type>::value, result_type>::__type _IsValidType;

      /**
       * Constructs a variate generator with the uniform random number
       * generator @p __eng for the random distribution @p __dist.
       *
       * @throws Any exceptions which may thrown by the copy constructors of
       * the @p _Engine or @p _Dist objects.
       */
      variate_generator(engine_type __eng, distribution_type __dist)
      : _M_engine(_Value<_Engine>::_S_ref(__eng)), _M_dist(__dist) { }

      /**
       * Gets the next generated value on the distribution.
       */
      result_type
      operator()()
      { return _M_dist(_M_engine); }

      /**
       * WTF?
       */
      template<typename _Tp>
        result_type
        operator()(_Tp __value)
        { return _M_dist(_M_engine, __value); }

      /**
       * Gets a reference to the underlying uniform random number generator
       * object.
       */
      engine_value_type&
      engine()
      { return _M_engine._M_g; }

      /**
       * Gets a const reference to the underlying uniform random number
       * generator object.
       */
      const engine_value_type&
      engine() const
      { return _M_engine._M_g; }

      /**
       * Gets a reference to the underlying random distribution.
       */
      distribution_type&
      distribution()
      { return _M_dist; }

      /**
       * Gets a const reference to the underlying random distribution.
       */
      const distribution_type&
      distribution() const
      { return _M_dist; }

      /**
       * Gets the closed lower bound of the distribution interval.
       */
      result_type
      min() const
      { return this->distribution().min(); }

      /**
       * Gets the closed upper bound of the distribution interval.
       */
      result_type
      max() const
      { return this->distribution().max(); }

    private:
      __detail::_Adaptor<engine_value_type, _Dist> _M_engine;
      distribution_type _M_dist;
    };


  /**
   * @addtogroup tr1_random_generators Random Number Generators
   * @ingroup tr1_random
   *
   * These classes define objects which provide random or pseudorandom
   * numbers, either from a discrete or a continuous interval.  The
   * random number generator supplied as a part of this library are
   * all uniform random number generators which provide a sequence of
   * random number uniformly distributed over their range.
   *
   * A number generator is a function object with an operator() that
   * takes zero arguments and returns a number.
   *
   * A compliant random number generator must satisfy the following
   * requirements.  <table border=1 cellpadding=10 cellspacing=0>
   * <caption align=top>Random Number Generator Requirements</caption>
   * <tr><td>To be documented.</td></tr> </table>
   *
   * @{
   */

  /**
   * @brief A model of a linear congruential random number generator.
   *
   * A random number generator that produces pseudorandom numbers using the
   * linear function @f$x_{i+1}\leftarrow(ax_{i} + c) \bmod m @f$.
   *
   * The template parameter @p _UIntType must be an unsigned integral type
   * large enough to store values up to (__m-1). If the template parameter
   * @p __m is 0, the modulus @p __m used is
   * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
   * parameters @p __a and @p __c must be less than @p __m.
   *
   * The size of the state is @f$ 1 @f$.
   */
  template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
    class linear_congruential
    {
      __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
      //  __glibcpp_class_requires(__a < __m && __c < __m)

    public:
      /** The type of the generated random value. */
      typedef _UIntType result_type;

      /** The multiplier. */
      static const _UIntType multiplier = __a;
      /** An increment. */
      static const _UIntType increment = __c;
      /** The modulus. */
      static const _UIntType modulus = __m;

      /**
       * Constructs a %linear_congruential random number generator engine with
       * seed @p __s.  The default seed value is 1.
       *
       * @param __s The initial seed value.
       */
      explicit
      linear_congruential(unsigned long __x0 = 1)
      { this->seed(__x0); }

      /**
       * Constructs a %linear_congruential random number generator engine
       * seeded from the generator function @p __g.
       *
       * @param __g The seed generator function.
       */
      template<class _Gen>
        linear_congruential(_Gen& __g)
        { this->seed(__g); }

      /**
       * Reseeds the %linear_congruential random number generator engine
       * sequence to the seed @g __s.
       *
       * @param __s The new seed.
       */
      void
      seed(unsigned long __s = 1);

      /**
       * Reseeds the %linear_congruential random number generator engine
       * sequence using values from the generator function @p __g.
       *
       * @param __g the seed generator function.
       */
      template<class _Gen>
        void
        seed(_Gen& __g)
        { seed(__g, typename is_fundamental<_Gen>::type()); }

      /**
       * Gets the smallest possible value in the output range.
       *
       * The minimum depends on the @p __c parameter: if it is zero, the
       * minimum generated must be > 0, otherwise 0 is allowed.
       */
      result_type
      min() const
      { return (__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) ? 1 : 0; }

      /**
       * Gets the largest possible value in the output range.
       */
      result_type
      max() const
      { return __m - 1; }

      /**
       * Gets the next random number in the sequence.
       */
      result_type
      operator()();

      /**
       * Compares two linear congruential random number generator
       * objects of the same type for equality.
       *
       * @param __lhs A linear congruential random number generator object.
       * @param __rhs Another linear congruential random number generator obj.
       *
       * @returns true if the two objects are equal, false otherwise.
       */
      friend bool
      operator==(const linear_congruential& __lhs,
		 const linear_congruential& __rhs)
      { return __lhs._M_x == __rhs._M_x; }

      /**
       * Compares two linear congruential random number generator
       * objects of the same type for inequality.
       *
       * @param __lhs A linear congruential random number generator object.
       * @param __rhs Another linear congruential random number generator obj.
       *
       * @returns true if the two objects are not equal, false otherwise.
       */
      friend bool
      operator!=(const linear_congruential& __lhs,
		 const linear_congruential& __rhs)
      { return !(__lhs == __rhs); }

      /**
       * Writes the textual representation of the state x(i) of x to @p __os.
       *
       * @param __os  The output stream.
       * @param __lcr A % linear_congruential random number generator.
       * @returns __os.
       */
      template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
	       _UIntType1 __m1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const linear_congruential<_UIntType1, __a1, __c1,
		   __m1>& __lcr);

      /**
       * Sets the state of the engine by reading its textual
       * representation from @p __is.
       *
       * The textual representation must have been previously written using an
       * output stream whose imbued locale and whose type's template
       * specialization arguments _CharT and _Traits were the same as those of
       * @p __is.
       *
       * @param __is  The input stream.
       * @param __lcr A % linear_congruential random number generator.
       * @returns __is.
       */
      template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
	       _UIntType1 __m1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   linear_congruential<_UIntType1, __a1, __c1, __m1>& __lcr);

    private:
      template<class _Gen>
        void
        seed(_Gen& __g, true_type)
        { return seed(static_cast<unsigned long>(__g)); }

      template<class _Gen>
        void
        seed(_Gen& __g, false_type);

      _UIntType _M_x;
    };

  /**
   * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
   */
  typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0;

  /**
   * An alternative LCR (Lehmer Generator function) .
   */
  typedef linear_congruential<unsigned long, 48271, 0, 2147483647> minstd_rand;


  /**
   * A generalized feedback shift register discrete random number generator.
   *
   * This algorithm avoids multiplication and division and is designed to be
   * friendly to a pipelined architecture.  If the parameters are chosen
   * correctly, this generator will produce numbers with a very long period and
   * fairly good apparent entropy, although still not cryptographically strong.
   *
   * The best way to use this generator is with the predefined mt19937 class.
   *
   * This algorithm was originally invented by Makoto Matsumoto and
   * Takuji Nishimura.
   *
   * @var word_size   The number of bits in each element of the state vector.
   * @var state_size  The degree of recursion.
   * @var shift_size  The period parameter.
   * @var mask_bits   The separation point bit index.
   * @var parameter_a The last row of the twist matrix.
   * @var output_u    The first right-shift tempering matrix parameter.
   * @var output_s    The first left-shift tempering matrix parameter.
   * @var output_b    The first left-shift tempering matrix mask.
   * @var output_t    The second left-shift tempering matrix parameter.
   * @var output_c    The second left-shift tempering matrix mask.
   * @var output_l    The second right-shift tempering matrix parameter.
   */
  template<class _UIntType, int __w, int __n, int __m, int __r,
	   _UIntType __a, int __u, int __s, _UIntType __b, int __t,
	   _UIntType __c, int __l>
    class mersenne_twister
    {
      __glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)

    public:
      // types
      typedef _UIntType result_type;

      // parameter values
      static const int       word_size   = __w;
      static const int       state_size  = __n;
      static const int       shift_size  = __m;
      static const int       mask_bits   = __r;
      static const _UIntType parameter_a = __a;
      static const int       output_u    = __u;
      static const int       output_s    = __s;
      static const _UIntType output_b    = __b;
      static const int       output_t    = __t;
      static const _UIntType output_c    = __c;
      static const int       output_l    = __l;

      // constructors and member function
      mersenne_twister()
      { seed(); }

      explicit
      mersenne_twister(unsigned long __value)
      { seed(__value); }

      template<class _Gen>
        mersenne_twister(_Gen& __g)
        { seed(__g); }

      void
      seed()
      { seed(5489UL); }

      void
      seed(unsigned long __value);

      template<class _Gen>
        void
        seed(_Gen& __g)
        { seed(__g, typename is_fundamental<_Gen>::type()); }

      result_type
      min() const
      { return 0; }

      result_type
      max() const
      { return __detail::_Shift<_UIntType, __w>::__value - 1; }

      result_type
      operator()();

      /**
       * Compares two % mersenne_twister random number generator objects of
       * the same type for equality.
       *
       * @param __lhs A % mersenne_twister random number generator object.
       * @param __rhs Another % mersenne_twister random number generator
       *              object.
       *
       * @returns true if the two objects are equal, false otherwise.
       */
      friend bool
      operator==(const mersenne_twister& __lhs,
		 const mersenne_twister& __rhs)
      { return std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x); }

      /**
       * Compares two % mersenne_twister random number generator objects of
       * the same type for inequality.
       *
       * @param __lhs A % mersenne_twister random number generator object.
       * @param __rhs Another % mersenne_twister random number generator
       *              object.
       *
       * @returns true if the two objects are not equal, false otherwise.
       */
      friend bool
      operator!=(const mersenne_twister& __lhs,
		 const mersenne_twister& __rhs)
      { return !(__lhs == __rhs); }

      /**
       * Inserts the current state of a % mersenne_twister random number
       * generator engine @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A % mersenne_twister random number generator engine.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
	       _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
	       _UIntType1 __c1, int __l1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
		   __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);

      /**
       * Extracts the current state of a % mersenne_twister random number
       * generator engine @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A % mersenne_twister random number generator engine.
       *
       * @returns The input stream with the state of @p __x extracted or in
       * an error state.
       */
      template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
	       _UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
	       _UIntType1 __c1, int __l1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
		   __a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);

    private:
      template<class _Gen>
        void
        seed(_Gen& __g, true_type)
        { return seed(static_cast<unsigned long>(__g)); }

      template<class _Gen>
        void
        seed(_Gen& __g, false_type);

      _UIntType _M_x[state_size];
      int       _M_p;
    };

  /**
   * The classic Mersenne Twister.
   *
   * Reference:
   * M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally
   * Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions
   * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
   */
  typedef mersenne_twister<
    unsigned long, 32, 624, 397, 31,
    0x9908b0dful, 11, 7,
    0x9d2c5680ul, 15,
    0xefc60000ul, 18
    > mt19937;


  /**
   * @brief The Marsaglia-Zaman generator.
   *
   * This is a model of a Generalized Fibonacci discrete random number
   * generator, sometimes referred to as the SWC generator.
   *
   * A discrete random number generator that produces pseudorandom
   * numbers using @f$x_{i}\leftarrow(x_{i - s} - x_{i - r} -
   * carry_{i-1}) \bmod m @f$.
   *
   * The size of the state is @f$ r @f$
   * and the maximum period of the generator is @f$ m^r - m^s -1 @f$.
   *
   * N1688[4.13] says <em>the template parameter _IntType shall denote
   * an integral type large enough to store values up to m</em>.
   *
   * @var _M_x     The state of the generator.  This is a ring buffer.
   * @var _M_carry The carry.
   * @var _M_p     Current index of x(i - r).
   */
  template<typename _IntType, _IntType __m, int __s, int __r>
    class subtract_with_carry
    {
      __glibcxx_class_requires(_IntType, _IntegerConcept)

    public:
      /** The type of the generated random value. */
      typedef _IntType result_type;

      // parameter values
      static const _IntType modulus   = __m;
      static const int      long_lag  = __r;
      static const int      short_lag = __s;

      /**
       * Constructs a default-initialized % subtract_with_carry random number
       * generator.
       */
      subtract_with_carry()
      { this->seed(); }

      /**
       * Constructs an explicitly seeded % subtract_with_carry random number
       * generator.
       */
      explicit
      subtract_with_carry(unsigned long __value)
      { this->seed(__value); }

      /**
       * Constructs a %subtract_with_carry random number generator engine
       * seeded from the generator function @p __g.
       *
       * @param __g The seed generator function.
       */
      template<class _Gen>
        subtract_with_carry(_Gen& __g)
        { this->seed(__g); }

      /**
       * Seeds the initial state @f$ x_0 @f$ of the random number generator.
       *
       * N1688[4.19] modifies this as follows.  If @p __value == 0,
       * sets value to 19780503.  In any case, with a linear
       * congruential generator lcg(i) having parameters @f$ m_{lcg} =
       * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
       * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
       * \dots lcg(r) \bmod m @f$ respectively.  If @f$ x_{-1} = 0 @f$
       * set carry to 1, otherwise sets carry to 0.
       */
      void
      seed(unsigned long __value = 19780503);

      /**
       * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry
       * random number generator.
       */
      template<class _Gen>
        void
        seed(_Gen& __g)
        { seed(__g, typename is_fundamental<_Gen>::type()); }

      /**
       * Gets the inclusive minimum value of the range of random integers
       * returned by this generator.
       */
      result_type
      min() const
      { return 0; }

      /**
       * Gets the inclusive maximum value of the range of random integers
       * returned by this generator.
       */
      result_type
      max() const
      { return this->modulus - 1; }

      /**
       * Gets the next random number in the sequence.
       */
      result_type
      operator()();

      /**
       * Compares two % subtract_with_carry random number generator objects of
       * the same type for equality.
       *
       * @param __lhs A % subtract_with_carry random number generator object.
       * @param __rhs Another % subtract_with_carry random number generator
       *              object.
       *
       * @returns true if the two objects are equal, false otherwise.
       */
      friend bool
      operator==(const subtract_with_carry& __lhs,
		 const subtract_with_carry& __rhs)
      { return std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x); }

      /**
       * Compares two % subtract_with_carry random number generator objects of
       * the same type for inequality.
       *
       * @param __lhs A % subtract_with_carry random number generator object.
       * @param __rhs Another % subtract_with_carry random number generator
       *              object.
       *
       * @returns true if the two objects are not equal, false otherwise.
       */
      friend bool
      operator!=(const subtract_with_carry& __lhs,
		 const subtract_with_carry& __rhs)
      { return !(__lhs == __rhs); }

      /**
       * Inserts the current state of a % subtract_with_carry random number
       * generator engine @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A % subtract_with_carry random number generator engine.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const subtract_with_carry<_IntType1, __m1, __s1,
		   __r1>& __x);

      /**
       * Extracts the current state of a % subtract_with_carry random number
       * generator engine @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A % subtract_with_carry random number generator engine.
       *
       * @returns The input stream with the state of @p __x extracted or in
       * an error state.
       */
      template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   subtract_with_carry<_IntType1, __m1, __s1, __r1>& __x);

    private:
      template<class _Gen>
        void
        seed(_Gen& __g, true_type)
        { return seed(static_cast<unsigned long>(__g)); }

      template<class _Gen>
        void
        seed(_Gen& __g, false_type);

      typedef typename __gnu_cxx::__add_unsigned<_IntType>::__type _UIntType;

      _UIntType  _M_x[long_lag];
      _UIntType  _M_carry;
      int        _M_p;
    };


  /**
   * @brief The Marsaglia-Zaman generator (floats version).
   *
   * @var _M_x     The state of the generator.  This is a ring buffer.
   * @var _M_carry The carry.
   * @var _M_p     Current index of x(i - r).
   * @var _M_npows Precomputed negative powers of 2.
   */
  template<typename _RealType, int __w, int __s, int __r>
    class subtract_with_carry_01
    {
    public:
      /** The type of the generated random value. */
      typedef _RealType result_type;

      // parameter values
      static const int      word_size = __w;
      static const int      long_lag  = __r;
      static const int      short_lag = __s;

      /**
       * Constructs a default-initialized % subtract_with_carry_01 random
       * number generator.
       */
      subtract_with_carry_01()
      {
	this->seed();
	_M_initialize_npows();
      }

      /**
       * Constructs an explicitly seeded % subtract_with_carry_01 random number
       * generator.
       */
      explicit
      subtract_with_carry_01(unsigned long __value)
      {
	this->seed(__value);
	_M_initialize_npows();
      }

      /**
       * Constructs a % subtract_with_carry_01 random number generator engine
       * seeded from the generator function @p __g.
       *
       * @param __g The seed generator function.
       */
      template<class _Gen>
        subtract_with_carry_01(_Gen& __g)
        {
	  this->seed(__g);
	  _M_initialize_npows();
	}

      /**
       * Seeds the initial state @f$ x_0 @f$ of the random number generator.
       */
      void
      seed(unsigned long __value = 19780503);

      /**
       * Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry_01
       * random number generator.
       */
      template<class _Gen>
        void
        seed(_Gen& __g)
        { seed(__g, typename is_fundamental<_Gen>::type()); }

      /**
       * Gets the minimum value of the range of random floats
       * returned by this generator.
       */
      result_type
      min() const
      { return 0.0; }

      /**
       * Gets the maximum value of the range of random floats
       * returned by this generator.
       */
      result_type
      max() const
      { return 1.0; }

      /**
       * Gets the next random number in the sequence.
       */
      result_type
      operator()();

      /**
       * Compares two % subtract_with_carry_01 random number generator objects
       * of the same type for equality.
       *
       * @param __lhs A % subtract_with_carry_01 random number
       *              generator object.
       * @param __rhs Another % subtract_with_carry_01 random number generator
       *              object.
       *
       * @returns true if the two objects are equal, false otherwise.
       */
      friend bool
      operator==(const subtract_with_carry_01& __lhs,
		 const subtract_with_carry_01& __rhs)
      {
	for (int __i = 0; __i < long_lag; ++__i)
	  if (!std::equal(__lhs._M_x[__i], __lhs._M_x[__i] + __n,
			  __rhs._M_x[__i]))
	    return false;
	return true;
      }

      /**
       * Compares two % subtract_with_carry_01 random number generator objects
       * of the same type for inequality.
       *
       * @param __lhs A % subtract_with_carry_01 random number
       *              generator object.
       *
       * @param __rhs Another % subtract_with_carry_01 random number generator
       *              object.
       *
       * @returns true if the two objects are not equal, false otherwise.
       */
      friend bool
      operator!=(const subtract_with_carry_01& __lhs,
		 const subtract_with_carry_01& __rhs)
      { return !(__lhs == __rhs); }

      /**
       * Inserts the current state of a % subtract_with_carry_01 random number
       * generator engine @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A % subtract_with_carry_01 random number generator engine.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _RealType1, int __w1, int __s1, int __r1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const subtract_with_carry_01<_RealType1, __w1, __s1,
		   __r1>& __x);

      /**
       * Extracts the current state of a % subtract_with_carry_01 random number
       * generator engine @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A % subtract_with_carry_01 random number generator engine.
       *
       * @returns The input stream with the state of @p __x extracted or in
       * an error state.
       */
      template<typename _RealType1, int __w1, int __s1, int __r1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   subtract_with_carry_01<_RealType1, __w1, __s1, __r1>& __x);

    private:
      template<class _Gen>
        void
        seed(_Gen& __g, true_type)
        { return seed(static_cast<unsigned long>(__g)); }

      template<class _Gen>
        void
        seed(_Gen& __g, false_type);

      void
      _M_initialize_npows();

      static const int __n = (__w + 31) / 32;

      typedef __detail::_UInt32Type _UInt32Type;
      _UInt32Type  _M_x[long_lag][__n];
      _RealType    _M_npows[__n];
      _UInt32Type  _M_carry;
      int          _M_p;
    };

  typedef subtract_with_carry_01<float, 24, 10, 24>   ranlux_base_01;

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 508. Bad parameters for ranlux64_base_01.
  typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01;


  /**
   * Produces random numbers from some base engine by discarding blocks of
   * data.
   *
   * 0 <= @p __r <= @p __p
   */
  template<class _UniformRandomNumberGenerator, int __p, int __r>
    class discard_block
    {
      // __glibcxx_class_requires(typename base_type::result_type,
      //                          ArithmeticTypeConcept)

    public:
      /** The type of the underlying generator engine. */
      typedef _UniformRandomNumberGenerator   base_type;
      /** The type of the generated random value. */
      typedef typename base_type::result_type result_type;

      // parameter values
      static const int block_size = __p;
      static const int used_block = __r;

      /**
       * Constructs a default %discard_block engine.
       *
       * The underlying engine is default constructed as well.
       */
      discard_block()
      : _M_n(0) { }

      /**
       * Copy constructs a %discard_block engine.
       *
       * Copies an existing base class random number generator.
       * @param rng An existing (base class) engine object.
       */
      explicit
      discard_block(const base_type& __rng)
      : _M_b(__rng), _M_n(0) { }

      /**
       * Seed constructs a %discard_block engine.
       *
       * Constructs the underlying generator engine seeded with @p __s.
       * @param __s A seed value for the base class engine.
       */
      explicit
      discard_block(unsigned long __s)
      : _M_b(__s), _M_n(0) { }

      /**
       * Generator construct a %discard_block engine.
       *
       * @param __g A seed generator function.
       */
      template<class _Gen>
        discard_block(_Gen& __g)
	: _M_b(__g), _M_n(0) { }

      /**
       * Reseeds the %discard_block object with the default seed for the
       * underlying base class generator engine.
       */
      void seed()
      {
	_M_b.seed();
	_M_n = 0;
      }

      /**
       * Reseeds the %discard_block object with the given seed generator
       * function.
       * @param __g A seed generator function.
       */
      template<class _Gen>
        void seed(_Gen& __g)
        {
	  _M_b.seed(__g);
	  _M_n = 0;
	}

      /**
       * Gets a const reference to the underlying generator engine object.
       */
      const base_type&
      base() const
      { return _M_b; }

      /**
       * Gets the minimum value in the generated random number range.
       */
      result_type
      min() const
      { return _M_b.min(); }

      /**
       * Gets the maximum value in the generated random number range.
       */
      result_type
      max() const
      { return _M_b.max(); }

      /**
       * Gets the next value in the generated random number sequence.
       */
      result_type
      operator()();

      /**
       * Compares two %discard_block random number generator objects of
       * the same type for equality.
       *
       * @param __lhs A %discard_block random number generator object.
       * @param __rhs Another %discard_block random number generator
       *              object.
       *
       * @returns true if the two objects are equal, false otherwise.
       */
      friend bool
      operator==(const discard_block& __lhs, const discard_block& __rhs)
      { return (__lhs._M_b == __rhs._M_b) && (__lhs._M_n == __rhs._M_n); }

      /**
       * Compares two %discard_block random number generator objects of
       * the same type for inequality.
       *
       * @param __lhs A %discard_block random number generator object.
       * @param __rhs Another %discard_block random number generator
       *              object.
       *
       * @returns true if the two objects are not equal, false otherwise.
       */
      friend bool
      operator!=(const discard_block& __lhs, const discard_block& __rhs)
      { return !(__lhs == __rhs); }

      /**
       * Inserts the current state of a %discard_block random number
       * generator engine @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %discard_block random number generator engine.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const discard_block<_UniformRandomNumberGenerator1,
		   __p1, __r1>& __x);

      /**
       * Extracts the current state of a % subtract_with_carry random number
       * generator engine @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %discard_block random number generator engine.
       *
       * @returns The input stream with the state of @p __x extracted or in
       * an error state.
       */
      template<class _UniformRandomNumberGenerator1, int __p1, int __r1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   discard_block<_UniformRandomNumberGenerator1,
		   __p1, __r1>& __x);

    private:
      base_type _M_b;
      int       _M_n;
    };


  /**
   * James's luxury-level-3 integer adaptation of Luescher's generator.
   */
  typedef discard_block<
    subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
      223,
      24
      > ranlux3;

  /**
   * James's luxury-level-4 integer adaptation of Luescher's generator.
   */
  typedef discard_block<
    subtract_with_carry<unsigned long, (1UL << 24), 10, 24>,
      389,
      24
      > ranlux4;

  typedef discard_block<
    subtract_with_carry_01<float, 24, 10, 24>,
      223,
      24
      > ranlux3_01;

  typedef discard_block<
    subtract_with_carry_01<float, 24, 10, 24>,
      389,
      24
      > ranlux4_01;


  /**
   * A random number generator adaptor class that combines two random number
   * generator engines into a single output sequence.
   */
  template<class _UniformRandomNumberGenerator1, int __s1,
	   class _UniformRandomNumberGenerator2, int __s2>
    class xor_combine
    {
      // __glibcxx_class_requires(typename _UniformRandomNumberGenerator1::
      //                          result_type, ArithmeticTypeConcept)
      // __glibcxx_class_requires(typename _UniformRandomNumberGenerator2::
      //                          result_type, ArithmeticTypeConcept)

    public:
      /** The type of the first underlying generator engine. */
      typedef _UniformRandomNumberGenerator1   base1_type;
      /** The type of the second underlying generator engine. */
      typedef _UniformRandomNumberGenerator2   base2_type;

    private:
      typedef typename base1_type::result_type _Result_type1;
      typedef typename base2_type::result_type _Result_type2;

    public:
      /** The type of the generated random value. */
      typedef typename __gnu_cxx::__conditional_type<(sizeof(_Result_type1)
						      > sizeof(_Result_type2)),
	_Result_type1, _Result_type2>::__type result_type;

      // parameter values
      static const int shift1 = __s1;
      static const int shift2 = __s2;

      // constructors and member function
      xor_combine()
      : _M_b1(), _M_b2()
      { _M_initialize_max(); }

      xor_combine(const base1_type& __rng1, const base2_type& __rng2)
      : _M_b1(__rng1), _M_b2(__rng2)
      { _M_initialize_max(); }

      xor_combine(unsigned long __s)
      : _M_b1(__s), _M_b2(__s + 1)
      { _M_initialize_max(); }

      template<class _Gen>
        xor_combine(_Gen& __g)
	: _M_b1(__g), _M_b2(__g)
        { _M_initialize_max(); }

      void
      seed()
      {
	_M_b1.seed();
	_M_b2.seed();
      }

      template<class _Gen>
        void
        seed(_Gen& __g)
        {
	  _M_b1.seed(__g);
	  _M_b2.seed(__g);
	}

      const base1_type&
      base1() const
      { return _M_b1; }

      const base2_type&
      base2() const
      { return _M_b2; }

      result_type
      min() const
      { return 0; }

      result_type
      max() const
      { return _M_max; }

      /**
       * Gets the next random number in the sequence.
       */
      // NB: Not exactly the TR1 formula, per N2079 instead.
      result_type
      operator()()
      {
	return ((result_type(_M_b1() - _M_b1.min()) << shift1)
		^ (result_type(_M_b2() - _M_b2.min()) << shift2));
      }

      /**
       * Compares two %xor_combine random number generator objects of
       * the same type for equality.
       *
       * @param __lhs A %xor_combine random number generator object.
       * @param __rhs Another %xor_combine random number generator
       *              object.
       *
       * @returns true if the two objects are equal, false otherwise.
       */
      friend bool
      operator==(const xor_combine& __lhs, const xor_combine& __rhs)
      {
	return (__lhs.base1() == __rhs.base1())
	        && (__lhs.base2() == __rhs.base2());
      }

      /**
       * Compares two %xor_combine random number generator objects of
       * the same type for inequality.
       *
       * @param __lhs A %xor_combine random number generator object.
       * @param __rhs Another %xor_combine random number generator
       *              object.
       *
       * @returns true if the two objects are not equal, false otherwise.
       */
      friend bool
      operator!=(const xor_combine& __lhs, const xor_combine& __rhs)
      { return !(__lhs == __rhs); }

      /**
       * Inserts the current state of a %xor_combine random number
       * generator engine @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %xor_combine random number generator engine.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<class _UniformRandomNumberGenerator11, int __s11,
	       class _UniformRandomNumberGenerator21, int __s21,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const xor_combine<_UniformRandomNumberGenerator11, __s11,
		   _UniformRandomNumberGenerator21, __s21>& __x);

      /**
       * Extracts the current state of a %xor_combine random number
       * generator engine @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %xor_combine random number generator engine.
       *
       * @returns The input stream with the state of @p __x extracted or in
       * an error state.
       */
      template<class _UniformRandomNumberGenerator11, int __s11,
	       class _UniformRandomNumberGenerator21, int __s21,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   xor_combine<_UniformRandomNumberGenerator11, __s11,
		   _UniformRandomNumberGenerator21, __s21>& __x);

    private:
      void
      _M_initialize_max();

      result_type
      _M_initialize_max_aux(result_type, result_type, int);

      base1_type  _M_b1;
      base2_type  _M_b2;
      result_type _M_max;
    };


  /**
   * A standard interface to a platform-specific non-deterministic
   * random number generator (if any are available).
   */
  class random_device
  {
  public:
    // types
    typedef unsigned int result_type;

    // constructors, destructors and member functions

#ifdef _GLIBCXX_USE_RANDOM_TR1

    explicit
    random_device(const std::string& __token = "/dev/urandom")
    {
      if ((__token != "/dev/urandom" && __token != "/dev/random")
	  || !(_M_file = std::fopen(__token.c_str(), "rb")))
	std::__throw_runtime_error(__N("random_device::"
				       "random_device(const std::string&)"));
    }

    ~random_device()
    { std::fclose(_M_file); }

#else

    explicit
    random_device(const std::string& __token = "mt19937")
    : _M_mt(_M_strtoul(__token)) { }

  private:
    static unsigned long
    _M_strtoul(const std::string& __str)
    {
      unsigned long __ret = 5489UL;
      if (__str != "mt19937")
	{
	  const char* __nptr = __str.c_str();
	  char* __endptr;
	  __ret = std::strtoul(__nptr, &__endptr, 0);
	  if (*__nptr == '\0' || *__endptr != '\0')
	    std::__throw_runtime_error(__N("random_device::_M_strtoul"
					   "(const std::string&)"));
	}
      return __ret;
    }

  public:

#endif

    result_type
    min() const
    { return std::numeric_limits<result_type>::min(); }

    result_type
    max() const
    { return std::numeric_limits<result_type>::max(); }

    double
    entropy() const
    { return 0.0; }

    result_type
    operator()()
    {
#ifdef _GLIBCXX_USE_RANDOM_TR1
      result_type __ret;
      std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type),
		 1, _M_file);
      return __ret;
#else
      return _M_mt();
#endif
    }

  private:
    random_device(const random_device&);
    void operator=(const random_device&);

#ifdef _GLIBCXX_USE_RANDOM_TR1
    FILE*        _M_file;
#else
    mt19937      _M_mt;
#endif
  };

  /// @} group tr1_random_generators

  /**
   * @addtogroup tr1_random_distributions Random Number Distributions
   * @ingroup tr1_random
   * @{
   */

  /**
   * @addtogroup tr1_random_distributions_discrete Discrete Distributions
   * @ingroup tr1_random_distributions
   * @{
   */

  /**
   * @brief Uniform discrete distribution for random numbers.
   * A discrete random distribution on the range @f$[min, max]@f$ with equal
   * probability throughout the range.
   */
  template<typename _IntType = int>
    class uniform_int
    {
      __glibcxx_class_requires(_IntType, _IntegerConcept)

    public:
      /** The type of the parameters of the distribution. */
      typedef _IntType input_type;
      /** The type of the range of the distribution. */
      typedef _IntType result_type;

    public:
      /**
       * Constructs a uniform distribution object.
       */
      explicit
      uniform_int(_IntType __min = 0, _IntType __max = 9)
      : _M_min(__min), _M_max(__max)
      {
	_GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
      }

      /**
       * Gets the inclusive lower bound of the distribution range.
       */
      result_type
      min() const
      { return _M_min; }

      /**
       * Gets the inclusive upper bound of the distribution range.
       */
      result_type
      max() const
      { return _M_max; }

      /**
       * Resets the distribution state.
       *
       * Does nothing for the uniform integer distribution.
       */
      void
      reset() { }

      /**
       * Gets a uniformly distributed random number in the range
       * @f$(min, max)@f$.
       */
      template<typename _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng)
        {
	  typedef typename _UniformRandomNumberGenerator::result_type
	    _UResult_type;
	  return _M_call(__urng, _M_min, _M_max,
			 typename is_integral<_UResult_type>::type());
	}

      /**
       * Gets a uniform random number in the range @f$[0, n)@f$.
       *
       * This function is aimed at use with std::random_shuffle.
       */
      template<typename _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng, result_type __n)
        {
	  typedef typename _UniformRandomNumberGenerator::result_type
	    _UResult_type;
	  return _M_call(__urng, 0, __n - 1,
			 typename is_integral<_UResult_type>::type());
	}

      /**
       * Inserts a %uniform_int random number distribution @p __x into the
       * output stream @p os.
       *
       * @param __os An output stream.
       * @param __x  A %uniform_int random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _IntType1, typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const uniform_int<_IntType1>& __x);

      /**
       * Extracts a %uniform_int random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %uniform_int random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _IntType1, typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   uniform_int<_IntType1>& __x);

    private:
      template<typename _UniformRandomNumberGenerator>
        result_type
        _M_call(_UniformRandomNumberGenerator& __urng,
		result_type __min, result_type __max, true_type);

      template<typename _UniformRandomNumberGenerator>
        result_type
        _M_call(_UniformRandomNumberGenerator& __urng,
		result_type __min, result_type __max, false_type)
        {
	  return result_type((__urng() - __urng.min())
			     / (__urng.max() - __urng.min())
			     * (__max - __min + 1)) + __min;
	}

      _IntType _M_min;
      _IntType _M_max;
    };


  /**
   * @brief A Bernoulli random number distribution.
   *
   * Generates a sequence of true and false values with likelihood @f$ p @f$
   * that true will come up and @f$ (1 - p) @f$ that false will appear.
   */
  class bernoulli_distribution
  {
  public:
    typedef int  input_type;
    typedef bool result_type;

  public:
    /**
     * Constructs a Bernoulli distribution with likelihood @p p.
     *
     * @param __p  [IN]  The likelihood of a true result being returned.  Must
     * be in the interval @f$ [0, 1] @f$.
     */
    explicit
    bernoulli_distribution(double __p = 0.5)
    : _M_p(__p)
    {
      _GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
    }

    /**
     * Gets the @p p parameter of the distribution.
     */
    double
    p() const
    { return _M_p; }

    /**
     * Resets the distribution state.
     *
     * Does nothing for a Bernoulli distribution.
     */
    void
    reset() { }

    /**
     * Gets the next value in the Bernoullian sequence.
     */
    template<class _UniformRandomNumberGenerator>
      result_type
      operator()(_UniformRandomNumberGenerator& __urng)
      {
	if ((__urng() - __urng.min()) < _M_p * (__urng.max() - __urng.min()))
	  return true;
	return false;
      }

    /**
     * Inserts a %bernoulli_distribution random number distribution
     * @p __x into the output stream @p __os.
     *
     * @param __os An output stream.
     * @param __x  A %bernoulli_distribution random number distribution.
     *
     * @returns The output stream with the state of @p __x inserted or in
     * an error state.
     */
    template<typename _CharT, typename _Traits>
      friend std::basic_ostream<_CharT, _Traits>&
      operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		 const bernoulli_distribution& __x);

    /**
     * Extracts a %bernoulli_distribution random number distribution
     * @p __x from the input stream @p __is.
     *
     * @param __is An input stream.
     * @param __x  A %bernoulli_distribution random number generator engine.
     *
     * @returns The input stream with @p __x extracted or in an error state.
     */
    template<typename _CharT, typename _Traits>
      friend std::basic_istream<_CharT, _Traits>&
      operator>>(std::basic_istream<_CharT, _Traits>& __is,
		 bernoulli_distribution& __x)
      { return __is >> __x._M_p; }

  private:
    double _M_p;
  };


  /**
   * @brief A discrete geometric random number distribution.
   *
   * The formula for the geometric probability mass function is
   * @f$ p(i) = (1 - p)p^{i-1} @f$ where @f$ p @f$ is the parameter of the
   * distribution.
   */
  template<typename _IntType = int, typename _RealType = double>
    class geometric_distribution
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _IntType  result_type;

      // constructors and member function
      explicit
      geometric_distribution(const _RealType& __p = _RealType(0.5))
      : _M_p(__p)
      {
	_GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
	_M_initialize();
      }

      /**
       * Gets the distribution parameter @p p.
       */
      _RealType
      p() const
      { return _M_p; }

      void
      reset() { }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng);

      /**
       * Inserts a %geometric_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %geometric_distribution random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _IntType1, typename _RealType1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const geometric_distribution<_IntType1, _RealType1>& __x);

      /**
       * Extracts a %geometric_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %geometric_distribution random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   geometric_distribution& __x)
        {
	  __is >> __x._M_p;
	  __x._M_initialize();
	  return __is;
	}

    private:
      void
      _M_initialize()
      { _M_log_p = std::log(_M_p); }

      _RealType _M_p;
      _RealType _M_log_p;
    };


  template<typename _RealType>
    class normal_distribution;

  /**
   * @brief A discrete Poisson random number distribution.
   *
   * The formula for the Poisson probability mass function is
   * @f$ p(i) = \frac{mean^i}{i!} e^{-mean} @f$ where @f$ mean @f$ is the
   * parameter of the distribution.
   */
  template<typename _IntType = int, typename _RealType = double>
    class poisson_distribution
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _IntType  result_type;

      // constructors and member function
      explicit
      poisson_distribution(const _RealType& __mean = _RealType(1))
      : _M_mean(__mean), _M_nd()
      {
	_GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
	_M_initialize();
      }

      /**
       * Gets the distribution parameter @p mean.
       */
      _RealType
      mean() const
      { return _M_mean; }

      void
      reset()
      { _M_nd.reset(); }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng);

      /**
       * Inserts a %poisson_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %poisson_distribution random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _IntType1, typename _RealType1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const poisson_distribution<_IntType1, _RealType1>& __x);

      /**
       * Extracts a %poisson_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %poisson_distribution random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _IntType1, typename _RealType1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   poisson_distribution<_IntType1, _RealType1>& __x);

    private:
      void
      _M_initialize();

      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
      normal_distribution<_RealType> _M_nd;

      _RealType _M_mean;

      // Hosts either log(mean) or the threshold of the simple method.
      _RealType _M_lm_thr;
#if _GLIBCXX_USE_C99_MATH_TR1
      _RealType _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
#endif
    };


  /**
   * @brief A discrete binomial random number distribution.
   *
   * The formula for the binomial probability mass function is
   * @f$ p(i) = \binom{n}{i} p^i (1 - p)^{t - i} @f$ where @f$ t @f$
   * and @f$ p @f$ are the parameters of the distribution.
   */
  template<typename _IntType = int, typename _RealType = double>
    class binomial_distribution
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _IntType  result_type;

      // constructors and member function
      explicit
      binomial_distribution(_IntType __t = 1,
			    const _RealType& __p = _RealType(0.5))
      : _M_t(__t), _M_p(__p), _M_nd()
      {
	_GLIBCXX_DEBUG_ASSERT((_M_t >= 0) && (_M_p >= 0.0) && (_M_p <= 1.0));
	_M_initialize();
      }

      /**
       * Gets the distribution @p t parameter.
       */
      _IntType
      t() const
      { return _M_t; }

      /**
       * Gets the distribution @p p parameter.
       */
      _RealType
      p() const
      { return _M_p; }

      void
      reset()
      { _M_nd.reset(); }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng);

      /**
       * Inserts a %binomial_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %binomial_distribution random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _IntType1, typename _RealType1,
	       typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const binomial_distribution<_IntType1, _RealType1>& __x);

      /**
       * Extracts a %binomial_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %binomial_distribution random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _IntType1, typename _RealType1,
	       typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   binomial_distribution<_IntType1, _RealType1>& __x);

    private:
      void
      _M_initialize();

      template<class _UniformRandomNumberGenerator>
        result_type
        _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);

      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
      normal_distribution<_RealType> _M_nd;

      _RealType _M_q;
#if _GLIBCXX_USE_C99_MATH_TR1
      _RealType _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
	        _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
#endif
      _RealType _M_p;
      _IntType  _M_t;

      bool      _M_easy;
    };

  /// @} group tr1_random_distributions_discrete

  /**
   * @addtogroup tr1_random_distributions_continuous Continuous Distributions
   * @ingroup tr1_random_distributions
   * @{
   */

  /**
   * @brief Uniform continuous distribution for random numbers.
   *
   * A continuous random distribution on the range [min, max) with equal
   * probability throughout the range.  The URNG should be real-valued and
   * deliver number in the range [0, 1).
   */
  template<typename _RealType = double>
    class uniform_real
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _RealType result_type;

    public:
      /**
       * Constructs a uniform_real object.
       *
       * @param __min [IN]  The lower bound of the distribution.
       * @param __max [IN]  The upper bound of the distribution.
       */
      explicit
      uniform_real(_RealType __min = _RealType(0),
		   _RealType __max = _RealType(1))
      : _M_min(__min), _M_max(__max)
      {
	_GLIBCXX_DEBUG_ASSERT(_M_min <= _M_max);
      }

      result_type
      min() const
      { return _M_min; }

      result_type
      max() const
      { return _M_max; }

      void
      reset() { }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng)
        { return (__urng() * (_M_max - _M_min)) + _M_min; }

      /**
       * Inserts a %uniform_real random number distribution @p __x into the
       * output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %uniform_real random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _RealType1, typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const uniform_real<_RealType1>& __x);

      /**
       * Extracts a %uniform_real random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %uniform_real random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _RealType1, typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   uniform_real<_RealType1>& __x);

    private:
      _RealType _M_min;
      _RealType _M_max;
    };


  /**
   * @brief An exponential continuous distribution for random numbers.
   *
   * The formula for the exponential probability mass function is
   * @f$ p(x) = \lambda e^{-\lambda x} @f$.
   *
   * <table border=1 cellpadding=10 cellspacing=0>
   * <caption align=top>Distribution Statistics</caption>
   * <tr><td>Mean</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
   * <tr><td>Median</td><td>@f$ \frac{\ln 2}{\lambda} @f$</td></tr>
   * <tr><td>Mode</td><td>@f$ zero @f$</td></tr>
   * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
   * <tr><td>Standard Deviation</td><td>@f$ \frac{1}{\lambda} @f$</td></tr>
   * </table>
   */
  template<typename _RealType = double>
    class exponential_distribution
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _RealType result_type;

    public:
      /**
       * Constructs an exponential distribution with inverse scale parameter
       * @f$ \lambda @f$.
       */
      explicit
      exponential_distribution(const result_type& __lambda = result_type(1))
      : _M_lambda(__lambda)
      {
	_GLIBCXX_DEBUG_ASSERT(_M_lambda > 0);
      }

      /**
       * Gets the inverse scale parameter of the distribution.
       */
      _RealType
      lambda() const
      { return _M_lambda; }

      /**
       * Resets the distribution.
       *
       * Has no effect on exponential distributions.
       */
      void
      reset() { }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng)
        { return -std::log(__urng()) / _M_lambda; }

      /**
       * Inserts a %exponential_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %exponential_distribution random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _RealType1, typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const exponential_distribution<_RealType1>& __x);

      /**
       * Extracts a %exponential_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x A %exponential_distribution random number
       *            generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   exponential_distribution& __x)
        { return __is >> __x._M_lambda; }

    private:
      result_type _M_lambda;
    };


  /**
   * @brief A normal continuous distribution for random numbers.
   *
   * The formula for the normal probability mass function is
   * @f$ p(x) = \frac{1}{\sigma \sqrt{2 \pi}}
   *            e^{- \frac{{x - mean}^ {2}}{2 \sigma ^ {2}} } @f$.
   */
  template<typename _RealType = double>
    class normal_distribution
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _RealType result_type;

    public:
      /**
       * Constructs a normal distribution with parameters @f$ mean @f$ and
       * @f$ \sigma @f$.
       */
      explicit
      normal_distribution(const result_type& __mean = result_type(0),
			  const result_type& __sigma = result_type(1))
      : _M_mean(__mean), _M_sigma(__sigma), _M_saved_available(false)
      {
	_GLIBCXX_DEBUG_ASSERT(_M_sigma > 0);
      }

      /**
       * Gets the mean of the distribution.
       */
      _RealType
      mean() const
      { return _M_mean; }

      /**
       * Gets the @f$ \sigma @f$ of the distribution.
       */
      _RealType
      sigma() const
      { return _M_sigma; }

      /**
       * Resets the distribution.
       */
      void
      reset()
      { _M_saved_available = false; }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng);

      /**
       * Inserts a %normal_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %normal_distribution random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _RealType1, typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const normal_distribution<_RealType1>& __x);

      /**
       * Extracts a %normal_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %normal_distribution random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _RealType1, typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   normal_distribution<_RealType1>& __x);

    private:
      result_type _M_mean;
      result_type _M_sigma;
      result_type _M_saved;
      bool        _M_saved_available;
    };


  /**
   * @brief A gamma continuous distribution for random numbers.
   *
   * The formula for the gamma probability mass function is
   * @f$ p(x) = \frac{1}{\Gamma(\alpha)} x^{\alpha - 1} e^{-x} @f$.
   */
  template<typename _RealType = double>
    class gamma_distribution
    {
    public:
      // types
      typedef _RealType input_type;
      typedef _RealType result_type;

    public:
      /**
       * Constructs a gamma distribution with parameters @f$ \alpha @f$.
       */
      explicit
      gamma_distribution(const result_type& __alpha_val = result_type(1))
      : _M_alpha(__alpha_val)
      {
	_GLIBCXX_DEBUG_ASSERT(_M_alpha > 0);
	_M_initialize();
      }

      /**
       * Gets the @f$ \alpha @f$ of the distribution.
       */
      _RealType
      alpha() const
      { return _M_alpha; }

      /**
       * Resets the distribution.
       */
      void
      reset() { }

      template<class _UniformRandomNumberGenerator>
        result_type
        operator()(_UniformRandomNumberGenerator& __urng);

      /**
       * Inserts a %gamma_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %gamma_distribution random number distribution.
       *
       * @returns The output stream with the state of @p __x inserted or in
       * an error state.
       */
      template<typename _RealType1, typename _CharT, typename _Traits>
        friend std::basic_ostream<_CharT, _Traits>&
        operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const gamma_distribution<_RealType1>& __x);

      /**
       * Extracts a %gamma_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %gamma_distribution random number generator engine.
       *
       * @returns The input stream with @p __x extracted or in an error state.
       */
      template<typename _CharT, typename _Traits>
        friend std::basic_istream<_CharT, _Traits>&
        operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   gamma_distribution& __x)
        {
	  __is >> __x._M_alpha;
	  __x._M_initialize();
	  return __is;
	}

    private:
      void
      _M_initialize();

      result_type _M_alpha;

      // Hosts either lambda of GB or d of modified Vaduva's.
      result_type _M_l_d;
    };

  /// @} group tr1_random_distributions_continuous
  /// @} group tr1_random_distributions
  /// @} group tr1_random
}

_GLIBCXX_END_NAMESPACE_VERSION
}

#endif // _GLIBCXX_TR1_RANDOM_H
