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

// Copyright (C) 2009, 2010, 2011 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<typename _Tp, _Tp __m, _Tp __a, _Tp __c, bool>
      struct _Mod;

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

    /*
     * 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>&,
		   const std::linear_congruential_engine<_UIntType1,
		   __a1, __c1, __m1>&);

      /**
       * @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>&,
		   std::linear_congruential_engine<_UIntType1, __a1,
		   __c1, __m1>&);

    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.
   *
   * @var word_size   The number of bits in each element of the state vector.
   * @var state_size  The degree of recursion.
   * @var shift_size  The period parameter.
   * @var mask_bits   The separation point bit index.
   * @var parameter_a The last row of the twist matrix.
   * @var output_u    The first right-shift tempering matrix parameter.
   * @var output_s    The first left-shift tempering matrix parameter.
   * @var output_b    The first left-shift tempering matrix mask.
   * @var output_t    The second left-shift tempering matrix parameter.
   * @var output_c    The second left-shift tempering matrix mask.
   * @var output_l    The second right-shift tempering matrix parameter.
   */
  template<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)
      {
	for (; __z != 0ULL; --__z)
	  (*this)();
      }

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

      /**
       * @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>&,
		   const std::mersenne_twister_engine<_UIntType1, __w1, __n1,
		   __m1, __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
		   __l1, __f1>&);

      /**
       * @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>&,
		   std::mersenne_twister_engine<_UIntType1, __w1, __n1, __m1,
		   __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
		   __l1, __f1>&);

    private:
      _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); }

      /**
       * @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& __rne)
      : _M_b(__rne), _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&& __rne)
      : _M_b(std::move(__rne)), _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
      { 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>&,
		   const std::discard_block_engine<_RandomNumberEngine1,
		   __p1, __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 %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>&,
		   std::discard_block_engine<_RandomNumberEngine1,
		   __p1, __r1>&);

    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& __rne)
      : _M_b(__rne) { }

      /**
       * @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&& __rne)
      : _M_b(std::move(__rne)) { }

      /**
       * @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
      { 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& __rne)
      : _M_b(__rne)
      { _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&& __rne)
      : _M_b(std::move(__rne))
      { _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
      { 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; }

      /**
       * @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>&,
		   const std::shuffle_order_engine<_RandomNumberEngine1,
		   __k1>&);

      /**
       * @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>&,
		   std::shuffle_order_engine<_RandomNumberEngine1, __k1>&);

    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 = "/dev/urandom")
    {
      if ((__token != "/dev/urandom" && __token != "/dev/random")
	  || !(_M_file = std::fopen(__token.c_str(), "rb")))
	std::__throw_runtime_error(__N("random_device::"
				       "random_device(const std::string&)"));
    }

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

#else

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

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

  public:

#endif

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

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

    double
    entropy() const
    { return 0.0; }

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

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

  private:

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

  /* @} */ // 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, this->param()); }

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

      param_type _M_param;
    };

  /**
   * @brief Return true if two uniform integer distributions have
   *        the same parameters.
   */
  template<typename _IntType>
    inline bool
    operator==(const std::uniform_int_distribution<_IntType>& __d1,
	       const std::uniform_int_distribution<_IntType>& __d2)
    { return __d1.param() == __d2.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 __min [IN]  The lower bound of the distribution.
       * @param __max [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, this->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();
	}

    private:
      param_type _M_param;
    };

  /**
   * @brief Return true if two uniform real distributions have
   *        the same parameters.
   */
  template<typename _IntType>
    inline bool
    operator==(const std::uniform_real_distribution<_IntType>& __d1,
	       const std::uniform_real_distribution<_IntType>& __d2)
    { return __d1.param() == __d2.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>::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, this->param()); }

      template<typename _UniformRandomNumberGenerator>
	result_type
	operator()(_UniformRandomNumberGenerator& __urng,
		   const param_type& __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>&,
		   const std::normal_distribution<_RealType1>&);

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

    private:
      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, this->param()); }

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

      /**
       * @brief Return true if two lognormal distributions have
       *        the same parameters and the sequences that would
       *        be generated are equal.
       */
      template<typename _RealType1>
        friend bool
        operator==(const std::lognormal_distribution<_RealType1>& __d1,
		   const std::lognormal_distribution<_RealType1>& __d2)
        { return (__d1.param() == __d2.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>&,
		   const std::lognormal_distribution<_RealType1>&);

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

    private:
      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, this->param()); }

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

      /**
       * @brief Return true if two gamma distributions have the same
       *        parameters and the sequences that would be generated
       *        are equal.
       */
      template<typename _RealType1>
        friend bool
        operator==(const std::gamma_distribution<_RealType1>& __d1,
		   const std::gamma_distribution<_RealType1>& __d2)
        { return (__d1.param() == __d2.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>&,
		   const std::gamma_distribution<_RealType1>&);

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

    private:
      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));
	}

      /**
       * @brief Return true if two Chi-squared distributions have
       *        the same parameters and the sequences that would be
       *        generated are equal.
       */
      template<typename _RealType1>
        friend bool
        operator==(const std::chi_squared_distribution<_RealType1>& __d1,
		   const std::chi_squared_distribution<_RealType1>& __d2)
        { return __d1.param() == __d2.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>&,
		   const std::chi_squared_distribution<_RealType1>&);

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

    private:
      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>::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, this->param()); }

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

    private:
      param_type _M_param;
    };

  /**
   * @brief Return true if two Cauchy distributions have
   *        the same parameters.
   */
  template<typename _RealType>
    inline bool
    operator==(const std::cauchy_distribution<_RealType>& __d1,
	       const std::cauchy_distribution<_RealType>& __d2)
    { return __d1.param() == __d2.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>&,
	       const std::cauchy_distribution<_RealType>&);

  /**
   * @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>&,
	       std::cauchy_distribution<_RealType>&);


  /**
   * @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()));
	}

      /**
       * @brief Return true if two Fisher f distributions have
       *        the same parameters and the sequences that would
       *        be generated are equal.
       */
      template<typename _RealType1>
        friend bool
        operator==(const std::fisher_f_distribution<_RealType1>& __d1,
		   const std::fisher_f_distribution<_RealType1>& __d2)
        { return (__d1.param() == __d2.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>&,
		   const std::fisher_f_distribution<_RealType1>&);

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

    private:
      param_type _M_param;

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

  /**
   * @brief Return true if two Fisher f distributions are diferent.
   */
  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>::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 _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);
        }

      /**
       * @brief Return true if two Student t distributions have
       *        the same parameters and the sequences that would
       *        be generated are equal.
       */
      template<typename _RealType1>
        friend bool
        operator==(const std::student_t_distribution<_RealType1>& __d1,
		   const std::student_t_distribution<_RealType1>& __d2)
        { return (__d1.param() == __d2.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>&,
		   const std::student_t_distribution<_RealType1>&);

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

    private:
      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, this->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;
      }

  private:
    param_type _M_param;
  };

  /**
   * @brief Return true if two Bernoulli distributions have
   *        the same parameters.
   */
  inline bool
  operator==(const std::bernoulli_distribution& __d1,
	     const std::bernoulli_distribution& __d2)
  { return __d1.param() == __d2.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>&,
	       const std::bernoulli_distribution&);

  /**
   * @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{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 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, this->param()); }

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

      /**
       * @brief Return true if two binomial distributions have
       *        the same parameters and the sequences that would
       *        be generated are equal.
       */
      template<typename _IntType1>
	friend bool
        operator==(const std::binomial_distribution<_IntType1>& __d1,
		   const std::binomial_distribution<_IntType1>& __d2)
