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

// Copyright (C) 2009, 2010 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.
 *  You should not attempt to use it directly.
 */

#ifndef _GLIBCXX_TR1_RANDOM_H
#define _GLIBCXX_TR1_RANDOM_H 1

#pragma GCC system_header

namespace std
{
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 remove_reference<_Engine>::type _BEngine;
	typedef typename _BEngine::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;
	}

      private:
	_Engine _M_g;
      };

    // Specialization for _Engine*.
    template<typename _Engine, typename _Distribution>
      struct _Adaptor<_Engine*, _Distribution>
      {
	typedef typename _Engine::result_type      _Engine_result_type;
	typedef typename _Distribution::input_type result_type;

      public:
	_Adaptor(_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;
	}

	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;
	}

      private:
	_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
    {
      // Concept requirements.
      __glibcxx_class_requires(_Engine, _CopyConstructibleConcept)
      //  __glibcxx_class_requires(_Engine, _EngineConcept)
      //  __glibcxx_class_requires(_Dist, _EngineConcept)

    public:
      typedef _Engine                                engine_type;
      typedef __detail::_Adaptor<_Engine, _Dist>     engine_value_type;
      typedef _Dist                                  distribution_type;
      typedef typename _Dist::result_type            result_type;

      // 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(__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; }

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

      /**
       * 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:
      engine_value_type _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
}
}

#endif // _GLIBCXX_TR1_RANDOM_H
