// 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 bits/random.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{random}
 */

#ifndef _RANDOM_H
#define _RANDOM_H 1

#include <vector>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  // [26.4] Random number generation

  /**
   * @defgroup random Random Number Generation
   * @ingroup numerics
   *
   * A facility for generating random numbers on selected distributions.
   * @{
   */

  /**
   * @brief A function template for converting the output of a (integral)
   * uniform random number generator to a floatng point result in the range
   * [0-1).
   */
  template<typename _RealType, size_t __bits,
	   typename _UniformRandomNumberGenerator>
    _RealType
    generate_canonical(_UniformRandomNumberGenerator& __g);

_GLIBCXX_END_NAMESPACE_VERSION

  /*
   * Implementation-space details.
   */
  namespace __detail
  {
  _GLIBCXX_BEGIN_NAMESPACE_VERSION

    template<typename _UIntType, size_t __w,
	     bool = __w < static_cast<size_t>
			  (std::numeric_limits<_UIntType>::digits)>
      struct _Shift
      { static const _UIntType __value = 0; };

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

    template<int __s,
	     int __which = ((__s <= __CHAR_BIT__ * sizeof (int))
			    + (__s <= __CHAR_BIT__ * sizeof (long))
			    + (__s <= __CHAR_BIT__ * sizeof (long long))
			    /* assume long long no bigger than __int128 */
			    + (__s <= 128))>
      struct _Select_uint_least_t
      {
	static_assert(__which < 0, /* needs to be dependent */
		      "sorry, would be too much trouble for a slow result");
      };

    template<int __s>
      struct _Select_uint_least_t<__s, 4>
      { typedef unsigned int type; };

    template<int __s>
      struct _Select_uint_least_t<__s, 3>
      { typedef unsigned long type; };

    template<int __s>
      struct _Select_uint_least_t<__s, 2>
      { typedef unsigned long long type; };

#ifdef _GLIBCXX_USE_INT128
    template<int __s>
      struct _Select_uint_least_t<__s, 1>
      { typedef unsigned __int128 type; };
#endif

    // Assume a != 0, a < m, c < m, x < m.
    template<typename _Tp, _Tp __m, _Tp __a, _Tp __c,
	     bool __big_enough = (!(__m & (__m - 1))
				  || (_Tp(-1) - __c) / __a >= __m - 1),
             bool __schrage_ok = __m % __a < __m / __a>
      struct _Mod
      {
	typedef typename _Select_uint_least_t<std::__lg(__a)
					      + std::__lg(__m) + 2>::type _Tp2;
	static _Tp
	__calc(_Tp __x)
	{ return static_cast<_Tp>((_Tp2(__a) * __x + __c) % __m); }
      };

    // Schrage.
    template<typename _Tp, _Tp __m, _Tp __a, _Tp __c>
      struct _Mod<_Tp, __m, __a, __c, false, true>
      {
	static _Tp
	__calc(_Tp __x);
      };

    // Special cases:
    // - for m == 2^n or m == 0, unsigned integer overflow is safe.
    // - a * (m - 1) + c fits in _Tp, there is no overflow.
    template<typename _Tp, _Tp __m, _Tp __a, _Tp __c, bool __s>
      struct _Mod<_Tp, __m, __a, __c, true, __s>
      {
	static _Tp
	__calc(_Tp __x)
	{
	  _Tp __res = __a * __x + __c;
	  if (__m)
	    __res %= __m;
	  return __res;
	}
      };

    template<typename _Tp, _Tp __m, _Tp __a = 1, _Tp __c = 0>
      inline _Tp
      __mod(_Tp __x)
      { return _Mod<_Tp, __m, __a, __c>::__calc(__x); }

    /* Determine whether number is a power of 2.  */
    template<typename _Tp>
      inline bool
      _Power_of_2(_Tp __x)
      {
	return ((__x - 1) & __x) == 0;
      };

    /*
     * An adaptor class for converting the output of any Generator into
     * the input for a specific Distribution.
     */
    template<typename _Engine, typename _DInputType>
      struct _Adaptor
      {

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

	_DInputType
	min() const
	{ return _DInputType(0); }

	_DInputType
	max() const
	{ return _DInputType(1); }

	/*
	 * Converts a value generated by the adapted random number generator
	 * into a value in the input domain for the dependent random number
	 * distribution.
	 */
	_DInputType
	operator()()
	{
	  return std::generate_canonical<_DInputType,
	                            std::numeric_limits<_DInputType>::digits,
	                            _Engine>(_M_g);
	}

      private:
	_Engine& _M_g;
      };

  _GLIBCXX_END_NAMESPACE_VERSION
  } // namespace __detail