#ifdef _GLIBCXX_USE_C99_MATH_TR1
	{ return __d1.param() == __d2.param() && __d1._M_nd == __d2._M_nd; }
#else
        { return __d1.param() == __d2.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>&,
		   const std::binomial_distribution<_IntType1>&);

      /**
       * @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>&,
		   std::binomial_distribution<_IntType1>&);

    private:
      template<typename _UniformRandomNumberGenerator>
	result_type
	_M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);

      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, this->param()); }

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

    private:
      param_type _M_param;
    };

  /**
   * @brief Return true if two geometric distributions have
   *        the same parameters.
   */
  template<typename _IntType>
    inline bool
    operator==(const std::geometric_distribution<_IntType>& __d1,
	       const std::geometric_distribution<_IntType>& __d2)
    { return __d1.param() == __d2.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>&,
	       const std::geometric_distribution<_IntType>&);

  /**
   * @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>&,
	       std::geometric_distribution<_IntType>&);


  /**
   * @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);

      /**
       * @brief Return true if two negative binomial distributions have
       *        the same parameters and the sequences that would be
       *        generated are equal.
       */
      template<typename _IntType1>
        friend bool
        operator==(const std::negative_binomial_distribution<_IntType1>& __d1,
		   const std::negative_binomial_distribution<_IntType1>& __d2)
        { return __d1.param() == __d2.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>&,
		   const std::negative_binomial_distribution<_IntType1>&);

      /**
       * @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>&,
		   std::negative_binomial_distribution<_IntType1>&);

    private:
      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, this->param()); }

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

       /**
	* @brief Return true if two Poisson distributions have the same
	*        parameters and the sequences that would be generated
	*        are equal.
	*/
      template<typename _IntType1>
        friend bool
        operator==(const std::poisson_distribution<_IntType1>& __d1,
		   const std::poisson_distribution<_IntType1>& __d2)
