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

// Copyright (C) 2009-2014 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

#pragma GCC system_header

namespace std _GLIBCXX_VISIBILITY(default)
{
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
  {
  _GLIBCXX_BEGIN_NAMESPACE_VERSION

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

  _GLIBCXX_END_NAMESPACE_VERSION
  } // namespace __detail

_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   * 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
_GLIBCXX_END_NAMESPACE_VERSION
}
}

#endif // _GLIBCXX_TR1_RANDOM_H