_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   * @addtogroup random_generators Random Number Generators
   * @ingroup 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 via
   * 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<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
    class linear_congruential_engine
    {
      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
		    "substituting _UIntType not an unsigned integral type");
      static_assert(__m == 0u || (__a < __m && __c < __m),
		    "template argument substituting __m out of bounds");

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

      /** The multiplier. */
      static constexpr result_type multiplier   = __a;
      /** An increment. */
      static constexpr result_type increment    = __c;
      /** The modulus. */
      static constexpr result_type modulus      = __m;
      static constexpr result_type default_seed = 1u;

      /**
       * @brief Constructs a %linear_congruential_engine random number
       *        generator engine with seed @p __s.  The default seed value
       *        is 1.
       *
       * @param __s The initial seed value.
       */
      explicit
      linear_congruential_engine(result_type __s = default_seed)
      { seed(__s); }

      /**
       * @brief Constructs a %linear_congruential_engine random number
       *        generator engine seeded from the seed sequence @p __q.
       *
       * @param __q the seed sequence.
       */
      template<typename _Sseq, typename = typename
	std::enable_if<!std::is_same<_Sseq, linear_congruential_engine>::value>
	       ::type>
        explicit
        linear_congruential_engine(_Sseq& __q)
        { seed(__q); }

      /**
       * @brief Reseeds the %linear_congruential_engine random number generator
       *        engine sequence to the seed @p __s.
       *
       * @param __s The new seed.
       */
      void
      seed(result_type __s = default_seed);

      /**
       * @brief Reseeds the %linear_congruential_engine random number generator
       *        engine
       * sequence using values from the seed sequence @p __q.
       *
       * @param __q the seed sequence.
       */
      template<typename _Sseq>
        typename std::enable_if<std::is_class<_Sseq>::value>::type
        seed(_Sseq& __q);

      /**
       * @brief 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.
       */
      static constexpr result_type
      min()
      { return __c == 0u ? 1u : 0u; }

      /**
       * @brief Gets the largest possible value in the output range.
       */
      static constexpr result_type
      max()
      { return __m - 1u; }

      /**
       * @brief Discard a sequence of random numbers.
       */
      void
      discard(unsigned long long __z)
      {
	for (; __z != 0ULL; --__z)
	  (*this)();
      }

      /**
       * @brief Gets the next random number in the sequence.
       */
      result_type
      operator()()
      {
	_M_x = __detail::__mod<_UIntType, __m, __a, __c>(_M_x);
	return _M_x;
      }

      /**
       * @brief 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
       *              object.
       *
       * @returns true if the infinite sequences of generated values
       *          would be equal, false otherwise.
       */
      friend bool
      operator==(const linear_congruential_engine& __lhs,
		 const linear_congruential_engine& __rhs)
      { return __lhs._M_x == __rhs._M_x; }

      /**
       * @brief Writes the textual representation of the state x(i) of x to
       *        @p __os.
       *
       * @param __os  The output stream.
       * @param __lcr A % linear_congruential_engine random number generator.
       * @returns __os.
       */
      template<typename _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 std::linear_congruential_engine<_UIntType1,
		   __a1, __c1, __m1>& __lcr);

      /**
       * @brief 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_engine random number generator.
       * @returns __is.
       */
      template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
	       _UIntType1 __m1, typename _CharT, typename _Traits>
	friend std::basic_istream<_CharT, _Traits>&
	operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   std::linear_congruential_engine<_UIntType1, __a1,
		   __c1, __m1>& __lcr);

    private:
      _UIntType _M_x;
    };

  /**
   * @brief 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
   *              object.
   *
   * @returns true if the infinite sequences of generated values
   *          would be different, false otherwise.
   */
  template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
    inline bool
    operator!=(const std::linear_congruential_engine<_UIntType, __a,
	       __c, __m>& __lhs,
	       const std::linear_congruential_engine<_UIntType, __a,
	       __c, __m>& __rhs)
    { return !(__lhs == __rhs); }


  /**
   * 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.
   *
   * @tparam __w  Word size, the number of bits in each element of 
   *              the state vector.
   * @tparam __n  The degree of recursion.
   * @tparam __m  The period parameter.
   * @tparam __r  The separation point bit index.
   * @tparam __a  The last row of the twist matrix.
   * @tparam __u  The first right-shift tempering matrix parameter.
   * @tparam __d  The first right-shift tempering matrix mask.
   * @tparam __s  The first left-shift tempering matrix parameter.
   * @tparam __b  The first left-shift tempering matrix mask.
   * @tparam __t  The second left-shift tempering matrix parameter.
   * @tparam __c  The second left-shift tempering matrix mask.
   * @tparam __l  The second right-shift tempering matrix parameter.
   * @tparam __f  Initialization multiplier.
   */
  template<typename _UIntType, size_t __w,
	   size_t __n, size_t __m, size_t __r,
	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
	   _UIntType __b, size_t __t,
	   _UIntType __c, size_t __l, _UIntType __f>
    class mersenne_twister_engine
    {
      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
		    "substituting _UIntType not an unsigned integral type");
      static_assert(1u <= __m && __m <= __n,
		    "template argument substituting __m out of bounds");
      static_assert(__r <= __w, "template argument substituting "
		    "__r out of bound");
      static_assert(__u <= __w, "template argument substituting "
		    "__u out of bound");
      static_assert(__s <= __w, "template argument substituting "
		    "__s out of bound");
      static_assert(__t <= __w, "template argument substituting "
		    "__t out of bound");
      static_assert(__l <= __w, "template argument substituting "
		    "__l out of bound");
      static_assert(__w <= std::numeric_limits<_UIntType>::digits,
		    "template argument substituting __w out of bound");
      static_assert(__a <= (__detail::_Shift<_UIntType, __w>::__value - 1),
		    "template argument substituting __a out of bound");
      static_assert(__b <= (__detail::_Shift<_UIntType, __w>::__value - 1),
		    "template argument substituting __b out of bound");
      static_assert(__c <= (__detail::_Shift<_UIntType, __w>::__value - 1),
		    "template argument substituting __c out of bound");
      static_assert(__d <= (__detail::_Shift<_UIntType, __w>::__value - 1),
		    "template argument substituting __d out of bound");
      static_assert(__f <= (__detail::_Shift<_UIntType, __w>::__value - 1),
		    "template argument substituting __f out of bound");

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

      // parameter values
      static constexpr size_t      word_size                 = __w;
      static constexpr size_t      state_size                = __n;
      static constexpr size_t      shift_size                = __m;
      static constexpr size_t      mask_bits                 = __r;
      static constexpr result_type xor_mask                  = __a;
      static constexpr size_t      tempering_u               = __u;
      static constexpr result_type tempering_d               = __d;
      static constexpr size_t      tempering_s               = __s;
      static constexpr result_type tempering_b               = __b;
      static constexpr size_t      tempering_t               = __t;
      static constexpr result_type tempering_c               = __c;
      static constexpr size_t      tempering_l               = __l;
      static constexpr result_type initialization_multiplier = __f;
      static constexpr result_type default_seed = 5489u;

      // constructors and member function
      explicit
      mersenne_twister_engine(result_type __sd = default_seed)
      { seed(__sd); }

      /**
       * @brief Constructs a %mersenne_twister_engine random number generator
       *        engine seeded from the seed sequence @p __q.
       *
       * @param __q the seed sequence.
       */
      template<typename _Sseq, typename = typename
        std::enable_if<!std::is_same<_Sseq, mersenne_twister_engine>::value>
	       ::type>
        explicit
        mersenne_twister_engine(_Sseq& __q)
        { seed(__q); }

      void
      seed(result_type __sd = default_seed);

      template<typename _Sseq>
	typename std::enable_if<std::is_class<_Sseq>::value>::type
        seed(_Sseq& __q);

      /**
       * @brief Gets the smallest possible value in the output range.
       */
      static constexpr result_type
      min()
      { return 0; };

      /**
       * @brief Gets the largest possible value in the output range.
       */
      static constexpr result_type
      max()
      { return __detail::_Shift<_UIntType, __w>::__value - 1; }

      /**
       * @brief Discard a sequence of random numbers.
       */
      void
      discard(unsigned long long __z);

      result_type
      operator()();

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

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

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

    private:
      void _M_gen_rand();

      _UIntType _M_x[state_size];
      size_t    _M_p;
    };

  /**
   * @brief Compares two % mersenne_twister_engine random number generator
   *        objects of the same type for inequality.
   *
   * @param __lhs A % mersenne_twister_engine random number generator
   *              object.
   * @param __rhs Another % mersenne_twister_engine random number
   *              generator object.
   *
   * @returns true if the infinite sequences of generated values
   *          would be different, false otherwise.
   */
  template<typename _UIntType, size_t __w,
	   size_t __n, size_t __m, size_t __r,
	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
	   _UIntType __b, size_t __t,
	   _UIntType __c, size_t __l, _UIntType __f>
    inline bool
    operator!=(const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
	       __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __lhs,
	       const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
	       __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __rhs)
    { return !(__lhs == __rhs); }


  /**
   * @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$.
   *
   * @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 _UIntType, size_t __w, size_t __s, size_t __r>
    class subtract_with_carry_engine
    {
      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
		    "substituting _UIntType not an unsigned integral type");
      static_assert(0u < __s && __s < __r,
		    "template argument substituting __s out of bounds");
      static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
		    "template argument substituting __w out of bounds");

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

      // parameter values
      static constexpr size_t      word_size    = __w;
      static constexpr size_t      short_lag    = __s;
      static constexpr size_t      long_lag     = __r;
      static constexpr result_type default_seed = 19780503u;

      /**
       * @brief Constructs an explicitly seeded % subtract_with_carry_engine
       *        random number generator.
       */
      explicit
      subtract_with_carry_engine(result_type __sd = default_seed)
      { seed(__sd); }

      /**
       * @brief Constructs a %subtract_with_carry_engine random number engine
       *        seeded from the seed sequence @p __q.
       *
       * @param __q the seed sequence.
       */
      template<typename _Sseq, typename = typename
        std::enable_if<!std::is_same<_Sseq, subtract_with_carry_engine>::value>
	       ::type>
        explicit
        subtract_with_carry_engine(_Sseq& __q)
        { seed(__q); }

      /**
       * @brief 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(result_type __sd = default_seed);

      /**
       * @brief Seeds the initial state @f$x_0@f$ of the
       * % subtract_with_carry_engine random number generator.
       */
      template<typename _Sseq>
	typename std::enable_if<std::is_class<_Sseq>::value>::type
        seed(_Sseq& __q);

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

      /**
       * @brief Gets the inclusive maximum value of the range of random
       * integers returned by this generator.
       */
      static constexpr result_type
      max()
      { return __detail::_Shift<_UIntType, __w>::__value - 1; }

      /**
       * @brief Discard a sequence of random numbers.
       */
      void
      discard(unsigned long long __z)
      {
	for (; __z != 0ULL; --__z)
	  (*this)();
      }

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

      /**
       * @brief Compares two % subtract_with_carry_engine random number
       *        generator objects of the same type for equality.
       *
       * @param __lhs A % subtract_with_carry_engine random number generator
       *              object.
       * @param __rhs Another % subtract_with_carry_engine random number
       *              generator object.
       *
       * @returns true if the infinite sequences of generated values
       *          would be equal, false otherwise.
      */
      friend bool
      operator==(const subtract_with_carry_engine& __lhs,
		 const subtract_with_carry_engine& __rhs)
      { return (std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x)
		&& __lhs._M_carry == __rhs._M_carry
		&& __lhs._M_p == __rhs._M_p); }

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

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

    private:
      _UIntType  _M_x[long_lag];
      _UIntType  _M_carry;
      size_t     _M_p;
    };

  /**
   * @brief Compares two % subtract_with_carry_engine random number
   *        generator objects of the same type for inequality.
   *
   * @param __lhs A % subtract_with_carry_engine random number generator
   *              object.
   * @param __rhs Another % subtract_with_carry_engine random number
   *              generator object.
   *
   * @returns true if the infinite sequences of generated values
   *          would be different, false otherwise.
   */
  template<typename _UIntType, size_t __w, size_t __s, size_t __r>
    inline bool
    operator!=(const std::subtract_with_carry_engine<_UIntType, __w,
	       __s, __r>& __lhs,
	       const std::subtract_with_carry_engine<_UIntType, __w,
	       __s, __r>& __rhs)
    { return !(__lhs == __rhs); }


  /**
   * Produces random numbers from some base engine by discarding blocks of
   * data.
   *
   * 0 <= @p __r <= @p __p
   */
  template<typename _RandomNumberEngine, size_t __p, size_t __r>
    class discard_block_engine
    {
      static_assert(1 <= __r && __r <= __p,
		    "template argument substituting __r out of bounds");

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

      // parameter values
      static constexpr size_t block_size = __p;
      static constexpr size_t used_block = __r;

      /**
       * @brief Constructs a default %discard_block_engine engine.
       *
       * The underlying engine is default constructed as well.
       */
      discard_block_engine()
      : _M_b(), _M_n(0) { }

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

      /**
       * @brief Move constructs a %discard_block_engine engine.
       *
       * Copies an existing base class random number generator.
       * @param __rng An existing (base class) engine object.
       */
      explicit
      discard_block_engine(_RandomNumberEngine&& __rng)
      : _M_b(std::move(__rng)), _M_n(0) { }

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

      /**
       * @brief Generator construct a %discard_block_engine engine.
       *
       * @param __q A seed sequence.
       */
      template<typename _Sseq, typename = typename
	std::enable_if<!std::is_same<_Sseq, discard_block_engine>::value
		       && !std::is_same<_Sseq, _RandomNumberEngine>::value>
	       ::type>
        explicit
        discard_block_engine(_Sseq& __q)
	: _M_b(__q), _M_n(0)
        { }

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

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

      /**
       * @brief Reseeds the %discard_block_engine object with the given seed
       *        sequence.
       * @param __q A seed generator function.
       */
      template<typename _Sseq>
        void
        seed(_Sseq& __q)
        {
	  _M_b.seed(__q);
	  _M_n = 0;
	}

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

      /**
       * @brief Gets the minimum value in the generated random number range.
       */
      static constexpr result_type
      min()
      { return _RandomNumberEngine::min(); }

      /**
       * @brief Gets the maximum value in the generated random number range.
       */
      static constexpr result_type
      max()
      { return _RandomNumberEngine::max(); }

      /**
       * @brief Discard a sequence of random numbers.
       */
      void
      discard(unsigned long long __z)
      {
	for (; __z != 0ULL; --__z)
	  (*this)();
      }

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

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

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

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

    private:
      _RandomNumberEngine _M_b;
      size_t _M_n;
    };

  /**
   * @brief Compares two %discard_block_engine random number generator
   *        objects of the same type for inequality.
   *
   * @param __lhs A %discard_block_engine random number generator object.
   * @param __rhs Another %discard_block_engine random number generator
   *              object.
   *
   * @returns true if the infinite sequences of generated values
   *          would be different, false otherwise.
   */
  template<typename _RandomNumberEngine, size_t __p, size_t __r>
    inline bool
    operator!=(const std::discard_block_engine<_RandomNumberEngine, __p,
	       __r>& __lhs,
	       const std::discard_block_engine<_RandomNumberEngine, __p,
	       __r>& __rhs)
    { return !(__lhs == __rhs); }


  /**
   * Produces random numbers by combining random numbers from some base
   * engine to produce random numbers with a specifies number of bits @p __w.
   */
  template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
    class independent_bits_engine
    {
      static_assert(std::is_unsigned<_UIntType>::value, "template argument "
		    "substituting _UIntType not an unsigned integral type");
      static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
		    "template argument substituting __w out of bounds");

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

      /**
       * @brief Constructs a default %independent_bits_engine engine.
       *
       * The underlying engine is default constructed as well.
       */
      independent_bits_engine()
      : _M_b() { }

      /**
       * @brief Copy constructs a %independent_bits_engine engine.
       *
       * Copies an existing base class random number generator.
       * @param __rng An existing (base class) engine object.
       */
      explicit
      independent_bits_engine(const _RandomNumberEngine& __rng)
      : _M_b(__rng) { }

      /**
       * @brief Move constructs a %independent_bits_engine engine.
       *
       * Copies an existing base class random number generator.
       * @param __rng An existing (base class) engine object.
       */
      explicit
      independent_bits_engine(_RandomNumberEngine&& __rng)
      : _M_b(std::move(__rng)) { }

      /**
       * @brief Seed constructs a %independent_bits_engine engine.
       *
       * Constructs the underlying generator engine seeded with @p __s.
       * @param __s A seed value for the base class engine.
       */
      explicit
      independent_bits_engine(result_type __s)
      : _M_b(__s) { }

      /**
       * @brief Generator construct a %independent_bits_engine engine.
       *
       * @param __q A seed sequence.
       */
      template<typename _Sseq, typename = typename
	std::enable_if<!std::is_same<_Sseq, independent_bits_engine>::value
		       && !std::is_same<_Sseq, _RandomNumberEngine>::value>
               ::type>
        explicit
        independent_bits_engine(_Sseq& __q)
        : _M_b(__q)
        { }

      /**
       * @brief Reseeds the %independent_bits_engine object with the default
       *        seed for the underlying base class generator engine.
       */
      void
      seed()
      { _M_b.seed(); }

      /**
       * @brief Reseeds the %independent_bits_engine object with the default
       *        seed for the underlying base class generator engine.
       */
      void
      seed(result_type __s)
      { _M_b.seed(__s); }

      /**
       * @brief Reseeds the %independent_bits_engine object with the given
       *        seed sequence.
       * @param __q A seed generator function.
       */
      template<typename _Sseq>
        void
        seed(_Sseq& __q)
        { _M_b.seed(__q); }

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

      /**
       * @brief Gets the minimum value in the generated random number range.
       */
      static constexpr result_type
      min()
      { return 0U; }

      /**
       * @brief Gets the maximum value in the generated random number range.
       */
      static constexpr result_type
      max()
      { return __detail::_Shift<_UIntType, __w>::__value - 1; }

      /**
       * @brief Discard a sequence of random numbers.
       */
      void
      discard(unsigned long long __z)
      {
	for (; __z != 0ULL; --__z)
	  (*this)();
      }

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

      /**
       * @brief Compares two %independent_bits_engine random number generator
       * objects of the same type for equality.
       *
       * @param __lhs A %independent_bits_engine random number generator
       *              object.
       * @param __rhs Another %independent_bits_engine random number generator
       *              object.
       *
       * @returns true if the infinite sequences of generated values
       *          would be equal, false otherwise.
       */
      friend bool
      operator==(const independent_bits_engine& __lhs,
		 const independent_bits_engine& __rhs)
      { return __lhs._M_b == __rhs._M_b; }

      /**
       * @brief Extracts the current state of a % subtract_with_carry_engine
       *        random number generator engine @p __x from the input stream
       *        @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %independent_bits_engine random number generator
       *             engine.
       *
       * @returns The input stream with the state of @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,
		   std::independent_bits_engine<_RandomNumberEngine,
		   __w, _UIntType>& __x)
	{
	  __is >> __x._M_b;
	  return __is;
	}

    private:
      _RandomNumberEngine _M_b;
    };

  /**
   * @brief Compares two %independent_bits_engine random number generator
   * objects of the same type for inequality.
   *
   * @param __lhs A %independent_bits_engine random number generator
   *              object.
   * @param __rhs Another %independent_bits_engine random number generator
   *              object.
   *
   * @returns true if the infinite sequences of generated values
   *          would be different, false otherwise.
   */
  template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
    inline bool
    operator!=(const std::independent_bits_engine<_RandomNumberEngine, __w,
	       _UIntType>& __lhs,
	       const std::independent_bits_engine<_RandomNumberEngine, __w,
	       _UIntType>& __rhs)
    { return !(__lhs == __rhs); }

  /**
   * @brief Inserts the current state of a %independent_bits_engine random
   *        number generator engine @p __x into the output stream @p __os.
   *
   * @param __os An output stream.
   * @param __x  A %independent_bits_engine random number generator engine.
   *
   * @returns The output stream with the state of @p __x inserted or in
   *          an error state.
   */
  template<typename _RandomNumberEngine, size_t __w, typename _UIntType,
	   typename _CharT, typename _Traits>
    std::basic_ostream<_CharT, _Traits>&
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
	       const std::independent_bits_engine<_RandomNumberEngine,
	       __w, _UIntType>& __x)
    {
      __os << __x.base();
      return __os;
    }


  /**
   * @brief Produces random numbers by combining random numbers from some
   * base engine to produce random numbers with a specifies number of bits
   * @p __w.
   */
  template<typename _RandomNumberEngine, size_t __k>
    class shuffle_order_engine
    {
      static_assert(1u <= __k, "template argument substituting "
		    "__k out of bound");

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

      static constexpr size_t table_size = __k;

      /**
       * @brief Constructs a default %shuffle_order_engine engine.
       *
       * The underlying engine is default constructed as well.
       */
      shuffle_order_engine()
      : _M_b()
      { _M_initialize(); }

      /**
       * @brief Copy constructs a %shuffle_order_engine engine.
       *
       * Copies an existing base class random number generator.
       * @param __rng An existing (base class) engine object.
       */
      explicit
      shuffle_order_engine(const _RandomNumberEngine& __rng)
      : _M_b(__rng)
      { _M_initialize(); }

      /**
       * @brief Move constructs a %shuffle_order_engine engine.
       *
       * Copies an existing base class random number generator.
       * @param __rng An existing (base class) engine object.
       */
      explicit
      shuffle_order_engine(_RandomNumberEngine&& __rng)
      : _M_b(std::move(__rng))
      { _M_initialize(); }

      /**
       * @brief Seed constructs a %shuffle_order_engine engine.
       *
       * Constructs the underlying generator engine seeded with @p __s.
       * @param __s A seed value for the base class engine.
       */
      explicit
      shuffle_order_engine(result_type __s)
      : _M_b(__s)
      { _M_initialize(); }

      /**
       * @brief Generator construct a %shuffle_order_engine engine.
       *
       * @param __q A seed sequence.
       */
      template<typename _Sseq, typename = typename
	std::enable_if<!std::is_same<_Sseq, shuffle_order_engine>::value
		       && !std::is_same<_Sseq, _RandomNumberEngine>::value>
	       ::type>
        explicit
        shuffle_order_engine(_Sseq& __q)
        : _M_b(__q)
        { _M_initialize(); }

      /**
       * @brief Reseeds the %shuffle_order_engine object with the default seed
                for the underlying base class generator engine.
       */
      void
      seed()
      {
	_M_b.seed();
	_M_initialize();
      }

      /**
       * @brief Reseeds the %shuffle_order_engine object with the default seed
       *        for the underlying base class generator engine.
       */
      void
      seed(result_type __s)
      {
	_M_b.seed(__s);
	_M_initialize();
      }

      /**
       * @brief Reseeds the %shuffle_order_engine object with the given seed
       *        sequence.
       * @param __q A seed generator function.
       */
      template<typename _Sseq>
        void
        seed(_Sseq& __q)
        {
	  _M_b.seed(__q);
	  _M_initialize();
	}

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

      /**
       * Gets the minimum value in the generated random number range.
       */
      static constexpr result_type
      min()
      { return _RandomNumberEngine::min(); }

      /**
       * Gets the maximum value in the generated random number range.
       */
      static constexpr result_type
      max()
      { return _RandomNumberEngine::max(); }

      /**
       * Discard a sequence of random numbers.
       */
      void
      discard(unsigned long long __z)
      {
	for (; __z != 0ULL; --__z)
	  (*this)();
      }

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

      /**
       * Compares two %shuffle_order_engine random number generator objects
       * of the same type for equality.
       *
       * @param __lhs A %shuffle_order_engine random number generator object.
       * @param __rhs Another %shuffle_order_engine random number generator
       *              object.
       *
       * @returns true if the infinite sequences of generated values
       *          would be equal, false otherwise.
      */
      friend bool
      operator==(const shuffle_order_engine& __lhs,
		 const shuffle_order_engine& __rhs)
      { return (__lhs._M_b == __rhs._M_b
		&& std::equal(__lhs._M_v, __lhs._M_v + __k, __rhs._M_v)
		&& __lhs._M_y == __rhs._M_y); }

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

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

    private:
      void _M_initialize()
      {
	for (size_t __i = 0; __i < __k; ++__i)
	  _M_v[__i] = _M_b();
	_M_y = _M_b();
      }

      _RandomNumberEngine _M_b;
      result_type _M_v[__k];
      result_type _M_y;
    };

  /**
   * Compares two %shuffle_order_engine random number generator objects
   * of the same type for inequality.
   *
   * @param __lhs A %shuffle_order_engine random number generator object.
   * @param __rhs Another %shuffle_order_engine random number generator
   *              object.
   *
   * @returns true if the infinite sequences of generated values
   *          would be different, false otherwise.
   */
  template<typename _RandomNumberEngine, size_t __k>
    inline bool
    operator!=(const std::shuffle_order_engine<_RandomNumberEngine,
	       __k>& __lhs,
	       const std::shuffle_order_engine<_RandomNumberEngine,
	       __k>& __rhs)
    { return !(__lhs == __rhs); }


  /**
   * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
   */
  typedef linear_congruential_engine<uint_fast32_t, 16807UL, 0UL, 2147483647UL>
  minstd_rand0;

  /**
   * An alternative LCR (Lehmer Generator function).
   */
  typedef linear_congruential_engine<uint_fast32_t, 48271UL, 0UL, 2147483647UL>
  minstd_rand;

  /**
   * 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_engine<
    uint_fast32_t,
    32, 624, 397, 31,
    0x9908b0dfUL, 11,
    0xffffffffUL, 7,
    0x9d2c5680UL, 15,
    0xefc60000UL, 18, 1812433253UL> mt19937;

  /**
   * An alternative Mersenne Twister.
   */
  typedef mersenne_twister_engine<
    uint_fast64_t,
    64, 312, 156, 31,
    0xb5026f5aa96619e9ULL, 29,
    0x5555555555555555ULL, 17,
    0x71d67fffeda60000ULL, 37,
    0xfff7eee000000000ULL, 43,
    6364136223846793005ULL> mt19937_64;

  typedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>
    ranlux24_base;

  typedef subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>
    ranlux48_base;

  typedef discard_block_engine<ranlux24_base, 223, 23> ranlux24;

  typedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;

  typedef shuffle_order_engine<minstd_rand0, 256> knuth_b;

  typedef minstd_rand0 default_random_engine;

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

    // constructors, destructors and member functions