#ifdef _GLIBCXX_USE_C99_MATH_TR1
        { return __d1.param() == __d2.param() && __d1._M_nd == __d2._M_nd; }
#else
        { return __d1.param() == __d2.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>&,
		   const std::poisson_distribution<_IntType1>&);

      /**
       * @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>&,
		   std::poisson_distribution<_IntType1>&);

    private:
      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, this->param()); }

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

    private:
      param_type _M_param;
    };

  /**
   * @brief Return true if two exponential distributions have the same
   *        parameters.
   */
  template<typename _RealType>
    inline bool
    operator==(const std::exponential_distribution<_RealType>& __d1,
	       const std::exponential_distribution<_RealType>& __d2)
    { return __d1.param() == __d2.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>&,
	       const std::exponential_distribution<_RealType>&);

  /**
   * @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>&,
	       std::exponential_distribution<_RealType>&);


  /**
   * @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, this->param()); }

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

    private:
      param_type _M_param;
    };

   /**
    * @brief Return true if two Weibull distributions have the same
    *        parameters.
    */
  template<typename _RealType>
    inline bool
    operator==(const std::weibull_distribution<_RealType>& __d1,
	       const std::weibull_distribution<_RealType>& __d2)
    { return __d1.param() == __d2.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>&,
	       const std::weibull_distribution<_RealType>&);

  /**
   * @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>&,
	       std::weibull_distribution<_RealType>&);


  /**
   * @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>::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, this->param()); }

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

    private:
      param_type _M_param;
    };

  /**
    * @brief Return true if two extreme value distributions have the same
    *        parameters.
   */
  template<typename _RealType>
    inline bool
    operator==(const std::extreme_value_distribution<_RealType>& __d1,
	       const std::extreme_value_distribution<_RealType>& __d2)
    { return __d1.param() == __d2.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>&,
	       const std::extreme_value_distribution<_RealType>&);

  /**
   * @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>&,
	       std::extreme_value_distribution<_RealType>&);


  /**
   * @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, this->param()); }

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

      /**
       * @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>&,
		   const std::discrete_distribution<_IntType1>&);

      /**
       * @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>&,
		   std::discrete_distribution<_IntType1>&);

    private:
      param_type _M_param;
    };

  /**
    * @brief Return true if two discrete distributions have the same
    *        parameters.
    */
  template<typename _IntType>
    inline bool
    operator==(const std::discrete_distribution<_IntType>& __d1,
	       const std::discrete_distribution<_IntType>& __d2)
    { return __d1.param() == __d2.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, this->param()); }

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

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

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

    private:
      param_type _M_param;
    };

  /**
    * @brief Return true if two piecewise constant distributions have the
    *        same parameters.
   */
  template<typename _RealType>
    inline bool
    operator==(const std::piecewise_constant_distribution<_RealType>& __d1,
	       const std::piecewise_constant_distribution<_RealType>& __d2)
    { return __d1.param() == __d2.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, this->param()); }

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

      /**
       * @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>&,
		   const std::piecewise_linear_distribution<_RealType1>&);

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

    private:
      param_type _M_param;
    };

  /**
    * @brief Return true if two piecewise linear distributions have the
    *        same parameters.
   */
  template<typename _RealType>
    inline bool
    operator==(const std::piecewise_linear_distribution<_RealType>& __d1,
	       const std::piecewise_linear_distribution<_RealType>& __d2)
    { return __d1.param() == __d2.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