#ifdef _GLIBCXX_USE_RANDOM_TR1

    explicit
    random_device(const std::string& __token = "default")
    {
      _M_init(__token);
    }

    ~random_device()
    { _M_fini(); }

#else

    explicit
    random_device(const std::string& __token = "mt19937")
    { _M_init_pretr1(__token); }

  public:

#endif

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

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

    double
    entropy() const noexcept
    { return 0.0; }

    result_type
    operator()()
    {
#ifdef _GLIBCXX_USE_RANDOM_TR1
      return this->_M_getval();
#else
      return this->_M_getval_pretr1();
#endif
    }

    // No copy functions.
    random_device(const random_device&) = delete;
    void operator=(const random_device&) = delete;

  private:

    void _M_init(const std::string& __token);
    void _M_init_pretr1(const std::string& __token);
    void _M_fini();

    result_type _M_getval();
    result_type _M_getval_pretr1();

    union
    {
      void*      _M_file;
      mt19937    _M_mt;
    };
  };

  /* @} */ // group random_generators

  /**
   * @addtogroup random_distributions Random Number Distributions
   * @ingroup random
   * @{
   */

  /**
   * @addtogroup random_distributions_uniform Uniform Distributions
   * @ingroup 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_distribution
    {
      static_assert(std::is_integral<_IntType>::value,
		    "template argument not an integral type");

    public:
      /** The type of the range of the distribution. */
      typedef _IntType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef uniform_int_distribution<_IntType> distribution_type;

	explicit
	param_type(_IntType __a = 0,
		   _IntType __b = std::numeric_limits<_IntType>::max())
	: _M_a(__a), _M_b(__b)
	{
	  _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
	}

	result_type
	a() const
	{ return _M_a; }

	result_type
	b() const
	{ return _M_b; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }

      private:
	_IntType _M_a;
	_IntType _M_b;
      };

    public:
      /**
       * @brief Constructs a uniform distribution object.
       */
      explicit
      uniform_int_distribution(_IntType __a = 0,
			   _IntType __b = std::numeric_limits<_IntType>::max())
      : _M_param(__a, __b)
      { }

      explicit
      uniform_int_distribution(const param_type& __p)
      : _M_param(__p)
      { }

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

      result_type
      a() const
      { return _M_param.a(); }

      result_type
      b() const
      { return _M_param.b(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the inclusive lower bound of the distribution range.
       */
      result_type
      min() const
      { return this->a(); }

      /**
       * @brief Returns the inclusive upper bound of the distribution range.
       */
      result_type
      max() const
      { return this->b(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
        { return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two uniform integer distributions have
       *        the same parameters.
       */
      friend bool
      operator==(const uniform_int_distribution& __d1,
		 const uniform_int_distribution& __d2)
      { return __d1._M_param == __d2._M_param; }

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;
    };

  /**
   * @brief Return true if two uniform integer distributions have
   *        different parameters.
   */
  template<typename _IntType>
    inline bool
    operator!=(const std::uniform_int_distribution<_IntType>& __d1,
	       const std::uniform_int_distribution<_IntType>& __d2)
    { return !(__d1 == __d2); }

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

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


  /**
   * @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_distribution
    {
      static_assert(std::is_floating_point<_RealType>::value,
		    "template argument not a floating point type");

    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef uniform_real_distribution<_RealType> distribution_type;

	explicit
	param_type(_RealType __a = _RealType(0),
		   _RealType __b = _RealType(1))
	: _M_a(__a), _M_b(__b)
	{
	  _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
	}

	result_type
	a() const
	{ return _M_a; }

	result_type
	b() const
	{ return _M_b; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }

      private:
	_RealType _M_a;
	_RealType _M_b;
      };

    public:
      /**
       * @brief Constructs a uniform_real_distribution object.
       *
       * @param __a [IN]  The lower bound of the distribution.
       * @param __b [IN]  The upper bound of the distribution.
       */
      explicit
      uniform_real_distribution(_RealType __a = _RealType(0),
				_RealType __b = _RealType(1))
      : _M_param(__a, __b)
      { }

      explicit
      uniform_real_distribution(const param_type& __p)
      : _M_param(__p)
      { }

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

      result_type
      a() const
      { return _M_param.a(); }

      result_type
      b() const
      { return _M_param.b(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the inclusive lower bound of the distribution range.
       */
      result_type
      min() const
      { return this->a(); }

      /**
       * @brief Returns the inclusive upper bound of the distribution range.
       */
      result_type
      max() const
      { return this->b(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
        { return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{
	  __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
	    __aurng(__urng);
	  return (__aurng() * (__p.b() - __p.a())) + __p.a();
	}

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two uniform real distributions have
       *        the same parameters.
       */
      friend bool
      operator==(const uniform_real_distribution& __d1,
		 const uniform_real_distribution& __d2)
      { return __d1._M_param == __d2._M_param; }

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;
    };

  /**
   * @brief Return true if two uniform real distributions have
   *        different parameters.
   */
  template<typename _IntType>
    inline bool
    operator!=(const std::uniform_real_distribution<_IntType>& __d1,
	       const std::uniform_real_distribution<_IntType>& __d2)
    { return !(__d1 == __d2); }

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

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

  /* @} */ // group random_distributions_uniform

  /**
   * @addtogroup random_distributions_normal Normal Distributions
   * @ingroup random_distributions
   * @{
   */

  /**
   * @brief A normal continuous distribution for random numbers.
   *
   * The formula for the normal probability density function is
   * @f[
   *     p(x|\mu,\sigma) = \frac{1}{\sigma \sqrt{2 \pi}}
   *            e^{- \frac{{x - \mu}^ {2}}{2 \sigma ^ {2}} } 
   * @f]
   */
  template<typename _RealType = double>
    class normal_distribution
    {
      static_assert(std::is_floating_point<_RealType>::value,
		    "template argument not a floating point type");

    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef normal_distribution<_RealType> distribution_type;

	explicit
	param_type(_RealType __mean = _RealType(0),
		   _RealType __stddev = _RealType(1))
	: _M_mean(__mean), _M_stddev(__stddev)
	{
	  _GLIBCXX_DEBUG_ASSERT(_M_stddev > _RealType(0));
	}

	_RealType
	mean() const
	{ return _M_mean; }

	_RealType
	stddev() const
	{ return _M_stddev; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return (__p1._M_mean == __p2._M_mean
		  && __p1._M_stddev == __p2._M_stddev); }

      private:
	_RealType _M_mean;
	_RealType _M_stddev;
      };

    public:
      /**
       * Constructs a normal distribution with parameters @f$mean@f$ and
       * standard deviation.
       */
      explicit
      normal_distribution(result_type __mean = result_type(0),
			  result_type __stddev = result_type(1))
      : _M_param(__mean, __stddev), _M_saved_available(false)
      { }

      explicit
      normal_distribution(const param_type& __p)
      : _M_param(__p), _M_saved_available(false)
      { }

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

      /**
       * @brief Returns the mean of the distribution.
       */
      _RealType
      mean() const
      { return _M_param.mean(); }

      /**
       * @brief Returns the standard deviation of the distribution.
       */
      _RealType
      stddev() const
      { return _M_param.stddev(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return std::numeric_limits<result_type>::lowest(); }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return std::numeric_limits<result_type>::max(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
	{ return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two normal distributions have
       *        the same parameters and the sequences that would
       *        be generated are equal.
       */
      template<typename _RealType1>
	friend bool
        operator==(const std::normal_distribution<_RealType1>& __d1,
		   const std::normal_distribution<_RealType1>& __d2);

      /**
       * @brief 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 std::normal_distribution<_RealType1>& __x);

      /**
       * @brief 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,
		   std::normal_distribution<_RealType1>& __x);

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type  _M_param;
      result_type _M_saved;
      bool        _M_saved_available;
    };

  /**
   * @brief Return true if two normal distributions are different.
   */
  template<typename _RealType>
    inline bool
    operator!=(const std::normal_distribution<_RealType>& __d1,
	       const std::normal_distribution<_RealType>& __d2)
    { return !(__d1 == __d2); }


  /**
   * @brief A lognormal_distribution random number distribution.
   *
   * The formula for the normal probability mass function is
   * @f[
   *     p(x|m,s) = \frac{1}{sx\sqrt{2\pi}}
   *                \exp{-\frac{(\ln{x} - m)^2}{2s^2}} 
   * @f]
   */
  template<typename _RealType = double>
    class lognormal_distribution
    {
      static_assert(std::is_floating_point<_RealType>::value,
		    "template argument not a floating point type");

    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef lognormal_distribution<_RealType> distribution_type;

	explicit
	param_type(_RealType __m = _RealType(0),
		   _RealType __s = _RealType(1))
	: _M_m(__m), _M_s(__s)
	{ }

	_RealType
	m() const
	{ return _M_m; }

	_RealType
	s() const
	{ return _M_s; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_m == __p2._M_m && __p1._M_s == __p2._M_s; }

      private:
	_RealType _M_m;
	_RealType _M_s;
      };

      explicit
      lognormal_distribution(_RealType __m = _RealType(0),
			     _RealType __s = _RealType(1))
      : _M_param(__m, __s), _M_nd()
      { }

      explicit
      lognormal_distribution(const param_type& __p)
      : _M_param(__p), _M_nd()
      { }

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

      /**
       *
       */
      _RealType
      m() const
      { return _M_param.m(); }

      _RealType
      s() const
      { return _M_param.s(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return result_type(0); }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return std::numeric_limits<result_type>::max(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
        { return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
        { return std::exp(__p.s() * _M_nd(__urng) + __p.m()); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two lognormal distributions have
       *        the same parameters and the sequences that would
       *        be generated are equal.
       */
      friend bool
      operator==(const lognormal_distribution& __d1,
		 const lognormal_distribution& __d2)
      { return (__d1._M_param == __d2._M_param
		&& __d1._M_nd == __d2._M_nd); }

      /**
       * @brief Inserts a %lognormal_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %lognormal_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 std::lognormal_distribution<_RealType1>& __x);

      /**
       * @brief Extracts a %lognormal_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x A %lognormal_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,
		   std::lognormal_distribution<_RealType1>& __x);

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;

      std::normal_distribution<result_type> _M_nd;
    };

  /**
   * @brief Return true if two lognormal distributions are different.
   */
  template<typename _RealType>
    inline bool
    operator!=(const std::lognormal_distribution<_RealType>& __d1,
	       const std::lognormal_distribution<_RealType>& __d2)
    { return !(__d1 == __d2); }


  /**
   * @brief A gamma continuous distribution for random numbers.
   *
   * The formula for the gamma probability density function is:
   * @f[
   *     p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
   *                         (x/\beta)^{\alpha - 1} e^{-x/\beta} 
   * @f]
   */
  template<typename _RealType = double>
    class gamma_distribution
    {
      static_assert(std::is_floating_point<_RealType>::value,
		    "template argument not a floating point type");

    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef gamma_distribution<_RealType> distribution_type;
	friend class gamma_distribution<_RealType>;

	explicit
	param_type(_RealType __alpha_val = _RealType(1),
		   _RealType __beta_val = _RealType(1))
	: _M_alpha(__alpha_val), _M_beta(__beta_val)
	{
	  _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0));
	  _M_initialize();
	}

	_RealType
	alpha() const
	{ return _M_alpha; }

	_RealType
	beta() const
	{ return _M_beta; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return (__p1._M_alpha == __p2._M_alpha
		  && __p1._M_beta == __p2._M_beta); }

      private:
	void
	_M_initialize();

	_RealType _M_alpha;
	_RealType _M_beta;

	_RealType _M_malpha, _M_a2;
      };

    public:
      /**
       * @brief Constructs a gamma distribution with parameters
       * @f$\alpha@f$ and @f$\beta@f$.
       */
      explicit
      gamma_distribution(_RealType __alpha_val = _RealType(1),
			 _RealType __beta_val = _RealType(1))
      : _M_param(__alpha_val, __beta_val), _M_nd()
      { }

      explicit
      gamma_distribution(const param_type& __p)
      : _M_param(__p), _M_nd()
      { }

      /**
       * @brief Resets the distribution state.
       */
      void
      reset()
      { _M_nd.reset(); }

      /**
       * @brief Returns the @f$\alpha@f$ of the distribution.
       */
      _RealType
      alpha() const
      { return _M_param.alpha(); }

      /**
       * @brief Returns the @f$\beta@f$ of the distribution.
       */
      _RealType
      beta() const
      { return _M_param.beta(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return result_type(0); }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return std::numeric_limits<result_type>::max(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
	{ return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two gamma distributions have the same
       *        parameters and the sequences that would be generated
       *        are equal.
       */
      friend bool
      operator==(const gamma_distribution& __d1,
		 const gamma_distribution& __d2)
      { return (__d1._M_param == __d2._M_param
		&& __d1._M_nd == __d2._M_nd); }

      /**
       * @brief 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 std::gamma_distribution<_RealType1>& __x);

      /**
       * @brief 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 _RealType1, typename _CharT, typename _Traits>
	friend std::basic_istream<_CharT, _Traits>&
	operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   std::gamma_distribution<_RealType1>& __x);

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;

      std::normal_distribution<result_type> _M_nd;
    };

  /**
   * @brief Return true if two gamma distributions are different.
   */
   template<typename _RealType>
     inline bool
     operator!=(const std::gamma_distribution<_RealType>& __d1,
		const std::gamma_distribution<_RealType>& __d2)
    { return !(__d1 == __d2); }


  /**
   * @brief A chi_squared_distribution random number distribution.
   *
   * The formula for the normal probability mass function is
   * @f$p(x|n) = \frac{x^{(n/2) - 1}e^{-x/2}}{\Gamma(n/2) 2^{n/2}}@f$
   */
  template<typename _RealType = double>
    class chi_squared_distribution
    {
      static_assert(std::is_floating_point<_RealType>::value,
		    "template argument not a floating point type");

    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef chi_squared_distribution<_RealType> distribution_type;

	explicit
	param_type(_RealType __n = _RealType(1))
	: _M_n(__n)
	{ }

	_RealType
	n() const
	{ return _M_n; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_n == __p2._M_n; }

      private:
	_RealType _M_n;
      };

      explicit
      chi_squared_distribution(_RealType __n = _RealType(1))
      : _M_param(__n), _M_gd(__n / 2)
      { }

      explicit
      chi_squared_distribution(const param_type& __p)
      : _M_param(__p), _M_gd(__p.n() / 2)
      { }

      /**
       * @brief Resets the distribution state.
       */
      void
      reset()
      { _M_gd.reset(); }

      /**
       *
       */
      _RealType
      n() const
      { return _M_param.n(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return result_type(0); }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return std::numeric_limits<result_type>::max(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
	{ return 2 * _M_gd(__urng); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
        {
	  typedef typename std::gamma_distribution<result_type>::param_type
	    param_type;
	  return 2 * _M_gd(__urng, param_type(__p.n() / 2));
	}

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
        { this->__generate_impl(__f, __t, __urng); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ typename std::gamma_distribution<result_type>::param_type
	    __p2(__p.n() / 2);
	  this->__generate_impl(__f, __t, __urng, __p2); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng)
        { this->__generate_impl(__f, __t, __urng); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ typename std::gamma_distribution<result_type>::param_type
	    __p2(__p.n() / 2);
	  this->__generate_impl(__f, __t, __urng, __p2); }

      /**
       * @brief Return true if two Chi-squared distributions have
       *        the same parameters and the sequences that would be
       *        generated are equal.
       */
      friend bool
      operator==(const chi_squared_distribution& __d1,
		 const chi_squared_distribution& __d2)
      { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; }

      /**
       * @brief Inserts a %chi_squared_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %chi_squared_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 std::chi_squared_distribution<_RealType1>& __x);

      /**
       * @brief Extracts a %chi_squared_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x A %chi_squared_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,
		   std::chi_squared_distribution<_RealType1>& __x);

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const typename
			std::gamma_distribution<result_type>::param_type& __p);

      param_type _M_param;

      std::gamma_distribution<result_type> _M_gd;
    };

  /**
   * @brief Return true if two Chi-squared distributions are different.
   */
  template<typename _RealType>
    inline bool
    operator!=(const std::chi_squared_distribution<_RealType>& __d1,
	       const std::chi_squared_distribution<_RealType>& __d2)
    { return !(__d1 == __d2); }


  /**
   * @brief A cauchy_distribution random number distribution.
   *
   * The formula for the normal probability mass function is
   * @f$p(x|a,b) = (\pi b (1 + (\frac{x-a}{b})^2))^{-1}@f$
   */
  template<typename _RealType = double>
    class cauchy_distribution
    {
      static_assert(std::is_floating_point<_RealType>::value,
		    "template argument not a floating point type");

    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef cauchy_distribution<_RealType> distribution_type;

	explicit
	param_type(_RealType __a = _RealType(0),
		   _RealType __b = _RealType(1))
	: _M_a(__a), _M_b(__b)
	{ }

	_RealType
	a() const
	{ return _M_a; }

	_RealType
	b() const
	{ return _M_b; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }

      private:
	_RealType _M_a;
	_RealType _M_b;
      };

      explicit
      cauchy_distribution(_RealType __a = _RealType(0),
			  _RealType __b = _RealType(1))
      : _M_param(__a, __b)
      { }

      explicit
      cauchy_distribution(const param_type& __p)
      : _M_param(__p)
      { }

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

      /**
       *
       */
      _RealType
      a() const
      { return _M_param.a(); }

      _RealType
      b() const
      { return _M_param.b(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return std::numeric_limits<result_type>::lowest(); }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return std::numeric_limits<result_type>::max(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
	{ return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two Cauchy distributions have
       *        the same parameters.
       */
      friend bool
      operator==(const cauchy_distribution& __d1,
		 const cauchy_distribution& __d2)
      { return __d1._M_param == __d2._M_param; }

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;
    };

  /**
   * @brief Return true if two Cauchy distributions have
   *        different parameters.
   */
  template<typename _RealType>
    inline bool
    operator!=(const std::cauchy_distribution<_RealType>& __d1,
	       const std::cauchy_distribution<_RealType>& __d2)
    { return !(__d1 == __d2); }

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

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


  /**
   * @brief A fisher_f_distribution random number distribution.
   *
   * The formula for the normal probability mass function is
   * @f[
   *     p(x|m,n) = \frac{\Gamma((m+n)/2)}{\Gamma(m/2)\Gamma(n/2)}
   *                (\frac{m}{n})^{m/2} x^{(m/2)-1}
   *                (1 + \frac{mx}{n})^{-(m+n)/2} 
   * @f]
   */
  template<typename _RealType = double>
    class fisher_f_distribution
    {
      static_assert(std::is_floating_point<_RealType>::value,
		    "template argument not a floating point type");

    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef fisher_f_distribution<_RealType> distribution_type;

	explicit
	param_type(_RealType __m = _RealType(1),
		   _RealType __n = _RealType(1))
	: _M_m(__m), _M_n(__n)
	{ }

	_RealType
	m() const
	{ return _M_m; }

	_RealType
	n() const
	{ return _M_n; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_m == __p2._M_m && __p1._M_n == __p2._M_n; }

      private:
	_RealType _M_m;
	_RealType _M_n;
      };

      explicit
      fisher_f_distribution(_RealType __m = _RealType(1),
			    _RealType __n = _RealType(1))
      : _M_param(__m, __n), _M_gd_x(__m / 2), _M_gd_y(__n / 2)
      { }

      explicit
      fisher_f_distribution(const param_type& __p)
      : _M_param(__p), _M_gd_x(__p.m() / 2), _M_gd_y(__p.n() / 2)
      { }

      /**
       * @brief Resets the distribution state.
       */
      void
      reset()
      {
	_M_gd_x.reset();
	_M_gd_y.reset();
      }

      /**
       *
       */
      _RealType
      m() const
      { return _M_param.m(); }

      _RealType
      n() const
      { return _M_param.n(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return result_type(0); }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return std::numeric_limits<result_type>::max(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
	{ return (_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
        {
	  typedef typename std::gamma_distribution<result_type>::param_type
	    param_type;
	  return ((_M_gd_x(__urng, param_type(__p.m() / 2)) * n())
		  / (_M_gd_y(__urng, param_type(__p.n() / 2)) * m()));
	}

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate_impl(__f, __t, __urng); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate_impl(__f, __t, __urng); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two Fisher f distributions have
       *        the same parameters and the sequences that would
       *        be generated are equal.
       */
      friend bool
      operator==(const fisher_f_distribution& __d1,
		 const fisher_f_distribution& __d2)
      { return (__d1._M_param == __d2._M_param
		&& __d1._M_gd_x == __d2._M_gd_x
		&& __d1._M_gd_y == __d2._M_gd_y); }

      /**
       * @brief Inserts a %fisher_f_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %fisher_f_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 std::fisher_f_distribution<_RealType1>& __x);

      /**
       * @brief Extracts a %fisher_f_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x A %fisher_f_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,
		   std::fisher_f_distribution<_RealType1>& __x);

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;

      std::gamma_distribution<result_type> _M_gd_x, _M_gd_y;
    };

  /**
   * @brief Return true if two Fisher f distributions are different.
   */
  template<typename _RealType>
    inline bool
    operator!=(const std::fisher_f_distribution<_RealType>& __d1,
	       const std::fisher_f_distribution<_RealType>& __d2)
    { return !(__d1 == __d2); }

  /**
   * @brief A student_t_distribution random number distribution.
   *
   * The formula for the normal probability mass function is:
   * @f[
   *     p(x|n) = \frac{1}{\sqrt(n\pi)} \frac{\Gamma((n+1)/2)}{\Gamma(n/2)}
   *              (1 + \frac{x^2}{n}) ^{-(n+1)/2} 
   * @f]
   */
  template<typename _RealType = double>
    class student_t_distribution
    {
      static_assert(std::is_floating_point<_RealType>::value,
		    "template argument not a floating point type");

    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef student_t_distribution<_RealType> distribution_type;

	explicit
	param_type(_RealType __n = _RealType(1))
	: _M_n(__n)
	{ }

	_RealType
	n() const
	{ return _M_n; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_n == __p2._M_n; }

      private:
	_RealType _M_n;
      };

      explicit
      student_t_distribution(_RealType __n = _RealType(1))
      : _M_param(__n), _M_nd(), _M_gd(__n / 2, 2)
      { }

      explicit
      student_t_distribution(const param_type& __p)
      : _M_param(__p), _M_nd(), _M_gd(__p.n() / 2, 2)
      { }

      /**
       * @brief Resets the distribution state.
       */
      void
      reset()
      {
	_M_nd.reset();
	_M_gd.reset();
      }

      /**
       *
       */
      _RealType
      n() const
      { return _M_param.n(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return std::numeric_limits<result_type>::lowest(); }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return std::numeric_limits<result_type>::max(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
        operator()(_UniformRandomNumberGenerator& __urng)
        { return _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
        {
	  typedef typename std::gamma_distribution<result_type>::param_type
	    param_type;
	
	  const result_type __g = _M_gd(__urng, param_type(__p.n() / 2, 2));
	  return _M_nd(__urng) * std::sqrt(__p.n() / __g);
        }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate_impl(__f, __t, __urng); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate_impl(__f, __t, __urng); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two Student t distributions have
       *        the same parameters and the sequences that would
       *        be generated are equal.
       */
      friend bool
      operator==(const student_t_distribution& __d1,
		 const student_t_distribution& __d2)
      { return (__d1._M_param == __d2._M_param
		&& __d1._M_nd == __d2._M_nd && __d1._M_gd == __d2._M_gd); }

      /**
       * @brief Inserts a %student_t_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %student_t_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 std::student_t_distribution<_RealType1>& __x);

      /**
       * @brief Extracts a %student_t_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x A %student_t_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,
		   std::student_t_distribution<_RealType1>& __x);

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng);
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;

      std::normal_distribution<result_type> _M_nd;
      std::gamma_distribution<result_type> _M_gd;
    };

  /**
   * @brief Return true if two Student t distributions are different.
   */
  template<typename _RealType>
    inline bool
    operator!=(const std::student_t_distribution<_RealType>& __d1,
	       const std::student_t_distribution<_RealType>& __d2)
    { return !(__d1 == __d2); }


  /* @} */ // group random_distributions_normal

  /**
   * @addtogroup random_distributions_bernoulli Bernoulli Distributions
   * @ingroup random_distributions
   * @{
   */

  /**
   * @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:
    /** The type of the range of the distribution. */
    typedef bool result_type;
    /** Parameter type. */
    struct param_type
    {
      typedef bernoulli_distribution distribution_type;

      explicit
      param_type(double __p = 0.5)
      : _M_p(__p)
      {
	_GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
      }

      double
      p() const
      { return _M_p; }

      friend bool
      operator==(const param_type& __p1, const param_type& __p2)
      { return __p1._M_p == __p2._M_p; }

    private:
      double _M_p;
    };

  public:
    /**
     * @brief 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_param(__p)
    { }

    explicit
    bernoulli_distribution(const param_type& __p)
    : _M_param(__p)
    { }

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

    /**
     * @brief Returns the @p p parameter of the distribution.
     */
    double
    p() const
    { return _M_param.p(); }

    /**
     * @brief Returns the parameter set of the distribution.
     */
    param_type
    param() const
    { return _M_param; }

    /**
     * @brief Sets the parameter set of the distribution.
     * @param __param The new parameter set of the distribution.
     */
    void
    param(const param_type& __param)
    { _M_param = __param; }

    /**
     * @brief Returns the greatest lower bound value of the distribution.
     */
    result_type
    min() const
    { return std::numeric_limits<result_type>::min(); }

    /**
     * @brief Returns the least upper bound value of the distribution.
     */
    result_type
    max() const
    { return std::numeric_limits<result_type>::max(); }

    /**
     * @brief Generating functions.
     */
    template<typename _UniformRandomNumberGenerator>
      result_type
      operator()(_UniformRandomNumberGenerator& __urng)
      { return this->operator()(__urng, _M_param); }

    template<typename _UniformRandomNumberGenerator>
      result_type
      operator()(_UniformRandomNumberGenerator& __urng,
		 const param_type& __p)
      {
	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
	  __aurng(__urng);
	if ((__aurng() - __aurng.min())
	     < __p.p() * (__aurng.max() - __aurng.min()))
	  return true;
	return false;
      }

    template<typename _ForwardIterator,
	     typename _UniformRandomNumberGenerator>
      void
      __generate(_ForwardIterator __f, _ForwardIterator __t,
		 _UniformRandomNumberGenerator& __urng)
      { this->__generate(__f, __t, __urng, _M_param); }

    template<typename _ForwardIterator,
	     typename _UniformRandomNumberGenerator>
      void
      __generate(_ForwardIterator __f, _ForwardIterator __t,
		 _UniformRandomNumberGenerator& __urng, const param_type& __p)
      { this->__generate_impl(__f, __t, __urng, __p); }

    template<typename _UniformRandomNumberGenerator>
      void
      __generate(result_type* __f, result_type* __t,
		 _UniformRandomNumberGenerator& __urng,
		 const param_type& __p)
      { this->__generate_impl(__f, __t, __urng, __p); }

    /**
     * @brief Return true if two Bernoulli distributions have
     *        the same parameters.
     */
    friend bool
    operator==(const bernoulli_distribution& __d1,
	       const bernoulli_distribution& __d2)
    { return __d1._M_param == __d2._M_param; }

  private:
    template<typename _ForwardIterator,
	     typename _UniformRandomNumberGenerator>
      void
      __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
		      _UniformRandomNumberGenerator& __urng,
		      const param_type& __p);

    param_type _M_param;
  };

  /**
   * @brief Return true if two Bernoulli distributions have
   *        different parameters.
   */
  inline bool
  operator!=(const std::bernoulli_distribution& __d1,
	     const std::bernoulli_distribution& __d2)
  { return !(__d1 == __d2); }

  /**
   * @brief 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>
    std::basic_ostream<_CharT, _Traits>&
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
	       const std::bernoulli_distribution& __x);

  /**
   * @brief 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>
    std::basic_istream<_CharT, _Traits>&
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
	       std::bernoulli_distribution& __x)
    {
      double __p;
      __is >> __p;
      __x.param(bernoulli_distribution::param_type(__p));
      return __is;
    }


  /**
   * @brief A discrete binomial random number distribution.
   *
   * The formula for the binomial probability density function is
   * @f$p(i|t,p) = \binom{t}{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>
    class binomial_distribution
    {
      static_assert(std::is_integral<_IntType>::value,
		    "template argument not an integral type");

    public:
      /** The type of the range of the distribution. */
      typedef _IntType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef binomial_distribution<_IntType> distribution_type;
	friend class binomial_distribution<_IntType>;

	explicit
	param_type(_IntType __t = _IntType(1), double __p = 0.5)
	: _M_t(__t), _M_p(__p)
	{
	  _GLIBCXX_DEBUG_ASSERT((_M_t >= _IntType(0))
				&& (_M_p >= 0.0)
				&& (_M_p <= 1.0));
	  _M_initialize();
	}

	_IntType
	t() const
	{ return _M_t; }

	double
	p() const
	{ return _M_p; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_t == __p2._M_t && __p1._M_p == __p2._M_p; }

      private:
	void
	_M_initialize();

	_IntType _M_t;
	double _M_p;

	double _M_q;
#if _GLIBCXX_USE_C99_MATH_TR1
	double _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
	       _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
#endif
	bool   _M_easy;
      };

      // constructors and member function
      explicit
      binomial_distribution(_IntType __t = _IntType(1),
			    double __p = 0.5)
      : _M_param(__t, __p), _M_nd()
      { }

      explicit
      binomial_distribution(const param_type& __p)
      : _M_param(__p), _M_nd()
      { }

      /**
       * @brief Resets the distribution state.
       */
      void
      reset()
      { _M_nd.reset(); }

      /**
       * @brief Returns the distribution @p t parameter.
       */
      _IntType
      t() const
      { return _M_param.t(); }

      /**
       * @brief Returns the distribution @p p parameter.
       */
      double
      p() const
      { return _M_param.p(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return 0; }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return _M_param.t(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
	{ return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two binomial distributions have
       *        the same parameters and the sequences that would
       *        be generated are equal.
       */
	friend bool
        operator==(const binomial_distribution& __d1,
		   const binomial_distribution& __d2)
#ifdef _GLIBCXX_USE_C99_MATH_TR1
	{ return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; }
#else
        { return __d1._M_param == __d2._M_param; }
#endif

      /**
       * @brief 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 _CharT, typename _Traits>
	friend std::basic_ostream<_CharT, _Traits>&
	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const std::binomial_distribution<_IntType1>& __x);

      /**
       * @brief 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 _CharT, typename _Traits>
	friend std::basic_istream<_CharT, _Traits>&
	operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   std::binomial_distribution<_IntType1>& __x);

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      template<typename _UniformRandomNumberGenerator>
	result_type
	_M_waiting(_UniformRandomNumberGenerator& __urng,
		   _IntType __t, double __q);

      param_type _M_param;

      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
      std::normal_distribution<double> _M_nd;
    };

  /**
   * @brief Return true if two binomial distributions are different.
   */
  template<typename _IntType>
    inline bool
    operator!=(const std::binomial_distribution<_IntType>& __d1,
	       const std::binomial_distribution<_IntType>& __d2)
    { return !(__d1 == __d2); }


  /**
   * @brief A discrete geometric random number distribution.
   *
   * The formula for the geometric probability density function is
   * @f$p(i|p) = p(1 - p)^{i}@f$ where @f$p@f$ is the parameter of the
   * distribution.
   */
  template<typename _IntType = int>
    class geometric_distribution
    {
      static_assert(std::is_integral<_IntType>::value,
		    "template argument not an integral type");

    public:
      /** The type of the range of the distribution. */
      typedef _IntType  result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef geometric_distribution<_IntType> distribution_type;
	friend class geometric_distribution<_IntType>;

	explicit
	param_type(double __p = 0.5)
	: _M_p(__p)
	{
	  _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
	  _M_initialize();
	}

	double
	p() const
	{ return _M_p; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_p == __p2._M_p; }

      private:
	void
	_M_initialize()
	{ _M_log_1_p = std::log(1.0 - _M_p); }

	double _M_p;

	double _M_log_1_p;
      };

      // constructors and member function
      explicit
      geometric_distribution(double __p = 0.5)
      : _M_param(__p)
      { }

      explicit
      geometric_distribution(const param_type& __p)
      : _M_param(__p)
      { }

      /**
       * @brief Resets the distribution state.
       *
       * Does nothing for the geometric distribution.
       */
      void
      reset() { }

      /**
       * @brief Returns the distribution parameter @p p.
       */
      double
      p() const
      { return _M_param.p(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return 0; }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return std::numeric_limits<result_type>::max(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
	{ return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two geometric distributions have
       *        the same parameters.
       */
      friend bool
      operator==(const geometric_distribution& __d1,
		 const geometric_distribution& __d2)
      { return __d1._M_param == __d2._M_param; }

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;
    };

  /**
   * @brief Return true if two geometric distributions have
   *        different parameters.
   */
  template<typename _IntType>
    inline bool
    operator!=(const std::geometric_distribution<_IntType>& __d1,
	       const std::geometric_distribution<_IntType>& __d2)
    { return !(__d1 == __d2); }

  /**
   * @brief 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 _IntType,
	   typename _CharT, typename _Traits>
    std::basic_ostream<_CharT, _Traits>&
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
	       const std::geometric_distribution<_IntType>& __x);

  /**
   * @brief 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 _IntType,
	   typename _CharT, typename _Traits>
    std::basic_istream<_CharT, _Traits>&
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
	       std::geometric_distribution<_IntType>& __x);


  /**
   * @brief A negative_binomial_distribution random number distribution.
   *
   * The formula for the negative 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>
    class negative_binomial_distribution
    {
      static_assert(std::is_integral<_IntType>::value,
		    "template argument not an integral type");

    public:
      /** The type of the range of the distribution. */
      typedef _IntType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef negative_binomial_distribution<_IntType> distribution_type;

	explicit
	param_type(_IntType __k = 1, double __p = 0.5)
	: _M_k(__k), _M_p(__p)
	{
	  _GLIBCXX_DEBUG_ASSERT((_M_k > 0) && (_M_p > 0.0) && (_M_p <= 1.0));
	}

	_IntType
	k() const
	{ return _M_k; }

	double
	p() const
	{ return _M_p; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_k == __p2._M_k && __p1._M_p == __p2._M_p; }

      private:
	_IntType _M_k;
	double _M_p;
      };

      explicit
      negative_binomial_distribution(_IntType __k = 1, double __p = 0.5)
      : _M_param(__k, __p), _M_gd(__k, (1.0 - __p) / __p)
      { }

      explicit
      negative_binomial_distribution(const param_type& __p)
      : _M_param(__p), _M_gd(__p.k(), (1.0 - __p.p()) / __p.p())
      { }

      /**
       * @brief Resets the distribution state.
       */
      void
      reset()
      { _M_gd.reset(); }

      /**
       * @brief Return the @f$k@f$ parameter of the distribution.
       */
      _IntType
      k() const
      { return _M_param.k(); }

      /**
       * @brief Return the @f$p@f$ parameter of the distribution.
       */
      double
      p() const
      { return _M_param.p(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return result_type(0); }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return std::numeric_limits<result_type>::max(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
        operator()(_UniformRandomNumberGenerator& __urng);

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate_impl(__f, __t, __urng); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate_impl(__f, __t, __urng); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two negative binomial distributions have
       *        the same parameters and the sequences that would be
       *        generated are equal.
       */
      friend bool
      operator==(const negative_binomial_distribution& __d1,
		 const negative_binomial_distribution& __d2)
      { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; }

      /**
       * @brief Inserts a %negative_binomial_distribution random
       *        number distribution @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %negative_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 _CharT, typename _Traits>
	friend std::basic_ostream<_CharT, _Traits>&
	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const std::negative_binomial_distribution<_IntType1>& __x);

      /**
       * @brief Extracts a %negative_binomial_distribution random number
       *        distribution @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x A %negative_binomial_distribution 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,
		   std::negative_binomial_distribution<_IntType1>& __x);

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng);
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;

      std::gamma_distribution<double> _M_gd;
    };

  /**
   * @brief Return true if two negative binomial distributions are different.
   */
  template<typename _IntType>
    inline bool
    operator!=(const std::negative_binomial_distribution<_IntType>& __d1,
	       const std::negative_binomial_distribution<_IntType>& __d2)
    { return !(__d1 == __d2); }


  /* @} */ // group random_distributions_bernoulli

  /**
   * @addtogroup random_distributions_poisson Poisson Distributions
   * @ingroup random_distributions
   * @{
   */

  /**
   * @brief A discrete Poisson random number distribution.
   *
   * The formula for the Poisson probability density function is
   * @f$p(i|\mu) = \frac{\mu^i}{i!} e^{-\mu}@f$ where @f$\mu@f$ is the
   * parameter of the distribution.
   */
  template<typename _IntType = int>
    class poisson_distribution
    {
      static_assert(std::is_integral<_IntType>::value,
		    "template argument not an integral type");

    public:
      /** The type of the range of the distribution. */
      typedef _IntType  result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef poisson_distribution<_IntType> distribution_type;
	friend class poisson_distribution<_IntType>;

	explicit
	param_type(double __mean = 1.0)
	: _M_mean(__mean)
	{
	  _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
	  _M_initialize();
	}

	double
	mean() const
	{ return _M_mean; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_mean == __p2._M_mean; }

      private:
	// Hosts either log(mean) or the threshold of the simple method.
	void
	_M_initialize();

	double _M_mean;

	double _M_lm_thr;
#if _GLIBCXX_USE_C99_MATH_TR1
	double _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
#endif
      };

      // constructors and member function
      explicit
      poisson_distribution(double __mean = 1.0)
      : _M_param(__mean), _M_nd()
      { }

      explicit
      poisson_distribution(const param_type& __p)
      : _M_param(__p), _M_nd()
      { }

      /**
       * @brief Resets the distribution state.
       */
      void
      reset()
      { _M_nd.reset(); }

      /**
       * @brief Returns the distribution parameter @p mean.
       */
      double
      mean() const
      { return _M_param.mean(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return 0; }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return std::numeric_limits<result_type>::max(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
	{ return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

       /**
	* @brief Return true if two Poisson distributions have the same
	*        parameters and the sequences that would be generated
	*        are equal.
	*/
      friend bool
      operator==(const poisson_distribution& __d1,
		 const poisson_distribution& __d2)
#ifdef _GLIBCXX_USE_C99_MATH_TR1
      { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; }
#else
      { return __d1._M_param == __d2._M_param; }
#endif

      /**
       * @brief 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 _CharT, typename _Traits>
	friend std::basic_ostream<_CharT, _Traits>&
	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		   const std::poisson_distribution<_IntType1>& __x);

      /**
       * @brief 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 _CharT, typename _Traits>
	friend std::basic_istream<_CharT, _Traits>&
	operator>>(std::basic_istream<_CharT, _Traits>& __is,
		   std::poisson_distribution<_IntType1>& __x);

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;

      // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
      std::normal_distribution<double> _M_nd;
    };

  /**
   * @brief Return true if two Poisson distributions are different.
   */
  template<typename _IntType>
    inline bool
    operator!=(const std::poisson_distribution<_IntType>& __d1,
	       const std::poisson_distribution<_IntType>& __d2)
    { return !(__d1 == __d2); }


  /**
   * @brief An exponential continuous distribution for random numbers.
   *
   * The formula for the exponential probability density function is
   * @f$p(x|\lambda) = \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
    {
      static_assert(std::is_floating_point<_RealType>::value,
		    "template argument not a floating point type");

    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef exponential_distribution<_RealType> distribution_type;

	explicit
	param_type(_RealType __lambda = _RealType(1))
	: _M_lambda(__lambda)
	{
	  _GLIBCXX_DEBUG_ASSERT(_M_lambda > _RealType(0));
	}

	_RealType
	lambda() const
	{ return _M_lambda; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_lambda == __p2._M_lambda; }

      private:
	_RealType _M_lambda;
      };

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

      explicit
      exponential_distribution(const param_type& __p)
      : _M_param(__p)
      { }

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

      /**
       * @brief Returns the inverse scale parameter of the distribution.
       */
      _RealType
      lambda() const
      { return _M_param.lambda(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return result_type(0); }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return std::numeric_limits<result_type>::max(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
        { return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{
	  __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
	    __aurng(__urng);
	  return -std::log(result_type(1) - __aurng()) / __p.lambda();
	}

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two exponential distributions have the same
       *        parameters.
       */
      friend bool
      operator==(const exponential_distribution& __d1,
		 const exponential_distribution& __d2)
      { return __d1._M_param == __d2._M_param; }

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;
    };

  /**
   * @brief Return true if two exponential distributions have different
   *        parameters.
   */
  template<typename _RealType>
    inline bool
    operator!=(const std::exponential_distribution<_RealType>& __d1,
	       const std::exponential_distribution<_RealType>& __d2)
    { return !(__d1 == __d2); }

  /**
   * @brief 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 _RealType, typename _CharT, typename _Traits>
    std::basic_ostream<_CharT, _Traits>&
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
	       const std::exponential_distribution<_RealType>& __x);

  /**
   * @brief 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 _RealType, typename _CharT, typename _Traits>
    std::basic_istream<_CharT, _Traits>&
    operator>>(std::basic_istream<_CharT, _Traits>& __is,
	       std::exponential_distribution<_RealType>& __x);


  /**
   * @brief A weibull_distribution random number distribution.
   *
   * The formula for the normal probability density function is:
   * @f[
   *     p(x|\alpha,\beta) = \frac{\alpha}{\beta} (\frac{x}{\beta})^{\alpha-1}
   *                         \exp{(-(\frac{x}{\beta})^\alpha)} 
   * @f]
   */
  template<typename _RealType = double>
    class weibull_distribution
    {
      static_assert(std::is_floating_point<_RealType>::value,
		    "template argument not a floating point type");

    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef weibull_distribution<_RealType> distribution_type;

	explicit
	param_type(_RealType __a = _RealType(1),
		   _RealType __b = _RealType(1))
	: _M_a(__a), _M_b(__b)
	{ }

	_RealType
	a() const
	{ return _M_a; }

	_RealType
	b() const
	{ return _M_b; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }

      private:
	_RealType _M_a;
	_RealType _M_b;
      };

      explicit
      weibull_distribution(_RealType __a = _RealType(1),
			   _RealType __b = _RealType(1))
      : _M_param(__a, __b)
      { }

      explicit
      weibull_distribution(const param_type& __p)
      : _M_param(__p)
      { }

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

      /**
       * @brief Return the @f$a@f$ parameter of the distribution.
       */
      _RealType
      a() const
      { return _M_param.a(); }

      /**
       * @brief Return the @f$b@f$ parameter of the distribution.
       */
      _RealType
      b() const
      { return _M_param.b(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return result_type(0); }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return std::numeric_limits<result_type>::max(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
	{ return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two Weibull distributions have the same
       *        parameters.
       */
      friend bool
      operator==(const weibull_distribution& __d1,
		 const weibull_distribution& __d2)
      { return __d1._M_param == __d2._M_param; }

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;
    };

   /**
    * @brief Return true if two Weibull distributions have different
    *        parameters.
    */
  template<typename _RealType>
    inline bool
    operator!=(const std::weibull_distribution<_RealType>& __d1,
	       const std::weibull_distribution<_RealType>& __d2)
    { return !(__d1 == __d2); }

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

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


  /**
   * @brief A extreme_value_distribution random number distribution.
   *
   * The formula for the normal probability mass function is
   * @f[
   *     p(x|a,b) = \frac{1}{b}
   *                \exp( \frac{a-x}{b} - \exp(\frac{a-x}{b})) 
   * @f]
   */
  template<typename _RealType = double>
    class extreme_value_distribution
    {
      static_assert(std::is_floating_point<_RealType>::value,
		    "template argument not a floating point type");

    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef extreme_value_distribution<_RealType> distribution_type;

	explicit
	param_type(_RealType __a = _RealType(0),
		   _RealType __b = _RealType(1))
	: _M_a(__a), _M_b(__b)
	{ }

	_RealType
	a() const
	{ return _M_a; }

	_RealType
	b() const
	{ return _M_b; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }

      private:
	_RealType _M_a;
	_RealType _M_b;
      };

      explicit
      extreme_value_distribution(_RealType __a = _RealType(0),
				 _RealType __b = _RealType(1))
      : _M_param(__a, __b)
      { }

      explicit
      extreme_value_distribution(const param_type& __p)
      : _M_param(__p)
      { }

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

      /**
       * @brief Return the @f$a@f$ parameter of the distribution.
       */
      _RealType
      a() const
      { return _M_param.a(); }

      /**
       * @brief Return the @f$b@f$ parameter of the distribution.
       */
      _RealType
      b() const
      { return _M_param.b(); }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return std::numeric_limits<result_type>::lowest(); }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      { return std::numeric_limits<result_type>::max(); }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
	{ return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two extreme value distributions have the same
       *        parameters.
       */
      friend bool
      operator==(const extreme_value_distribution& __d1,
		 const extreme_value_distribution& __d2)
      { return __d1._M_param == __d2._M_param; }

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;
    };

  /**
    * @brief Return true if two extreme value distributions have different
    *        parameters.
   */
  template<typename _RealType>
    inline bool
    operator!=(const std::extreme_value_distribution<_RealType>& __d1,
	       const std::extreme_value_distribution<_RealType>& __d2)
    { return !(__d1 == __d2); }

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

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


  /**
   * @brief A discrete_distribution random number distribution.
   *
   * The formula for the discrete probability mass function is
   *
   */
  template<typename _IntType = int>
    class discrete_distribution
    {
      static_assert(std::is_integral<_IntType>::value,
		    "template argument not an integral type");

    public:
      /** The type of the range of the distribution. */
      typedef _IntType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef discrete_distribution<_IntType> distribution_type;
	friend class discrete_distribution<_IntType>;

	param_type()
	: _M_prob(), _M_cp()
	{ }

	template<typename _InputIterator>
	  param_type(_InputIterator __wbegin,
		     _InputIterator __wend)
	  : _M_prob(__wbegin, __wend), _M_cp()
	  { _M_initialize(); }

	param_type(initializer_list<double> __wil)
	: _M_prob(__wil.begin(), __wil.end()), _M_cp()
	{ _M_initialize(); }

	template<typename _Func>
	  param_type(size_t __nw, double __xmin, double __xmax,
		     _Func __fw);

	// See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
	param_type(const param_type&) = default;
	param_type& operator=(const param_type&) = default;

	std::vector<double>
	probabilities() const
	{ return _M_prob.empty() ? std::vector<double>(1, 1.0) : _M_prob; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_prob == __p2._M_prob; }

      private:
	void
	_M_initialize();

	std::vector<double> _M_prob;
	std::vector<double> _M_cp;
      };

      discrete_distribution()
      : _M_param()
      { }

      template<typename _InputIterator>
	discrete_distribution(_InputIterator __wbegin,
			      _InputIterator __wend)
	: _M_param(__wbegin, __wend)
	{ }

      discrete_distribution(initializer_list<double> __wl)
      : _M_param(__wl)
      { }

      template<typename _Func>
	discrete_distribution(size_t __nw, double __xmin, double __xmax,
			      _Func __fw)
	: _M_param(__nw, __xmin, __xmax, __fw)
	{ }

      explicit
      discrete_distribution(const param_type& __p)
      : _M_param(__p)
      { }

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

      /**
       * @brief Returns the probabilities of the distribution.
       */
      std::vector<double>
      probabilities() const
      {
	return _M_param._M_prob.empty()
	  ? std::vector<double>(1, 1.0) : _M_param._M_prob;
      }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      { return result_type(0); }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      {
	return _M_param._M_prob.empty()
	  ? result_type(0) : result_type(_M_param._M_prob.size() - 1);
      }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
	{ return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two discrete distributions have the same
       *        parameters.
       */
      friend bool
      operator==(const discrete_distribution& __d1,
		 const discrete_distribution& __d2)
      { return __d1._M_param == __d2._M_param; }

      /**
       * @brief Inserts a %discrete_distribution random number distribution
       * @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %discrete_distribution 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 std::discrete_distribution<_IntType1>& __x);

      /**
       * @brief Extracts a %discrete_distribution random number distribution
       * @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x A %discrete_distribution 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,
		   std::discrete_distribution<_IntType1>& __x);

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;
    };

  /**
    * @brief Return true if two discrete distributions have different
    *        parameters.
    */
  template<typename _IntType>
    inline bool
    operator!=(const std::discrete_distribution<_IntType>& __d1,
	       const std::discrete_distribution<_IntType>& __d2)
    { return !(__d1 == __d2); }


  /**
   * @brief A piecewise_constant_distribution random number distribution.
   *
   * The formula for the piecewise constant probability mass function is
   *
   */
  template<typename _RealType = double>
    class piecewise_constant_distribution
    {
      static_assert(std::is_floating_point<_RealType>::value,
		    "template argument not a floating point type");

    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef piecewise_constant_distribution<_RealType> distribution_type;
	friend class piecewise_constant_distribution<_RealType>;

	param_type()
	: _M_int(), _M_den(), _M_cp()
	{ }

	template<typename _InputIteratorB, typename _InputIteratorW>
	  param_type(_InputIteratorB __bfirst,
		     _InputIteratorB __bend,
		     _InputIteratorW __wbegin);

	template<typename _Func>
	  param_type(initializer_list<_RealType> __bi, _Func __fw);

	template<typename _Func>
	  param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
		     _Func __fw);

	// See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
	param_type(const param_type&) = default;
	param_type& operator=(const param_type&) = default;

	std::vector<_RealType>
	intervals() const
	{
	  if (_M_int.empty())
	    {
	      std::vector<_RealType> __tmp(2);
	      __tmp[1] = _RealType(1);
	      return __tmp;
	    }
	  else
	    return _M_int;
	}

	std::vector<double>
	densities() const
	{ return _M_den.empty() ? std::vector<double>(1, 1.0) : _M_den; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; }

      private:
	void
	_M_initialize();

	std::vector<_RealType> _M_int;
	std::vector<double> _M_den;
	std::vector<double> _M_cp;
      };

      explicit
      piecewise_constant_distribution()
      : _M_param()
      { }

      template<typename _InputIteratorB, typename _InputIteratorW>
	piecewise_constant_distribution(_InputIteratorB __bfirst,
					_InputIteratorB __bend,
					_InputIteratorW __wbegin)
	: _M_param(__bfirst, __bend, __wbegin)
	{ }

      template<typename _Func>
	piecewise_constant_distribution(initializer_list<_RealType> __bl,
					_Func __fw)
	: _M_param(__bl, __fw)
	{ }

      template<typename _Func>
	piecewise_constant_distribution(size_t __nw,
					_RealType __xmin, _RealType __xmax,
					_Func __fw)
	: _M_param(__nw, __xmin, __xmax, __fw)
	{ }

      explicit
      piecewise_constant_distribution(const param_type& __p)
      : _M_param(__p)
      { }

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

      /**
       * @brief Returns a vector of the intervals.
       */
      std::vector<_RealType>
      intervals() const
      {
	if (_M_param._M_int.empty())
	  {
	    std::vector<_RealType> __tmp(2);
	    __tmp[1] = _RealType(1);
	    return __tmp;
	  }
	else
	  return _M_param._M_int;
      }

      /**
       * @brief Returns a vector of the probability densities.
       */
      std::vector<double>
      densities() const
      {
	return _M_param._M_den.empty()
	  ? std::vector<double>(1, 1.0) : _M_param._M_den;
      }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      {
	return _M_param._M_int.empty()
	  ? result_type(0) : _M_param._M_int.front();
      }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      {
	return _M_param._M_int.empty()
	  ? result_type(1) : _M_param._M_int.back();
      }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
	{ return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two piecewise constant distributions have the
       *        same parameters.
       */
      friend bool
      operator==(const piecewise_constant_distribution& __d1,
		 const piecewise_constant_distribution& __d2)
      { return __d1._M_param == __d2._M_param; }

      /**
       * @brief Inserts a %piecewise_constant_distribution random
       *        number distribution @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %piecewise_constant_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 std::piecewise_constant_distribution<_RealType1>& __x);

      /**
       * @brief Extracts a %piecewise_constant_distribution random
       *        number distribution @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x A %piecewise_constant_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,
		   std::piecewise_constant_distribution<_RealType1>& __x);

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;
    };

  /**
    * @brief Return true if two piecewise constant distributions have 
    *        different parameters.
   */
  template<typename _RealType>
    inline bool
    operator!=(const std::piecewise_constant_distribution<_RealType>& __d1,
	       const std::piecewise_constant_distribution<_RealType>& __d2)
    { return !(__d1 == __d2); }


  /**
   * @brief A piecewise_linear_distribution random number distribution.
   *
   * The formula for the piecewise linear probability mass function is
   *
   */
  template<typename _RealType = double>
    class piecewise_linear_distribution
    {
      static_assert(std::is_floating_point<_RealType>::value,
		    "template argument not a floating point type");

    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
      /** Parameter type. */
      struct param_type
      {
	typedef piecewise_linear_distribution<_RealType> distribution_type;
	friend class piecewise_linear_distribution<_RealType>;

	param_type()
	: _M_int(), _M_den(), _M_cp(), _M_m()
	{ }

	template<typename _InputIteratorB, typename _InputIteratorW>
	  param_type(_InputIteratorB __bfirst,
		     _InputIteratorB __bend,
		     _InputIteratorW __wbegin);

	template<typename _Func>
	  param_type(initializer_list<_RealType> __bl, _Func __fw);

	template<typename _Func>
	  param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
		     _Func __fw);

	// See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
	param_type(const param_type&) = default;
	param_type& operator=(const param_type&) = default;

	std::vector<_RealType>
	intervals() const
	{
	  if (_M_int.empty())
	    {
	      std::vector<_RealType> __tmp(2);
	      __tmp[1] = _RealType(1);
	      return __tmp;
	    }
	  else
	    return _M_int;
	}

	std::vector<double>
	densities() const
	{ return _M_den.empty() ? std::vector<double>(2, 1.0) : _M_den; }

	friend bool
	operator==(const param_type& __p1, const param_type& __p2)
	{ return (__p1._M_int == __p2._M_int
		  && __p1._M_den == __p2._M_den); }

      private:
	void
	_M_initialize();

	std::vector<_RealType> _M_int;
	std::vector<double> _M_den;
	std::vector<double> _M_cp;
	std::vector<double> _M_m;
      };

      explicit
      piecewise_linear_distribution()
      : _M_param()
      { }

      template<typename _InputIteratorB, typename _InputIteratorW>
	piecewise_linear_distribution(_InputIteratorB __bfirst,
				      _InputIteratorB __bend,
				      _InputIteratorW __wbegin)
	: _M_param(__bfirst, __bend, __wbegin)
	{ }

      template<typename _Func>
	piecewise_linear_distribution(initializer_list<_RealType> __bl,
				      _Func __fw)
	: _M_param(__bl, __fw)
	{ }

      template<typename _Func>
	piecewise_linear_distribution(size_t __nw,
				      _RealType __xmin, _RealType __xmax,
				      _Func __fw)
	: _M_param(__nw, __xmin, __xmax, __fw)
	{ }

      explicit
      piecewise_linear_distribution(const param_type& __p)
      : _M_param(__p)
      { }

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

      /**
       * @brief Return the intervals of the distribution.
       */
      std::vector<_RealType>
      intervals() const
      {
	if (_M_param._M_int.empty())
	  {
	    std::vector<_RealType> __tmp(2);
	    __tmp[1] = _RealType(1);
	    return __tmp;
	  }
	else
	  return _M_param._M_int;
      }

      /**
       * @brief Return a vector of the probability densities of the
       *        distribution.
       */
      std::vector<double>
      densities() const
      {
	return _M_param._M_den.empty()
	  ? std::vector<double>(2, 1.0) : _M_param._M_den;
      }

      /**
       * @brief Returns the parameter set of the distribution.
       */
      param_type
      param() const
      { return _M_param; }

      /**
       * @brief Sets the parameter set of the distribution.
       * @param __param The new parameter set of the distribution.
       */
      void
      param(const param_type& __param)
      { _M_param = __param; }

      /**
       * @brief Returns the greatest lower bound value of the distribution.
       */
      result_type
      min() const
      {
	return _M_param._M_int.empty()
	  ? result_type(0) : _M_param._M_int.front();
      }

      /**
       * @brief Returns the least upper bound value of the distribution.
       */
      result_type
      max() const
      {
	return _M_param._M_int.empty()
	  ? result_type(1) : _M_param._M_int.back();
      }

      /**
       * @brief Generating functions.
       */
      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng)
	{ return this->operator()(__urng, _M_param); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __p);

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng)
	{ this->__generate(__f, __t, __urng, _M_param); }

      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate(_ForwardIterator __f, _ForwardIterator __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      template<typename _UniformRandomNumberGenerator>
	void
	__generate(result_type* __f, result_type* __t,
		   _UniformRandomNumberGenerator& __urng,
		   const param_type& __p)
	{ this->__generate_impl(__f, __t, __urng, __p); }

      /**
       * @brief Return true if two piecewise linear distributions have the
       *        same parameters.
       */
      friend bool
      operator==(const piecewise_linear_distribution& __d1,
		 const piecewise_linear_distribution& __d2)
      { return __d1._M_param == __d2._M_param; }

      /**
       * @brief Inserts a %piecewise_linear_distribution random number
       *        distribution @p __x into the output stream @p __os.
       *
       * @param __os An output stream.
       * @param __x  A %piecewise_linear_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 std::piecewise_linear_distribution<_RealType1>& __x);

      /**
       * @brief Extracts a %piecewise_linear_distribution random number
       *        distribution @p __x from the input stream @p __is.
       *
       * @param __is An input stream.
       * @param __x  A %piecewise_linear_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,
		   std::piecewise_linear_distribution<_RealType1>& __x);

    private:
      template<typename _ForwardIterator,
	       typename _UniformRandomNumberGenerator>
	void
	__generate_impl(_ForwardIterator __f, _ForwardIterator __t,
			_UniformRandomNumberGenerator& __urng,
			const param_type& __p);

      param_type _M_param;
    };

  /**
    * @brief Return true if two piecewise linear distributions have
    *        different parameters.
   */
  template<typename _RealType>
    inline bool
    operator!=(const std::piecewise_linear_distribution<_RealType>& __d1,
	       const std::piecewise_linear_distribution<_RealType>& __d2)
    { return !(__d1 == __d2); }


  /* @} */ // group random_distributions_poisson

  /* @} */ // group random_distributions

  /**
   * @addtogroup random_utilities Random Number Utilities
   * @ingroup random
   * @{
   */

  /**
   * @brief The seed_seq class generates sequences of seeds for random
   *        number generators.
   */
  class seed_seq
  {

  public:
    /** The type of the seed vales. */
    typedef uint_least32_t result_type;

    /** Default constructor. */
    seed_seq()
    : _M_v()
    { }

    template<typename _IntType>
      seed_seq(std::initializer_list<_IntType> il);

    template<typename _InputIterator>
      seed_seq(_InputIterator __begin, _InputIterator __end);

    // generating functions
    template<typename _RandomAccessIterator>
      void
      generate(_RandomAccessIterator __begin, _RandomAccessIterator __end);

    // property functions
    size_t size() const
    { return _M_v.size(); }

    template<typename OutputIterator>
      void
      param(OutputIterator __dest) const
      { std::copy(_M_v.begin(), _M_v.end(), __dest); }

  private:
    ///
    std::vector<result_type> _M_v;
  };

  /* @} */ // group random_utilities

  /* @} */ // group random

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif
