xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/bits/random.h (revision 81fc95a5293ee307c688a350a3feb4734aaddbb4)
1e4b17023SJohn Marino // random number generation -*- C++ -*-
2e4b17023SJohn Marino 
3*5ce9237cSJohn Marino // Copyright (C) 2009-2012 Free Software Foundation, Inc.
4e4b17023SJohn Marino //
5e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library.  This library is free
6e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the
7e4b17023SJohn Marino // terms of the GNU General Public License as published by the
8e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option)
9e4b17023SJohn Marino // any later version.
10e4b17023SJohn Marino 
11e4b17023SJohn Marino // This library is distributed in the hope that it will be useful,
12e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
13e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14e4b17023SJohn Marino // GNU General Public License for more details.
15e4b17023SJohn Marino 
16e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
17e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
18e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
19e4b17023SJohn Marino 
20e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
21e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
22e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
24e4b17023SJohn Marino 
25e4b17023SJohn Marino /**
26e4b17023SJohn Marino  * @file bits/random.h
27e4b17023SJohn Marino  *  This is an internal header file, included by other library headers.
28e4b17023SJohn Marino  *  Do not attempt to use it directly. @headername{random}
29e4b17023SJohn Marino  */
30e4b17023SJohn Marino 
31e4b17023SJohn Marino #ifndef _RANDOM_H
32e4b17023SJohn Marino #define _RANDOM_H 1
33e4b17023SJohn Marino 
34e4b17023SJohn Marino #include <vector>
35e4b17023SJohn Marino 
_GLIBCXX_VISIBILITY(default)36e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default)
37e4b17023SJohn Marino {
38e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
39e4b17023SJohn Marino 
40e4b17023SJohn Marino   // [26.4] Random number generation
41e4b17023SJohn Marino 
42e4b17023SJohn Marino   /**
43e4b17023SJohn Marino    * @defgroup random Random Number Generation
44e4b17023SJohn Marino    * @ingroup numerics
45e4b17023SJohn Marino    *
46e4b17023SJohn Marino    * A facility for generating random numbers on selected distributions.
47e4b17023SJohn Marino    * @{
48e4b17023SJohn Marino    */
49e4b17023SJohn Marino 
50e4b17023SJohn Marino   /**
51e4b17023SJohn Marino    * @brief A function template for converting the output of a (integral)
52e4b17023SJohn Marino    * uniform random number generator to a floatng point result in the range
53e4b17023SJohn Marino    * [0-1).
54e4b17023SJohn Marino    */
55e4b17023SJohn Marino   template<typename _RealType, size_t __bits,
56e4b17023SJohn Marino 	   typename _UniformRandomNumberGenerator>
57e4b17023SJohn Marino     _RealType
58e4b17023SJohn Marino     generate_canonical(_UniformRandomNumberGenerator& __g);
59e4b17023SJohn Marino 
60e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
61e4b17023SJohn Marino 
62e4b17023SJohn Marino   /*
63e4b17023SJohn Marino    * Implementation-space details.
64e4b17023SJohn Marino    */
65e4b17023SJohn Marino   namespace __detail
66e4b17023SJohn Marino   {
67e4b17023SJohn Marino   _GLIBCXX_BEGIN_NAMESPACE_VERSION
68e4b17023SJohn Marino 
69e4b17023SJohn Marino     template<typename _UIntType, size_t __w,
70e4b17023SJohn Marino 	     bool = __w < static_cast<size_t>
71e4b17023SJohn Marino 			  (std::numeric_limits<_UIntType>::digits)>
72e4b17023SJohn Marino       struct _Shift
73e4b17023SJohn Marino       { static const _UIntType __value = 0; };
74e4b17023SJohn Marino 
75e4b17023SJohn Marino     template<typename _UIntType, size_t __w>
76e4b17023SJohn Marino       struct _Shift<_UIntType, __w, true>
77e4b17023SJohn Marino       { static const _UIntType __value = _UIntType(1) << __w; };
78e4b17023SJohn Marino 
79e4b17023SJohn Marino     template<typename _Tp, _Tp __m, _Tp __a, _Tp __c, bool>
80e4b17023SJohn Marino       struct _Mod;
81e4b17023SJohn Marino 
82e4b17023SJohn Marino     // Dispatch based on modulus value to prevent divide-by-zero compile-time
83e4b17023SJohn Marino     // errors when m == 0.
84e4b17023SJohn Marino     template<typename _Tp, _Tp __m, _Tp __a = 1, _Tp __c = 0>
85e4b17023SJohn Marino       inline _Tp
86e4b17023SJohn Marino       __mod(_Tp __x)
87e4b17023SJohn Marino       { return _Mod<_Tp, __m, __a, __c, __m == 0>::__calc(__x); }
88e4b17023SJohn Marino 
89e4b17023SJohn Marino     /*
90e4b17023SJohn Marino      * An adaptor class for converting the output of any Generator into
91e4b17023SJohn Marino      * the input for a specific Distribution.
92e4b17023SJohn Marino      */
93e4b17023SJohn Marino     template<typename _Engine, typename _DInputType>
94e4b17023SJohn Marino       struct _Adaptor
95e4b17023SJohn Marino       {
96e4b17023SJohn Marino 
97e4b17023SJohn Marino       public:
98e4b17023SJohn Marino 	_Adaptor(_Engine& __g)
99e4b17023SJohn Marino 	: _M_g(__g) { }
100e4b17023SJohn Marino 
101e4b17023SJohn Marino 	_DInputType
102e4b17023SJohn Marino 	min() const
103e4b17023SJohn Marino 	{ return _DInputType(0); }
104e4b17023SJohn Marino 
105e4b17023SJohn Marino 	_DInputType
106e4b17023SJohn Marino 	max() const
107e4b17023SJohn Marino 	{ return _DInputType(1); }
108e4b17023SJohn Marino 
109e4b17023SJohn Marino 	/*
110e4b17023SJohn Marino 	 * Converts a value generated by the adapted random number generator
111e4b17023SJohn Marino 	 * into a value in the input domain for the dependent random number
112e4b17023SJohn Marino 	 * distribution.
113e4b17023SJohn Marino 	 */
114e4b17023SJohn Marino 	_DInputType
115e4b17023SJohn Marino 	operator()()
116e4b17023SJohn Marino 	{
117e4b17023SJohn Marino 	  return std::generate_canonical<_DInputType,
118e4b17023SJohn Marino 	                            std::numeric_limits<_DInputType>::digits,
119e4b17023SJohn Marino 	                            _Engine>(_M_g);
120e4b17023SJohn Marino 	}
121e4b17023SJohn Marino 
122e4b17023SJohn Marino       private:
123e4b17023SJohn Marino 	_Engine& _M_g;
124e4b17023SJohn Marino       };
125e4b17023SJohn Marino 
126e4b17023SJohn Marino   _GLIBCXX_END_NAMESPACE_VERSION
127e4b17023SJohn Marino   } // namespace __detail
128e4b17023SJohn Marino 
129e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
130e4b17023SJohn Marino 
131e4b17023SJohn Marino   /**
132e4b17023SJohn Marino    * @addtogroup random_generators Random Number Generators
133e4b17023SJohn Marino    * @ingroup random
134e4b17023SJohn Marino    *
135e4b17023SJohn Marino    * These classes define objects which provide random or pseudorandom
136e4b17023SJohn Marino    * numbers, either from a discrete or a continuous interval.  The
137e4b17023SJohn Marino    * random number generator supplied as a part of this library are
138e4b17023SJohn Marino    * all uniform random number generators which provide a sequence of
139e4b17023SJohn Marino    * random number uniformly distributed over their range.
140e4b17023SJohn Marino    *
141e4b17023SJohn Marino    * A number generator is a function object with an operator() that
142e4b17023SJohn Marino    * takes zero arguments and returns a number.
143e4b17023SJohn Marino    *
144e4b17023SJohn Marino    * A compliant random number generator must satisfy the following
145e4b17023SJohn Marino    * requirements.  <table border=1 cellpadding=10 cellspacing=0>
146e4b17023SJohn Marino    * <caption align=top>Random Number Generator Requirements</caption>
147e4b17023SJohn Marino    * <tr><td>To be documented.</td></tr> </table>
148e4b17023SJohn Marino    *
149e4b17023SJohn Marino    * @{
150e4b17023SJohn Marino    */
151e4b17023SJohn Marino 
152e4b17023SJohn Marino   /**
153e4b17023SJohn Marino    * @brief A model of a linear congruential random number generator.
154e4b17023SJohn Marino    *
155e4b17023SJohn Marino    * A random number generator that produces pseudorandom numbers via
156e4b17023SJohn Marino    * linear function:
157e4b17023SJohn Marino    * @f[
158e4b17023SJohn Marino    *     x_{i+1}\leftarrow(ax_{i} + c) \bmod m
159e4b17023SJohn Marino    * @f]
160e4b17023SJohn Marino    *
161e4b17023SJohn Marino    * The template parameter @p _UIntType must be an unsigned integral type
162e4b17023SJohn Marino    * large enough to store values up to (__m-1). If the template parameter
163e4b17023SJohn Marino    * @p __m is 0, the modulus @p __m used is
164e4b17023SJohn Marino    * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
165e4b17023SJohn Marino    * parameters @p __a and @p __c must be less than @p __m.
166e4b17023SJohn Marino    *
167e4b17023SJohn Marino    * The size of the state is @f$1@f$.
168e4b17023SJohn Marino    */
169e4b17023SJohn Marino   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
170e4b17023SJohn Marino     class linear_congruential_engine
171e4b17023SJohn Marino     {
172e4b17023SJohn Marino       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
173e4b17023SJohn Marino 		    "substituting _UIntType not an unsigned integral type");
174e4b17023SJohn Marino       static_assert(__m == 0u || (__a < __m && __c < __m),
175e4b17023SJohn Marino 		    "template argument substituting __m out of bounds");
176e4b17023SJohn Marino 
177e4b17023SJohn Marino       // XXX FIXME:
178e4b17023SJohn Marino       // _Mod::__calc should handle correctly __m % __a >= __m / __a too.
179e4b17023SJohn Marino       static_assert(__m % __a < __m / __a,
180e4b17023SJohn Marino 		    "sorry, not implemented yet: try a smaller 'a' constant");
181e4b17023SJohn Marino 
182e4b17023SJohn Marino     public:
183e4b17023SJohn Marino       /** The type of the generated random value. */
184e4b17023SJohn Marino       typedef _UIntType result_type;
185e4b17023SJohn Marino 
186e4b17023SJohn Marino       /** The multiplier. */
187e4b17023SJohn Marino       static constexpr result_type multiplier   = __a;
188e4b17023SJohn Marino       /** An increment. */
189e4b17023SJohn Marino       static constexpr result_type increment    = __c;
190e4b17023SJohn Marino       /** The modulus. */
191e4b17023SJohn Marino       static constexpr result_type modulus      = __m;
192e4b17023SJohn Marino       static constexpr result_type default_seed = 1u;
193e4b17023SJohn Marino 
194e4b17023SJohn Marino       /**
195e4b17023SJohn Marino        * @brief Constructs a %linear_congruential_engine random number
196e4b17023SJohn Marino        *        generator engine with seed @p __s.  The default seed value
197e4b17023SJohn Marino        *        is 1.
198e4b17023SJohn Marino        *
199e4b17023SJohn Marino        * @param __s The initial seed value.
200e4b17023SJohn Marino        */
201e4b17023SJohn Marino       explicit
202e4b17023SJohn Marino       linear_congruential_engine(result_type __s = default_seed)
203e4b17023SJohn Marino       { seed(__s); }
204e4b17023SJohn Marino 
205e4b17023SJohn Marino       /**
206e4b17023SJohn Marino        * @brief Constructs a %linear_congruential_engine random number
207e4b17023SJohn Marino        *        generator engine seeded from the seed sequence @p __q.
208e4b17023SJohn Marino        *
209e4b17023SJohn Marino        * @param __q the seed sequence.
210e4b17023SJohn Marino        */
211e4b17023SJohn Marino       template<typename _Sseq, typename = typename
212e4b17023SJohn Marino 	std::enable_if<!std::is_same<_Sseq, linear_congruential_engine>::value>
213e4b17023SJohn Marino 	       ::type>
214e4b17023SJohn Marino         explicit
215e4b17023SJohn Marino         linear_congruential_engine(_Sseq& __q)
216e4b17023SJohn Marino         { seed(__q); }
217e4b17023SJohn Marino 
218e4b17023SJohn Marino       /**
219e4b17023SJohn Marino        * @brief Reseeds the %linear_congruential_engine random number generator
220e4b17023SJohn Marino        *        engine sequence to the seed @p __s.
221e4b17023SJohn Marino        *
222e4b17023SJohn Marino        * @param __s The new seed.
223e4b17023SJohn Marino        */
224e4b17023SJohn Marino       void
225e4b17023SJohn Marino       seed(result_type __s = default_seed);
226e4b17023SJohn Marino 
227e4b17023SJohn Marino       /**
228e4b17023SJohn Marino        * @brief Reseeds the %linear_congruential_engine random number generator
229e4b17023SJohn Marino        *        engine
230e4b17023SJohn Marino        * sequence using values from the seed sequence @p __q.
231e4b17023SJohn Marino        *
232e4b17023SJohn Marino        * @param __q the seed sequence.
233e4b17023SJohn Marino        */
234e4b17023SJohn Marino       template<typename _Sseq>
235e4b17023SJohn Marino         typename std::enable_if<std::is_class<_Sseq>::value>::type
236e4b17023SJohn Marino         seed(_Sseq& __q);
237e4b17023SJohn Marino 
238e4b17023SJohn Marino       /**
239e4b17023SJohn Marino        * @brief Gets the smallest possible value in the output range.
240e4b17023SJohn Marino        *
241e4b17023SJohn Marino        * The minimum depends on the @p __c parameter: if it is zero, the
242e4b17023SJohn Marino        * minimum generated must be > 0, otherwise 0 is allowed.
243e4b17023SJohn Marino        */
244e4b17023SJohn Marino       static constexpr result_type
245e4b17023SJohn Marino       min()
246e4b17023SJohn Marino       { return __c == 0u ? 1u : 0u; }
247e4b17023SJohn Marino 
248e4b17023SJohn Marino       /**
249e4b17023SJohn Marino        * @brief Gets the largest possible value in the output range.
250e4b17023SJohn Marino        */
251e4b17023SJohn Marino       static constexpr result_type
252e4b17023SJohn Marino       max()
253e4b17023SJohn Marino       { return __m - 1u; }
254e4b17023SJohn Marino 
255e4b17023SJohn Marino       /**
256e4b17023SJohn Marino        * @brief Discard a sequence of random numbers.
257e4b17023SJohn Marino        */
258e4b17023SJohn Marino       void
259e4b17023SJohn Marino       discard(unsigned long long __z)
260e4b17023SJohn Marino       {
261e4b17023SJohn Marino 	for (; __z != 0ULL; --__z)
262e4b17023SJohn Marino 	  (*this)();
263e4b17023SJohn Marino       }
264e4b17023SJohn Marino 
265e4b17023SJohn Marino       /**
266e4b17023SJohn Marino        * @brief Gets the next random number in the sequence.
267e4b17023SJohn Marino        */
268e4b17023SJohn Marino       result_type
269e4b17023SJohn Marino       operator()()
270e4b17023SJohn Marino       {
271e4b17023SJohn Marino 	_M_x = __detail::__mod<_UIntType, __m, __a, __c>(_M_x);
272e4b17023SJohn Marino 	return _M_x;
273e4b17023SJohn Marino       }
274e4b17023SJohn Marino 
275e4b17023SJohn Marino       /**
276e4b17023SJohn Marino        * @brief Compares two linear congruential random number generator
277e4b17023SJohn Marino        * objects of the same type for equality.
278e4b17023SJohn Marino        *
279e4b17023SJohn Marino        * @param __lhs A linear congruential random number generator object.
280e4b17023SJohn Marino        * @param __rhs Another linear congruential random number generator
281e4b17023SJohn Marino        *              object.
282e4b17023SJohn Marino        *
283e4b17023SJohn Marino        * @returns true if the infinite sequences of generated values
284e4b17023SJohn Marino        *          would be equal, false otherwise.
285e4b17023SJohn Marino        */
286e4b17023SJohn Marino       friend bool
287e4b17023SJohn Marino       operator==(const linear_congruential_engine& __lhs,
288e4b17023SJohn Marino 		 const linear_congruential_engine& __rhs)
289e4b17023SJohn Marino       { return __lhs._M_x == __rhs._M_x; }
290e4b17023SJohn Marino 
291e4b17023SJohn Marino       /**
292e4b17023SJohn Marino        * @brief Writes the textual representation of the state x(i) of x to
293e4b17023SJohn Marino        *        @p __os.
294e4b17023SJohn Marino        *
295e4b17023SJohn Marino        * @param __os  The output stream.
296e4b17023SJohn Marino        * @param __lcr A % linear_congruential_engine random number generator.
297e4b17023SJohn Marino        * @returns __os.
298e4b17023SJohn Marino        */
299e4b17023SJohn Marino       template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
300e4b17023SJohn Marino 	       _UIntType1 __m1, typename _CharT, typename _Traits>
301e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
302e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
303e4b17023SJohn Marino 		   const std::linear_congruential_engine<_UIntType1,
304e4b17023SJohn Marino 		   __a1, __c1, __m1>& __lcr);
305e4b17023SJohn Marino 
306e4b17023SJohn Marino       /**
307e4b17023SJohn Marino        * @brief Sets the state of the engine by reading its textual
308e4b17023SJohn Marino        *        representation from @p __is.
309e4b17023SJohn Marino        *
310e4b17023SJohn Marino        * The textual representation must have been previously written using
311e4b17023SJohn Marino        * an output stream whose imbued locale and whose type's template
312e4b17023SJohn Marino        * specialization arguments _CharT and _Traits were the same as those
313e4b17023SJohn Marino        * of @p __is.
314e4b17023SJohn Marino        *
315e4b17023SJohn Marino        * @param __is  The input stream.
316e4b17023SJohn Marino        * @param __lcr A % linear_congruential_engine random number generator.
317e4b17023SJohn Marino        * @returns __is.
318e4b17023SJohn Marino        */
319e4b17023SJohn Marino       template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
320e4b17023SJohn Marino 	       _UIntType1 __m1, typename _CharT, typename _Traits>
321e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
322e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
323e4b17023SJohn Marino 		   std::linear_congruential_engine<_UIntType1, __a1,
324e4b17023SJohn Marino 		   __c1, __m1>& __lcr);
325e4b17023SJohn Marino 
326e4b17023SJohn Marino     private:
327e4b17023SJohn Marino       _UIntType _M_x;
328e4b17023SJohn Marino     };
329e4b17023SJohn Marino 
330e4b17023SJohn Marino   /**
331e4b17023SJohn Marino    * @brief Compares two linear congruential random number generator
332e4b17023SJohn Marino    * objects of the same type for inequality.
333e4b17023SJohn Marino    *
334e4b17023SJohn Marino    * @param __lhs A linear congruential random number generator object.
335e4b17023SJohn Marino    * @param __rhs Another linear congruential random number generator
336e4b17023SJohn Marino    *              object.
337e4b17023SJohn Marino    *
338e4b17023SJohn Marino    * @returns true if the infinite sequences of generated values
339e4b17023SJohn Marino    *          would be different, false otherwise.
340e4b17023SJohn Marino    */
341e4b17023SJohn Marino   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
342e4b17023SJohn Marino     inline bool
343e4b17023SJohn Marino     operator!=(const std::linear_congruential_engine<_UIntType, __a,
344e4b17023SJohn Marino 	       __c, __m>& __lhs,
345e4b17023SJohn Marino 	       const std::linear_congruential_engine<_UIntType, __a,
346e4b17023SJohn Marino 	       __c, __m>& __rhs)
347e4b17023SJohn Marino     { return !(__lhs == __rhs); }
348e4b17023SJohn Marino 
349e4b17023SJohn Marino 
350e4b17023SJohn Marino   /**
351e4b17023SJohn Marino    * A generalized feedback shift register discrete random number generator.
352e4b17023SJohn Marino    *
353e4b17023SJohn Marino    * This algorithm avoids multiplication and division and is designed to be
354e4b17023SJohn Marino    * friendly to a pipelined architecture.  If the parameters are chosen
355e4b17023SJohn Marino    * correctly, this generator will produce numbers with a very long period and
356e4b17023SJohn Marino    * fairly good apparent entropy, although still not cryptographically strong.
357e4b17023SJohn Marino    *
358e4b17023SJohn Marino    * The best way to use this generator is with the predefined mt19937 class.
359e4b17023SJohn Marino    *
360e4b17023SJohn Marino    * This algorithm was originally invented by Makoto Matsumoto and
361e4b17023SJohn Marino    * Takuji Nishimura.
362e4b17023SJohn Marino    *
363e4b17023SJohn Marino    * @tparam __w  Word size, the number of bits in each element of
364e4b17023SJohn Marino    *              the state vector.
365e4b17023SJohn Marino    * @tparam __n  The degree of recursion.
366e4b17023SJohn Marino    * @tparam __m  The period parameter.
367e4b17023SJohn Marino    * @tparam __r  The separation point bit index.
368e4b17023SJohn Marino    * @tparam __a  The last row of the twist matrix.
369e4b17023SJohn Marino    * @tparam __u  The first right-shift tempering matrix parameter.
370e4b17023SJohn Marino    * @tparam __d  The first right-shift tempering matrix mask.
371e4b17023SJohn Marino    * @tparam __s  The first left-shift tempering matrix parameter.
372e4b17023SJohn Marino    * @tparam __b  The first left-shift tempering matrix mask.
373e4b17023SJohn Marino    * @tparam __t  The second left-shift tempering matrix parameter.
374e4b17023SJohn Marino    * @tparam __c  The second left-shift tempering matrix mask.
375e4b17023SJohn Marino    * @tparam __l  The second right-shift tempering matrix parameter.
376e4b17023SJohn Marino    * @tparam __f  Initialization multiplier.
377e4b17023SJohn Marino    */
378e4b17023SJohn Marino   template<typename _UIntType, size_t __w,
379e4b17023SJohn Marino 	   size_t __n, size_t __m, size_t __r,
380e4b17023SJohn Marino 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
381e4b17023SJohn Marino 	   _UIntType __b, size_t __t,
382e4b17023SJohn Marino 	   _UIntType __c, size_t __l, _UIntType __f>
383e4b17023SJohn Marino     class mersenne_twister_engine
384e4b17023SJohn Marino     {
385e4b17023SJohn Marino       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
386e4b17023SJohn Marino 		    "substituting _UIntType not an unsigned integral type");
387e4b17023SJohn Marino       static_assert(1u <= __m && __m <= __n,
388e4b17023SJohn Marino 		    "template argument substituting __m out of bounds");
389e4b17023SJohn Marino       static_assert(__r <= __w, "template argument substituting "
390e4b17023SJohn Marino 		    "__r out of bound");
391e4b17023SJohn Marino       static_assert(__u <= __w, "template argument substituting "
392e4b17023SJohn Marino 		    "__u out of bound");
393e4b17023SJohn Marino       static_assert(__s <= __w, "template argument substituting "
394e4b17023SJohn Marino 		    "__s out of bound");
395e4b17023SJohn Marino       static_assert(__t <= __w, "template argument substituting "
396e4b17023SJohn Marino 		    "__t out of bound");
397e4b17023SJohn Marino       static_assert(__l <= __w, "template argument substituting "
398e4b17023SJohn Marino 		    "__l out of bound");
399e4b17023SJohn Marino       static_assert(__w <= std::numeric_limits<_UIntType>::digits,
400e4b17023SJohn Marino 		    "template argument substituting __w out of bound");
401e4b17023SJohn Marino       static_assert(__a <= (__detail::_Shift<_UIntType, __w>::__value - 1),
402e4b17023SJohn Marino 		    "template argument substituting __a out of bound");
403e4b17023SJohn Marino       static_assert(__b <= (__detail::_Shift<_UIntType, __w>::__value - 1),
404e4b17023SJohn Marino 		    "template argument substituting __b out of bound");
405e4b17023SJohn Marino       static_assert(__c <= (__detail::_Shift<_UIntType, __w>::__value - 1),
406e4b17023SJohn Marino 		    "template argument substituting __c out of bound");
407e4b17023SJohn Marino       static_assert(__d <= (__detail::_Shift<_UIntType, __w>::__value - 1),
408e4b17023SJohn Marino 		    "template argument substituting __d out of bound");
409e4b17023SJohn Marino       static_assert(__f <= (__detail::_Shift<_UIntType, __w>::__value - 1),
410e4b17023SJohn Marino 		    "template argument substituting __f out of bound");
411e4b17023SJohn Marino 
412e4b17023SJohn Marino     public:
413e4b17023SJohn Marino       /** The type of the generated random value. */
414e4b17023SJohn Marino       typedef _UIntType result_type;
415e4b17023SJohn Marino 
416e4b17023SJohn Marino       // parameter values
417e4b17023SJohn Marino       static constexpr size_t      word_size                 = __w;
418e4b17023SJohn Marino       static constexpr size_t      state_size                = __n;
419e4b17023SJohn Marino       static constexpr size_t      shift_size                = __m;
420e4b17023SJohn Marino       static constexpr size_t      mask_bits                 = __r;
421e4b17023SJohn Marino       static constexpr result_type xor_mask                  = __a;
422e4b17023SJohn Marino       static constexpr size_t      tempering_u               = __u;
423e4b17023SJohn Marino       static constexpr result_type tempering_d               = __d;
424e4b17023SJohn Marino       static constexpr size_t      tempering_s               = __s;
425e4b17023SJohn Marino       static constexpr result_type tempering_b               = __b;
426e4b17023SJohn Marino       static constexpr size_t      tempering_t               = __t;
427e4b17023SJohn Marino       static constexpr result_type tempering_c               = __c;
428e4b17023SJohn Marino       static constexpr size_t      tempering_l               = __l;
429e4b17023SJohn Marino       static constexpr result_type initialization_multiplier = __f;
430e4b17023SJohn Marino       static constexpr result_type default_seed = 5489u;
431e4b17023SJohn Marino 
432e4b17023SJohn Marino       // constructors and member function
433e4b17023SJohn Marino       explicit
434e4b17023SJohn Marino       mersenne_twister_engine(result_type __sd = default_seed)
435e4b17023SJohn Marino       { seed(__sd); }
436e4b17023SJohn Marino 
437e4b17023SJohn Marino       /**
438e4b17023SJohn Marino        * @brief Constructs a %mersenne_twister_engine random number generator
439e4b17023SJohn Marino        *        engine seeded from the seed sequence @p __q.
440e4b17023SJohn Marino        *
441e4b17023SJohn Marino        * @param __q the seed sequence.
442e4b17023SJohn Marino        */
443e4b17023SJohn Marino       template<typename _Sseq, typename = typename
444e4b17023SJohn Marino         std::enable_if<!std::is_same<_Sseq, mersenne_twister_engine>::value>
445e4b17023SJohn Marino 	       ::type>
446e4b17023SJohn Marino         explicit
447e4b17023SJohn Marino         mersenne_twister_engine(_Sseq& __q)
448e4b17023SJohn Marino         { seed(__q); }
449e4b17023SJohn Marino 
450e4b17023SJohn Marino       void
451e4b17023SJohn Marino       seed(result_type __sd = default_seed);
452e4b17023SJohn Marino 
453e4b17023SJohn Marino       template<typename _Sseq>
454e4b17023SJohn Marino 	typename std::enable_if<std::is_class<_Sseq>::value>::type
455e4b17023SJohn Marino         seed(_Sseq& __q);
456e4b17023SJohn Marino 
457e4b17023SJohn Marino       /**
458e4b17023SJohn Marino        * @brief Gets the smallest possible value in the output range.
459e4b17023SJohn Marino        */
460e4b17023SJohn Marino       static constexpr result_type
461e4b17023SJohn Marino       min()
462e4b17023SJohn Marino       { return 0; };
463e4b17023SJohn Marino 
464e4b17023SJohn Marino       /**
465e4b17023SJohn Marino        * @brief Gets the largest possible value in the output range.
466e4b17023SJohn Marino        */
467e4b17023SJohn Marino       static constexpr result_type
468e4b17023SJohn Marino       max()
469e4b17023SJohn Marino       { return __detail::_Shift<_UIntType, __w>::__value - 1; }
470e4b17023SJohn Marino 
471e4b17023SJohn Marino       /**
472e4b17023SJohn Marino        * @brief Discard a sequence of random numbers.
473e4b17023SJohn Marino        */
474e4b17023SJohn Marino       void
475e4b17023SJohn Marino       discard(unsigned long long __z)
476e4b17023SJohn Marino       {
477e4b17023SJohn Marino 	for (; __z != 0ULL; --__z)
478e4b17023SJohn Marino 	  (*this)();
479e4b17023SJohn Marino       }
480e4b17023SJohn Marino 
481e4b17023SJohn Marino       result_type
482e4b17023SJohn Marino       operator()();
483e4b17023SJohn Marino 
484e4b17023SJohn Marino       /**
485e4b17023SJohn Marino        * @brief Compares two % mersenne_twister_engine random number generator
486e4b17023SJohn Marino        *        objects of the same type for equality.
487e4b17023SJohn Marino        *
488e4b17023SJohn Marino        * @param __lhs A % mersenne_twister_engine random number generator
489e4b17023SJohn Marino        *              object.
490e4b17023SJohn Marino        * @param __rhs Another % mersenne_twister_engine random number
491e4b17023SJohn Marino        *              generator object.
492e4b17023SJohn Marino        *
493e4b17023SJohn Marino        * @returns true if the infinite sequences of generated values
494e4b17023SJohn Marino        *          would be equal, false otherwise.
495e4b17023SJohn Marino        */
496e4b17023SJohn Marino       friend bool
497e4b17023SJohn Marino       operator==(const mersenne_twister_engine& __lhs,
498e4b17023SJohn Marino 		 const mersenne_twister_engine& __rhs)
499e4b17023SJohn Marino       { return (std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x)
500e4b17023SJohn Marino 		&& __lhs._M_p == __rhs._M_p); }
501e4b17023SJohn Marino 
502e4b17023SJohn Marino       /**
503e4b17023SJohn Marino        * @brief Inserts the current state of a % mersenne_twister_engine
504e4b17023SJohn Marino        *        random number generator engine @p __x into the output stream
505e4b17023SJohn Marino        *        @p __os.
506e4b17023SJohn Marino        *
507e4b17023SJohn Marino        * @param __os An output stream.
508e4b17023SJohn Marino        * @param __x  A % mersenne_twister_engine random number generator
509e4b17023SJohn Marino        *             engine.
510e4b17023SJohn Marino        *
511e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
512e4b17023SJohn Marino        * an error state.
513e4b17023SJohn Marino        */
514e4b17023SJohn Marino       template<typename _UIntType1,
515e4b17023SJohn Marino 	       size_t __w1, size_t __n1,
516e4b17023SJohn Marino 	       size_t __m1, size_t __r1,
517e4b17023SJohn Marino 	       _UIntType1 __a1, size_t __u1,
518e4b17023SJohn Marino 	       _UIntType1 __d1, size_t __s1,
519e4b17023SJohn Marino 	       _UIntType1 __b1, size_t __t1,
520e4b17023SJohn Marino 	       _UIntType1 __c1, size_t __l1, _UIntType1 __f1,
521e4b17023SJohn Marino 	       typename _CharT, typename _Traits>
522e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
523e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
524e4b17023SJohn Marino 		   const std::mersenne_twister_engine<_UIntType1, __w1, __n1,
525e4b17023SJohn Marino 		   __m1, __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
526e4b17023SJohn Marino 		   __l1, __f1>& __x);
527e4b17023SJohn Marino 
528e4b17023SJohn Marino       /**
529e4b17023SJohn Marino        * @brief Extracts the current state of a % mersenne_twister_engine
530e4b17023SJohn Marino        *        random number generator engine @p __x from the input stream
531e4b17023SJohn Marino        *        @p __is.
532e4b17023SJohn Marino        *
533e4b17023SJohn Marino        * @param __is An input stream.
534e4b17023SJohn Marino        * @param __x  A % mersenne_twister_engine random number generator
535e4b17023SJohn Marino        *             engine.
536e4b17023SJohn Marino        *
537e4b17023SJohn Marino        * @returns The input stream with the state of @p __x extracted or in
538e4b17023SJohn Marino        * an error state.
539e4b17023SJohn Marino        */
540e4b17023SJohn Marino       template<typename _UIntType1,
541e4b17023SJohn Marino 	       size_t __w1, size_t __n1,
542e4b17023SJohn Marino 	       size_t __m1, size_t __r1,
543e4b17023SJohn Marino 	       _UIntType1 __a1, size_t __u1,
544e4b17023SJohn Marino 	       _UIntType1 __d1, size_t __s1,
545e4b17023SJohn Marino 	       _UIntType1 __b1, size_t __t1,
546e4b17023SJohn Marino 	       _UIntType1 __c1, size_t __l1, _UIntType1 __f1,
547e4b17023SJohn Marino 	       typename _CharT, typename _Traits>
548e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
549e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
550e4b17023SJohn Marino 		   std::mersenne_twister_engine<_UIntType1, __w1, __n1, __m1,
551e4b17023SJohn Marino 		   __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1,
552e4b17023SJohn Marino 		   __l1, __f1>& __x);
553e4b17023SJohn Marino 
554e4b17023SJohn Marino     private:
555e4b17023SJohn Marino       _UIntType _M_x[state_size];
556e4b17023SJohn Marino       size_t    _M_p;
557e4b17023SJohn Marino     };
558e4b17023SJohn Marino 
559e4b17023SJohn Marino   /**
560e4b17023SJohn Marino    * @brief Compares two % mersenne_twister_engine random number generator
561e4b17023SJohn Marino    *        objects of the same type for inequality.
562e4b17023SJohn Marino    *
563e4b17023SJohn Marino    * @param __lhs A % mersenne_twister_engine random number generator
564e4b17023SJohn Marino    *              object.
565e4b17023SJohn Marino    * @param __rhs Another % mersenne_twister_engine random number
566e4b17023SJohn Marino    *              generator object.
567e4b17023SJohn Marino    *
568e4b17023SJohn Marino    * @returns true if the infinite sequences of generated values
569e4b17023SJohn Marino    *          would be different, false otherwise.
570e4b17023SJohn Marino    */
571e4b17023SJohn Marino   template<typename _UIntType, size_t __w,
572e4b17023SJohn Marino 	   size_t __n, size_t __m, size_t __r,
573e4b17023SJohn Marino 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
574e4b17023SJohn Marino 	   _UIntType __b, size_t __t,
575e4b17023SJohn Marino 	   _UIntType __c, size_t __l, _UIntType __f>
576e4b17023SJohn Marino     inline bool
577e4b17023SJohn Marino     operator!=(const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
578e4b17023SJohn Marino 	       __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __lhs,
579e4b17023SJohn Marino 	       const std::mersenne_twister_engine<_UIntType, __w, __n, __m,
580e4b17023SJohn Marino 	       __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __rhs)
581e4b17023SJohn Marino     { return !(__lhs == __rhs); }
582e4b17023SJohn Marino 
583e4b17023SJohn Marino 
584e4b17023SJohn Marino   /**
585e4b17023SJohn Marino    * @brief The Marsaglia-Zaman generator.
586e4b17023SJohn Marino    *
587e4b17023SJohn Marino    * This is a model of a Generalized Fibonacci discrete random number
588e4b17023SJohn Marino    * generator, sometimes referred to as the SWC generator.
589e4b17023SJohn Marino    *
590e4b17023SJohn Marino    * A discrete random number generator that produces pseudorandom
591e4b17023SJohn Marino    * numbers using:
592e4b17023SJohn Marino    * @f[
593e4b17023SJohn Marino    *     x_{i}\leftarrow(x_{i - s} - x_{i - r} - carry_{i-1}) \bmod m
594e4b17023SJohn Marino    * @f]
595e4b17023SJohn Marino    *
596e4b17023SJohn Marino    * The size of the state is @f$r@f$
597e4b17023SJohn Marino    * and the maximum period of the generator is @f$(m^r - m^s - 1)@f$.
598e4b17023SJohn Marino    *
599e4b17023SJohn Marino    * @var _M_x     The state of the generator.  This is a ring buffer.
600e4b17023SJohn Marino    * @var _M_carry The carry.
601e4b17023SJohn Marino    * @var _M_p     Current index of x(i - r).
602e4b17023SJohn Marino    */
603e4b17023SJohn Marino   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
604e4b17023SJohn Marino     class subtract_with_carry_engine
605e4b17023SJohn Marino     {
606e4b17023SJohn Marino       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
607e4b17023SJohn Marino 		    "substituting _UIntType not an unsigned integral type");
608e4b17023SJohn Marino       static_assert(0u < __s && __s < __r,
609e4b17023SJohn Marino 		    "template argument substituting __s out of bounds");
610e4b17023SJohn Marino       static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
611e4b17023SJohn Marino 		    "template argument substituting __w out of bounds");
612e4b17023SJohn Marino 
613e4b17023SJohn Marino     public:
614e4b17023SJohn Marino       /** The type of the generated random value. */
615e4b17023SJohn Marino       typedef _UIntType result_type;
616e4b17023SJohn Marino 
617e4b17023SJohn Marino       // parameter values
618e4b17023SJohn Marino       static constexpr size_t      word_size    = __w;
619e4b17023SJohn Marino       static constexpr size_t      short_lag    = __s;
620e4b17023SJohn Marino       static constexpr size_t      long_lag     = __r;
621e4b17023SJohn Marino       static constexpr result_type default_seed = 19780503u;
622e4b17023SJohn Marino 
623e4b17023SJohn Marino       /**
624e4b17023SJohn Marino        * @brief Constructs an explicitly seeded % subtract_with_carry_engine
625e4b17023SJohn Marino        *        random number generator.
626e4b17023SJohn Marino        */
627e4b17023SJohn Marino       explicit
628e4b17023SJohn Marino       subtract_with_carry_engine(result_type __sd = default_seed)
629e4b17023SJohn Marino       { seed(__sd); }
630e4b17023SJohn Marino 
631e4b17023SJohn Marino       /**
632e4b17023SJohn Marino        * @brief Constructs a %subtract_with_carry_engine random number engine
633e4b17023SJohn Marino        *        seeded from the seed sequence @p __q.
634e4b17023SJohn Marino        *
635e4b17023SJohn Marino        * @param __q the seed sequence.
636e4b17023SJohn Marino        */
637e4b17023SJohn Marino       template<typename _Sseq, typename = typename
638e4b17023SJohn Marino         std::enable_if<!std::is_same<_Sseq, subtract_with_carry_engine>::value>
639e4b17023SJohn Marino 	       ::type>
640e4b17023SJohn Marino         explicit
641e4b17023SJohn Marino         subtract_with_carry_engine(_Sseq& __q)
642e4b17023SJohn Marino         { seed(__q); }
643e4b17023SJohn Marino 
644e4b17023SJohn Marino       /**
645e4b17023SJohn Marino        * @brief Seeds the initial state @f$x_0@f$ of the random number
646e4b17023SJohn Marino        *        generator.
647e4b17023SJohn Marino        *
648e4b17023SJohn Marino        * N1688[4.19] modifies this as follows.  If @p __value == 0,
649e4b17023SJohn Marino        * sets value to 19780503.  In any case, with a linear
650e4b17023SJohn Marino        * congruential generator lcg(i) having parameters @f$ m_{lcg} =
651e4b17023SJohn Marino        * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
652e4b17023SJohn Marino        * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
653e4b17023SJohn Marino        * \dots lcg(r) \bmod m @f$ respectively.  If @f$ x_{-1} = 0 @f$
654e4b17023SJohn Marino        * set carry to 1, otherwise sets carry to 0.
655e4b17023SJohn Marino        */
656e4b17023SJohn Marino       void
657e4b17023SJohn Marino       seed(result_type __sd = default_seed);
658e4b17023SJohn Marino 
659e4b17023SJohn Marino       /**
660e4b17023SJohn Marino        * @brief Seeds the initial state @f$x_0@f$ of the
661e4b17023SJohn Marino        * % subtract_with_carry_engine random number generator.
662e4b17023SJohn Marino        */
663e4b17023SJohn Marino       template<typename _Sseq>
664e4b17023SJohn Marino 	typename std::enable_if<std::is_class<_Sseq>::value>::type
665e4b17023SJohn Marino         seed(_Sseq& __q);
666e4b17023SJohn Marino 
667e4b17023SJohn Marino       /**
668e4b17023SJohn Marino        * @brief Gets the inclusive minimum value of the range of random
669e4b17023SJohn Marino        * integers returned by this generator.
670e4b17023SJohn Marino        */
671e4b17023SJohn Marino       static constexpr result_type
672e4b17023SJohn Marino       min()
673e4b17023SJohn Marino       { return 0; }
674e4b17023SJohn Marino 
675e4b17023SJohn Marino       /**
676e4b17023SJohn Marino        * @brief Gets the inclusive maximum value of the range of random
677e4b17023SJohn Marino        * integers returned by this generator.
678e4b17023SJohn Marino        */
679e4b17023SJohn Marino       static constexpr result_type
680e4b17023SJohn Marino       max()
681e4b17023SJohn Marino       { return __detail::_Shift<_UIntType, __w>::__value - 1; }
682e4b17023SJohn Marino 
683e4b17023SJohn Marino       /**
684e4b17023SJohn Marino        * @brief Discard a sequence of random numbers.
685e4b17023SJohn Marino        */
686e4b17023SJohn Marino       void
687e4b17023SJohn Marino       discard(unsigned long long __z)
688e4b17023SJohn Marino       {
689e4b17023SJohn Marino 	for (; __z != 0ULL; --__z)
690e4b17023SJohn Marino 	  (*this)();
691e4b17023SJohn Marino       }
692e4b17023SJohn Marino 
693e4b17023SJohn Marino       /**
694e4b17023SJohn Marino        * @brief Gets the next random number in the sequence.
695e4b17023SJohn Marino        */
696e4b17023SJohn Marino       result_type
697e4b17023SJohn Marino       operator()();
698e4b17023SJohn Marino 
699e4b17023SJohn Marino       /**
700e4b17023SJohn Marino        * @brief Compares two % subtract_with_carry_engine random number
701e4b17023SJohn Marino        *        generator objects of the same type for equality.
702e4b17023SJohn Marino        *
703e4b17023SJohn Marino        * @param __lhs A % subtract_with_carry_engine random number generator
704e4b17023SJohn Marino        *              object.
705e4b17023SJohn Marino        * @param __rhs Another % subtract_with_carry_engine random number
706e4b17023SJohn Marino        *              generator object.
707e4b17023SJohn Marino        *
708e4b17023SJohn Marino        * @returns true if the infinite sequences of generated values
709e4b17023SJohn Marino        *          would be equal, false otherwise.
710e4b17023SJohn Marino       */
711e4b17023SJohn Marino       friend bool
712e4b17023SJohn Marino       operator==(const subtract_with_carry_engine& __lhs,
713e4b17023SJohn Marino 		 const subtract_with_carry_engine& __rhs)
714e4b17023SJohn Marino       { return (std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x)
715e4b17023SJohn Marino 		&& __lhs._M_carry == __rhs._M_carry
716e4b17023SJohn Marino 		&& __lhs._M_p == __rhs._M_p); }
717e4b17023SJohn Marino 
718e4b17023SJohn Marino       /**
719e4b17023SJohn Marino        * @brief Inserts the current state of a % subtract_with_carry_engine
720e4b17023SJohn Marino        *        random number generator engine @p __x into the output stream
721e4b17023SJohn Marino        *        @p __os.
722e4b17023SJohn Marino        *
723e4b17023SJohn Marino        * @param __os An output stream.
724e4b17023SJohn Marino        * @param __x  A % subtract_with_carry_engine random number generator
725e4b17023SJohn Marino        *             engine.
726e4b17023SJohn Marino        *
727e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
728e4b17023SJohn Marino        * an error state.
729e4b17023SJohn Marino        */
730e4b17023SJohn Marino       template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1,
731e4b17023SJohn Marino 	       typename _CharT, typename _Traits>
732e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
733e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>&,
734e4b17023SJohn Marino 		   const std::subtract_with_carry_engine<_UIntType1, __w1,
735e4b17023SJohn Marino 		   __s1, __r1>&);
736e4b17023SJohn Marino 
737e4b17023SJohn Marino       /**
738e4b17023SJohn Marino        * @brief Extracts the current state of a % subtract_with_carry_engine
739e4b17023SJohn Marino        *        random number generator engine @p __x from the input stream
740e4b17023SJohn Marino        *        @p __is.
741e4b17023SJohn Marino        *
742e4b17023SJohn Marino        * @param __is An input stream.
743e4b17023SJohn Marino        * @param __x  A % subtract_with_carry_engine random number generator
744e4b17023SJohn Marino        *             engine.
745e4b17023SJohn Marino        *
746e4b17023SJohn Marino        * @returns The input stream with the state of @p __x extracted or in
747e4b17023SJohn Marino        * an error state.
748e4b17023SJohn Marino        */
749e4b17023SJohn Marino       template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1,
750e4b17023SJohn Marino 	       typename _CharT, typename _Traits>
751e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
752e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>&,
753e4b17023SJohn Marino 		   std::subtract_with_carry_engine<_UIntType1, __w1,
754e4b17023SJohn Marino 		   __s1, __r1>&);
755e4b17023SJohn Marino 
756e4b17023SJohn Marino     private:
757e4b17023SJohn Marino       _UIntType  _M_x[long_lag];
758e4b17023SJohn Marino       _UIntType  _M_carry;
759e4b17023SJohn Marino       size_t     _M_p;
760e4b17023SJohn Marino     };
761e4b17023SJohn Marino 
762e4b17023SJohn Marino   /**
763e4b17023SJohn Marino    * @brief Compares two % subtract_with_carry_engine random number
764e4b17023SJohn Marino    *        generator objects of the same type for inequality.
765e4b17023SJohn Marino    *
766e4b17023SJohn Marino    * @param __lhs A % subtract_with_carry_engine random number generator
767e4b17023SJohn Marino    *              object.
768e4b17023SJohn Marino    * @param __rhs Another % subtract_with_carry_engine random number
769e4b17023SJohn Marino    *              generator object.
770e4b17023SJohn Marino    *
771e4b17023SJohn Marino    * @returns true if the infinite sequences of generated values
772e4b17023SJohn Marino    *          would be different, false otherwise.
773e4b17023SJohn Marino    */
774e4b17023SJohn Marino   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
775e4b17023SJohn Marino     inline bool
776e4b17023SJohn Marino     operator!=(const std::subtract_with_carry_engine<_UIntType, __w,
777e4b17023SJohn Marino 	       __s, __r>& __lhs,
778e4b17023SJohn Marino 	       const std::subtract_with_carry_engine<_UIntType, __w,
779e4b17023SJohn Marino 	       __s, __r>& __rhs)
780e4b17023SJohn Marino     { return !(__lhs == __rhs); }
781e4b17023SJohn Marino 
782e4b17023SJohn Marino 
783e4b17023SJohn Marino   /**
784e4b17023SJohn Marino    * Produces random numbers from some base engine by discarding blocks of
785e4b17023SJohn Marino    * data.
786e4b17023SJohn Marino    *
787e4b17023SJohn Marino    * 0 <= @p __r <= @p __p
788e4b17023SJohn Marino    */
789e4b17023SJohn Marino   template<typename _RandomNumberEngine, size_t __p, size_t __r>
790e4b17023SJohn Marino     class discard_block_engine
791e4b17023SJohn Marino     {
792e4b17023SJohn Marino       static_assert(1 <= __r && __r <= __p,
793e4b17023SJohn Marino 		    "template argument substituting __r out of bounds");
794e4b17023SJohn Marino 
795e4b17023SJohn Marino     public:
796e4b17023SJohn Marino       /** The type of the generated random value. */
797e4b17023SJohn Marino       typedef typename _RandomNumberEngine::result_type result_type;
798e4b17023SJohn Marino 
799e4b17023SJohn Marino       // parameter values
800e4b17023SJohn Marino       static constexpr size_t block_size = __p;
801e4b17023SJohn Marino       static constexpr size_t used_block = __r;
802e4b17023SJohn Marino 
803e4b17023SJohn Marino       /**
804e4b17023SJohn Marino        * @brief Constructs a default %discard_block_engine engine.
805e4b17023SJohn Marino        *
806e4b17023SJohn Marino        * The underlying engine is default constructed as well.
807e4b17023SJohn Marino        */
808e4b17023SJohn Marino       discard_block_engine()
809e4b17023SJohn Marino       : _M_b(), _M_n(0) { }
810e4b17023SJohn Marino 
811e4b17023SJohn Marino       /**
812e4b17023SJohn Marino        * @brief Copy constructs a %discard_block_engine engine.
813e4b17023SJohn Marino        *
814e4b17023SJohn Marino        * Copies an existing base class random number generator.
815e4b17023SJohn Marino        * @param __rng An existing (base class) engine object.
816e4b17023SJohn Marino        */
817e4b17023SJohn Marino       explicit
818e4b17023SJohn Marino       discard_block_engine(const _RandomNumberEngine& __rng)
819e4b17023SJohn Marino       : _M_b(__rng), _M_n(0) { }
820e4b17023SJohn Marino 
821e4b17023SJohn Marino       /**
822e4b17023SJohn Marino        * @brief Move constructs a %discard_block_engine engine.
823e4b17023SJohn Marino        *
824e4b17023SJohn Marino        * Copies an existing base class random number generator.
825e4b17023SJohn Marino        * @param __rng An existing (base class) engine object.
826e4b17023SJohn Marino        */
827e4b17023SJohn Marino       explicit
828e4b17023SJohn Marino       discard_block_engine(_RandomNumberEngine&& __rng)
829e4b17023SJohn Marino       : _M_b(std::move(__rng)), _M_n(0) { }
830e4b17023SJohn Marino 
831e4b17023SJohn Marino       /**
832e4b17023SJohn Marino        * @brief Seed constructs a %discard_block_engine engine.
833e4b17023SJohn Marino        *
834e4b17023SJohn Marino        * Constructs the underlying generator engine seeded with @p __s.
835e4b17023SJohn Marino        * @param __s A seed value for the base class engine.
836e4b17023SJohn Marino        */
837e4b17023SJohn Marino       explicit
838e4b17023SJohn Marino       discard_block_engine(result_type __s)
839e4b17023SJohn Marino       : _M_b(__s), _M_n(0) { }
840e4b17023SJohn Marino 
841e4b17023SJohn Marino       /**
842e4b17023SJohn Marino        * @brief Generator construct a %discard_block_engine engine.
843e4b17023SJohn Marino        *
844e4b17023SJohn Marino        * @param __q A seed sequence.
845e4b17023SJohn Marino        */
846e4b17023SJohn Marino       template<typename _Sseq, typename = typename
847e4b17023SJohn Marino 	std::enable_if<!std::is_same<_Sseq, discard_block_engine>::value
848e4b17023SJohn Marino 		       && !std::is_same<_Sseq, _RandomNumberEngine>::value>
849e4b17023SJohn Marino 	       ::type>
850e4b17023SJohn Marino         explicit
851e4b17023SJohn Marino         discard_block_engine(_Sseq& __q)
852e4b17023SJohn Marino 	: _M_b(__q), _M_n(0)
853e4b17023SJohn Marino         { }
854e4b17023SJohn Marino 
855e4b17023SJohn Marino       /**
856e4b17023SJohn Marino        * @brief Reseeds the %discard_block_engine object with the default
857e4b17023SJohn Marino        *        seed for the underlying base class generator engine.
858e4b17023SJohn Marino        */
859e4b17023SJohn Marino       void
860e4b17023SJohn Marino       seed()
861e4b17023SJohn Marino       {
862e4b17023SJohn Marino 	_M_b.seed();
863e4b17023SJohn Marino 	_M_n = 0;
864e4b17023SJohn Marino       }
865e4b17023SJohn Marino 
866e4b17023SJohn Marino       /**
867e4b17023SJohn Marino        * @brief Reseeds the %discard_block_engine object with the default
868e4b17023SJohn Marino        *        seed for the underlying base class generator engine.
869e4b17023SJohn Marino        */
870e4b17023SJohn Marino       void
871e4b17023SJohn Marino       seed(result_type __s)
872e4b17023SJohn Marino       {
873e4b17023SJohn Marino 	_M_b.seed(__s);
874e4b17023SJohn Marino 	_M_n = 0;
875e4b17023SJohn Marino       }
876e4b17023SJohn Marino 
877e4b17023SJohn Marino       /**
878e4b17023SJohn Marino        * @brief Reseeds the %discard_block_engine object with the given seed
879e4b17023SJohn Marino        *        sequence.
880e4b17023SJohn Marino        * @param __q A seed generator function.
881e4b17023SJohn Marino        */
882e4b17023SJohn Marino       template<typename _Sseq>
883e4b17023SJohn Marino         void
884e4b17023SJohn Marino         seed(_Sseq& __q)
885e4b17023SJohn Marino         {
886e4b17023SJohn Marino 	  _M_b.seed(__q);
887e4b17023SJohn Marino 	  _M_n = 0;
888e4b17023SJohn Marino 	}
889e4b17023SJohn Marino 
890e4b17023SJohn Marino       /**
891e4b17023SJohn Marino        * @brief Gets a const reference to the underlying generator engine
892e4b17023SJohn Marino        *        object.
893e4b17023SJohn Marino        */
894e4b17023SJohn Marino       const _RandomNumberEngine&
895e4b17023SJohn Marino       base() const noexcept
896e4b17023SJohn Marino       { return _M_b; }
897e4b17023SJohn Marino 
898e4b17023SJohn Marino       /**
899e4b17023SJohn Marino        * @brief Gets the minimum value in the generated random number range.
900e4b17023SJohn Marino        */
901e4b17023SJohn Marino       static constexpr result_type
902e4b17023SJohn Marino       min()
903e4b17023SJohn Marino       { return _RandomNumberEngine::min(); }
904e4b17023SJohn Marino 
905e4b17023SJohn Marino       /**
906e4b17023SJohn Marino        * @brief Gets the maximum value in the generated random number range.
907e4b17023SJohn Marino        */
908e4b17023SJohn Marino       static constexpr result_type
909e4b17023SJohn Marino       max()
910e4b17023SJohn Marino       { return _RandomNumberEngine::max(); }
911e4b17023SJohn Marino 
912e4b17023SJohn Marino       /**
913e4b17023SJohn Marino        * @brief Discard a sequence of random numbers.
914e4b17023SJohn Marino        */
915e4b17023SJohn Marino       void
916e4b17023SJohn Marino       discard(unsigned long long __z)
917e4b17023SJohn Marino       {
918e4b17023SJohn Marino 	for (; __z != 0ULL; --__z)
919e4b17023SJohn Marino 	  (*this)();
920e4b17023SJohn Marino       }
921e4b17023SJohn Marino 
922e4b17023SJohn Marino       /**
923e4b17023SJohn Marino        * @brief Gets the next value in the generated random number sequence.
924e4b17023SJohn Marino        */
925e4b17023SJohn Marino       result_type
926e4b17023SJohn Marino       operator()();
927e4b17023SJohn Marino 
928e4b17023SJohn Marino       /**
929e4b17023SJohn Marino        * @brief Compares two %discard_block_engine random number generator
930e4b17023SJohn Marino        *        objects of the same type for equality.
931e4b17023SJohn Marino        *
932e4b17023SJohn Marino        * @param __lhs A %discard_block_engine random number generator object.
933e4b17023SJohn Marino        * @param __rhs Another %discard_block_engine random number generator
934e4b17023SJohn Marino        *              object.
935e4b17023SJohn Marino        *
936e4b17023SJohn Marino        * @returns true if the infinite sequences of generated values
937e4b17023SJohn Marino        *          would be equal, false otherwise.
938e4b17023SJohn Marino        */
939e4b17023SJohn Marino       friend bool
940e4b17023SJohn Marino       operator==(const discard_block_engine& __lhs,
941e4b17023SJohn Marino 		 const discard_block_engine& __rhs)
942e4b17023SJohn Marino       { return __lhs._M_b == __rhs._M_b && __lhs._M_n == __rhs._M_n; }
943e4b17023SJohn Marino 
944e4b17023SJohn Marino       /**
945e4b17023SJohn Marino        * @brief Inserts the current state of a %discard_block_engine random
946e4b17023SJohn Marino        *        number generator engine @p __x into the output stream
947e4b17023SJohn Marino        *        @p __os.
948e4b17023SJohn Marino        *
949e4b17023SJohn Marino        * @param __os An output stream.
950e4b17023SJohn Marino        * @param __x  A %discard_block_engine random number generator engine.
951e4b17023SJohn Marino        *
952e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
953e4b17023SJohn Marino        * an error state.
954e4b17023SJohn Marino        */
955e4b17023SJohn Marino       template<typename _RandomNumberEngine1, size_t __p1, size_t __r1,
956e4b17023SJohn Marino 	       typename _CharT, typename _Traits>
957e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
958e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
959e4b17023SJohn Marino 		   const std::discard_block_engine<_RandomNumberEngine1,
960e4b17023SJohn Marino 		   __p1, __r1>& __x);
961e4b17023SJohn Marino 
962e4b17023SJohn Marino       /**
963e4b17023SJohn Marino        * @brief Extracts the current state of a % subtract_with_carry_engine
964e4b17023SJohn Marino        *        random number generator engine @p __x from the input stream
965e4b17023SJohn Marino        *        @p __is.
966e4b17023SJohn Marino        *
967e4b17023SJohn Marino        * @param __is An input stream.
968e4b17023SJohn Marino        * @param __x  A %discard_block_engine random number generator engine.
969e4b17023SJohn Marino        *
970e4b17023SJohn Marino        * @returns The input stream with the state of @p __x extracted or in
971e4b17023SJohn Marino        * an error state.
972e4b17023SJohn Marino        */
973e4b17023SJohn Marino       template<typename _RandomNumberEngine1, size_t __p1, size_t __r1,
974e4b17023SJohn Marino 	       typename _CharT, typename _Traits>
975e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
976e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
977e4b17023SJohn Marino 		   std::discard_block_engine<_RandomNumberEngine1,
978e4b17023SJohn Marino 		   __p1, __r1>& __x);
979e4b17023SJohn Marino 
980e4b17023SJohn Marino     private:
981e4b17023SJohn Marino       _RandomNumberEngine _M_b;
982e4b17023SJohn Marino       size_t _M_n;
983e4b17023SJohn Marino     };
984e4b17023SJohn Marino 
985e4b17023SJohn Marino   /**
986e4b17023SJohn Marino    * @brief Compares two %discard_block_engine random number generator
987e4b17023SJohn Marino    *        objects of the same type for inequality.
988e4b17023SJohn Marino    *
989e4b17023SJohn Marino    * @param __lhs A %discard_block_engine random number generator object.
990e4b17023SJohn Marino    * @param __rhs Another %discard_block_engine random number generator
991e4b17023SJohn Marino    *              object.
992e4b17023SJohn Marino    *
993e4b17023SJohn Marino    * @returns true if the infinite sequences of generated values
994e4b17023SJohn Marino    *          would be different, false otherwise.
995e4b17023SJohn Marino    */
996e4b17023SJohn Marino   template<typename _RandomNumberEngine, size_t __p, size_t __r>
997e4b17023SJohn Marino     inline bool
998e4b17023SJohn Marino     operator!=(const std::discard_block_engine<_RandomNumberEngine, __p,
999e4b17023SJohn Marino 	       __r>& __lhs,
1000e4b17023SJohn Marino 	       const std::discard_block_engine<_RandomNumberEngine, __p,
1001e4b17023SJohn Marino 	       __r>& __rhs)
1002e4b17023SJohn Marino     { return !(__lhs == __rhs); }
1003e4b17023SJohn Marino 
1004e4b17023SJohn Marino 
1005e4b17023SJohn Marino   /**
1006e4b17023SJohn Marino    * Produces random numbers by combining random numbers from some base
1007e4b17023SJohn Marino    * engine to produce random numbers with a specifies number of bits @p __w.
1008e4b17023SJohn Marino    */
1009e4b17023SJohn Marino   template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
1010e4b17023SJohn Marino     class independent_bits_engine
1011e4b17023SJohn Marino     {
1012e4b17023SJohn Marino       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
1013e4b17023SJohn Marino 		    "substituting _UIntType not an unsigned integral type");
1014e4b17023SJohn Marino       static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits,
1015e4b17023SJohn Marino 		    "template argument substituting __w out of bounds");
1016e4b17023SJohn Marino 
1017e4b17023SJohn Marino     public:
1018e4b17023SJohn Marino       /** The type of the generated random value. */
1019e4b17023SJohn Marino       typedef _UIntType result_type;
1020e4b17023SJohn Marino 
1021e4b17023SJohn Marino       /**
1022e4b17023SJohn Marino        * @brief Constructs a default %independent_bits_engine engine.
1023e4b17023SJohn Marino        *
1024e4b17023SJohn Marino        * The underlying engine is default constructed as well.
1025e4b17023SJohn Marino        */
1026e4b17023SJohn Marino       independent_bits_engine()
1027e4b17023SJohn Marino       : _M_b() { }
1028e4b17023SJohn Marino 
1029e4b17023SJohn Marino       /**
1030e4b17023SJohn Marino        * @brief Copy constructs a %independent_bits_engine engine.
1031e4b17023SJohn Marino        *
1032e4b17023SJohn Marino        * Copies an existing base class random number generator.
1033e4b17023SJohn Marino        * @param __rng An existing (base class) engine object.
1034e4b17023SJohn Marino        */
1035e4b17023SJohn Marino       explicit
1036e4b17023SJohn Marino       independent_bits_engine(const _RandomNumberEngine& __rng)
1037e4b17023SJohn Marino       : _M_b(__rng) { }
1038e4b17023SJohn Marino 
1039e4b17023SJohn Marino       /**
1040e4b17023SJohn Marino        * @brief Move constructs a %independent_bits_engine engine.
1041e4b17023SJohn Marino        *
1042e4b17023SJohn Marino        * Copies an existing base class random number generator.
1043e4b17023SJohn Marino        * @param __rng An existing (base class) engine object.
1044e4b17023SJohn Marino        */
1045e4b17023SJohn Marino       explicit
1046e4b17023SJohn Marino       independent_bits_engine(_RandomNumberEngine&& __rng)
1047e4b17023SJohn Marino       : _M_b(std::move(__rng)) { }
1048e4b17023SJohn Marino 
1049e4b17023SJohn Marino       /**
1050e4b17023SJohn Marino        * @brief Seed constructs a %independent_bits_engine engine.
1051e4b17023SJohn Marino        *
1052e4b17023SJohn Marino        * Constructs the underlying generator engine seeded with @p __s.
1053e4b17023SJohn Marino        * @param __s A seed value for the base class engine.
1054e4b17023SJohn Marino        */
1055e4b17023SJohn Marino       explicit
1056e4b17023SJohn Marino       independent_bits_engine(result_type __s)
1057e4b17023SJohn Marino       : _M_b(__s) { }
1058e4b17023SJohn Marino 
1059e4b17023SJohn Marino       /**
1060e4b17023SJohn Marino        * @brief Generator construct a %independent_bits_engine engine.
1061e4b17023SJohn Marino        *
1062e4b17023SJohn Marino        * @param __q A seed sequence.
1063e4b17023SJohn Marino        */
1064e4b17023SJohn Marino       template<typename _Sseq, typename = typename
1065e4b17023SJohn Marino 	std::enable_if<!std::is_same<_Sseq, independent_bits_engine>::value
1066e4b17023SJohn Marino 		       && !std::is_same<_Sseq, _RandomNumberEngine>::value>
1067e4b17023SJohn Marino                ::type>
1068e4b17023SJohn Marino         explicit
1069e4b17023SJohn Marino         independent_bits_engine(_Sseq& __q)
1070e4b17023SJohn Marino         : _M_b(__q)
1071e4b17023SJohn Marino         { }
1072e4b17023SJohn Marino 
1073e4b17023SJohn Marino       /**
1074e4b17023SJohn Marino        * @brief Reseeds the %independent_bits_engine object with the default
1075e4b17023SJohn Marino        *        seed for the underlying base class generator engine.
1076e4b17023SJohn Marino        */
1077e4b17023SJohn Marino       void
1078e4b17023SJohn Marino       seed()
1079e4b17023SJohn Marino       { _M_b.seed(); }
1080e4b17023SJohn Marino 
1081e4b17023SJohn Marino       /**
1082e4b17023SJohn Marino        * @brief Reseeds the %independent_bits_engine object with the default
1083e4b17023SJohn Marino        *        seed for the underlying base class generator engine.
1084e4b17023SJohn Marino        */
1085e4b17023SJohn Marino       void
1086e4b17023SJohn Marino       seed(result_type __s)
1087e4b17023SJohn Marino       { _M_b.seed(__s); }
1088e4b17023SJohn Marino 
1089e4b17023SJohn Marino       /**
1090e4b17023SJohn Marino        * @brief Reseeds the %independent_bits_engine object with the given
1091e4b17023SJohn Marino        *        seed sequence.
1092e4b17023SJohn Marino        * @param __q A seed generator function.
1093e4b17023SJohn Marino        */
1094e4b17023SJohn Marino       template<typename _Sseq>
1095e4b17023SJohn Marino         void
1096e4b17023SJohn Marino         seed(_Sseq& __q)
1097e4b17023SJohn Marino         { _M_b.seed(__q); }
1098e4b17023SJohn Marino 
1099e4b17023SJohn Marino       /**
1100e4b17023SJohn Marino        * @brief Gets a const reference to the underlying generator engine
1101e4b17023SJohn Marino        *        object.
1102e4b17023SJohn Marino        */
1103e4b17023SJohn Marino       const _RandomNumberEngine&
1104e4b17023SJohn Marino       base() const noexcept
1105e4b17023SJohn Marino       { return _M_b; }
1106e4b17023SJohn Marino 
1107e4b17023SJohn Marino       /**
1108e4b17023SJohn Marino        * @brief Gets the minimum value in the generated random number range.
1109e4b17023SJohn Marino        */
1110e4b17023SJohn Marino       static constexpr result_type
1111e4b17023SJohn Marino       min()
1112e4b17023SJohn Marino       { return 0U; }
1113e4b17023SJohn Marino 
1114e4b17023SJohn Marino       /**
1115e4b17023SJohn Marino        * @brief Gets the maximum value in the generated random number range.
1116e4b17023SJohn Marino        */
1117e4b17023SJohn Marino       static constexpr result_type
1118e4b17023SJohn Marino       max()
1119e4b17023SJohn Marino       { return __detail::_Shift<_UIntType, __w>::__value - 1; }
1120e4b17023SJohn Marino 
1121e4b17023SJohn Marino       /**
1122e4b17023SJohn Marino        * @brief Discard a sequence of random numbers.
1123e4b17023SJohn Marino        */
1124e4b17023SJohn Marino       void
1125e4b17023SJohn Marino       discard(unsigned long long __z)
1126e4b17023SJohn Marino       {
1127e4b17023SJohn Marino 	for (; __z != 0ULL; --__z)
1128e4b17023SJohn Marino 	  (*this)();
1129e4b17023SJohn Marino       }
1130e4b17023SJohn Marino 
1131e4b17023SJohn Marino       /**
1132e4b17023SJohn Marino        * @brief Gets the next value in the generated random number sequence.
1133e4b17023SJohn Marino        */
1134e4b17023SJohn Marino       result_type
1135e4b17023SJohn Marino       operator()();
1136e4b17023SJohn Marino 
1137e4b17023SJohn Marino       /**
1138e4b17023SJohn Marino        * @brief Compares two %independent_bits_engine random number generator
1139e4b17023SJohn Marino        * objects of the same type for equality.
1140e4b17023SJohn Marino        *
1141e4b17023SJohn Marino        * @param __lhs A %independent_bits_engine random number generator
1142e4b17023SJohn Marino        *              object.
1143e4b17023SJohn Marino        * @param __rhs Another %independent_bits_engine random number generator
1144e4b17023SJohn Marino        *              object.
1145e4b17023SJohn Marino        *
1146e4b17023SJohn Marino        * @returns true if the infinite sequences of generated values
1147e4b17023SJohn Marino        *          would be equal, false otherwise.
1148e4b17023SJohn Marino        */
1149e4b17023SJohn Marino       friend bool
1150e4b17023SJohn Marino       operator==(const independent_bits_engine& __lhs,
1151e4b17023SJohn Marino 		 const independent_bits_engine& __rhs)
1152e4b17023SJohn Marino       { return __lhs._M_b == __rhs._M_b; }
1153e4b17023SJohn Marino 
1154e4b17023SJohn Marino       /**
1155e4b17023SJohn Marino        * @brief Extracts the current state of a % subtract_with_carry_engine
1156e4b17023SJohn Marino        *        random number generator engine @p __x from the input stream
1157e4b17023SJohn Marino        *        @p __is.
1158e4b17023SJohn Marino        *
1159e4b17023SJohn Marino        * @param __is An input stream.
1160e4b17023SJohn Marino        * @param __x  A %independent_bits_engine random number generator
1161e4b17023SJohn Marino        *             engine.
1162e4b17023SJohn Marino        *
1163e4b17023SJohn Marino        * @returns The input stream with the state of @p __x extracted or in
1164e4b17023SJohn Marino        *          an error state.
1165e4b17023SJohn Marino        */
1166e4b17023SJohn Marino       template<typename _CharT, typename _Traits>
1167e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
1168e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
1169e4b17023SJohn Marino 		   std::independent_bits_engine<_RandomNumberEngine,
1170e4b17023SJohn Marino 		   __w, _UIntType>& __x)
1171e4b17023SJohn Marino 	{
1172e4b17023SJohn Marino 	  __is >> __x._M_b;
1173e4b17023SJohn Marino 	  return __is;
1174e4b17023SJohn Marino 	}
1175e4b17023SJohn Marino 
1176e4b17023SJohn Marino     private:
1177e4b17023SJohn Marino       _RandomNumberEngine _M_b;
1178e4b17023SJohn Marino     };
1179e4b17023SJohn Marino 
1180e4b17023SJohn Marino   /**
1181e4b17023SJohn Marino    * @brief Compares two %independent_bits_engine random number generator
1182e4b17023SJohn Marino    * objects of the same type for inequality.
1183e4b17023SJohn Marino    *
1184e4b17023SJohn Marino    * @param __lhs A %independent_bits_engine random number generator
1185e4b17023SJohn Marino    *              object.
1186e4b17023SJohn Marino    * @param __rhs Another %independent_bits_engine random number generator
1187e4b17023SJohn Marino    *              object.
1188e4b17023SJohn Marino    *
1189e4b17023SJohn Marino    * @returns true if the infinite sequences of generated values
1190e4b17023SJohn Marino    *          would be different, false otherwise.
1191e4b17023SJohn Marino    */
1192e4b17023SJohn Marino   template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
1193e4b17023SJohn Marino     inline bool
1194e4b17023SJohn Marino     operator!=(const std::independent_bits_engine<_RandomNumberEngine, __w,
1195e4b17023SJohn Marino 	       _UIntType>& __lhs,
1196e4b17023SJohn Marino 	       const std::independent_bits_engine<_RandomNumberEngine, __w,
1197e4b17023SJohn Marino 	       _UIntType>& __rhs)
1198e4b17023SJohn Marino     { return !(__lhs == __rhs); }
1199e4b17023SJohn Marino 
1200e4b17023SJohn Marino   /**
1201e4b17023SJohn Marino    * @brief Inserts the current state of a %independent_bits_engine random
1202e4b17023SJohn Marino    *        number generator engine @p __x into the output stream @p __os.
1203e4b17023SJohn Marino    *
1204e4b17023SJohn Marino    * @param __os An output stream.
1205e4b17023SJohn Marino    * @param __x  A %independent_bits_engine random number generator engine.
1206e4b17023SJohn Marino    *
1207e4b17023SJohn Marino    * @returns The output stream with the state of @p __x inserted or in
1208e4b17023SJohn Marino    *          an error state.
1209e4b17023SJohn Marino    */
1210e4b17023SJohn Marino   template<typename _RandomNumberEngine, size_t __w, typename _UIntType,
1211e4b17023SJohn Marino 	   typename _CharT, typename _Traits>
1212e4b17023SJohn Marino     std::basic_ostream<_CharT, _Traits>&
1213e4b17023SJohn Marino     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1214e4b17023SJohn Marino 	       const std::independent_bits_engine<_RandomNumberEngine,
1215e4b17023SJohn Marino 	       __w, _UIntType>& __x)
1216e4b17023SJohn Marino     {
1217e4b17023SJohn Marino       __os << __x.base();
1218e4b17023SJohn Marino       return __os;
1219e4b17023SJohn Marino     }
1220e4b17023SJohn Marino 
1221e4b17023SJohn Marino 
1222e4b17023SJohn Marino   /**
1223e4b17023SJohn Marino    * @brief Produces random numbers by combining random numbers from some
1224e4b17023SJohn Marino    * base engine to produce random numbers with a specifies number of bits
1225e4b17023SJohn Marino    * @p __w.
1226e4b17023SJohn Marino    */
1227e4b17023SJohn Marino   template<typename _RandomNumberEngine, size_t __k>
1228e4b17023SJohn Marino     class shuffle_order_engine
1229e4b17023SJohn Marino     {
1230e4b17023SJohn Marino       static_assert(1u <= __k, "template argument substituting "
1231e4b17023SJohn Marino 		    "__k out of bound");
1232e4b17023SJohn Marino 
1233e4b17023SJohn Marino     public:
1234e4b17023SJohn Marino       /** The type of the generated random value. */
1235e4b17023SJohn Marino       typedef typename _RandomNumberEngine::result_type result_type;
1236e4b17023SJohn Marino 
1237e4b17023SJohn Marino       static constexpr size_t table_size = __k;
1238e4b17023SJohn Marino 
1239e4b17023SJohn Marino       /**
1240e4b17023SJohn Marino        * @brief Constructs a default %shuffle_order_engine engine.
1241e4b17023SJohn Marino        *
1242e4b17023SJohn Marino        * The underlying engine is default constructed as well.
1243e4b17023SJohn Marino        */
1244e4b17023SJohn Marino       shuffle_order_engine()
1245e4b17023SJohn Marino       : _M_b()
1246e4b17023SJohn Marino       { _M_initialize(); }
1247e4b17023SJohn Marino 
1248e4b17023SJohn Marino       /**
1249e4b17023SJohn Marino        * @brief Copy constructs a %shuffle_order_engine engine.
1250e4b17023SJohn Marino        *
1251e4b17023SJohn Marino        * Copies an existing base class random number generator.
1252e4b17023SJohn Marino        * @param __rng An existing (base class) engine object.
1253e4b17023SJohn Marino        */
1254e4b17023SJohn Marino       explicit
1255e4b17023SJohn Marino       shuffle_order_engine(const _RandomNumberEngine& __rng)
1256e4b17023SJohn Marino       : _M_b(__rng)
1257e4b17023SJohn Marino       { _M_initialize(); }
1258e4b17023SJohn Marino 
1259e4b17023SJohn Marino       /**
1260e4b17023SJohn Marino        * @brief Move constructs a %shuffle_order_engine engine.
1261e4b17023SJohn Marino        *
1262e4b17023SJohn Marino        * Copies an existing base class random number generator.
1263e4b17023SJohn Marino        * @param __rng An existing (base class) engine object.
1264e4b17023SJohn Marino        */
1265e4b17023SJohn Marino       explicit
1266e4b17023SJohn Marino       shuffle_order_engine(_RandomNumberEngine&& __rng)
1267e4b17023SJohn Marino       : _M_b(std::move(__rng))
1268e4b17023SJohn Marino       { _M_initialize(); }
1269e4b17023SJohn Marino 
1270e4b17023SJohn Marino       /**
1271e4b17023SJohn Marino        * @brief Seed constructs a %shuffle_order_engine engine.
1272e4b17023SJohn Marino        *
1273e4b17023SJohn Marino        * Constructs the underlying generator engine seeded with @p __s.
1274e4b17023SJohn Marino        * @param __s A seed value for the base class engine.
1275e4b17023SJohn Marino        */
1276e4b17023SJohn Marino       explicit
1277e4b17023SJohn Marino       shuffle_order_engine(result_type __s)
1278e4b17023SJohn Marino       : _M_b(__s)
1279e4b17023SJohn Marino       { _M_initialize(); }
1280e4b17023SJohn Marino 
1281e4b17023SJohn Marino       /**
1282e4b17023SJohn Marino        * @brief Generator construct a %shuffle_order_engine engine.
1283e4b17023SJohn Marino        *
1284e4b17023SJohn Marino        * @param __q A seed sequence.
1285e4b17023SJohn Marino        */
1286e4b17023SJohn Marino       template<typename _Sseq, typename = typename
1287e4b17023SJohn Marino 	std::enable_if<!std::is_same<_Sseq, shuffle_order_engine>::value
1288e4b17023SJohn Marino 		       && !std::is_same<_Sseq, _RandomNumberEngine>::value>
1289e4b17023SJohn Marino 	       ::type>
1290e4b17023SJohn Marino         explicit
1291e4b17023SJohn Marino         shuffle_order_engine(_Sseq& __q)
1292e4b17023SJohn Marino         : _M_b(__q)
1293e4b17023SJohn Marino         { _M_initialize(); }
1294e4b17023SJohn Marino 
1295e4b17023SJohn Marino       /**
1296e4b17023SJohn Marino        * @brief Reseeds the %shuffle_order_engine object with the default seed
1297e4b17023SJohn Marino                 for the underlying base class generator engine.
1298e4b17023SJohn Marino        */
1299e4b17023SJohn Marino       void
1300e4b17023SJohn Marino       seed()
1301e4b17023SJohn Marino       {
1302e4b17023SJohn Marino 	_M_b.seed();
1303e4b17023SJohn Marino 	_M_initialize();
1304e4b17023SJohn Marino       }
1305e4b17023SJohn Marino 
1306e4b17023SJohn Marino       /**
1307e4b17023SJohn Marino        * @brief Reseeds the %shuffle_order_engine object with the default seed
1308e4b17023SJohn Marino        *        for the underlying base class generator engine.
1309e4b17023SJohn Marino        */
1310e4b17023SJohn Marino       void
1311e4b17023SJohn Marino       seed(result_type __s)
1312e4b17023SJohn Marino       {
1313e4b17023SJohn Marino 	_M_b.seed(__s);
1314e4b17023SJohn Marino 	_M_initialize();
1315e4b17023SJohn Marino       }
1316e4b17023SJohn Marino 
1317e4b17023SJohn Marino       /**
1318e4b17023SJohn Marino        * @brief Reseeds the %shuffle_order_engine object with the given seed
1319e4b17023SJohn Marino        *        sequence.
1320e4b17023SJohn Marino        * @param __q A seed generator function.
1321e4b17023SJohn Marino        */
1322e4b17023SJohn Marino       template<typename _Sseq>
1323e4b17023SJohn Marino         void
1324e4b17023SJohn Marino         seed(_Sseq& __q)
1325e4b17023SJohn Marino         {
1326e4b17023SJohn Marino 	  _M_b.seed(__q);
1327e4b17023SJohn Marino 	  _M_initialize();
1328e4b17023SJohn Marino 	}
1329e4b17023SJohn Marino 
1330e4b17023SJohn Marino       /**
1331e4b17023SJohn Marino        * Gets a const reference to the underlying generator engine object.
1332e4b17023SJohn Marino        */
1333e4b17023SJohn Marino       const _RandomNumberEngine&
1334e4b17023SJohn Marino       base() const noexcept
1335e4b17023SJohn Marino       { return _M_b; }
1336e4b17023SJohn Marino 
1337e4b17023SJohn Marino       /**
1338e4b17023SJohn Marino        * Gets the minimum value in the generated random number range.
1339e4b17023SJohn Marino        */
1340e4b17023SJohn Marino       static constexpr result_type
1341e4b17023SJohn Marino       min()
1342e4b17023SJohn Marino       { return _RandomNumberEngine::min(); }
1343e4b17023SJohn Marino 
1344e4b17023SJohn Marino       /**
1345e4b17023SJohn Marino        * Gets the maximum value in the generated random number range.
1346e4b17023SJohn Marino        */
1347e4b17023SJohn Marino       static constexpr result_type
1348e4b17023SJohn Marino       max()
1349e4b17023SJohn Marino       { return _RandomNumberEngine::max(); }
1350e4b17023SJohn Marino 
1351e4b17023SJohn Marino       /**
1352e4b17023SJohn Marino        * Discard a sequence of random numbers.
1353e4b17023SJohn Marino        */
1354e4b17023SJohn Marino       void
1355e4b17023SJohn Marino       discard(unsigned long long __z)
1356e4b17023SJohn Marino       {
1357e4b17023SJohn Marino 	for (; __z != 0ULL; --__z)
1358e4b17023SJohn Marino 	  (*this)();
1359e4b17023SJohn Marino       }
1360e4b17023SJohn Marino 
1361e4b17023SJohn Marino       /**
1362e4b17023SJohn Marino        * Gets the next value in the generated random number sequence.
1363e4b17023SJohn Marino        */
1364e4b17023SJohn Marino       result_type
1365e4b17023SJohn Marino       operator()();
1366e4b17023SJohn Marino 
1367e4b17023SJohn Marino       /**
1368e4b17023SJohn Marino        * Compares two %shuffle_order_engine random number generator objects
1369e4b17023SJohn Marino        * of the same type for equality.
1370e4b17023SJohn Marino        *
1371e4b17023SJohn Marino        * @param __lhs A %shuffle_order_engine random number generator object.
1372e4b17023SJohn Marino        * @param __rhs Another %shuffle_order_engine random number generator
1373e4b17023SJohn Marino        *              object.
1374e4b17023SJohn Marino        *
1375e4b17023SJohn Marino        * @returns true if the infinite sequences of generated values
1376e4b17023SJohn Marino        *          would be equal, false otherwise.
1377e4b17023SJohn Marino       */
1378e4b17023SJohn Marino       friend bool
1379e4b17023SJohn Marino       operator==(const shuffle_order_engine& __lhs,
1380e4b17023SJohn Marino 		 const shuffle_order_engine& __rhs)
1381e4b17023SJohn Marino       { return (__lhs._M_b == __rhs._M_b
1382e4b17023SJohn Marino 		&& std::equal(__lhs._M_v, __lhs._M_v + __k, __rhs._M_v)
1383e4b17023SJohn Marino 		&& __lhs._M_y == __rhs._M_y); }
1384e4b17023SJohn Marino 
1385e4b17023SJohn Marino       /**
1386e4b17023SJohn Marino        * @brief Inserts the current state of a %shuffle_order_engine random
1387e4b17023SJohn Marino        *        number generator engine @p __x into the output stream
1388e4b17023SJohn Marino 	@p __os.
1389e4b17023SJohn Marino        *
1390e4b17023SJohn Marino        * @param __os An output stream.
1391e4b17023SJohn Marino        * @param __x  A %shuffle_order_engine random number generator engine.
1392e4b17023SJohn Marino        *
1393e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
1394e4b17023SJohn Marino        * an error state.
1395e4b17023SJohn Marino        */
1396e4b17023SJohn Marino       template<typename _RandomNumberEngine1, size_t __k1,
1397e4b17023SJohn Marino 	       typename _CharT, typename _Traits>
1398e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
1399e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1400e4b17023SJohn Marino 		   const std::shuffle_order_engine<_RandomNumberEngine1,
1401e4b17023SJohn Marino 		   __k1>& __x);
1402e4b17023SJohn Marino 
1403e4b17023SJohn Marino       /**
1404e4b17023SJohn Marino        * @brief Extracts the current state of a % subtract_with_carry_engine
1405e4b17023SJohn Marino        *        random number generator engine @p __x from the input stream
1406e4b17023SJohn Marino        *        @p __is.
1407e4b17023SJohn Marino        *
1408e4b17023SJohn Marino        * @param __is An input stream.
1409e4b17023SJohn Marino        * @param __x  A %shuffle_order_engine random number generator engine.
1410e4b17023SJohn Marino        *
1411e4b17023SJohn Marino        * @returns The input stream with the state of @p __x extracted or in
1412e4b17023SJohn Marino        * an error state.
1413e4b17023SJohn Marino        */
1414e4b17023SJohn Marino       template<typename _RandomNumberEngine1, size_t __k1,
1415e4b17023SJohn Marino 	       typename _CharT, typename _Traits>
1416e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
1417e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
1418e4b17023SJohn Marino 		   std::shuffle_order_engine<_RandomNumberEngine1, __k1>& __x);
1419e4b17023SJohn Marino 
1420e4b17023SJohn Marino     private:
1421e4b17023SJohn Marino       void _M_initialize()
1422e4b17023SJohn Marino       {
1423e4b17023SJohn Marino 	for (size_t __i = 0; __i < __k; ++__i)
1424e4b17023SJohn Marino 	  _M_v[__i] = _M_b();
1425e4b17023SJohn Marino 	_M_y = _M_b();
1426e4b17023SJohn Marino       }
1427e4b17023SJohn Marino 
1428e4b17023SJohn Marino       _RandomNumberEngine _M_b;
1429e4b17023SJohn Marino       result_type _M_v[__k];
1430e4b17023SJohn Marino       result_type _M_y;
1431e4b17023SJohn Marino     };
1432e4b17023SJohn Marino 
1433e4b17023SJohn Marino   /**
1434e4b17023SJohn Marino    * Compares two %shuffle_order_engine random number generator objects
1435e4b17023SJohn Marino    * of the same type for inequality.
1436e4b17023SJohn Marino    *
1437e4b17023SJohn Marino    * @param __lhs A %shuffle_order_engine random number generator object.
1438e4b17023SJohn Marino    * @param __rhs Another %shuffle_order_engine random number generator
1439e4b17023SJohn Marino    *              object.
1440e4b17023SJohn Marino    *
1441e4b17023SJohn Marino    * @returns true if the infinite sequences of generated values
1442e4b17023SJohn Marino    *          would be different, false otherwise.
1443e4b17023SJohn Marino    */
1444e4b17023SJohn Marino   template<typename _RandomNumberEngine, size_t __k>
1445e4b17023SJohn Marino     inline bool
1446e4b17023SJohn Marino     operator!=(const std::shuffle_order_engine<_RandomNumberEngine,
1447e4b17023SJohn Marino 	       __k>& __lhs,
1448e4b17023SJohn Marino 	       const std::shuffle_order_engine<_RandomNumberEngine,
1449e4b17023SJohn Marino 	       __k>& __rhs)
1450e4b17023SJohn Marino     { return !(__lhs == __rhs); }
1451e4b17023SJohn Marino 
1452e4b17023SJohn Marino 
1453e4b17023SJohn Marino   /**
1454e4b17023SJohn Marino    * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
1455e4b17023SJohn Marino    */
1456e4b17023SJohn Marino   typedef linear_congruential_engine<uint_fast32_t, 16807UL, 0UL, 2147483647UL>
1457e4b17023SJohn Marino   minstd_rand0;
1458e4b17023SJohn Marino 
1459e4b17023SJohn Marino   /**
1460e4b17023SJohn Marino    * An alternative LCR (Lehmer Generator function).
1461e4b17023SJohn Marino    */
1462e4b17023SJohn Marino   typedef linear_congruential_engine<uint_fast32_t, 48271UL, 0UL, 2147483647UL>
1463e4b17023SJohn Marino   minstd_rand;
1464e4b17023SJohn Marino 
1465e4b17023SJohn Marino   /**
1466e4b17023SJohn Marino    * The classic Mersenne Twister.
1467e4b17023SJohn Marino    *
1468e4b17023SJohn Marino    * Reference:
1469e4b17023SJohn Marino    * M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally
1470e4b17023SJohn Marino    * Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions
1471e4b17023SJohn Marino    * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
1472e4b17023SJohn Marino    */
1473e4b17023SJohn Marino   typedef mersenne_twister_engine<
1474e4b17023SJohn Marino     uint_fast32_t,
1475e4b17023SJohn Marino     32, 624, 397, 31,
1476e4b17023SJohn Marino     0x9908b0dfUL, 11,
1477e4b17023SJohn Marino     0xffffffffUL, 7,
1478e4b17023SJohn Marino     0x9d2c5680UL, 15,
1479e4b17023SJohn Marino     0xefc60000UL, 18, 1812433253UL> mt19937;
1480e4b17023SJohn Marino 
1481e4b17023SJohn Marino   /**
1482e4b17023SJohn Marino    * An alternative Mersenne Twister.
1483e4b17023SJohn Marino    */
1484e4b17023SJohn Marino   typedef mersenne_twister_engine<
1485e4b17023SJohn Marino     uint_fast64_t,
1486e4b17023SJohn Marino     64, 312, 156, 31,
1487e4b17023SJohn Marino     0xb5026f5aa96619e9ULL, 29,
1488e4b17023SJohn Marino     0x5555555555555555ULL, 17,
1489e4b17023SJohn Marino     0x71d67fffeda60000ULL, 37,
1490e4b17023SJohn Marino     0xfff7eee000000000ULL, 43,
1491e4b17023SJohn Marino     6364136223846793005ULL> mt19937_64;
1492e4b17023SJohn Marino 
1493e4b17023SJohn Marino   typedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>
1494e4b17023SJohn Marino     ranlux24_base;
1495e4b17023SJohn Marino 
1496e4b17023SJohn Marino   typedef subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>
1497e4b17023SJohn Marino     ranlux48_base;
1498e4b17023SJohn Marino 
1499e4b17023SJohn Marino   typedef discard_block_engine<ranlux24_base, 223, 23> ranlux24;
1500e4b17023SJohn Marino 
1501e4b17023SJohn Marino   typedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;
1502e4b17023SJohn Marino 
1503e4b17023SJohn Marino   typedef shuffle_order_engine<minstd_rand0, 256> knuth_b;
1504e4b17023SJohn Marino 
1505e4b17023SJohn Marino   typedef minstd_rand0 default_random_engine;
1506e4b17023SJohn Marino 
1507e4b17023SJohn Marino   /**
1508e4b17023SJohn Marino    * A standard interface to a platform-specific non-deterministic
1509e4b17023SJohn Marino    * random number generator (if any are available).
1510e4b17023SJohn Marino    */
1511e4b17023SJohn Marino   class random_device
1512e4b17023SJohn Marino   {
1513e4b17023SJohn Marino   public:
1514e4b17023SJohn Marino     /** The type of the generated random value. */
1515e4b17023SJohn Marino     typedef unsigned int result_type;
1516e4b17023SJohn Marino 
1517e4b17023SJohn Marino     // constructors, destructors and member functions
1518e4b17023SJohn Marino 
1519e4b17023SJohn Marino #ifdef _GLIBCXX_USE_RANDOM_TR1
1520e4b17023SJohn Marino 
1521e4b17023SJohn Marino     explicit
1522e4b17023SJohn Marino     random_device(const std::string& __token = "/dev/urandom")
1523e4b17023SJohn Marino     {
1524e4b17023SJohn Marino       if ((__token != "/dev/urandom" && __token != "/dev/random")
1525e4b17023SJohn Marino 	  || !(_M_file = std::fopen(__token.c_str(), "rb")))
1526e4b17023SJohn Marino 	std::__throw_runtime_error(__N("random_device::"
1527e4b17023SJohn Marino 				       "random_device(const std::string&)"));
1528e4b17023SJohn Marino     }
1529e4b17023SJohn Marino 
1530e4b17023SJohn Marino     ~random_device()
1531e4b17023SJohn Marino     { std::fclose(_M_file); }
1532e4b17023SJohn Marino 
1533e4b17023SJohn Marino #else
1534e4b17023SJohn Marino 
1535e4b17023SJohn Marino     explicit
1536e4b17023SJohn Marino     random_device(const std::string& __token = "mt19937")
1537e4b17023SJohn Marino     : _M_mt(_M_strtoul(__token)) { }
1538e4b17023SJohn Marino 
1539e4b17023SJohn Marino   private:
1540e4b17023SJohn Marino     static unsigned long
1541e4b17023SJohn Marino     _M_strtoul(const std::string& __str)
1542e4b17023SJohn Marino     {
1543e4b17023SJohn Marino       unsigned long __ret = 5489UL;
1544e4b17023SJohn Marino       if (__str != "mt19937")
1545e4b17023SJohn Marino 	{
1546e4b17023SJohn Marino 	  const char* __nptr = __str.c_str();
1547e4b17023SJohn Marino 	  char* __endptr;
1548e4b17023SJohn Marino 	  __ret = std::strtoul(__nptr, &__endptr, 0);
1549e4b17023SJohn Marino 	  if (*__nptr == '\0' || *__endptr != '\0')
1550e4b17023SJohn Marino 	    std::__throw_runtime_error(__N("random_device::_M_strtoul"
1551e4b17023SJohn Marino 					   "(const std::string&)"));
1552e4b17023SJohn Marino 	}
1553e4b17023SJohn Marino       return __ret;
1554e4b17023SJohn Marino     }
1555e4b17023SJohn Marino 
1556e4b17023SJohn Marino   public:
1557e4b17023SJohn Marino 
1558e4b17023SJohn Marino #endif
1559e4b17023SJohn Marino 
1560e4b17023SJohn Marino     static constexpr result_type
1561e4b17023SJohn Marino     min()
1562e4b17023SJohn Marino     { return std::numeric_limits<result_type>::min(); }
1563e4b17023SJohn Marino 
1564e4b17023SJohn Marino     static constexpr result_type
1565e4b17023SJohn Marino     max()
1566e4b17023SJohn Marino     { return std::numeric_limits<result_type>::max(); }
1567e4b17023SJohn Marino 
1568e4b17023SJohn Marino     double
1569e4b17023SJohn Marino     entropy() const noexcept
1570e4b17023SJohn Marino     { return 0.0; }
1571e4b17023SJohn Marino 
1572e4b17023SJohn Marino     result_type
1573e4b17023SJohn Marino     operator()()
1574e4b17023SJohn Marino     {
1575e4b17023SJohn Marino #ifdef _GLIBCXX_USE_RANDOM_TR1
1576e4b17023SJohn Marino       result_type __ret;
1577e4b17023SJohn Marino       std::fread(reinterpret_cast<void*>(&__ret), sizeof(result_type),
1578e4b17023SJohn Marino 		 1, _M_file);
1579e4b17023SJohn Marino       return __ret;
1580e4b17023SJohn Marino #else
1581e4b17023SJohn Marino       return _M_mt();
1582e4b17023SJohn Marino #endif
1583e4b17023SJohn Marino     }
1584e4b17023SJohn Marino 
1585e4b17023SJohn Marino     // No copy functions.
1586e4b17023SJohn Marino     random_device(const random_device&) = delete;
1587e4b17023SJohn Marino     void operator=(const random_device&) = delete;
1588e4b17023SJohn Marino 
1589e4b17023SJohn Marino   private:
1590e4b17023SJohn Marino 
1591e4b17023SJohn Marino #ifdef _GLIBCXX_USE_RANDOM_TR1
1592e4b17023SJohn Marino     FILE*        _M_file;
1593e4b17023SJohn Marino #else
1594e4b17023SJohn Marino     mt19937      _M_mt;
1595e4b17023SJohn Marino #endif
1596e4b17023SJohn Marino   };
1597e4b17023SJohn Marino 
1598e4b17023SJohn Marino   /* @} */ // group random_generators
1599e4b17023SJohn Marino 
1600e4b17023SJohn Marino   /**
1601e4b17023SJohn Marino    * @addtogroup random_distributions Random Number Distributions
1602e4b17023SJohn Marino    * @ingroup random
1603e4b17023SJohn Marino    * @{
1604e4b17023SJohn Marino    */
1605e4b17023SJohn Marino 
1606e4b17023SJohn Marino   /**
1607e4b17023SJohn Marino    * @addtogroup random_distributions_uniform Uniform Distributions
1608e4b17023SJohn Marino    * @ingroup random_distributions
1609e4b17023SJohn Marino    * @{
1610e4b17023SJohn Marino    */
1611e4b17023SJohn Marino 
1612e4b17023SJohn Marino   /**
1613e4b17023SJohn Marino    * @brief Uniform discrete distribution for random numbers.
1614e4b17023SJohn Marino    * A discrete random distribution on the range @f$[min, max]@f$ with equal
1615e4b17023SJohn Marino    * probability throughout the range.
1616e4b17023SJohn Marino    */
1617e4b17023SJohn Marino   template<typename _IntType = int>
1618e4b17023SJohn Marino     class uniform_int_distribution
1619e4b17023SJohn Marino     {
1620e4b17023SJohn Marino       static_assert(std::is_integral<_IntType>::value,
1621e4b17023SJohn Marino 		    "template argument not an integral type");
1622e4b17023SJohn Marino 
1623e4b17023SJohn Marino     public:
1624e4b17023SJohn Marino       /** The type of the range of the distribution. */
1625e4b17023SJohn Marino       typedef _IntType result_type;
1626e4b17023SJohn Marino       /** Parameter type. */
1627e4b17023SJohn Marino       struct param_type
1628e4b17023SJohn Marino       {
1629e4b17023SJohn Marino 	typedef uniform_int_distribution<_IntType> distribution_type;
1630e4b17023SJohn Marino 
1631e4b17023SJohn Marino 	explicit
1632e4b17023SJohn Marino 	param_type(_IntType __a = 0,
1633e4b17023SJohn Marino 		   _IntType __b = std::numeric_limits<_IntType>::max())
1634e4b17023SJohn Marino 	: _M_a(__a), _M_b(__b)
1635e4b17023SJohn Marino 	{
1636e4b17023SJohn Marino 	  _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
1637e4b17023SJohn Marino 	}
1638e4b17023SJohn Marino 
1639e4b17023SJohn Marino 	result_type
1640e4b17023SJohn Marino 	a() const
1641e4b17023SJohn Marino 	{ return _M_a; }
1642e4b17023SJohn Marino 
1643e4b17023SJohn Marino 	result_type
1644e4b17023SJohn Marino 	b() const
1645e4b17023SJohn Marino 	{ return _M_b; }
1646e4b17023SJohn Marino 
1647e4b17023SJohn Marino 	friend bool
1648e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
1649e4b17023SJohn Marino 	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
1650e4b17023SJohn Marino 
1651e4b17023SJohn Marino       private:
1652e4b17023SJohn Marino 	_IntType _M_a;
1653e4b17023SJohn Marino 	_IntType _M_b;
1654e4b17023SJohn Marino       };
1655e4b17023SJohn Marino 
1656e4b17023SJohn Marino     public:
1657e4b17023SJohn Marino       /**
1658e4b17023SJohn Marino        * @brief Constructs a uniform distribution object.
1659e4b17023SJohn Marino        */
1660e4b17023SJohn Marino       explicit
1661e4b17023SJohn Marino       uniform_int_distribution(_IntType __a = 0,
1662e4b17023SJohn Marino 			   _IntType __b = std::numeric_limits<_IntType>::max())
1663e4b17023SJohn Marino       : _M_param(__a, __b)
1664e4b17023SJohn Marino       { }
1665e4b17023SJohn Marino 
1666e4b17023SJohn Marino       explicit
1667e4b17023SJohn Marino       uniform_int_distribution(const param_type& __p)
1668e4b17023SJohn Marino       : _M_param(__p)
1669e4b17023SJohn Marino       { }
1670e4b17023SJohn Marino 
1671e4b17023SJohn Marino       /**
1672e4b17023SJohn Marino        * @brief Resets the distribution state.
1673e4b17023SJohn Marino        *
1674e4b17023SJohn Marino        * Does nothing for the uniform integer distribution.
1675e4b17023SJohn Marino        */
1676e4b17023SJohn Marino       void
1677e4b17023SJohn Marino       reset() { }
1678e4b17023SJohn Marino 
1679e4b17023SJohn Marino       result_type
1680e4b17023SJohn Marino       a() const
1681e4b17023SJohn Marino       { return _M_param.a(); }
1682e4b17023SJohn Marino 
1683e4b17023SJohn Marino       result_type
1684e4b17023SJohn Marino       b() const
1685e4b17023SJohn Marino       { return _M_param.b(); }
1686e4b17023SJohn Marino 
1687e4b17023SJohn Marino       /**
1688e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
1689e4b17023SJohn Marino        */
1690e4b17023SJohn Marino       param_type
1691e4b17023SJohn Marino       param() const
1692e4b17023SJohn Marino       { return _M_param; }
1693e4b17023SJohn Marino 
1694e4b17023SJohn Marino       /**
1695e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
1696e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
1697e4b17023SJohn Marino        */
1698e4b17023SJohn Marino       void
1699e4b17023SJohn Marino       param(const param_type& __param)
1700e4b17023SJohn Marino       { _M_param = __param; }
1701e4b17023SJohn Marino 
1702e4b17023SJohn Marino       /**
1703e4b17023SJohn Marino        * @brief Returns the inclusive lower bound of the distribution range.
1704e4b17023SJohn Marino        */
1705e4b17023SJohn Marino       result_type
1706e4b17023SJohn Marino       min() const
1707e4b17023SJohn Marino       { return this->a(); }
1708e4b17023SJohn Marino 
1709e4b17023SJohn Marino       /**
1710e4b17023SJohn Marino        * @brief Returns the inclusive upper bound of the distribution range.
1711e4b17023SJohn Marino        */
1712e4b17023SJohn Marino       result_type
1713e4b17023SJohn Marino       max() const
1714e4b17023SJohn Marino       { return this->b(); }
1715e4b17023SJohn Marino 
1716e4b17023SJohn Marino       /**
1717e4b17023SJohn Marino        * @brief Generating functions.
1718e4b17023SJohn Marino        */
1719e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
1720e4b17023SJohn Marino 	result_type
1721e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
1722*5ce9237cSJohn Marino         { return this->operator()(__urng, _M_param); }
1723e4b17023SJohn Marino 
1724e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
1725e4b17023SJohn Marino 	result_type
1726e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
1727e4b17023SJohn Marino 		   const param_type& __p);
1728e4b17023SJohn Marino 
1729e4b17023SJohn Marino       /**
1730e4b17023SJohn Marino        * @brief Return true if two uniform integer distributions have
1731e4b17023SJohn Marino        *        the same parameters.
1732e4b17023SJohn Marino        */
1733*5ce9237cSJohn Marino       friend bool
1734*5ce9237cSJohn Marino       operator==(const uniform_int_distribution& __d1,
1735*5ce9237cSJohn Marino 		 const uniform_int_distribution& __d2)
1736*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param; }
1737*5ce9237cSJohn Marino 
1738*5ce9237cSJohn Marino     private:
1739*5ce9237cSJohn Marino       param_type _M_param;
1740*5ce9237cSJohn Marino     };
1741e4b17023SJohn Marino 
1742e4b17023SJohn Marino   /**
1743e4b17023SJohn Marino    * @brief Return true if two uniform integer distributions have
1744e4b17023SJohn Marino    *        different parameters.
1745e4b17023SJohn Marino    */
1746e4b17023SJohn Marino   template<typename _IntType>
1747e4b17023SJohn Marino     inline bool
1748e4b17023SJohn Marino     operator!=(const std::uniform_int_distribution<_IntType>& __d1,
1749e4b17023SJohn Marino 	       const std::uniform_int_distribution<_IntType>& __d2)
1750e4b17023SJohn Marino     { return !(__d1 == __d2); }
1751e4b17023SJohn Marino 
1752e4b17023SJohn Marino   /**
1753e4b17023SJohn Marino    * @brief Inserts a %uniform_int_distribution random number
1754e4b17023SJohn Marino    *        distribution @p __x into the output stream @p os.
1755e4b17023SJohn Marino    *
1756e4b17023SJohn Marino    * @param __os An output stream.
1757e4b17023SJohn Marino    * @param __x  A %uniform_int_distribution random number distribution.
1758e4b17023SJohn Marino    *
1759e4b17023SJohn Marino    * @returns The output stream with the state of @p __x inserted or in
1760e4b17023SJohn Marino    * an error state.
1761e4b17023SJohn Marino    */
1762e4b17023SJohn Marino   template<typename _IntType, typename _CharT, typename _Traits>
1763e4b17023SJohn Marino     std::basic_ostream<_CharT, _Traits>&
1764e4b17023SJohn Marino     operator<<(std::basic_ostream<_CharT, _Traits>&,
1765e4b17023SJohn Marino 	       const std::uniform_int_distribution<_IntType>&);
1766e4b17023SJohn Marino 
1767e4b17023SJohn Marino   /**
1768e4b17023SJohn Marino    * @brief Extracts a %uniform_int_distribution random number distribution
1769e4b17023SJohn Marino    * @p __x from the input stream @p __is.
1770e4b17023SJohn Marino    *
1771e4b17023SJohn Marino    * @param __is An input stream.
1772e4b17023SJohn Marino    * @param __x  A %uniform_int_distribution random number generator engine.
1773e4b17023SJohn Marino    *
1774e4b17023SJohn Marino    * @returns The input stream with @p __x extracted or in an error state.
1775e4b17023SJohn Marino    */
1776e4b17023SJohn Marino   template<typename _IntType, typename _CharT, typename _Traits>
1777e4b17023SJohn Marino     std::basic_istream<_CharT, _Traits>&
1778e4b17023SJohn Marino     operator>>(std::basic_istream<_CharT, _Traits>&,
1779e4b17023SJohn Marino 	       std::uniform_int_distribution<_IntType>&);
1780e4b17023SJohn Marino 
1781e4b17023SJohn Marino 
1782e4b17023SJohn Marino   /**
1783e4b17023SJohn Marino    * @brief Uniform continuous distribution for random numbers.
1784e4b17023SJohn Marino    *
1785e4b17023SJohn Marino    * A continuous random distribution on the range [min, max) with equal
1786e4b17023SJohn Marino    * probability throughout the range.  The URNG should be real-valued and
1787e4b17023SJohn Marino    * deliver number in the range [0, 1).
1788e4b17023SJohn Marino    */
1789e4b17023SJohn Marino   template<typename _RealType = double>
1790e4b17023SJohn Marino     class uniform_real_distribution
1791e4b17023SJohn Marino     {
1792e4b17023SJohn Marino       static_assert(std::is_floating_point<_RealType>::value,
1793e4b17023SJohn Marino 		    "template argument not a floating point type");
1794e4b17023SJohn Marino 
1795e4b17023SJohn Marino     public:
1796e4b17023SJohn Marino       /** The type of the range of the distribution. */
1797e4b17023SJohn Marino       typedef _RealType result_type;
1798e4b17023SJohn Marino       /** Parameter type. */
1799e4b17023SJohn Marino       struct param_type
1800e4b17023SJohn Marino       {
1801e4b17023SJohn Marino 	typedef uniform_real_distribution<_RealType> distribution_type;
1802e4b17023SJohn Marino 
1803e4b17023SJohn Marino 	explicit
1804e4b17023SJohn Marino 	param_type(_RealType __a = _RealType(0),
1805e4b17023SJohn Marino 		   _RealType __b = _RealType(1))
1806e4b17023SJohn Marino 	: _M_a(__a), _M_b(__b)
1807e4b17023SJohn Marino 	{
1808e4b17023SJohn Marino 	  _GLIBCXX_DEBUG_ASSERT(_M_a <= _M_b);
1809e4b17023SJohn Marino 	}
1810e4b17023SJohn Marino 
1811e4b17023SJohn Marino 	result_type
1812e4b17023SJohn Marino 	a() const
1813e4b17023SJohn Marino 	{ return _M_a; }
1814e4b17023SJohn Marino 
1815e4b17023SJohn Marino 	result_type
1816e4b17023SJohn Marino 	b() const
1817e4b17023SJohn Marino 	{ return _M_b; }
1818e4b17023SJohn Marino 
1819e4b17023SJohn Marino 	friend bool
1820e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
1821e4b17023SJohn Marino 	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
1822e4b17023SJohn Marino 
1823e4b17023SJohn Marino       private:
1824e4b17023SJohn Marino 	_RealType _M_a;
1825e4b17023SJohn Marino 	_RealType _M_b;
1826e4b17023SJohn Marino       };
1827e4b17023SJohn Marino 
1828e4b17023SJohn Marino     public:
1829e4b17023SJohn Marino       /**
1830e4b17023SJohn Marino        * @brief Constructs a uniform_real_distribution object.
1831e4b17023SJohn Marino        *
1832e4b17023SJohn Marino        * @param __a [IN]  The lower bound of the distribution.
1833e4b17023SJohn Marino        * @param __b [IN]  The upper bound of the distribution.
1834e4b17023SJohn Marino        */
1835e4b17023SJohn Marino       explicit
1836e4b17023SJohn Marino       uniform_real_distribution(_RealType __a = _RealType(0),
1837e4b17023SJohn Marino 				_RealType __b = _RealType(1))
1838e4b17023SJohn Marino       : _M_param(__a, __b)
1839e4b17023SJohn Marino       { }
1840e4b17023SJohn Marino 
1841e4b17023SJohn Marino       explicit
1842e4b17023SJohn Marino       uniform_real_distribution(const param_type& __p)
1843e4b17023SJohn Marino       : _M_param(__p)
1844e4b17023SJohn Marino       { }
1845e4b17023SJohn Marino 
1846e4b17023SJohn Marino       /**
1847e4b17023SJohn Marino        * @brief Resets the distribution state.
1848e4b17023SJohn Marino        *
1849e4b17023SJohn Marino        * Does nothing for the uniform real distribution.
1850e4b17023SJohn Marino        */
1851e4b17023SJohn Marino       void
1852e4b17023SJohn Marino       reset() { }
1853e4b17023SJohn Marino 
1854e4b17023SJohn Marino       result_type
1855e4b17023SJohn Marino       a() const
1856e4b17023SJohn Marino       { return _M_param.a(); }
1857e4b17023SJohn Marino 
1858e4b17023SJohn Marino       result_type
1859e4b17023SJohn Marino       b() const
1860e4b17023SJohn Marino       { return _M_param.b(); }
1861e4b17023SJohn Marino 
1862e4b17023SJohn Marino       /**
1863e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
1864e4b17023SJohn Marino        */
1865e4b17023SJohn Marino       param_type
1866e4b17023SJohn Marino       param() const
1867e4b17023SJohn Marino       { return _M_param; }
1868e4b17023SJohn Marino 
1869e4b17023SJohn Marino       /**
1870e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
1871e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
1872e4b17023SJohn Marino        */
1873e4b17023SJohn Marino       void
1874e4b17023SJohn Marino       param(const param_type& __param)
1875e4b17023SJohn Marino       { _M_param = __param; }
1876e4b17023SJohn Marino 
1877e4b17023SJohn Marino       /**
1878e4b17023SJohn Marino        * @brief Returns the inclusive lower bound of the distribution range.
1879e4b17023SJohn Marino        */
1880e4b17023SJohn Marino       result_type
1881e4b17023SJohn Marino       min() const
1882e4b17023SJohn Marino       { return this->a(); }
1883e4b17023SJohn Marino 
1884e4b17023SJohn Marino       /**
1885e4b17023SJohn Marino        * @brief Returns the inclusive upper bound of the distribution range.
1886e4b17023SJohn Marino        */
1887e4b17023SJohn Marino       result_type
1888e4b17023SJohn Marino       max() const
1889e4b17023SJohn Marino       { return this->b(); }
1890e4b17023SJohn Marino 
1891e4b17023SJohn Marino       /**
1892e4b17023SJohn Marino        * @brief Generating functions.
1893e4b17023SJohn Marino        */
1894e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
1895e4b17023SJohn Marino 	result_type
1896e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
1897*5ce9237cSJohn Marino         { return this->operator()(__urng, _M_param); }
1898e4b17023SJohn Marino 
1899e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
1900e4b17023SJohn Marino 	result_type
1901e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
1902e4b17023SJohn Marino 		   const param_type& __p)
1903e4b17023SJohn Marino 	{
1904e4b17023SJohn Marino 	  __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1905e4b17023SJohn Marino 	    __aurng(__urng);
1906e4b17023SJohn Marino 	  return (__aurng() * (__p.b() - __p.a())) + __p.a();
1907e4b17023SJohn Marino 	}
1908e4b17023SJohn Marino 
1909e4b17023SJohn Marino       /**
1910e4b17023SJohn Marino        * @brief Return true if two uniform real distributions have
1911e4b17023SJohn Marino        *        the same parameters.
1912e4b17023SJohn Marino        */
1913*5ce9237cSJohn Marino       friend bool
1914*5ce9237cSJohn Marino       operator==(const uniform_real_distribution& __d1,
1915*5ce9237cSJohn Marino 		 const uniform_real_distribution& __d2)
1916*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param; }
1917*5ce9237cSJohn Marino 
1918*5ce9237cSJohn Marino     private:
1919*5ce9237cSJohn Marino       param_type _M_param;
1920*5ce9237cSJohn Marino     };
1921e4b17023SJohn Marino 
1922e4b17023SJohn Marino   /**
1923e4b17023SJohn Marino    * @brief Return true if two uniform real distributions have
1924e4b17023SJohn Marino    *        different parameters.
1925e4b17023SJohn Marino    */
1926e4b17023SJohn Marino   template<typename _IntType>
1927e4b17023SJohn Marino     inline bool
1928e4b17023SJohn Marino     operator!=(const std::uniform_real_distribution<_IntType>& __d1,
1929e4b17023SJohn Marino 	       const std::uniform_real_distribution<_IntType>& __d2)
1930e4b17023SJohn Marino     { return !(__d1 == __d2); }
1931e4b17023SJohn Marino 
1932e4b17023SJohn Marino   /**
1933e4b17023SJohn Marino    * @brief Inserts a %uniform_real_distribution random number
1934e4b17023SJohn Marino    *        distribution @p __x into the output stream @p __os.
1935e4b17023SJohn Marino    *
1936e4b17023SJohn Marino    * @param __os An output stream.
1937e4b17023SJohn Marino    * @param __x  A %uniform_real_distribution random number distribution.
1938e4b17023SJohn Marino    *
1939e4b17023SJohn Marino    * @returns The output stream with the state of @p __x inserted or in
1940e4b17023SJohn Marino    *          an error state.
1941e4b17023SJohn Marino    */
1942e4b17023SJohn Marino   template<typename _RealType, typename _CharT, typename _Traits>
1943e4b17023SJohn Marino     std::basic_ostream<_CharT, _Traits>&
1944e4b17023SJohn Marino     operator<<(std::basic_ostream<_CharT, _Traits>&,
1945e4b17023SJohn Marino 	       const std::uniform_real_distribution<_RealType>&);
1946e4b17023SJohn Marino 
1947e4b17023SJohn Marino   /**
1948e4b17023SJohn Marino    * @brief Extracts a %uniform_real_distribution random number distribution
1949e4b17023SJohn Marino    * @p __x from the input stream @p __is.
1950e4b17023SJohn Marino    *
1951e4b17023SJohn Marino    * @param __is An input stream.
1952e4b17023SJohn Marino    * @param __x  A %uniform_real_distribution random number generator engine.
1953e4b17023SJohn Marino    *
1954e4b17023SJohn Marino    * @returns The input stream with @p __x extracted or in an error state.
1955e4b17023SJohn Marino    */
1956e4b17023SJohn Marino   template<typename _RealType, typename _CharT, typename _Traits>
1957e4b17023SJohn Marino     std::basic_istream<_CharT, _Traits>&
1958e4b17023SJohn Marino     operator>>(std::basic_istream<_CharT, _Traits>&,
1959e4b17023SJohn Marino 	       std::uniform_real_distribution<_RealType>&);
1960e4b17023SJohn Marino 
1961e4b17023SJohn Marino   /* @} */ // group random_distributions_uniform
1962e4b17023SJohn Marino 
1963e4b17023SJohn Marino   /**
1964e4b17023SJohn Marino    * @addtogroup random_distributions_normal Normal Distributions
1965e4b17023SJohn Marino    * @ingroup random_distributions
1966e4b17023SJohn Marino    * @{
1967e4b17023SJohn Marino    */
1968e4b17023SJohn Marino 
1969e4b17023SJohn Marino   /**
1970e4b17023SJohn Marino    * @brief A normal continuous distribution for random numbers.
1971e4b17023SJohn Marino    *
1972e4b17023SJohn Marino    * The formula for the normal probability density function is
1973e4b17023SJohn Marino    * @f[
1974e4b17023SJohn Marino    *     p(x|\mu,\sigma) = \frac{1}{\sigma \sqrt{2 \pi}}
1975e4b17023SJohn Marino    *            e^{- \frac{{x - \mu}^ {2}}{2 \sigma ^ {2}} }
1976e4b17023SJohn Marino    * @f]
1977e4b17023SJohn Marino    */
1978e4b17023SJohn Marino   template<typename _RealType = double>
1979e4b17023SJohn Marino     class normal_distribution
1980e4b17023SJohn Marino     {
1981e4b17023SJohn Marino       static_assert(std::is_floating_point<_RealType>::value,
1982e4b17023SJohn Marino 		    "template argument not a floating point type");
1983e4b17023SJohn Marino 
1984e4b17023SJohn Marino     public:
1985e4b17023SJohn Marino       /** The type of the range of the distribution. */
1986e4b17023SJohn Marino       typedef _RealType result_type;
1987e4b17023SJohn Marino       /** Parameter type. */
1988e4b17023SJohn Marino       struct param_type
1989e4b17023SJohn Marino       {
1990e4b17023SJohn Marino 	typedef normal_distribution<_RealType> distribution_type;
1991e4b17023SJohn Marino 
1992e4b17023SJohn Marino 	explicit
1993e4b17023SJohn Marino 	param_type(_RealType __mean = _RealType(0),
1994e4b17023SJohn Marino 		   _RealType __stddev = _RealType(1))
1995e4b17023SJohn Marino 	: _M_mean(__mean), _M_stddev(__stddev)
1996e4b17023SJohn Marino 	{
1997e4b17023SJohn Marino 	  _GLIBCXX_DEBUG_ASSERT(_M_stddev > _RealType(0));
1998e4b17023SJohn Marino 	}
1999e4b17023SJohn Marino 
2000e4b17023SJohn Marino 	_RealType
2001e4b17023SJohn Marino 	mean() const
2002e4b17023SJohn Marino 	{ return _M_mean; }
2003e4b17023SJohn Marino 
2004e4b17023SJohn Marino 	_RealType
2005e4b17023SJohn Marino 	stddev() const
2006e4b17023SJohn Marino 	{ return _M_stddev; }
2007e4b17023SJohn Marino 
2008e4b17023SJohn Marino 	friend bool
2009e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
2010e4b17023SJohn Marino 	{ return (__p1._M_mean == __p2._M_mean
2011e4b17023SJohn Marino 		  && __p1._M_stddev == __p2._M_stddev); }
2012e4b17023SJohn Marino 
2013e4b17023SJohn Marino       private:
2014e4b17023SJohn Marino 	_RealType _M_mean;
2015e4b17023SJohn Marino 	_RealType _M_stddev;
2016e4b17023SJohn Marino       };
2017e4b17023SJohn Marino 
2018e4b17023SJohn Marino     public:
2019e4b17023SJohn Marino       /**
2020e4b17023SJohn Marino        * Constructs a normal distribution with parameters @f$mean@f$ and
2021e4b17023SJohn Marino        * standard deviation.
2022e4b17023SJohn Marino        */
2023e4b17023SJohn Marino       explicit
2024e4b17023SJohn Marino       normal_distribution(result_type __mean = result_type(0),
2025e4b17023SJohn Marino 			  result_type __stddev = result_type(1))
2026e4b17023SJohn Marino       : _M_param(__mean, __stddev), _M_saved_available(false)
2027e4b17023SJohn Marino       { }
2028e4b17023SJohn Marino 
2029e4b17023SJohn Marino       explicit
2030e4b17023SJohn Marino       normal_distribution(const param_type& __p)
2031e4b17023SJohn Marino       : _M_param(__p), _M_saved_available(false)
2032e4b17023SJohn Marino       { }
2033e4b17023SJohn Marino 
2034e4b17023SJohn Marino       /**
2035e4b17023SJohn Marino        * @brief Resets the distribution state.
2036e4b17023SJohn Marino        */
2037e4b17023SJohn Marino       void
2038e4b17023SJohn Marino       reset()
2039e4b17023SJohn Marino       { _M_saved_available = false; }
2040e4b17023SJohn Marino 
2041e4b17023SJohn Marino       /**
2042e4b17023SJohn Marino        * @brief Returns the mean of the distribution.
2043e4b17023SJohn Marino        */
2044e4b17023SJohn Marino       _RealType
2045e4b17023SJohn Marino       mean() const
2046e4b17023SJohn Marino       { return _M_param.mean(); }
2047e4b17023SJohn Marino 
2048e4b17023SJohn Marino       /**
2049e4b17023SJohn Marino        * @brief Returns the standard deviation of the distribution.
2050e4b17023SJohn Marino        */
2051e4b17023SJohn Marino       _RealType
2052e4b17023SJohn Marino       stddev() const
2053e4b17023SJohn Marino       { return _M_param.stddev(); }
2054e4b17023SJohn Marino 
2055e4b17023SJohn Marino       /**
2056e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
2057e4b17023SJohn Marino        */
2058e4b17023SJohn Marino       param_type
2059e4b17023SJohn Marino       param() const
2060e4b17023SJohn Marino       { return _M_param; }
2061e4b17023SJohn Marino 
2062e4b17023SJohn Marino       /**
2063e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
2064e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
2065e4b17023SJohn Marino        */
2066e4b17023SJohn Marino       void
2067e4b17023SJohn Marino       param(const param_type& __param)
2068e4b17023SJohn Marino       { _M_param = __param; }
2069e4b17023SJohn Marino 
2070e4b17023SJohn Marino       /**
2071e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
2072e4b17023SJohn Marino        */
2073e4b17023SJohn Marino       result_type
2074e4b17023SJohn Marino       min() const
2075e4b17023SJohn Marino       { return std::numeric_limits<result_type>::min(); }
2076e4b17023SJohn Marino 
2077e4b17023SJohn Marino       /**
2078e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
2079e4b17023SJohn Marino        */
2080e4b17023SJohn Marino       result_type
2081e4b17023SJohn Marino       max() const
2082e4b17023SJohn Marino       { return std::numeric_limits<result_type>::max(); }
2083e4b17023SJohn Marino 
2084e4b17023SJohn Marino       /**
2085e4b17023SJohn Marino        * @brief Generating functions.
2086e4b17023SJohn Marino        */
2087e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
2088e4b17023SJohn Marino 	result_type
2089e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
2090*5ce9237cSJohn Marino 	{ return this->operator()(__urng, _M_param); }
2091e4b17023SJohn Marino 
2092e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
2093e4b17023SJohn Marino 	result_type
2094e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
2095e4b17023SJohn Marino 		   const param_type& __p);
2096e4b17023SJohn Marino 
2097e4b17023SJohn Marino       /**
2098e4b17023SJohn Marino        * @brief Return true if two normal distributions have
2099e4b17023SJohn Marino        *        the same parameters and the sequences that would
2100e4b17023SJohn Marino        *        be generated are equal.
2101e4b17023SJohn Marino        */
2102e4b17023SJohn Marino       template<typename _RealType1>
2103e4b17023SJohn Marino 	friend bool
2104e4b17023SJohn Marino         operator==(const std::normal_distribution<_RealType1>& __d1,
2105e4b17023SJohn Marino 		   const std::normal_distribution<_RealType1>& __d2);
2106e4b17023SJohn Marino 
2107e4b17023SJohn Marino       /**
2108e4b17023SJohn Marino        * @brief Inserts a %normal_distribution random number distribution
2109e4b17023SJohn Marino        * @p __x into the output stream @p __os.
2110e4b17023SJohn Marino        *
2111e4b17023SJohn Marino        * @param __os An output stream.
2112e4b17023SJohn Marino        * @param __x  A %normal_distribution random number distribution.
2113e4b17023SJohn Marino        *
2114e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
2115e4b17023SJohn Marino        * an error state.
2116e4b17023SJohn Marino        */
2117e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
2118e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
2119e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2120e4b17023SJohn Marino 		   const std::normal_distribution<_RealType1>& __x);
2121e4b17023SJohn Marino 
2122e4b17023SJohn Marino       /**
2123e4b17023SJohn Marino        * @brief Extracts a %normal_distribution random number distribution
2124e4b17023SJohn Marino        * @p __x from the input stream @p __is.
2125e4b17023SJohn Marino        *
2126e4b17023SJohn Marino        * @param __is An input stream.
2127e4b17023SJohn Marino        * @param __x  A %normal_distribution random number generator engine.
2128e4b17023SJohn Marino        *
2129e4b17023SJohn Marino        * @returns The input stream with @p __x extracted or in an error
2130e4b17023SJohn Marino        *          state.
2131e4b17023SJohn Marino        */
2132e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
2133e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
2134e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
2135e4b17023SJohn Marino 		   std::normal_distribution<_RealType1>& __x);
2136e4b17023SJohn Marino 
2137e4b17023SJohn Marino     private:
2138e4b17023SJohn Marino       param_type  _M_param;
2139e4b17023SJohn Marino       result_type _M_saved;
2140e4b17023SJohn Marino       bool        _M_saved_available;
2141e4b17023SJohn Marino     };
2142e4b17023SJohn Marino 
2143e4b17023SJohn Marino   /**
2144e4b17023SJohn Marino    * @brief Return true if two normal distributions are different.
2145e4b17023SJohn Marino    */
2146e4b17023SJohn Marino   template<typename _RealType>
2147e4b17023SJohn Marino     inline bool
2148e4b17023SJohn Marino     operator!=(const std::normal_distribution<_RealType>& __d1,
2149e4b17023SJohn Marino 	       const std::normal_distribution<_RealType>& __d2)
2150e4b17023SJohn Marino     { return !(__d1 == __d2); }
2151e4b17023SJohn Marino 
2152e4b17023SJohn Marino 
2153e4b17023SJohn Marino   /**
2154e4b17023SJohn Marino    * @brief A lognormal_distribution random number distribution.
2155e4b17023SJohn Marino    *
2156e4b17023SJohn Marino    * The formula for the normal probability mass function is
2157e4b17023SJohn Marino    * @f[
2158e4b17023SJohn Marino    *     p(x|m,s) = \frac{1}{sx\sqrt{2\pi}}
2159e4b17023SJohn Marino    *                \exp{-\frac{(\ln{x} - m)^2}{2s^2}}
2160e4b17023SJohn Marino    * @f]
2161e4b17023SJohn Marino    */
2162e4b17023SJohn Marino   template<typename _RealType = double>
2163e4b17023SJohn Marino     class lognormal_distribution
2164e4b17023SJohn Marino     {
2165e4b17023SJohn Marino       static_assert(std::is_floating_point<_RealType>::value,
2166e4b17023SJohn Marino 		    "template argument not a floating point type");
2167e4b17023SJohn Marino 
2168e4b17023SJohn Marino     public:
2169e4b17023SJohn Marino       /** The type of the range of the distribution. */
2170e4b17023SJohn Marino       typedef _RealType result_type;
2171e4b17023SJohn Marino       /** Parameter type. */
2172e4b17023SJohn Marino       struct param_type
2173e4b17023SJohn Marino       {
2174e4b17023SJohn Marino 	typedef lognormal_distribution<_RealType> distribution_type;
2175e4b17023SJohn Marino 
2176e4b17023SJohn Marino 	explicit
2177e4b17023SJohn Marino 	param_type(_RealType __m = _RealType(0),
2178e4b17023SJohn Marino 		   _RealType __s = _RealType(1))
2179e4b17023SJohn Marino 	: _M_m(__m), _M_s(__s)
2180e4b17023SJohn Marino 	{ }
2181e4b17023SJohn Marino 
2182e4b17023SJohn Marino 	_RealType
2183e4b17023SJohn Marino 	m() const
2184e4b17023SJohn Marino 	{ return _M_m; }
2185e4b17023SJohn Marino 
2186e4b17023SJohn Marino 	_RealType
2187e4b17023SJohn Marino 	s() const
2188e4b17023SJohn Marino 	{ return _M_s; }
2189e4b17023SJohn Marino 
2190e4b17023SJohn Marino 	friend bool
2191e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
2192e4b17023SJohn Marino 	{ return __p1._M_m == __p2._M_m && __p1._M_s == __p2._M_s; }
2193e4b17023SJohn Marino 
2194e4b17023SJohn Marino       private:
2195e4b17023SJohn Marino 	_RealType _M_m;
2196e4b17023SJohn Marino 	_RealType _M_s;
2197e4b17023SJohn Marino       };
2198e4b17023SJohn Marino 
2199e4b17023SJohn Marino       explicit
2200e4b17023SJohn Marino       lognormal_distribution(_RealType __m = _RealType(0),
2201e4b17023SJohn Marino 			     _RealType __s = _RealType(1))
2202e4b17023SJohn Marino       : _M_param(__m, __s), _M_nd()
2203e4b17023SJohn Marino       { }
2204e4b17023SJohn Marino 
2205e4b17023SJohn Marino       explicit
2206e4b17023SJohn Marino       lognormal_distribution(const param_type& __p)
2207e4b17023SJohn Marino       : _M_param(__p), _M_nd()
2208e4b17023SJohn Marino       { }
2209e4b17023SJohn Marino 
2210e4b17023SJohn Marino       /**
2211e4b17023SJohn Marino        * Resets the distribution state.
2212e4b17023SJohn Marino        */
2213e4b17023SJohn Marino       void
2214e4b17023SJohn Marino       reset()
2215e4b17023SJohn Marino       { _M_nd.reset(); }
2216e4b17023SJohn Marino 
2217e4b17023SJohn Marino       /**
2218e4b17023SJohn Marino        *
2219e4b17023SJohn Marino        */
2220e4b17023SJohn Marino       _RealType
2221e4b17023SJohn Marino       m() const
2222e4b17023SJohn Marino       { return _M_param.m(); }
2223e4b17023SJohn Marino 
2224e4b17023SJohn Marino       _RealType
2225e4b17023SJohn Marino       s() const
2226e4b17023SJohn Marino       { return _M_param.s(); }
2227e4b17023SJohn Marino 
2228e4b17023SJohn Marino       /**
2229e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
2230e4b17023SJohn Marino        */
2231e4b17023SJohn Marino       param_type
2232e4b17023SJohn Marino       param() const
2233e4b17023SJohn Marino       { return _M_param; }
2234e4b17023SJohn Marino 
2235e4b17023SJohn Marino       /**
2236e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
2237e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
2238e4b17023SJohn Marino        */
2239e4b17023SJohn Marino       void
2240e4b17023SJohn Marino       param(const param_type& __param)
2241e4b17023SJohn Marino       { _M_param = __param; }
2242e4b17023SJohn Marino 
2243e4b17023SJohn Marino       /**
2244e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
2245e4b17023SJohn Marino        */
2246e4b17023SJohn Marino       result_type
2247e4b17023SJohn Marino       min() const
2248e4b17023SJohn Marino       { return result_type(0); }
2249e4b17023SJohn Marino 
2250e4b17023SJohn Marino       /**
2251e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
2252e4b17023SJohn Marino        */
2253e4b17023SJohn Marino       result_type
2254e4b17023SJohn Marino       max() const
2255e4b17023SJohn Marino       { return std::numeric_limits<result_type>::max(); }
2256e4b17023SJohn Marino 
2257e4b17023SJohn Marino       /**
2258e4b17023SJohn Marino        * @brief Generating functions.
2259e4b17023SJohn Marino        */
2260e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
2261e4b17023SJohn Marino 	result_type
2262e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
2263*5ce9237cSJohn Marino 	{ return this->operator()(__urng, _M_param); }
2264e4b17023SJohn Marino 
2265e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
2266e4b17023SJohn Marino 	result_type
2267e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
2268e4b17023SJohn Marino 		   const param_type& __p)
2269e4b17023SJohn Marino         { return std::exp(__p.s() * _M_nd(__urng) + __p.m()); }
2270e4b17023SJohn Marino 
2271e4b17023SJohn Marino       /**
2272e4b17023SJohn Marino        * @brief Return true if two lognormal distributions have
2273e4b17023SJohn Marino        *        the same parameters and the sequences that would
2274e4b17023SJohn Marino        *        be generated are equal.
2275e4b17023SJohn Marino        */
2276e4b17023SJohn Marino       friend bool
2277e4b17023SJohn Marino       operator==(const lognormal_distribution& __d1,
2278e4b17023SJohn Marino 		 const lognormal_distribution& __d2)
2279*5ce9237cSJohn Marino       { return (__d1._M_param == __d2._M_param
2280e4b17023SJohn Marino 		&& __d1._M_nd == __d2._M_nd); }
2281e4b17023SJohn Marino 
2282e4b17023SJohn Marino       /**
2283e4b17023SJohn Marino        * @brief Inserts a %lognormal_distribution random number distribution
2284e4b17023SJohn Marino        * @p __x into the output stream @p __os.
2285e4b17023SJohn Marino        *
2286e4b17023SJohn Marino        * @param __os An output stream.
2287e4b17023SJohn Marino        * @param __x  A %lognormal_distribution random number distribution.
2288e4b17023SJohn Marino        *
2289e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
2290e4b17023SJohn Marino        * an error state.
2291e4b17023SJohn Marino        */
2292e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
2293e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
2294e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2295e4b17023SJohn Marino 		   const std::lognormal_distribution<_RealType1>& __x);
2296e4b17023SJohn Marino 
2297e4b17023SJohn Marino       /**
2298e4b17023SJohn Marino        * @brief Extracts a %lognormal_distribution random number distribution
2299e4b17023SJohn Marino        * @p __x from the input stream @p __is.
2300e4b17023SJohn Marino        *
2301e4b17023SJohn Marino        * @param __is An input stream.
2302e4b17023SJohn Marino        * @param __x A %lognormal_distribution random number
2303e4b17023SJohn Marino        *            generator engine.
2304e4b17023SJohn Marino        *
2305e4b17023SJohn Marino        * @returns The input stream with @p __x extracted or in an error state.
2306e4b17023SJohn Marino        */
2307e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
2308e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
2309e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
2310e4b17023SJohn Marino 		   std::lognormal_distribution<_RealType1>& __x);
2311e4b17023SJohn Marino 
2312e4b17023SJohn Marino     private:
2313e4b17023SJohn Marino       param_type _M_param;
2314e4b17023SJohn Marino 
2315e4b17023SJohn Marino       std::normal_distribution<result_type> _M_nd;
2316e4b17023SJohn Marino     };
2317e4b17023SJohn Marino 
2318e4b17023SJohn Marino   /**
2319e4b17023SJohn Marino    * @brief Return true if two lognormal distributions are different.
2320e4b17023SJohn Marino    */
2321e4b17023SJohn Marino   template<typename _RealType>
2322e4b17023SJohn Marino     inline bool
2323e4b17023SJohn Marino     operator!=(const std::lognormal_distribution<_RealType>& __d1,
2324e4b17023SJohn Marino 	       const std::lognormal_distribution<_RealType>& __d2)
2325e4b17023SJohn Marino     { return !(__d1 == __d2); }
2326e4b17023SJohn Marino 
2327e4b17023SJohn Marino 
2328e4b17023SJohn Marino   /**
2329e4b17023SJohn Marino    * @brief A gamma continuous distribution for random numbers.
2330e4b17023SJohn Marino    *
2331e4b17023SJohn Marino    * The formula for the gamma probability density function is:
2332e4b17023SJohn Marino    * @f[
2333e4b17023SJohn Marino    *     p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
2334e4b17023SJohn Marino    *                         (x/\beta)^{\alpha - 1} e^{-x/\beta}
2335e4b17023SJohn Marino    * @f]
2336e4b17023SJohn Marino    */
2337e4b17023SJohn Marino   template<typename _RealType = double>
2338e4b17023SJohn Marino     class gamma_distribution
2339e4b17023SJohn Marino     {
2340e4b17023SJohn Marino       static_assert(std::is_floating_point<_RealType>::value,
2341e4b17023SJohn Marino 		    "template argument not a floating point type");
2342e4b17023SJohn Marino 
2343e4b17023SJohn Marino     public:
2344e4b17023SJohn Marino       /** The type of the range of the distribution. */
2345e4b17023SJohn Marino       typedef _RealType result_type;
2346e4b17023SJohn Marino       /** Parameter type. */
2347e4b17023SJohn Marino       struct param_type
2348e4b17023SJohn Marino       {
2349e4b17023SJohn Marino 	typedef gamma_distribution<_RealType> distribution_type;
2350e4b17023SJohn Marino 	friend class gamma_distribution<_RealType>;
2351e4b17023SJohn Marino 
2352e4b17023SJohn Marino 	explicit
2353e4b17023SJohn Marino 	param_type(_RealType __alpha_val = _RealType(1),
2354e4b17023SJohn Marino 		   _RealType __beta_val = _RealType(1))
2355e4b17023SJohn Marino 	: _M_alpha(__alpha_val), _M_beta(__beta_val)
2356e4b17023SJohn Marino 	{
2357e4b17023SJohn Marino 	  _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0));
2358e4b17023SJohn Marino 	  _M_initialize();
2359e4b17023SJohn Marino 	}
2360e4b17023SJohn Marino 
2361e4b17023SJohn Marino 	_RealType
2362e4b17023SJohn Marino 	alpha() const
2363e4b17023SJohn Marino 	{ return _M_alpha; }
2364e4b17023SJohn Marino 
2365e4b17023SJohn Marino 	_RealType
2366e4b17023SJohn Marino 	beta() const
2367e4b17023SJohn Marino 	{ return _M_beta; }
2368e4b17023SJohn Marino 
2369e4b17023SJohn Marino 	friend bool
2370e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
2371e4b17023SJohn Marino 	{ return (__p1._M_alpha == __p2._M_alpha
2372e4b17023SJohn Marino 		  && __p1._M_beta == __p2._M_beta); }
2373e4b17023SJohn Marino 
2374e4b17023SJohn Marino       private:
2375e4b17023SJohn Marino 	void
2376e4b17023SJohn Marino 	_M_initialize();
2377e4b17023SJohn Marino 
2378e4b17023SJohn Marino 	_RealType _M_alpha;
2379e4b17023SJohn Marino 	_RealType _M_beta;
2380e4b17023SJohn Marino 
2381e4b17023SJohn Marino 	_RealType _M_malpha, _M_a2;
2382e4b17023SJohn Marino       };
2383e4b17023SJohn Marino 
2384e4b17023SJohn Marino     public:
2385e4b17023SJohn Marino       /**
2386e4b17023SJohn Marino        * @brief Constructs a gamma distribution with parameters
2387e4b17023SJohn Marino        * @f$\alpha@f$ and @f$\beta@f$.
2388e4b17023SJohn Marino        */
2389e4b17023SJohn Marino       explicit
2390e4b17023SJohn Marino       gamma_distribution(_RealType __alpha_val = _RealType(1),
2391e4b17023SJohn Marino 			 _RealType __beta_val = _RealType(1))
2392e4b17023SJohn Marino       : _M_param(__alpha_val, __beta_val), _M_nd()
2393e4b17023SJohn Marino       { }
2394e4b17023SJohn Marino 
2395e4b17023SJohn Marino       explicit
2396e4b17023SJohn Marino       gamma_distribution(const param_type& __p)
2397e4b17023SJohn Marino       : _M_param(__p), _M_nd()
2398e4b17023SJohn Marino       { }
2399e4b17023SJohn Marino 
2400e4b17023SJohn Marino       /**
2401e4b17023SJohn Marino        * @brief Resets the distribution state.
2402e4b17023SJohn Marino        */
2403e4b17023SJohn Marino       void
2404e4b17023SJohn Marino       reset()
2405e4b17023SJohn Marino       { _M_nd.reset(); }
2406e4b17023SJohn Marino 
2407e4b17023SJohn Marino       /**
2408e4b17023SJohn Marino        * @brief Returns the @f$\alpha@f$ of the distribution.
2409e4b17023SJohn Marino        */
2410e4b17023SJohn Marino       _RealType
2411e4b17023SJohn Marino       alpha() const
2412e4b17023SJohn Marino       { return _M_param.alpha(); }
2413e4b17023SJohn Marino 
2414e4b17023SJohn Marino       /**
2415e4b17023SJohn Marino        * @brief Returns the @f$\beta@f$ of the distribution.
2416e4b17023SJohn Marino        */
2417e4b17023SJohn Marino       _RealType
2418e4b17023SJohn Marino       beta() const
2419e4b17023SJohn Marino       { return _M_param.beta(); }
2420e4b17023SJohn Marino 
2421e4b17023SJohn Marino       /**
2422e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
2423e4b17023SJohn Marino        */
2424e4b17023SJohn Marino       param_type
2425e4b17023SJohn Marino       param() const
2426e4b17023SJohn Marino       { return _M_param; }
2427e4b17023SJohn Marino 
2428e4b17023SJohn Marino       /**
2429e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
2430e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
2431e4b17023SJohn Marino        */
2432e4b17023SJohn Marino       void
2433e4b17023SJohn Marino       param(const param_type& __param)
2434e4b17023SJohn Marino       { _M_param = __param; }
2435e4b17023SJohn Marino 
2436e4b17023SJohn Marino       /**
2437e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
2438e4b17023SJohn Marino        */
2439e4b17023SJohn Marino       result_type
2440e4b17023SJohn Marino       min() const
2441e4b17023SJohn Marino       { return result_type(0); }
2442e4b17023SJohn Marino 
2443e4b17023SJohn Marino       /**
2444e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
2445e4b17023SJohn Marino        */
2446e4b17023SJohn Marino       result_type
2447e4b17023SJohn Marino       max() const
2448e4b17023SJohn Marino       { return std::numeric_limits<result_type>::max(); }
2449e4b17023SJohn Marino 
2450e4b17023SJohn Marino       /**
2451e4b17023SJohn Marino        * @brief Generating functions.
2452e4b17023SJohn Marino        */
2453e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
2454e4b17023SJohn Marino 	result_type
2455e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
2456*5ce9237cSJohn Marino 	{ return this->operator()(__urng, _M_param); }
2457e4b17023SJohn Marino 
2458e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
2459e4b17023SJohn Marino 	result_type
2460e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
2461e4b17023SJohn Marino 		   const param_type& __p);
2462e4b17023SJohn Marino 
2463e4b17023SJohn Marino       /**
2464e4b17023SJohn Marino        * @brief Return true if two gamma distributions have the same
2465e4b17023SJohn Marino        *        parameters and the sequences that would be generated
2466e4b17023SJohn Marino        *        are equal.
2467e4b17023SJohn Marino        */
2468e4b17023SJohn Marino       friend bool
2469e4b17023SJohn Marino       operator==(const gamma_distribution& __d1,
2470e4b17023SJohn Marino 		 const gamma_distribution& __d2)
2471*5ce9237cSJohn Marino       { return (__d1._M_param == __d2._M_param
2472e4b17023SJohn Marino 		&& __d1._M_nd == __d2._M_nd); }
2473e4b17023SJohn Marino 
2474e4b17023SJohn Marino       /**
2475e4b17023SJohn Marino        * @brief Inserts a %gamma_distribution random number distribution
2476e4b17023SJohn Marino        * @p __x into the output stream @p __os.
2477e4b17023SJohn Marino        *
2478e4b17023SJohn Marino        * @param __os An output stream.
2479e4b17023SJohn Marino        * @param __x  A %gamma_distribution random number distribution.
2480e4b17023SJohn Marino        *
2481e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
2482e4b17023SJohn Marino        * an error state.
2483e4b17023SJohn Marino        */
2484e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
2485e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
2486e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2487e4b17023SJohn Marino 		   const std::gamma_distribution<_RealType1>& __x);
2488e4b17023SJohn Marino 
2489e4b17023SJohn Marino       /**
2490e4b17023SJohn Marino        * @brief Extracts a %gamma_distribution random number distribution
2491e4b17023SJohn Marino        * @p __x from the input stream @p __is.
2492e4b17023SJohn Marino        *
2493e4b17023SJohn Marino        * @param __is An input stream.
2494e4b17023SJohn Marino        * @param __x  A %gamma_distribution random number generator engine.
2495e4b17023SJohn Marino        *
2496e4b17023SJohn Marino        * @returns The input stream with @p __x extracted or in an error state.
2497e4b17023SJohn Marino        */
2498e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
2499e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
2500e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
2501e4b17023SJohn Marino 		   std::gamma_distribution<_RealType1>& __x);
2502e4b17023SJohn Marino 
2503e4b17023SJohn Marino     private:
2504e4b17023SJohn Marino       param_type _M_param;
2505e4b17023SJohn Marino 
2506e4b17023SJohn Marino       std::normal_distribution<result_type> _M_nd;
2507e4b17023SJohn Marino     };
2508e4b17023SJohn Marino 
2509e4b17023SJohn Marino   /**
2510e4b17023SJohn Marino    * @brief Return true if two gamma distributions are different.
2511e4b17023SJohn Marino    */
2512e4b17023SJohn Marino    template<typename _RealType>
2513e4b17023SJohn Marino     inline bool
2514e4b17023SJohn Marino      operator!=(const std::gamma_distribution<_RealType>& __d1,
2515e4b17023SJohn Marino 		const std::gamma_distribution<_RealType>& __d2)
2516e4b17023SJohn Marino     { return !(__d1 == __d2); }
2517e4b17023SJohn Marino 
2518e4b17023SJohn Marino 
2519e4b17023SJohn Marino   /**
2520e4b17023SJohn Marino    * @brief A chi_squared_distribution random number distribution.
2521e4b17023SJohn Marino    *
2522e4b17023SJohn Marino    * The formula for the normal probability mass function is
2523e4b17023SJohn Marino    * @f$p(x|n) = \frac{x^{(n/2) - 1}e^{-x/2}}{\Gamma(n/2) 2^{n/2}}@f$
2524e4b17023SJohn Marino    */
2525e4b17023SJohn Marino   template<typename _RealType = double>
2526e4b17023SJohn Marino     class chi_squared_distribution
2527e4b17023SJohn Marino     {
2528e4b17023SJohn Marino       static_assert(std::is_floating_point<_RealType>::value,
2529e4b17023SJohn Marino 		    "template argument not a floating point type");
2530e4b17023SJohn Marino 
2531e4b17023SJohn Marino     public:
2532e4b17023SJohn Marino       /** The type of the range of the distribution. */
2533e4b17023SJohn Marino       typedef _RealType result_type;
2534e4b17023SJohn Marino       /** Parameter type. */
2535e4b17023SJohn Marino       struct param_type
2536e4b17023SJohn Marino       {
2537e4b17023SJohn Marino 	typedef chi_squared_distribution<_RealType> distribution_type;
2538e4b17023SJohn Marino 
2539e4b17023SJohn Marino 	explicit
2540e4b17023SJohn Marino 	param_type(_RealType __n = _RealType(1))
2541e4b17023SJohn Marino 	: _M_n(__n)
2542e4b17023SJohn Marino 	{ }
2543e4b17023SJohn Marino 
2544e4b17023SJohn Marino 	_RealType
2545e4b17023SJohn Marino 	n() const
2546e4b17023SJohn Marino 	{ return _M_n; }
2547e4b17023SJohn Marino 
2548e4b17023SJohn Marino 	friend bool
2549e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
2550e4b17023SJohn Marino 	{ return __p1._M_n == __p2._M_n; }
2551e4b17023SJohn Marino 
2552e4b17023SJohn Marino       private:
2553e4b17023SJohn Marino 	_RealType _M_n;
2554e4b17023SJohn Marino       };
2555e4b17023SJohn Marino 
2556e4b17023SJohn Marino       explicit
2557e4b17023SJohn Marino       chi_squared_distribution(_RealType __n = _RealType(1))
2558e4b17023SJohn Marino       : _M_param(__n), _M_gd(__n / 2)
2559e4b17023SJohn Marino       { }
2560e4b17023SJohn Marino 
2561e4b17023SJohn Marino       explicit
2562e4b17023SJohn Marino       chi_squared_distribution(const param_type& __p)
2563e4b17023SJohn Marino       : _M_param(__p), _M_gd(__p.n() / 2)
2564e4b17023SJohn Marino       { }
2565e4b17023SJohn Marino 
2566e4b17023SJohn Marino       /**
2567e4b17023SJohn Marino        * @brief Resets the distribution state.
2568e4b17023SJohn Marino        */
2569e4b17023SJohn Marino       void
2570e4b17023SJohn Marino       reset()
2571e4b17023SJohn Marino       { _M_gd.reset(); }
2572e4b17023SJohn Marino 
2573e4b17023SJohn Marino       /**
2574e4b17023SJohn Marino        *
2575e4b17023SJohn Marino        */
2576e4b17023SJohn Marino       _RealType
2577e4b17023SJohn Marino       n() const
2578e4b17023SJohn Marino       { return _M_param.n(); }
2579e4b17023SJohn Marino 
2580e4b17023SJohn Marino       /**
2581e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
2582e4b17023SJohn Marino        */
2583e4b17023SJohn Marino       param_type
2584e4b17023SJohn Marino       param() const
2585e4b17023SJohn Marino       { return _M_param; }
2586e4b17023SJohn Marino 
2587e4b17023SJohn Marino       /**
2588e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
2589e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
2590e4b17023SJohn Marino        */
2591e4b17023SJohn Marino       void
2592e4b17023SJohn Marino       param(const param_type& __param)
2593e4b17023SJohn Marino       { _M_param = __param; }
2594e4b17023SJohn Marino 
2595e4b17023SJohn Marino       /**
2596e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
2597e4b17023SJohn Marino        */
2598e4b17023SJohn Marino       result_type
2599e4b17023SJohn Marino       min() const
2600e4b17023SJohn Marino       { return result_type(0); }
2601e4b17023SJohn Marino 
2602e4b17023SJohn Marino       /**
2603e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
2604e4b17023SJohn Marino        */
2605e4b17023SJohn Marino       result_type
2606e4b17023SJohn Marino       max() const
2607e4b17023SJohn Marino       { return std::numeric_limits<result_type>::max(); }
2608e4b17023SJohn Marino 
2609e4b17023SJohn Marino       /**
2610e4b17023SJohn Marino        * @brief Generating functions.
2611e4b17023SJohn Marino        */
2612e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
2613e4b17023SJohn Marino 	result_type
2614e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
2615e4b17023SJohn Marino 	{ return 2 * _M_gd(__urng); }
2616e4b17023SJohn Marino 
2617e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
2618e4b17023SJohn Marino 	result_type
2619e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
2620e4b17023SJohn Marino 		   const param_type& __p)
2621e4b17023SJohn Marino         {
2622e4b17023SJohn Marino 	  typedef typename std::gamma_distribution<result_type>::param_type
2623e4b17023SJohn Marino 	    param_type;
2624e4b17023SJohn Marino 	  return 2 * _M_gd(__urng, param_type(__p.n() / 2));
2625e4b17023SJohn Marino 	}
2626e4b17023SJohn Marino 
2627e4b17023SJohn Marino       /**
2628e4b17023SJohn Marino        * @brief Return true if two Chi-squared distributions have
2629e4b17023SJohn Marino        *        the same parameters and the sequences that would be
2630e4b17023SJohn Marino        *        generated are equal.
2631e4b17023SJohn Marino        */
2632e4b17023SJohn Marino       friend bool
2633e4b17023SJohn Marino       operator==(const chi_squared_distribution& __d1,
2634e4b17023SJohn Marino 		 const chi_squared_distribution& __d2)
2635*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; }
2636e4b17023SJohn Marino 
2637e4b17023SJohn Marino       /**
2638e4b17023SJohn Marino        * @brief Inserts a %chi_squared_distribution random number distribution
2639e4b17023SJohn Marino        * @p __x into the output stream @p __os.
2640e4b17023SJohn Marino        *
2641e4b17023SJohn Marino        * @param __os An output stream.
2642e4b17023SJohn Marino        * @param __x  A %chi_squared_distribution random number distribution.
2643e4b17023SJohn Marino        *
2644e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
2645e4b17023SJohn Marino        * an error state.
2646e4b17023SJohn Marino        */
2647e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
2648e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
2649e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2650e4b17023SJohn Marino 		   const std::chi_squared_distribution<_RealType1>& __x);
2651e4b17023SJohn Marino 
2652e4b17023SJohn Marino       /**
2653e4b17023SJohn Marino        * @brief Extracts a %chi_squared_distribution random number distribution
2654e4b17023SJohn Marino        * @p __x from the input stream @p __is.
2655e4b17023SJohn Marino        *
2656e4b17023SJohn Marino        * @param __is An input stream.
2657e4b17023SJohn Marino        * @param __x A %chi_squared_distribution random number
2658e4b17023SJohn Marino        *            generator engine.
2659e4b17023SJohn Marino        *
2660e4b17023SJohn Marino        * @returns The input stream with @p __x extracted or in an error state.
2661e4b17023SJohn Marino        */
2662e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
2663e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
2664e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
2665e4b17023SJohn Marino 		   std::chi_squared_distribution<_RealType1>& __x);
2666e4b17023SJohn Marino 
2667e4b17023SJohn Marino     private:
2668e4b17023SJohn Marino       param_type _M_param;
2669e4b17023SJohn Marino 
2670e4b17023SJohn Marino       std::gamma_distribution<result_type> _M_gd;
2671e4b17023SJohn Marino     };
2672e4b17023SJohn Marino 
2673e4b17023SJohn Marino   /**
2674e4b17023SJohn Marino    * @brief Return true if two Chi-squared distributions are different.
2675e4b17023SJohn Marino    */
2676e4b17023SJohn Marino   template<typename _RealType>
2677e4b17023SJohn Marino     inline bool
2678e4b17023SJohn Marino     operator!=(const std::chi_squared_distribution<_RealType>& __d1,
2679e4b17023SJohn Marino 	       const std::chi_squared_distribution<_RealType>& __d2)
2680e4b17023SJohn Marino     { return !(__d1 == __d2); }
2681e4b17023SJohn Marino 
2682e4b17023SJohn Marino 
2683e4b17023SJohn Marino   /**
2684e4b17023SJohn Marino    * @brief A cauchy_distribution random number distribution.
2685e4b17023SJohn Marino    *
2686e4b17023SJohn Marino    * The formula for the normal probability mass function is
2687e4b17023SJohn Marino    * @f$p(x|a,b) = (\pi b (1 + (\frac{x-a}{b})^2))^{-1}@f$
2688e4b17023SJohn Marino    */
2689e4b17023SJohn Marino   template<typename _RealType = double>
2690e4b17023SJohn Marino     class cauchy_distribution
2691e4b17023SJohn Marino     {
2692e4b17023SJohn Marino       static_assert(std::is_floating_point<_RealType>::value,
2693e4b17023SJohn Marino 		    "template argument not a floating point type");
2694e4b17023SJohn Marino 
2695e4b17023SJohn Marino     public:
2696e4b17023SJohn Marino       /** The type of the range of the distribution. */
2697e4b17023SJohn Marino       typedef _RealType result_type;
2698e4b17023SJohn Marino       /** Parameter type. */
2699e4b17023SJohn Marino       struct param_type
2700e4b17023SJohn Marino       {
2701e4b17023SJohn Marino 	typedef cauchy_distribution<_RealType> distribution_type;
2702e4b17023SJohn Marino 
2703e4b17023SJohn Marino 	explicit
2704e4b17023SJohn Marino 	param_type(_RealType __a = _RealType(0),
2705e4b17023SJohn Marino 		   _RealType __b = _RealType(1))
2706e4b17023SJohn Marino 	: _M_a(__a), _M_b(__b)
2707e4b17023SJohn Marino 	{ }
2708e4b17023SJohn Marino 
2709e4b17023SJohn Marino 	_RealType
2710e4b17023SJohn Marino 	a() const
2711e4b17023SJohn Marino 	{ return _M_a; }
2712e4b17023SJohn Marino 
2713e4b17023SJohn Marino 	_RealType
2714e4b17023SJohn Marino 	b() const
2715e4b17023SJohn Marino 	{ return _M_b; }
2716e4b17023SJohn Marino 
2717e4b17023SJohn Marino 	friend bool
2718e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
2719e4b17023SJohn Marino 	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
2720e4b17023SJohn Marino 
2721e4b17023SJohn Marino       private:
2722e4b17023SJohn Marino 	_RealType _M_a;
2723e4b17023SJohn Marino 	_RealType _M_b;
2724e4b17023SJohn Marino       };
2725e4b17023SJohn Marino 
2726e4b17023SJohn Marino       explicit
2727e4b17023SJohn Marino       cauchy_distribution(_RealType __a = _RealType(0),
2728e4b17023SJohn Marino 			  _RealType __b = _RealType(1))
2729e4b17023SJohn Marino       : _M_param(__a, __b)
2730e4b17023SJohn Marino       { }
2731e4b17023SJohn Marino 
2732e4b17023SJohn Marino       explicit
2733e4b17023SJohn Marino       cauchy_distribution(const param_type& __p)
2734e4b17023SJohn Marino       : _M_param(__p)
2735e4b17023SJohn Marino       { }
2736e4b17023SJohn Marino 
2737e4b17023SJohn Marino       /**
2738e4b17023SJohn Marino        * @brief Resets the distribution state.
2739e4b17023SJohn Marino        */
2740e4b17023SJohn Marino       void
2741e4b17023SJohn Marino       reset()
2742e4b17023SJohn Marino       { }
2743e4b17023SJohn Marino 
2744e4b17023SJohn Marino       /**
2745e4b17023SJohn Marino        *
2746e4b17023SJohn Marino        */
2747e4b17023SJohn Marino       _RealType
2748e4b17023SJohn Marino       a() const
2749e4b17023SJohn Marino       { return _M_param.a(); }
2750e4b17023SJohn Marino 
2751e4b17023SJohn Marino       _RealType
2752e4b17023SJohn Marino       b() const
2753e4b17023SJohn Marino       { return _M_param.b(); }
2754e4b17023SJohn Marino 
2755e4b17023SJohn Marino       /**
2756e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
2757e4b17023SJohn Marino        */
2758e4b17023SJohn Marino       param_type
2759e4b17023SJohn Marino       param() const
2760e4b17023SJohn Marino       { return _M_param; }
2761e4b17023SJohn Marino 
2762e4b17023SJohn Marino       /**
2763e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
2764e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
2765e4b17023SJohn Marino        */
2766e4b17023SJohn Marino       void
2767e4b17023SJohn Marino       param(const param_type& __param)
2768e4b17023SJohn Marino       { _M_param = __param; }
2769e4b17023SJohn Marino 
2770e4b17023SJohn Marino       /**
2771e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
2772e4b17023SJohn Marino        */
2773e4b17023SJohn Marino       result_type
2774e4b17023SJohn Marino       min() const
2775e4b17023SJohn Marino       { return std::numeric_limits<result_type>::min(); }
2776e4b17023SJohn Marino 
2777e4b17023SJohn Marino       /**
2778e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
2779e4b17023SJohn Marino        */
2780e4b17023SJohn Marino       result_type
2781e4b17023SJohn Marino       max() const
2782e4b17023SJohn Marino       { return std::numeric_limits<result_type>::max(); }
2783e4b17023SJohn Marino 
2784e4b17023SJohn Marino       /**
2785e4b17023SJohn Marino        * @brief Generating functions.
2786e4b17023SJohn Marino        */
2787e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
2788e4b17023SJohn Marino 	result_type
2789e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
2790*5ce9237cSJohn Marino 	{ return this->operator()(__urng, _M_param); }
2791e4b17023SJohn Marino 
2792e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
2793e4b17023SJohn Marino 	result_type
2794e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
2795e4b17023SJohn Marino 		   const param_type& __p);
2796e4b17023SJohn Marino 
2797e4b17023SJohn Marino       /**
2798e4b17023SJohn Marino        * @brief Return true if two Cauchy distributions have
2799e4b17023SJohn Marino        *        the same parameters.
2800e4b17023SJohn Marino        */
2801*5ce9237cSJohn Marino       friend bool
2802*5ce9237cSJohn Marino       operator==(const cauchy_distribution& __d1,
2803*5ce9237cSJohn Marino 		 const cauchy_distribution& __d2)
2804*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param; }
2805*5ce9237cSJohn Marino 
2806*5ce9237cSJohn Marino     private:
2807*5ce9237cSJohn Marino       param_type _M_param;
2808*5ce9237cSJohn Marino     };
2809e4b17023SJohn Marino 
2810e4b17023SJohn Marino   /**
2811e4b17023SJohn Marino    * @brief Return true if two Cauchy distributions have
2812e4b17023SJohn Marino    *        different parameters.
2813e4b17023SJohn Marino    */
2814e4b17023SJohn Marino   template<typename _RealType>
2815e4b17023SJohn Marino     inline bool
2816e4b17023SJohn Marino     operator!=(const std::cauchy_distribution<_RealType>& __d1,
2817e4b17023SJohn Marino 	       const std::cauchy_distribution<_RealType>& __d2)
2818e4b17023SJohn Marino     { return !(__d1 == __d2); }
2819e4b17023SJohn Marino 
2820e4b17023SJohn Marino   /**
2821e4b17023SJohn Marino    * @brief Inserts a %cauchy_distribution random number distribution
2822e4b17023SJohn Marino    * @p __x into the output stream @p __os.
2823e4b17023SJohn Marino    *
2824e4b17023SJohn Marino    * @param __os An output stream.
2825e4b17023SJohn Marino    * @param __x  A %cauchy_distribution random number distribution.
2826e4b17023SJohn Marino    *
2827e4b17023SJohn Marino    * @returns The output stream with the state of @p __x inserted or in
2828e4b17023SJohn Marino    * an error state.
2829e4b17023SJohn Marino    */
2830e4b17023SJohn Marino   template<typename _RealType, typename _CharT, typename _Traits>
2831e4b17023SJohn Marino     std::basic_ostream<_CharT, _Traits>&
2832e4b17023SJohn Marino     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2833e4b17023SJohn Marino 	       const std::cauchy_distribution<_RealType>& __x);
2834e4b17023SJohn Marino 
2835e4b17023SJohn Marino   /**
2836e4b17023SJohn Marino    * @brief Extracts a %cauchy_distribution random number distribution
2837e4b17023SJohn Marino    * @p __x from the input stream @p __is.
2838e4b17023SJohn Marino    *
2839e4b17023SJohn Marino    * @param __is An input stream.
2840e4b17023SJohn Marino    * @param __x A %cauchy_distribution random number
2841e4b17023SJohn Marino    *            generator engine.
2842e4b17023SJohn Marino    *
2843e4b17023SJohn Marino    * @returns The input stream with @p __x extracted or in an error state.
2844e4b17023SJohn Marino    */
2845e4b17023SJohn Marino   template<typename _RealType, typename _CharT, typename _Traits>
2846e4b17023SJohn Marino     std::basic_istream<_CharT, _Traits>&
2847e4b17023SJohn Marino     operator>>(std::basic_istream<_CharT, _Traits>& __is,
2848e4b17023SJohn Marino 	       std::cauchy_distribution<_RealType>& __x);
2849e4b17023SJohn Marino 
2850e4b17023SJohn Marino 
2851e4b17023SJohn Marino   /**
2852e4b17023SJohn Marino    * @brief A fisher_f_distribution random number distribution.
2853e4b17023SJohn Marino    *
2854e4b17023SJohn Marino    * The formula for the normal probability mass function is
2855e4b17023SJohn Marino    * @f[
2856e4b17023SJohn Marino    *     p(x|m,n) = \frac{\Gamma((m+n)/2)}{\Gamma(m/2)\Gamma(n/2)}
2857e4b17023SJohn Marino    *                (\frac{m}{n})^{m/2} x^{(m/2)-1}
2858e4b17023SJohn Marino    *                (1 + \frac{mx}{n})^{-(m+n)/2}
2859e4b17023SJohn Marino    * @f]
2860e4b17023SJohn Marino    */
2861e4b17023SJohn Marino   template<typename _RealType = double>
2862e4b17023SJohn Marino     class fisher_f_distribution
2863e4b17023SJohn Marino     {
2864e4b17023SJohn Marino       static_assert(std::is_floating_point<_RealType>::value,
2865e4b17023SJohn Marino 		    "template argument not a floating point type");
2866e4b17023SJohn Marino 
2867e4b17023SJohn Marino     public:
2868e4b17023SJohn Marino       /** The type of the range of the distribution. */
2869e4b17023SJohn Marino       typedef _RealType result_type;
2870e4b17023SJohn Marino       /** Parameter type. */
2871e4b17023SJohn Marino       struct param_type
2872e4b17023SJohn Marino       {
2873e4b17023SJohn Marino 	typedef fisher_f_distribution<_RealType> distribution_type;
2874e4b17023SJohn Marino 
2875e4b17023SJohn Marino 	explicit
2876e4b17023SJohn Marino 	param_type(_RealType __m = _RealType(1),
2877e4b17023SJohn Marino 		   _RealType __n = _RealType(1))
2878e4b17023SJohn Marino 	: _M_m(__m), _M_n(__n)
2879e4b17023SJohn Marino 	{ }
2880e4b17023SJohn Marino 
2881e4b17023SJohn Marino 	_RealType
2882e4b17023SJohn Marino 	m() const
2883e4b17023SJohn Marino 	{ return _M_m; }
2884e4b17023SJohn Marino 
2885e4b17023SJohn Marino 	_RealType
2886e4b17023SJohn Marino 	n() const
2887e4b17023SJohn Marino 	{ return _M_n; }
2888e4b17023SJohn Marino 
2889e4b17023SJohn Marino 	friend bool
2890e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
2891e4b17023SJohn Marino 	{ return __p1._M_m == __p2._M_m && __p1._M_n == __p2._M_n; }
2892e4b17023SJohn Marino 
2893e4b17023SJohn Marino       private:
2894e4b17023SJohn Marino 	_RealType _M_m;
2895e4b17023SJohn Marino 	_RealType _M_n;
2896e4b17023SJohn Marino       };
2897e4b17023SJohn Marino 
2898e4b17023SJohn Marino       explicit
2899e4b17023SJohn Marino       fisher_f_distribution(_RealType __m = _RealType(1),
2900e4b17023SJohn Marino 			    _RealType __n = _RealType(1))
2901e4b17023SJohn Marino       : _M_param(__m, __n), _M_gd_x(__m / 2), _M_gd_y(__n / 2)
2902e4b17023SJohn Marino       { }
2903e4b17023SJohn Marino 
2904e4b17023SJohn Marino       explicit
2905e4b17023SJohn Marino       fisher_f_distribution(const param_type& __p)
2906e4b17023SJohn Marino       : _M_param(__p), _M_gd_x(__p.m() / 2), _M_gd_y(__p.n() / 2)
2907e4b17023SJohn Marino       { }
2908e4b17023SJohn Marino 
2909e4b17023SJohn Marino       /**
2910e4b17023SJohn Marino        * @brief Resets the distribution state.
2911e4b17023SJohn Marino        */
2912e4b17023SJohn Marino       void
2913e4b17023SJohn Marino       reset()
2914e4b17023SJohn Marino       {
2915e4b17023SJohn Marino 	_M_gd_x.reset();
2916e4b17023SJohn Marino 	_M_gd_y.reset();
2917e4b17023SJohn Marino       }
2918e4b17023SJohn Marino 
2919e4b17023SJohn Marino       /**
2920e4b17023SJohn Marino        *
2921e4b17023SJohn Marino        */
2922e4b17023SJohn Marino       _RealType
2923e4b17023SJohn Marino       m() const
2924e4b17023SJohn Marino       { return _M_param.m(); }
2925e4b17023SJohn Marino 
2926e4b17023SJohn Marino       _RealType
2927e4b17023SJohn Marino       n() const
2928e4b17023SJohn Marino       { return _M_param.n(); }
2929e4b17023SJohn Marino 
2930e4b17023SJohn Marino       /**
2931e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
2932e4b17023SJohn Marino        */
2933e4b17023SJohn Marino       param_type
2934e4b17023SJohn Marino       param() const
2935e4b17023SJohn Marino       { return _M_param; }
2936e4b17023SJohn Marino 
2937e4b17023SJohn Marino       /**
2938e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
2939e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
2940e4b17023SJohn Marino        */
2941e4b17023SJohn Marino       void
2942e4b17023SJohn Marino       param(const param_type& __param)
2943e4b17023SJohn Marino       { _M_param = __param; }
2944e4b17023SJohn Marino 
2945e4b17023SJohn Marino       /**
2946e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
2947e4b17023SJohn Marino        */
2948e4b17023SJohn Marino       result_type
2949e4b17023SJohn Marino       min() const
2950e4b17023SJohn Marino       { return result_type(0); }
2951e4b17023SJohn Marino 
2952e4b17023SJohn Marino       /**
2953e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
2954e4b17023SJohn Marino        */
2955e4b17023SJohn Marino       result_type
2956e4b17023SJohn Marino       max() const
2957e4b17023SJohn Marino       { return std::numeric_limits<result_type>::max(); }
2958e4b17023SJohn Marino 
2959e4b17023SJohn Marino       /**
2960e4b17023SJohn Marino        * @brief Generating functions.
2961e4b17023SJohn Marino        */
2962e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
2963e4b17023SJohn Marino 	result_type
2964e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
2965e4b17023SJohn Marino 	{ return (_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()); }
2966e4b17023SJohn Marino 
2967e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
2968e4b17023SJohn Marino 	result_type
2969e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
2970e4b17023SJohn Marino 		   const param_type& __p)
2971e4b17023SJohn Marino         {
2972e4b17023SJohn Marino 	  typedef typename std::gamma_distribution<result_type>::param_type
2973e4b17023SJohn Marino 	    param_type;
2974e4b17023SJohn Marino 	  return ((_M_gd_x(__urng, param_type(__p.m() / 2)) * n())
2975e4b17023SJohn Marino 		  / (_M_gd_y(__urng, param_type(__p.n() / 2)) * m()));
2976e4b17023SJohn Marino 	}
2977e4b17023SJohn Marino 
2978e4b17023SJohn Marino       /**
2979e4b17023SJohn Marino        * @brief Return true if two Fisher f distributions have
2980e4b17023SJohn Marino        *        the same parameters and the sequences that would
2981e4b17023SJohn Marino        *        be generated are equal.
2982e4b17023SJohn Marino        */
2983e4b17023SJohn Marino       friend bool
2984e4b17023SJohn Marino       operator==(const fisher_f_distribution& __d1,
2985e4b17023SJohn Marino 		 const fisher_f_distribution& __d2)
2986*5ce9237cSJohn Marino       { return (__d1._M_param == __d2._M_param
2987e4b17023SJohn Marino 		&& __d1._M_gd_x == __d2._M_gd_x
2988e4b17023SJohn Marino 		&& __d1._M_gd_y == __d2._M_gd_y); }
2989e4b17023SJohn Marino 
2990e4b17023SJohn Marino       /**
2991e4b17023SJohn Marino        * @brief Inserts a %fisher_f_distribution random number distribution
2992e4b17023SJohn Marino        * @p __x into the output stream @p __os.
2993e4b17023SJohn Marino        *
2994e4b17023SJohn Marino        * @param __os An output stream.
2995e4b17023SJohn Marino        * @param __x  A %fisher_f_distribution random number distribution.
2996e4b17023SJohn Marino        *
2997e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
2998e4b17023SJohn Marino        * an error state.
2999e4b17023SJohn Marino        */
3000e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
3001e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
3002e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3003e4b17023SJohn Marino 		   const std::fisher_f_distribution<_RealType1>& __x);
3004e4b17023SJohn Marino 
3005e4b17023SJohn Marino       /**
3006e4b17023SJohn Marino        * @brief Extracts a %fisher_f_distribution random number distribution
3007e4b17023SJohn Marino        * @p __x from the input stream @p __is.
3008e4b17023SJohn Marino        *
3009e4b17023SJohn Marino        * @param __is An input stream.
3010e4b17023SJohn Marino        * @param __x A %fisher_f_distribution random number
3011e4b17023SJohn Marino        *            generator engine.
3012e4b17023SJohn Marino        *
3013e4b17023SJohn Marino        * @returns The input stream with @p __x extracted or in an error state.
3014e4b17023SJohn Marino        */
3015e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
3016e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
3017e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
3018e4b17023SJohn Marino 		   std::fisher_f_distribution<_RealType1>& __x);
3019e4b17023SJohn Marino 
3020e4b17023SJohn Marino     private:
3021e4b17023SJohn Marino       param_type _M_param;
3022e4b17023SJohn Marino 
3023e4b17023SJohn Marino       std::gamma_distribution<result_type> _M_gd_x, _M_gd_y;
3024e4b17023SJohn Marino     };
3025e4b17023SJohn Marino 
3026e4b17023SJohn Marino   /**
3027e4b17023SJohn Marino    * @brief Return true if two Fisher f distributions are diferent.
3028e4b17023SJohn Marino    */
3029e4b17023SJohn Marino   template<typename _RealType>
3030e4b17023SJohn Marino     inline bool
3031e4b17023SJohn Marino     operator!=(const std::fisher_f_distribution<_RealType>& __d1,
3032e4b17023SJohn Marino 	       const std::fisher_f_distribution<_RealType>& __d2)
3033e4b17023SJohn Marino     { return !(__d1 == __d2); }
3034e4b17023SJohn Marino 
3035e4b17023SJohn Marino   /**
3036e4b17023SJohn Marino    * @brief A student_t_distribution random number distribution.
3037e4b17023SJohn Marino    *
3038e4b17023SJohn Marino    * The formula for the normal probability mass function is:
3039e4b17023SJohn Marino    * @f[
3040e4b17023SJohn Marino    *     p(x|n) = \frac{1}{\sqrt(n\pi)} \frac{\Gamma((n+1)/2)}{\Gamma(n/2)}
3041e4b17023SJohn Marino    *              (1 + \frac{x^2}{n}) ^{-(n+1)/2}
3042e4b17023SJohn Marino    * @f]
3043e4b17023SJohn Marino    */
3044e4b17023SJohn Marino   template<typename _RealType = double>
3045e4b17023SJohn Marino     class student_t_distribution
3046e4b17023SJohn Marino     {
3047e4b17023SJohn Marino       static_assert(std::is_floating_point<_RealType>::value,
3048e4b17023SJohn Marino 		    "template argument not a floating point type");
3049e4b17023SJohn Marino 
3050e4b17023SJohn Marino     public:
3051e4b17023SJohn Marino       /** The type of the range of the distribution. */
3052e4b17023SJohn Marino       typedef _RealType result_type;
3053e4b17023SJohn Marino       /** Parameter type. */
3054e4b17023SJohn Marino       struct param_type
3055e4b17023SJohn Marino       {
3056e4b17023SJohn Marino 	typedef student_t_distribution<_RealType> distribution_type;
3057e4b17023SJohn Marino 
3058e4b17023SJohn Marino 	explicit
3059e4b17023SJohn Marino 	param_type(_RealType __n = _RealType(1))
3060e4b17023SJohn Marino 	: _M_n(__n)
3061e4b17023SJohn Marino 	{ }
3062e4b17023SJohn Marino 
3063e4b17023SJohn Marino 	_RealType
3064e4b17023SJohn Marino 	n() const
3065e4b17023SJohn Marino 	{ return _M_n; }
3066e4b17023SJohn Marino 
3067e4b17023SJohn Marino 	friend bool
3068e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
3069e4b17023SJohn Marino 	{ return __p1._M_n == __p2._M_n; }
3070e4b17023SJohn Marino 
3071e4b17023SJohn Marino       private:
3072e4b17023SJohn Marino 	_RealType _M_n;
3073e4b17023SJohn Marino       };
3074e4b17023SJohn Marino 
3075e4b17023SJohn Marino       explicit
3076e4b17023SJohn Marino       student_t_distribution(_RealType __n = _RealType(1))
3077e4b17023SJohn Marino       : _M_param(__n), _M_nd(), _M_gd(__n / 2, 2)
3078e4b17023SJohn Marino       { }
3079e4b17023SJohn Marino 
3080e4b17023SJohn Marino       explicit
3081e4b17023SJohn Marino       student_t_distribution(const param_type& __p)
3082e4b17023SJohn Marino       : _M_param(__p), _M_nd(), _M_gd(__p.n() / 2, 2)
3083e4b17023SJohn Marino       { }
3084e4b17023SJohn Marino 
3085e4b17023SJohn Marino       /**
3086e4b17023SJohn Marino        * @brief Resets the distribution state.
3087e4b17023SJohn Marino        */
3088e4b17023SJohn Marino       void
3089e4b17023SJohn Marino       reset()
3090e4b17023SJohn Marino       {
3091e4b17023SJohn Marino 	_M_nd.reset();
3092e4b17023SJohn Marino 	_M_gd.reset();
3093e4b17023SJohn Marino       }
3094e4b17023SJohn Marino 
3095e4b17023SJohn Marino       /**
3096e4b17023SJohn Marino        *
3097e4b17023SJohn Marino        */
3098e4b17023SJohn Marino       _RealType
3099e4b17023SJohn Marino       n() const
3100e4b17023SJohn Marino       { return _M_param.n(); }
3101e4b17023SJohn Marino 
3102e4b17023SJohn Marino       /**
3103e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
3104e4b17023SJohn Marino        */
3105e4b17023SJohn Marino       param_type
3106e4b17023SJohn Marino       param() const
3107e4b17023SJohn Marino       { return _M_param; }
3108e4b17023SJohn Marino 
3109e4b17023SJohn Marino       /**
3110e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
3111e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
3112e4b17023SJohn Marino        */
3113e4b17023SJohn Marino       void
3114e4b17023SJohn Marino       param(const param_type& __param)
3115e4b17023SJohn Marino       { _M_param = __param; }
3116e4b17023SJohn Marino 
3117e4b17023SJohn Marino       /**
3118e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
3119e4b17023SJohn Marino        */
3120e4b17023SJohn Marino       result_type
3121e4b17023SJohn Marino       min() const
3122e4b17023SJohn Marino       { return std::numeric_limits<result_type>::min(); }
3123e4b17023SJohn Marino 
3124e4b17023SJohn Marino       /**
3125e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
3126e4b17023SJohn Marino        */
3127e4b17023SJohn Marino       result_type
3128e4b17023SJohn Marino       max() const
3129e4b17023SJohn Marino       { return std::numeric_limits<result_type>::max(); }
3130e4b17023SJohn Marino 
3131e4b17023SJohn Marino       /**
3132e4b17023SJohn Marino        * @brief Generating functions.
3133e4b17023SJohn Marino        */
3134e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
3135e4b17023SJohn Marino 	result_type
3136e4b17023SJohn Marino         operator()(_UniformRandomNumberGenerator& __urng)
3137e4b17023SJohn Marino         { return _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); }
3138e4b17023SJohn Marino 
3139e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
3140e4b17023SJohn Marino 	result_type
3141e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
3142e4b17023SJohn Marino 		   const param_type& __p)
3143e4b17023SJohn Marino         {
3144e4b17023SJohn Marino 	  typedef typename std::gamma_distribution<result_type>::param_type
3145e4b17023SJohn Marino 	    param_type;
3146e4b17023SJohn Marino 
3147e4b17023SJohn Marino 	  const result_type __g = _M_gd(__urng, param_type(__p.n() / 2, 2));
3148e4b17023SJohn Marino 	  return _M_nd(__urng) * std::sqrt(__p.n() / __g);
3149e4b17023SJohn Marino         }
3150e4b17023SJohn Marino 
3151e4b17023SJohn Marino       /**
3152e4b17023SJohn Marino        * @brief Return true if two Student t distributions have
3153e4b17023SJohn Marino        *        the same parameters and the sequences that would
3154e4b17023SJohn Marino        *        be generated are equal.
3155e4b17023SJohn Marino        */
3156e4b17023SJohn Marino       friend bool
3157e4b17023SJohn Marino       operator==(const student_t_distribution& __d1,
3158e4b17023SJohn Marino 		 const student_t_distribution& __d2)
3159*5ce9237cSJohn Marino       { return (__d1._M_param == __d2._M_param
3160e4b17023SJohn Marino 		&& __d1._M_nd == __d2._M_nd && __d1._M_gd == __d2._M_gd); }
3161e4b17023SJohn Marino 
3162e4b17023SJohn Marino       /**
3163e4b17023SJohn Marino        * @brief Inserts a %student_t_distribution random number distribution
3164e4b17023SJohn Marino        * @p __x into the output stream @p __os.
3165e4b17023SJohn Marino        *
3166e4b17023SJohn Marino        * @param __os An output stream.
3167e4b17023SJohn Marino        * @param __x  A %student_t_distribution random number distribution.
3168e4b17023SJohn Marino        *
3169e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
3170e4b17023SJohn Marino        * an error state.
3171e4b17023SJohn Marino        */
3172e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
3173e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
3174e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3175e4b17023SJohn Marino 		   const std::student_t_distribution<_RealType1>& __x);
3176e4b17023SJohn Marino 
3177e4b17023SJohn Marino       /**
3178e4b17023SJohn Marino        * @brief Extracts a %student_t_distribution random number distribution
3179e4b17023SJohn Marino        * @p __x from the input stream @p __is.
3180e4b17023SJohn Marino        *
3181e4b17023SJohn Marino        * @param __is An input stream.
3182e4b17023SJohn Marino        * @param __x A %student_t_distribution random number
3183e4b17023SJohn Marino        *            generator engine.
3184e4b17023SJohn Marino        *
3185e4b17023SJohn Marino        * @returns The input stream with @p __x extracted or in an error state.
3186e4b17023SJohn Marino        */
3187e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
3188e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
3189e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
3190e4b17023SJohn Marino 		   std::student_t_distribution<_RealType1>& __x);
3191e4b17023SJohn Marino 
3192e4b17023SJohn Marino     private:
3193e4b17023SJohn Marino       param_type _M_param;
3194e4b17023SJohn Marino 
3195e4b17023SJohn Marino       std::normal_distribution<result_type> _M_nd;
3196e4b17023SJohn Marino       std::gamma_distribution<result_type> _M_gd;
3197e4b17023SJohn Marino     };
3198e4b17023SJohn Marino 
3199e4b17023SJohn Marino   /**
3200e4b17023SJohn Marino    * @brief Return true if two Student t distributions are different.
3201e4b17023SJohn Marino    */
3202e4b17023SJohn Marino   template<typename _RealType>
3203e4b17023SJohn Marino     inline bool
3204e4b17023SJohn Marino     operator!=(const std::student_t_distribution<_RealType>& __d1,
3205e4b17023SJohn Marino 	       const std::student_t_distribution<_RealType>& __d2)
3206e4b17023SJohn Marino     { return !(__d1 == __d2); }
3207e4b17023SJohn Marino 
3208e4b17023SJohn Marino 
3209e4b17023SJohn Marino   /* @} */ // group random_distributions_normal
3210e4b17023SJohn Marino 
3211e4b17023SJohn Marino   /**
3212e4b17023SJohn Marino    * @addtogroup random_distributions_bernoulli Bernoulli Distributions
3213e4b17023SJohn Marino    * @ingroup random_distributions
3214e4b17023SJohn Marino    * @{
3215e4b17023SJohn Marino    */
3216e4b17023SJohn Marino 
3217e4b17023SJohn Marino   /**
3218e4b17023SJohn Marino    * @brief A Bernoulli random number distribution.
3219e4b17023SJohn Marino    *
3220e4b17023SJohn Marino    * Generates a sequence of true and false values with likelihood @f$p@f$
3221e4b17023SJohn Marino    * that true will come up and @f$(1 - p)@f$ that false will appear.
3222e4b17023SJohn Marino    */
3223e4b17023SJohn Marino   class bernoulli_distribution
3224e4b17023SJohn Marino   {
3225e4b17023SJohn Marino   public:
3226e4b17023SJohn Marino     /** The type of the range of the distribution. */
3227e4b17023SJohn Marino     typedef bool result_type;
3228e4b17023SJohn Marino     /** Parameter type. */
3229e4b17023SJohn Marino     struct param_type
3230e4b17023SJohn Marino     {
3231e4b17023SJohn Marino       typedef bernoulli_distribution distribution_type;
3232e4b17023SJohn Marino 
3233e4b17023SJohn Marino       explicit
3234e4b17023SJohn Marino       param_type(double __p = 0.5)
3235e4b17023SJohn Marino       : _M_p(__p)
3236e4b17023SJohn Marino       {
3237e4b17023SJohn Marino 	_GLIBCXX_DEBUG_ASSERT((_M_p >= 0.0) && (_M_p <= 1.0));
3238e4b17023SJohn Marino       }
3239e4b17023SJohn Marino 
3240e4b17023SJohn Marino       double
3241e4b17023SJohn Marino       p() const
3242e4b17023SJohn Marino       { return _M_p; }
3243e4b17023SJohn Marino 
3244e4b17023SJohn Marino       friend bool
3245e4b17023SJohn Marino       operator==(const param_type& __p1, const param_type& __p2)
3246e4b17023SJohn Marino       { return __p1._M_p == __p2._M_p; }
3247e4b17023SJohn Marino 
3248e4b17023SJohn Marino     private:
3249e4b17023SJohn Marino       double _M_p;
3250e4b17023SJohn Marino     };
3251e4b17023SJohn Marino 
3252e4b17023SJohn Marino   public:
3253e4b17023SJohn Marino     /**
3254e4b17023SJohn Marino      * @brief Constructs a Bernoulli distribution with likelihood @p p.
3255e4b17023SJohn Marino      *
3256e4b17023SJohn Marino      * @param __p  [IN]  The likelihood of a true result being returned.
3257e4b17023SJohn Marino      *                   Must be in the interval @f$[0, 1]@f$.
3258e4b17023SJohn Marino      */
3259e4b17023SJohn Marino     explicit
3260e4b17023SJohn Marino     bernoulli_distribution(double __p = 0.5)
3261e4b17023SJohn Marino     : _M_param(__p)
3262e4b17023SJohn Marino     { }
3263e4b17023SJohn Marino 
3264e4b17023SJohn Marino     explicit
3265e4b17023SJohn Marino     bernoulli_distribution(const param_type& __p)
3266e4b17023SJohn Marino     : _M_param(__p)
3267e4b17023SJohn Marino     { }
3268e4b17023SJohn Marino 
3269e4b17023SJohn Marino     /**
3270e4b17023SJohn Marino      * @brief Resets the distribution state.
3271e4b17023SJohn Marino      *
3272e4b17023SJohn Marino      * Does nothing for a Bernoulli distribution.
3273e4b17023SJohn Marino      */
3274e4b17023SJohn Marino     void
3275e4b17023SJohn Marino     reset() { }
3276e4b17023SJohn Marino 
3277e4b17023SJohn Marino     /**
3278e4b17023SJohn Marino      * @brief Returns the @p p parameter of the distribution.
3279e4b17023SJohn Marino      */
3280e4b17023SJohn Marino     double
3281e4b17023SJohn Marino     p() const
3282e4b17023SJohn Marino     { return _M_param.p(); }
3283e4b17023SJohn Marino 
3284e4b17023SJohn Marino     /**
3285e4b17023SJohn Marino      * @brief Returns the parameter set of the distribution.
3286e4b17023SJohn Marino      */
3287e4b17023SJohn Marino     param_type
3288e4b17023SJohn Marino     param() const
3289e4b17023SJohn Marino     { return _M_param; }
3290e4b17023SJohn Marino 
3291e4b17023SJohn Marino     /**
3292e4b17023SJohn Marino      * @brief Sets the parameter set of the distribution.
3293e4b17023SJohn Marino      * @param __param The new parameter set of the distribution.
3294e4b17023SJohn Marino      */
3295e4b17023SJohn Marino     void
3296e4b17023SJohn Marino     param(const param_type& __param)
3297e4b17023SJohn Marino     { _M_param = __param; }
3298e4b17023SJohn Marino 
3299e4b17023SJohn Marino     /**
3300e4b17023SJohn Marino      * @brief Returns the greatest lower bound value of the distribution.
3301e4b17023SJohn Marino      */
3302e4b17023SJohn Marino     result_type
3303e4b17023SJohn Marino     min() const
3304e4b17023SJohn Marino     { return std::numeric_limits<result_type>::min(); }
3305e4b17023SJohn Marino 
3306e4b17023SJohn Marino     /**
3307e4b17023SJohn Marino      * @brief Returns the least upper bound value of the distribution.
3308e4b17023SJohn Marino      */
3309e4b17023SJohn Marino     result_type
3310e4b17023SJohn Marino     max() const
3311e4b17023SJohn Marino     { return std::numeric_limits<result_type>::max(); }
3312e4b17023SJohn Marino 
3313e4b17023SJohn Marino     /**
3314e4b17023SJohn Marino      * @brief Generating functions.
3315e4b17023SJohn Marino      */
3316e4b17023SJohn Marino     template<typename _UniformRandomNumberGenerator>
3317e4b17023SJohn Marino       result_type
3318e4b17023SJohn Marino       operator()(_UniformRandomNumberGenerator& __urng)
3319*5ce9237cSJohn Marino       { return this->operator()(__urng, _M_param); }
3320e4b17023SJohn Marino 
3321e4b17023SJohn Marino     template<typename _UniformRandomNumberGenerator>
3322e4b17023SJohn Marino       result_type
3323e4b17023SJohn Marino       operator()(_UniformRandomNumberGenerator& __urng,
3324e4b17023SJohn Marino 		 const param_type& __p)
3325e4b17023SJohn Marino       {
3326e4b17023SJohn Marino 	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
3327e4b17023SJohn Marino 	  __aurng(__urng);
3328e4b17023SJohn Marino 	if ((__aurng() - __aurng.min())
3329e4b17023SJohn Marino 	     < __p.p() * (__aurng.max() - __aurng.min()))
3330e4b17023SJohn Marino 	  return true;
3331e4b17023SJohn Marino 	return false;
3332e4b17023SJohn Marino       }
3333e4b17023SJohn Marino 
3334e4b17023SJohn Marino     /**
3335e4b17023SJohn Marino      * @brief Return true if two Bernoulli distributions have
3336e4b17023SJohn Marino      *        the same parameters.
3337e4b17023SJohn Marino      */
3338*5ce9237cSJohn Marino     friend bool
3339*5ce9237cSJohn Marino     operator==(const bernoulli_distribution& __d1,
3340*5ce9237cSJohn Marino 	       const bernoulli_distribution& __d2)
3341*5ce9237cSJohn Marino     { return __d1._M_param == __d2._M_param; }
3342*5ce9237cSJohn Marino 
3343*5ce9237cSJohn Marino   private:
3344*5ce9237cSJohn Marino     param_type _M_param;
3345*5ce9237cSJohn Marino   };
3346e4b17023SJohn Marino 
3347e4b17023SJohn Marino   /**
3348e4b17023SJohn Marino    * @brief Return true if two Bernoulli distributions have
3349e4b17023SJohn Marino    *        different parameters.
3350e4b17023SJohn Marino    */
3351e4b17023SJohn Marino   inline bool
3352e4b17023SJohn Marino   operator!=(const std::bernoulli_distribution& __d1,
3353e4b17023SJohn Marino 	     const std::bernoulli_distribution& __d2)
3354e4b17023SJohn Marino   { return !(__d1 == __d2); }
3355e4b17023SJohn Marino 
3356e4b17023SJohn Marino   /**
3357e4b17023SJohn Marino    * @brief Inserts a %bernoulli_distribution random number distribution
3358e4b17023SJohn Marino    * @p __x into the output stream @p __os.
3359e4b17023SJohn Marino    *
3360e4b17023SJohn Marino    * @param __os An output stream.
3361e4b17023SJohn Marino    * @param __x  A %bernoulli_distribution random number distribution.
3362e4b17023SJohn Marino    *
3363e4b17023SJohn Marino    * @returns The output stream with the state of @p __x inserted or in
3364e4b17023SJohn Marino    * an error state.
3365e4b17023SJohn Marino    */
3366e4b17023SJohn Marino   template<typename _CharT, typename _Traits>
3367e4b17023SJohn Marino     std::basic_ostream<_CharT, _Traits>&
3368e4b17023SJohn Marino     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3369e4b17023SJohn Marino 	       const std::bernoulli_distribution& __x);
3370e4b17023SJohn Marino 
3371e4b17023SJohn Marino   /**
3372e4b17023SJohn Marino    * @brief Extracts a %bernoulli_distribution random number distribution
3373e4b17023SJohn Marino    * @p __x from the input stream @p __is.
3374e4b17023SJohn Marino    *
3375e4b17023SJohn Marino    * @param __is An input stream.
3376e4b17023SJohn Marino    * @param __x  A %bernoulli_distribution random number generator engine.
3377e4b17023SJohn Marino    *
3378e4b17023SJohn Marino    * @returns The input stream with @p __x extracted or in an error state.
3379e4b17023SJohn Marino    */
3380e4b17023SJohn Marino   template<typename _CharT, typename _Traits>
3381e4b17023SJohn Marino     std::basic_istream<_CharT, _Traits>&
3382e4b17023SJohn Marino     operator>>(std::basic_istream<_CharT, _Traits>& __is,
3383e4b17023SJohn Marino 	       std::bernoulli_distribution& __x)
3384e4b17023SJohn Marino     {
3385e4b17023SJohn Marino       double __p;
3386e4b17023SJohn Marino       __is >> __p;
3387e4b17023SJohn Marino       __x.param(bernoulli_distribution::param_type(__p));
3388e4b17023SJohn Marino       return __is;
3389e4b17023SJohn Marino     }
3390e4b17023SJohn Marino 
3391e4b17023SJohn Marino 
3392e4b17023SJohn Marino   /**
3393e4b17023SJohn Marino    * @brief A discrete binomial random number distribution.
3394e4b17023SJohn Marino    *
3395e4b17023SJohn Marino    * The formula for the binomial probability density function is
3396e4b17023SJohn Marino    * @f$p(i|t,p) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
3397e4b17023SJohn Marino    * and @f$p@f$ are the parameters of the distribution.
3398e4b17023SJohn Marino    */
3399e4b17023SJohn Marino   template<typename _IntType = int>
3400e4b17023SJohn Marino     class binomial_distribution
3401e4b17023SJohn Marino     {
3402e4b17023SJohn Marino       static_assert(std::is_integral<_IntType>::value,
3403e4b17023SJohn Marino 		    "template argument not an integral type");
3404e4b17023SJohn Marino 
3405e4b17023SJohn Marino     public:
3406e4b17023SJohn Marino       /** The type of the range of the distribution. */
3407e4b17023SJohn Marino       typedef _IntType result_type;
3408e4b17023SJohn Marino       /** Parameter type. */
3409e4b17023SJohn Marino       struct param_type
3410e4b17023SJohn Marino       {
3411e4b17023SJohn Marino 	typedef binomial_distribution<_IntType> distribution_type;
3412e4b17023SJohn Marino 	friend class binomial_distribution<_IntType>;
3413e4b17023SJohn Marino 
3414e4b17023SJohn Marino 	explicit
3415e4b17023SJohn Marino 	param_type(_IntType __t = _IntType(1), double __p = 0.5)
3416e4b17023SJohn Marino 	: _M_t(__t), _M_p(__p)
3417e4b17023SJohn Marino 	{
3418e4b17023SJohn Marino 	  _GLIBCXX_DEBUG_ASSERT((_M_t >= _IntType(0))
3419e4b17023SJohn Marino 				&& (_M_p >= 0.0)
3420e4b17023SJohn Marino 				&& (_M_p <= 1.0));
3421e4b17023SJohn Marino 	  _M_initialize();
3422e4b17023SJohn Marino 	}
3423e4b17023SJohn Marino 
3424e4b17023SJohn Marino 	_IntType
3425e4b17023SJohn Marino 	t() const
3426e4b17023SJohn Marino 	{ return _M_t; }
3427e4b17023SJohn Marino 
3428e4b17023SJohn Marino 	double
3429e4b17023SJohn Marino 	p() const
3430e4b17023SJohn Marino 	{ return _M_p; }
3431e4b17023SJohn Marino 
3432e4b17023SJohn Marino 	friend bool
3433e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
3434e4b17023SJohn Marino 	{ return __p1._M_t == __p2._M_t && __p1._M_p == __p2._M_p; }
3435e4b17023SJohn Marino 
3436e4b17023SJohn Marino       private:
3437e4b17023SJohn Marino 	void
3438e4b17023SJohn Marino 	_M_initialize();
3439e4b17023SJohn Marino 
3440e4b17023SJohn Marino 	_IntType _M_t;
3441e4b17023SJohn Marino 	double _M_p;
3442e4b17023SJohn Marino 
3443e4b17023SJohn Marino 	double _M_q;
3444e4b17023SJohn Marino #if _GLIBCXX_USE_C99_MATH_TR1
3445e4b17023SJohn Marino 	double _M_d1, _M_d2, _M_s1, _M_s2, _M_c,
3446e4b17023SJohn Marino 	       _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p;
3447e4b17023SJohn Marino #endif
3448e4b17023SJohn Marino 	bool   _M_easy;
3449e4b17023SJohn Marino       };
3450e4b17023SJohn Marino 
3451e4b17023SJohn Marino       // constructors and member function
3452e4b17023SJohn Marino       explicit
3453e4b17023SJohn Marino       binomial_distribution(_IntType __t = _IntType(1),
3454e4b17023SJohn Marino 			    double __p = 0.5)
3455e4b17023SJohn Marino       : _M_param(__t, __p), _M_nd()
3456e4b17023SJohn Marino       { }
3457e4b17023SJohn Marino 
3458e4b17023SJohn Marino       explicit
3459e4b17023SJohn Marino       binomial_distribution(const param_type& __p)
3460e4b17023SJohn Marino       : _M_param(__p), _M_nd()
3461e4b17023SJohn Marino       { }
3462e4b17023SJohn Marino 
3463e4b17023SJohn Marino       /**
3464e4b17023SJohn Marino        * @brief Resets the distribution state.
3465e4b17023SJohn Marino        */
3466e4b17023SJohn Marino       void
3467e4b17023SJohn Marino       reset()
3468e4b17023SJohn Marino       { _M_nd.reset(); }
3469e4b17023SJohn Marino 
3470e4b17023SJohn Marino       /**
3471e4b17023SJohn Marino        * @brief Returns the distribution @p t parameter.
3472e4b17023SJohn Marino        */
3473e4b17023SJohn Marino       _IntType
3474e4b17023SJohn Marino       t() const
3475e4b17023SJohn Marino       { return _M_param.t(); }
3476e4b17023SJohn Marino 
3477e4b17023SJohn Marino       /**
3478e4b17023SJohn Marino        * @brief Returns the distribution @p p parameter.
3479e4b17023SJohn Marino        */
3480e4b17023SJohn Marino       double
3481e4b17023SJohn Marino       p() const
3482e4b17023SJohn Marino       { return _M_param.p(); }
3483e4b17023SJohn Marino 
3484e4b17023SJohn Marino       /**
3485e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
3486e4b17023SJohn Marino        */
3487e4b17023SJohn Marino       param_type
3488e4b17023SJohn Marino       param() const
3489e4b17023SJohn Marino       { return _M_param; }
3490e4b17023SJohn Marino 
3491e4b17023SJohn Marino       /**
3492e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
3493e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
3494e4b17023SJohn Marino        */
3495e4b17023SJohn Marino       void
3496e4b17023SJohn Marino       param(const param_type& __param)
3497e4b17023SJohn Marino       { _M_param = __param; }
3498e4b17023SJohn Marino 
3499e4b17023SJohn Marino       /**
3500e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
3501e4b17023SJohn Marino        */
3502e4b17023SJohn Marino       result_type
3503e4b17023SJohn Marino       min() const
3504e4b17023SJohn Marino       { return 0; }
3505e4b17023SJohn Marino 
3506e4b17023SJohn Marino       /**
3507e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
3508e4b17023SJohn Marino        */
3509e4b17023SJohn Marino       result_type
3510e4b17023SJohn Marino       max() const
3511e4b17023SJohn Marino       { return _M_param.t(); }
3512e4b17023SJohn Marino 
3513e4b17023SJohn Marino       /**
3514e4b17023SJohn Marino        * @brief Generating functions.
3515e4b17023SJohn Marino        */
3516e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
3517e4b17023SJohn Marino 	result_type
3518e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
3519*5ce9237cSJohn Marino 	{ return this->operator()(__urng, _M_param); }
3520e4b17023SJohn Marino 
3521e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
3522e4b17023SJohn Marino 	result_type
3523e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
3524e4b17023SJohn Marino 		   const param_type& __p);
3525e4b17023SJohn Marino 
3526e4b17023SJohn Marino       /**
3527e4b17023SJohn Marino        * @brief Return true if two binomial distributions have
3528e4b17023SJohn Marino        *        the same parameters and the sequences that would
3529e4b17023SJohn Marino        *        be generated are equal.
3530e4b17023SJohn Marino        */
3531e4b17023SJohn Marino 	friend bool
3532e4b17023SJohn Marino         operator==(const binomial_distribution& __d1,
3533e4b17023SJohn Marino 		   const binomial_distribution& __d2)
3534e4b17023SJohn Marino #ifdef _GLIBCXX_USE_C99_MATH_TR1
3535*5ce9237cSJohn Marino 	{ return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; }
3536e4b17023SJohn Marino #else
3537*5ce9237cSJohn Marino         { return __d1._M_param == __d2._M_param; }
3538e4b17023SJohn Marino #endif
3539e4b17023SJohn Marino 
3540e4b17023SJohn Marino       /**
3541e4b17023SJohn Marino        * @brief Inserts a %binomial_distribution random number distribution
3542e4b17023SJohn Marino        * @p __x into the output stream @p __os.
3543e4b17023SJohn Marino        *
3544e4b17023SJohn Marino        * @param __os An output stream.
3545e4b17023SJohn Marino        * @param __x  A %binomial_distribution random number distribution.
3546e4b17023SJohn Marino        *
3547e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
3548e4b17023SJohn Marino        * an error state.
3549e4b17023SJohn Marino        */
3550e4b17023SJohn Marino       template<typename _IntType1,
3551e4b17023SJohn Marino 	       typename _CharT, typename _Traits>
3552e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
3553e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3554e4b17023SJohn Marino 		   const std::binomial_distribution<_IntType1>& __x);
3555e4b17023SJohn Marino 
3556e4b17023SJohn Marino       /**
3557e4b17023SJohn Marino        * @brief Extracts a %binomial_distribution random number distribution
3558e4b17023SJohn Marino        * @p __x from the input stream @p __is.
3559e4b17023SJohn Marino        *
3560e4b17023SJohn Marino        * @param __is An input stream.
3561e4b17023SJohn Marino        * @param __x  A %binomial_distribution random number generator engine.
3562e4b17023SJohn Marino        *
3563e4b17023SJohn Marino        * @returns The input stream with @p __x extracted or in an error
3564e4b17023SJohn Marino        *          state.
3565e4b17023SJohn Marino        */
3566e4b17023SJohn Marino       template<typename _IntType1,
3567e4b17023SJohn Marino 	       typename _CharT, typename _Traits>
3568e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
3569e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
3570e4b17023SJohn Marino 		   std::binomial_distribution<_IntType1>& __x);
3571e4b17023SJohn Marino 
3572e4b17023SJohn Marino     private:
3573e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
3574e4b17023SJohn Marino 	result_type
3575e4b17023SJohn Marino 	_M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t);
3576e4b17023SJohn Marino 
3577e4b17023SJohn Marino       param_type _M_param;
3578e4b17023SJohn Marino 
3579e4b17023SJohn Marino       // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
3580e4b17023SJohn Marino       std::normal_distribution<double> _M_nd;
3581e4b17023SJohn Marino     };
3582e4b17023SJohn Marino 
3583e4b17023SJohn Marino   /**
3584e4b17023SJohn Marino    * @brief Return true if two binomial distributions are different.
3585e4b17023SJohn Marino    */
3586e4b17023SJohn Marino   template<typename _IntType>
3587e4b17023SJohn Marino     inline bool
3588e4b17023SJohn Marino     operator!=(const std::binomial_distribution<_IntType>& __d1,
3589e4b17023SJohn Marino 	       const std::binomial_distribution<_IntType>& __d2)
3590e4b17023SJohn Marino     { return !(__d1 == __d2); }
3591e4b17023SJohn Marino 
3592e4b17023SJohn Marino 
3593e4b17023SJohn Marino   /**
3594e4b17023SJohn Marino    * @brief A discrete geometric random number distribution.
3595e4b17023SJohn Marino    *
3596e4b17023SJohn Marino    * The formula for the geometric probability density function is
3597e4b17023SJohn Marino    * @f$p(i|p) = p(1 - p)^{i}@f$ where @f$p@f$ is the parameter of the
3598e4b17023SJohn Marino    * distribution.
3599e4b17023SJohn Marino    */
3600e4b17023SJohn Marino   template<typename _IntType = int>
3601e4b17023SJohn Marino     class geometric_distribution
3602e4b17023SJohn Marino     {
3603e4b17023SJohn Marino       static_assert(std::is_integral<_IntType>::value,
3604e4b17023SJohn Marino 		    "template argument not an integral type");
3605e4b17023SJohn Marino 
3606e4b17023SJohn Marino     public:
3607e4b17023SJohn Marino       /** The type of the range of the distribution. */
3608e4b17023SJohn Marino       typedef _IntType  result_type;
3609e4b17023SJohn Marino       /** Parameter type. */
3610e4b17023SJohn Marino       struct param_type
3611e4b17023SJohn Marino       {
3612e4b17023SJohn Marino 	typedef geometric_distribution<_IntType> distribution_type;
3613e4b17023SJohn Marino 	friend class geometric_distribution<_IntType>;
3614e4b17023SJohn Marino 
3615e4b17023SJohn Marino 	explicit
3616e4b17023SJohn Marino 	param_type(double __p = 0.5)
3617e4b17023SJohn Marino 	: _M_p(__p)
3618e4b17023SJohn Marino 	{
3619e4b17023SJohn Marino 	  _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0));
3620e4b17023SJohn Marino 	  _M_initialize();
3621e4b17023SJohn Marino 	}
3622e4b17023SJohn Marino 
3623e4b17023SJohn Marino 	double
3624e4b17023SJohn Marino 	p() const
3625e4b17023SJohn Marino 	{ return _M_p; }
3626e4b17023SJohn Marino 
3627e4b17023SJohn Marino 	friend bool
3628e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
3629e4b17023SJohn Marino 	{ return __p1._M_p == __p2._M_p; }
3630e4b17023SJohn Marino 
3631e4b17023SJohn Marino       private:
3632e4b17023SJohn Marino 	void
3633e4b17023SJohn Marino 	_M_initialize()
3634e4b17023SJohn Marino 	{ _M_log_1_p = std::log(1.0 - _M_p); }
3635e4b17023SJohn Marino 
3636e4b17023SJohn Marino 	double _M_p;
3637e4b17023SJohn Marino 
3638e4b17023SJohn Marino 	double _M_log_1_p;
3639e4b17023SJohn Marino       };
3640e4b17023SJohn Marino 
3641e4b17023SJohn Marino       // constructors and member function
3642e4b17023SJohn Marino       explicit
3643e4b17023SJohn Marino       geometric_distribution(double __p = 0.5)
3644e4b17023SJohn Marino       : _M_param(__p)
3645e4b17023SJohn Marino       { }
3646e4b17023SJohn Marino 
3647e4b17023SJohn Marino       explicit
3648e4b17023SJohn Marino       geometric_distribution(const param_type& __p)
3649e4b17023SJohn Marino       : _M_param(__p)
3650e4b17023SJohn Marino       { }
3651e4b17023SJohn Marino 
3652e4b17023SJohn Marino       /**
3653e4b17023SJohn Marino        * @brief Resets the distribution state.
3654e4b17023SJohn Marino        *
3655e4b17023SJohn Marino        * Does nothing for the geometric distribution.
3656e4b17023SJohn Marino        */
3657e4b17023SJohn Marino       void
3658e4b17023SJohn Marino       reset() { }
3659e4b17023SJohn Marino 
3660e4b17023SJohn Marino       /**
3661e4b17023SJohn Marino        * @brief Returns the distribution parameter @p p.
3662e4b17023SJohn Marino        */
3663e4b17023SJohn Marino       double
3664e4b17023SJohn Marino       p() const
3665e4b17023SJohn Marino       { return _M_param.p(); }
3666e4b17023SJohn Marino 
3667e4b17023SJohn Marino       /**
3668e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
3669e4b17023SJohn Marino        */
3670e4b17023SJohn Marino       param_type
3671e4b17023SJohn Marino       param() const
3672e4b17023SJohn Marino       { return _M_param; }
3673e4b17023SJohn Marino 
3674e4b17023SJohn Marino       /**
3675e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
3676e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
3677e4b17023SJohn Marino        */
3678e4b17023SJohn Marino       void
3679e4b17023SJohn Marino       param(const param_type& __param)
3680e4b17023SJohn Marino       { _M_param = __param; }
3681e4b17023SJohn Marino 
3682e4b17023SJohn Marino       /**
3683e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
3684e4b17023SJohn Marino        */
3685e4b17023SJohn Marino       result_type
3686e4b17023SJohn Marino       min() const
3687e4b17023SJohn Marino       { return 0; }
3688e4b17023SJohn Marino 
3689e4b17023SJohn Marino       /**
3690e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
3691e4b17023SJohn Marino        */
3692e4b17023SJohn Marino       result_type
3693e4b17023SJohn Marino       max() const
3694e4b17023SJohn Marino       { return std::numeric_limits<result_type>::max(); }
3695e4b17023SJohn Marino 
3696e4b17023SJohn Marino       /**
3697e4b17023SJohn Marino        * @brief Generating functions.
3698e4b17023SJohn Marino        */
3699e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
3700e4b17023SJohn Marino 	result_type
3701e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
3702*5ce9237cSJohn Marino 	{ return this->operator()(__urng, _M_param); }
3703e4b17023SJohn Marino 
3704e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
3705e4b17023SJohn Marino 	result_type
3706e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
3707e4b17023SJohn Marino 		   const param_type& __p);
3708e4b17023SJohn Marino 
3709e4b17023SJohn Marino       /**
3710e4b17023SJohn Marino        * @brief Return true if two geometric distributions have
3711e4b17023SJohn Marino        *        the same parameters.
3712e4b17023SJohn Marino        */
3713*5ce9237cSJohn Marino       friend bool
3714*5ce9237cSJohn Marino       operator==(const geometric_distribution& __d1,
3715*5ce9237cSJohn Marino 		 const geometric_distribution& __d2)
3716*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param; }
3717*5ce9237cSJohn Marino 
3718*5ce9237cSJohn Marino     private:
3719*5ce9237cSJohn Marino       param_type _M_param;
3720*5ce9237cSJohn Marino     };
3721e4b17023SJohn Marino 
3722e4b17023SJohn Marino   /**
3723e4b17023SJohn Marino    * @brief Return true if two geometric distributions have
3724e4b17023SJohn Marino    *        different parameters.
3725e4b17023SJohn Marino    */
3726e4b17023SJohn Marino   template<typename _IntType>
3727e4b17023SJohn Marino     inline bool
3728e4b17023SJohn Marino     operator!=(const std::geometric_distribution<_IntType>& __d1,
3729e4b17023SJohn Marino 	       const std::geometric_distribution<_IntType>& __d2)
3730e4b17023SJohn Marino     { return !(__d1 == __d2); }
3731e4b17023SJohn Marino 
3732e4b17023SJohn Marino   /**
3733e4b17023SJohn Marino    * @brief Inserts a %geometric_distribution random number distribution
3734e4b17023SJohn Marino    * @p __x into the output stream @p __os.
3735e4b17023SJohn Marino    *
3736e4b17023SJohn Marino    * @param __os An output stream.
3737e4b17023SJohn Marino    * @param __x  A %geometric_distribution random number distribution.
3738e4b17023SJohn Marino    *
3739e4b17023SJohn Marino    * @returns The output stream with the state of @p __x inserted or in
3740e4b17023SJohn Marino    * an error state.
3741e4b17023SJohn Marino    */
3742e4b17023SJohn Marino   template<typename _IntType,
3743e4b17023SJohn Marino 	   typename _CharT, typename _Traits>
3744e4b17023SJohn Marino     std::basic_ostream<_CharT, _Traits>&
3745e4b17023SJohn Marino     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3746e4b17023SJohn Marino 	       const std::geometric_distribution<_IntType>& __x);
3747e4b17023SJohn Marino 
3748e4b17023SJohn Marino   /**
3749e4b17023SJohn Marino    * @brief Extracts a %geometric_distribution random number distribution
3750e4b17023SJohn Marino    * @p __x from the input stream @p __is.
3751e4b17023SJohn Marino    *
3752e4b17023SJohn Marino    * @param __is An input stream.
3753e4b17023SJohn Marino    * @param __x  A %geometric_distribution random number generator engine.
3754e4b17023SJohn Marino    *
3755e4b17023SJohn Marino    * @returns The input stream with @p __x extracted or in an error state.
3756e4b17023SJohn Marino    */
3757e4b17023SJohn Marino   template<typename _IntType,
3758e4b17023SJohn Marino 	   typename _CharT, typename _Traits>
3759e4b17023SJohn Marino     std::basic_istream<_CharT, _Traits>&
3760e4b17023SJohn Marino     operator>>(std::basic_istream<_CharT, _Traits>& __is,
3761e4b17023SJohn Marino 	       std::geometric_distribution<_IntType>& __x);
3762e4b17023SJohn Marino 
3763e4b17023SJohn Marino 
3764e4b17023SJohn Marino   /**
3765e4b17023SJohn Marino    * @brief A negative_binomial_distribution random number distribution.
3766e4b17023SJohn Marino    *
3767e4b17023SJohn Marino    * The formula for the negative binomial probability mass function is
3768e4b17023SJohn Marino    * @f$p(i) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$
3769e4b17023SJohn Marino    * and @f$p@f$ are the parameters of the distribution.
3770e4b17023SJohn Marino    */
3771e4b17023SJohn Marino   template<typename _IntType = int>
3772e4b17023SJohn Marino     class negative_binomial_distribution
3773e4b17023SJohn Marino     {
3774e4b17023SJohn Marino       static_assert(std::is_integral<_IntType>::value,
3775e4b17023SJohn Marino 		    "template argument not an integral type");
3776e4b17023SJohn Marino 
3777e4b17023SJohn Marino     public:
3778e4b17023SJohn Marino       /** The type of the range of the distribution. */
3779e4b17023SJohn Marino       typedef _IntType result_type;
3780e4b17023SJohn Marino       /** Parameter type. */
3781e4b17023SJohn Marino       struct param_type
3782e4b17023SJohn Marino       {
3783e4b17023SJohn Marino 	typedef negative_binomial_distribution<_IntType> distribution_type;
3784e4b17023SJohn Marino 
3785e4b17023SJohn Marino 	explicit
3786e4b17023SJohn Marino 	param_type(_IntType __k = 1, double __p = 0.5)
3787e4b17023SJohn Marino 	: _M_k(__k), _M_p(__p)
3788e4b17023SJohn Marino 	{
3789e4b17023SJohn Marino 	  _GLIBCXX_DEBUG_ASSERT((_M_k > 0) && (_M_p > 0.0) && (_M_p <= 1.0));
3790e4b17023SJohn Marino 	}
3791e4b17023SJohn Marino 
3792e4b17023SJohn Marino 	_IntType
3793e4b17023SJohn Marino 	k() const
3794e4b17023SJohn Marino 	{ return _M_k; }
3795e4b17023SJohn Marino 
3796e4b17023SJohn Marino 	double
3797e4b17023SJohn Marino 	p() const
3798e4b17023SJohn Marino 	{ return _M_p; }
3799e4b17023SJohn Marino 
3800e4b17023SJohn Marino 	friend bool
3801e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
3802e4b17023SJohn Marino 	{ return __p1._M_k == __p2._M_k && __p1._M_p == __p2._M_p; }
3803e4b17023SJohn Marino 
3804e4b17023SJohn Marino       private:
3805e4b17023SJohn Marino 	_IntType _M_k;
3806e4b17023SJohn Marino 	double _M_p;
3807e4b17023SJohn Marino       };
3808e4b17023SJohn Marino 
3809e4b17023SJohn Marino       explicit
3810e4b17023SJohn Marino       negative_binomial_distribution(_IntType __k = 1, double __p = 0.5)
3811e4b17023SJohn Marino       : _M_param(__k, __p), _M_gd(__k, (1.0 - __p) / __p)
3812e4b17023SJohn Marino       { }
3813e4b17023SJohn Marino 
3814e4b17023SJohn Marino       explicit
3815e4b17023SJohn Marino       negative_binomial_distribution(const param_type& __p)
3816e4b17023SJohn Marino       : _M_param(__p), _M_gd(__p.k(), (1.0 - __p.p()) / __p.p())
3817e4b17023SJohn Marino       { }
3818e4b17023SJohn Marino 
3819e4b17023SJohn Marino       /**
3820e4b17023SJohn Marino        * @brief Resets the distribution state.
3821e4b17023SJohn Marino        */
3822e4b17023SJohn Marino       void
3823e4b17023SJohn Marino       reset()
3824e4b17023SJohn Marino       { _M_gd.reset(); }
3825e4b17023SJohn Marino 
3826e4b17023SJohn Marino       /**
3827e4b17023SJohn Marino        * @brief Return the @f$k@f$ parameter of the distribution.
3828e4b17023SJohn Marino        */
3829e4b17023SJohn Marino       _IntType
3830e4b17023SJohn Marino       k() const
3831e4b17023SJohn Marino       { return _M_param.k(); }
3832e4b17023SJohn Marino 
3833e4b17023SJohn Marino       /**
3834e4b17023SJohn Marino        * @brief Return the @f$p@f$ parameter of the distribution.
3835e4b17023SJohn Marino        */
3836e4b17023SJohn Marino       double
3837e4b17023SJohn Marino       p() const
3838e4b17023SJohn Marino       { return _M_param.p(); }
3839e4b17023SJohn Marino 
3840e4b17023SJohn Marino       /**
3841e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
3842e4b17023SJohn Marino        */
3843e4b17023SJohn Marino       param_type
3844e4b17023SJohn Marino       param() const
3845e4b17023SJohn Marino       { return _M_param; }
3846e4b17023SJohn Marino 
3847e4b17023SJohn Marino       /**
3848e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
3849e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
3850e4b17023SJohn Marino        */
3851e4b17023SJohn Marino       void
3852e4b17023SJohn Marino       param(const param_type& __param)
3853e4b17023SJohn Marino       { _M_param = __param; }
3854e4b17023SJohn Marino 
3855e4b17023SJohn Marino       /**
3856e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
3857e4b17023SJohn Marino        */
3858e4b17023SJohn Marino       result_type
3859e4b17023SJohn Marino       min() const
3860e4b17023SJohn Marino       { return result_type(0); }
3861e4b17023SJohn Marino 
3862e4b17023SJohn Marino       /**
3863e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
3864e4b17023SJohn Marino        */
3865e4b17023SJohn Marino       result_type
3866e4b17023SJohn Marino       max() const
3867e4b17023SJohn Marino       { return std::numeric_limits<result_type>::max(); }
3868e4b17023SJohn Marino 
3869e4b17023SJohn Marino       /**
3870e4b17023SJohn Marino        * @brief Generating functions.
3871e4b17023SJohn Marino        */
3872e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
3873e4b17023SJohn Marino 	result_type
3874e4b17023SJohn Marino         operator()(_UniformRandomNumberGenerator& __urng);
3875e4b17023SJohn Marino 
3876e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
3877e4b17023SJohn Marino 	result_type
3878e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
3879e4b17023SJohn Marino 		   const param_type& __p);
3880e4b17023SJohn Marino 
3881e4b17023SJohn Marino       /**
3882e4b17023SJohn Marino        * @brief Return true if two negative binomial distributions have
3883e4b17023SJohn Marino        *        the same parameters and the sequences that would be
3884e4b17023SJohn Marino        *        generated are equal.
3885e4b17023SJohn Marino        */
3886e4b17023SJohn Marino       friend bool
3887e4b17023SJohn Marino       operator==(const negative_binomial_distribution& __d1,
3888e4b17023SJohn Marino 		 const negative_binomial_distribution& __d2)
3889*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; }
3890e4b17023SJohn Marino 
3891e4b17023SJohn Marino       /**
3892e4b17023SJohn Marino        * @brief Inserts a %negative_binomial_distribution random
3893e4b17023SJohn Marino        *        number distribution @p __x into the output stream @p __os.
3894e4b17023SJohn Marino        *
3895e4b17023SJohn Marino        * @param __os An output stream.
3896e4b17023SJohn Marino        * @param __x  A %negative_binomial_distribution random number
3897e4b17023SJohn Marino        *             distribution.
3898e4b17023SJohn Marino        *
3899e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
3900e4b17023SJohn Marino        *          an error state.
3901e4b17023SJohn Marino        */
3902e4b17023SJohn Marino       template<typename _IntType1, typename _CharT, typename _Traits>
3903e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
3904e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3905e4b17023SJohn Marino 		   const std::negative_binomial_distribution<_IntType1>& __x);
3906e4b17023SJohn Marino 
3907e4b17023SJohn Marino       /**
3908e4b17023SJohn Marino        * @brief Extracts a %negative_binomial_distribution random number
3909e4b17023SJohn Marino        *        distribution @p __x from the input stream @p __is.
3910e4b17023SJohn Marino        *
3911e4b17023SJohn Marino        * @param __is An input stream.
3912e4b17023SJohn Marino        * @param __x A %negative_binomial_distribution random number
3913e4b17023SJohn Marino        *            generator engine.
3914e4b17023SJohn Marino        *
3915e4b17023SJohn Marino        * @returns The input stream with @p __x extracted or in an error state.
3916e4b17023SJohn Marino        */
3917e4b17023SJohn Marino       template<typename _IntType1, typename _CharT, typename _Traits>
3918e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
3919e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
3920e4b17023SJohn Marino 		   std::negative_binomial_distribution<_IntType1>& __x);
3921e4b17023SJohn Marino 
3922e4b17023SJohn Marino     private:
3923e4b17023SJohn Marino       param_type _M_param;
3924e4b17023SJohn Marino 
3925e4b17023SJohn Marino       std::gamma_distribution<double> _M_gd;
3926e4b17023SJohn Marino     };
3927e4b17023SJohn Marino 
3928e4b17023SJohn Marino   /**
3929e4b17023SJohn Marino    * @brief Return true if two negative binomial distributions are different.
3930e4b17023SJohn Marino    */
3931e4b17023SJohn Marino   template<typename _IntType>
3932e4b17023SJohn Marino     inline bool
3933e4b17023SJohn Marino     operator!=(const std::negative_binomial_distribution<_IntType>& __d1,
3934e4b17023SJohn Marino 	       const std::negative_binomial_distribution<_IntType>& __d2)
3935e4b17023SJohn Marino     { return !(__d1 == __d2); }
3936e4b17023SJohn Marino 
3937e4b17023SJohn Marino 
3938e4b17023SJohn Marino   /* @} */ // group random_distributions_bernoulli
3939e4b17023SJohn Marino 
3940e4b17023SJohn Marino   /**
3941e4b17023SJohn Marino    * @addtogroup random_distributions_poisson Poisson Distributions
3942e4b17023SJohn Marino    * @ingroup random_distributions
3943e4b17023SJohn Marino    * @{
3944e4b17023SJohn Marino    */
3945e4b17023SJohn Marino 
3946e4b17023SJohn Marino   /**
3947e4b17023SJohn Marino    * @brief A discrete Poisson random number distribution.
3948e4b17023SJohn Marino    *
3949e4b17023SJohn Marino    * The formula for the Poisson probability density function is
3950e4b17023SJohn Marino    * @f$p(i|\mu) = \frac{\mu^i}{i!} e^{-\mu}@f$ where @f$\mu@f$ is the
3951e4b17023SJohn Marino    * parameter of the distribution.
3952e4b17023SJohn Marino    */
3953e4b17023SJohn Marino   template<typename _IntType = int>
3954e4b17023SJohn Marino     class poisson_distribution
3955e4b17023SJohn Marino     {
3956e4b17023SJohn Marino       static_assert(std::is_integral<_IntType>::value,
3957e4b17023SJohn Marino 		    "template argument not an integral type");
3958e4b17023SJohn Marino 
3959e4b17023SJohn Marino     public:
3960e4b17023SJohn Marino       /** The type of the range of the distribution. */
3961e4b17023SJohn Marino       typedef _IntType  result_type;
3962e4b17023SJohn Marino       /** Parameter type. */
3963e4b17023SJohn Marino       struct param_type
3964e4b17023SJohn Marino       {
3965e4b17023SJohn Marino 	typedef poisson_distribution<_IntType> distribution_type;
3966e4b17023SJohn Marino 	friend class poisson_distribution<_IntType>;
3967e4b17023SJohn Marino 
3968e4b17023SJohn Marino 	explicit
3969e4b17023SJohn Marino 	param_type(double __mean = 1.0)
3970e4b17023SJohn Marino 	: _M_mean(__mean)
3971e4b17023SJohn Marino 	{
3972e4b17023SJohn Marino 	  _GLIBCXX_DEBUG_ASSERT(_M_mean > 0.0);
3973e4b17023SJohn Marino 	  _M_initialize();
3974e4b17023SJohn Marino 	}
3975e4b17023SJohn Marino 
3976e4b17023SJohn Marino 	double
3977e4b17023SJohn Marino 	mean() const
3978e4b17023SJohn Marino 	{ return _M_mean; }
3979e4b17023SJohn Marino 
3980e4b17023SJohn Marino 	friend bool
3981e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
3982e4b17023SJohn Marino 	{ return __p1._M_mean == __p2._M_mean; }
3983e4b17023SJohn Marino 
3984e4b17023SJohn Marino       private:
3985e4b17023SJohn Marino 	// Hosts either log(mean) or the threshold of the simple method.
3986e4b17023SJohn Marino 	void
3987e4b17023SJohn Marino 	_M_initialize();
3988e4b17023SJohn Marino 
3989e4b17023SJohn Marino 	double _M_mean;
3990e4b17023SJohn Marino 
3991e4b17023SJohn Marino 	double _M_lm_thr;
3992e4b17023SJohn Marino #if _GLIBCXX_USE_C99_MATH_TR1
3993e4b17023SJohn Marino 	double _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb;
3994e4b17023SJohn Marino #endif
3995e4b17023SJohn Marino       };
3996e4b17023SJohn Marino 
3997e4b17023SJohn Marino       // constructors and member function
3998e4b17023SJohn Marino       explicit
3999e4b17023SJohn Marino       poisson_distribution(double __mean = 1.0)
4000e4b17023SJohn Marino       : _M_param(__mean), _M_nd()
4001e4b17023SJohn Marino       { }
4002e4b17023SJohn Marino 
4003e4b17023SJohn Marino       explicit
4004e4b17023SJohn Marino       poisson_distribution(const param_type& __p)
4005e4b17023SJohn Marino       : _M_param(__p), _M_nd()
4006e4b17023SJohn Marino       { }
4007e4b17023SJohn Marino 
4008e4b17023SJohn Marino       /**
4009e4b17023SJohn Marino        * @brief Resets the distribution state.
4010e4b17023SJohn Marino        */
4011e4b17023SJohn Marino       void
4012e4b17023SJohn Marino       reset()
4013e4b17023SJohn Marino       { _M_nd.reset(); }
4014e4b17023SJohn Marino 
4015e4b17023SJohn Marino       /**
4016e4b17023SJohn Marino        * @brief Returns the distribution parameter @p mean.
4017e4b17023SJohn Marino        */
4018e4b17023SJohn Marino       double
4019e4b17023SJohn Marino       mean() const
4020e4b17023SJohn Marino       { return _M_param.mean(); }
4021e4b17023SJohn Marino 
4022e4b17023SJohn Marino       /**
4023e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
4024e4b17023SJohn Marino        */
4025e4b17023SJohn Marino       param_type
4026e4b17023SJohn Marino       param() const
4027e4b17023SJohn Marino       { return _M_param; }
4028e4b17023SJohn Marino 
4029e4b17023SJohn Marino       /**
4030e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
4031e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
4032e4b17023SJohn Marino        */
4033e4b17023SJohn Marino       void
4034e4b17023SJohn Marino       param(const param_type& __param)
4035e4b17023SJohn Marino       { _M_param = __param; }
4036e4b17023SJohn Marino 
4037e4b17023SJohn Marino       /**
4038e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
4039e4b17023SJohn Marino        */
4040e4b17023SJohn Marino       result_type
4041e4b17023SJohn Marino       min() const
4042e4b17023SJohn Marino       { return 0; }
4043e4b17023SJohn Marino 
4044e4b17023SJohn Marino       /**
4045e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
4046e4b17023SJohn Marino        */
4047e4b17023SJohn Marino       result_type
4048e4b17023SJohn Marino       max() const
4049e4b17023SJohn Marino       { return std::numeric_limits<result_type>::max(); }
4050e4b17023SJohn Marino 
4051e4b17023SJohn Marino       /**
4052e4b17023SJohn Marino        * @brief Generating functions.
4053e4b17023SJohn Marino        */
4054e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
4055e4b17023SJohn Marino 	result_type
4056e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
4057*5ce9237cSJohn Marino 	{ return this->operator()(__urng, _M_param); }
4058e4b17023SJohn Marino 
4059e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
4060e4b17023SJohn Marino 	result_type
4061e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
4062e4b17023SJohn Marino 		   const param_type& __p);
4063e4b17023SJohn Marino 
4064e4b17023SJohn Marino        /**
4065e4b17023SJohn Marino 	* @brief Return true if two Poisson distributions have the same
4066e4b17023SJohn Marino 	*        parameters and the sequences that would be generated
4067e4b17023SJohn Marino 	*        are equal.
4068e4b17023SJohn Marino 	*/
4069e4b17023SJohn Marino       friend bool
4070e4b17023SJohn Marino       operator==(const poisson_distribution& __d1,
4071e4b17023SJohn Marino 		 const poisson_distribution& __d2)
4072e4b17023SJohn Marino #ifdef _GLIBCXX_USE_C99_MATH_TR1
4073*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; }
4074e4b17023SJohn Marino #else
4075*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param; }
4076e4b17023SJohn Marino #endif
4077e4b17023SJohn Marino 
4078e4b17023SJohn Marino       /**
4079e4b17023SJohn Marino        * @brief Inserts a %poisson_distribution random number distribution
4080e4b17023SJohn Marino        * @p __x into the output stream @p __os.
4081e4b17023SJohn Marino        *
4082e4b17023SJohn Marino        * @param __os An output stream.
4083e4b17023SJohn Marino        * @param __x  A %poisson_distribution random number distribution.
4084e4b17023SJohn Marino        *
4085e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
4086e4b17023SJohn Marino        * an error state.
4087e4b17023SJohn Marino        */
4088e4b17023SJohn Marino       template<typename _IntType1, typename _CharT, typename _Traits>
4089e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
4090e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4091e4b17023SJohn Marino 		   const std::poisson_distribution<_IntType1>& __x);
4092e4b17023SJohn Marino 
4093e4b17023SJohn Marino       /**
4094e4b17023SJohn Marino        * @brief Extracts a %poisson_distribution random number distribution
4095e4b17023SJohn Marino        * @p __x from the input stream @p __is.
4096e4b17023SJohn Marino        *
4097e4b17023SJohn Marino        * @param __is An input stream.
4098e4b17023SJohn Marino        * @param __x  A %poisson_distribution random number generator engine.
4099e4b17023SJohn Marino        *
4100e4b17023SJohn Marino        * @returns The input stream with @p __x extracted or in an error
4101e4b17023SJohn Marino        *          state.
4102e4b17023SJohn Marino        */
4103e4b17023SJohn Marino       template<typename _IntType1, typename _CharT, typename _Traits>
4104e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
4105e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
4106e4b17023SJohn Marino 		   std::poisson_distribution<_IntType1>& __x);
4107e4b17023SJohn Marino 
4108e4b17023SJohn Marino     private:
4109e4b17023SJohn Marino       param_type _M_param;
4110e4b17023SJohn Marino 
4111e4b17023SJohn Marino       // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
4112e4b17023SJohn Marino       std::normal_distribution<double> _M_nd;
4113e4b17023SJohn Marino     };
4114e4b17023SJohn Marino 
4115e4b17023SJohn Marino   /**
4116e4b17023SJohn Marino    * @brief Return true if two Poisson distributions are different.
4117e4b17023SJohn Marino    */
4118e4b17023SJohn Marino   template<typename _IntType>
4119e4b17023SJohn Marino     inline bool
4120e4b17023SJohn Marino     operator!=(const std::poisson_distribution<_IntType>& __d1,
4121e4b17023SJohn Marino 	       const std::poisson_distribution<_IntType>& __d2)
4122e4b17023SJohn Marino     { return !(__d1 == __d2); }
4123e4b17023SJohn Marino 
4124e4b17023SJohn Marino 
4125e4b17023SJohn Marino   /**
4126e4b17023SJohn Marino    * @brief An exponential continuous distribution for random numbers.
4127e4b17023SJohn Marino    *
4128e4b17023SJohn Marino    * The formula for the exponential probability density function is
4129e4b17023SJohn Marino    * @f$p(x|\lambda) = \lambda e^{-\lambda x}@f$.
4130e4b17023SJohn Marino    *
4131e4b17023SJohn Marino    * <table border=1 cellpadding=10 cellspacing=0>
4132e4b17023SJohn Marino    * <caption align=top>Distribution Statistics</caption>
4133e4b17023SJohn Marino    * <tr><td>Mean</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
4134e4b17023SJohn Marino    * <tr><td>Median</td><td>@f$\frac{\ln 2}{\lambda}@f$</td></tr>
4135e4b17023SJohn Marino    * <tr><td>Mode</td><td>@f$zero@f$</td></tr>
4136e4b17023SJohn Marino    * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr>
4137e4b17023SJohn Marino    * <tr><td>Standard Deviation</td><td>@f$\frac{1}{\lambda}@f$</td></tr>
4138e4b17023SJohn Marino    * </table>
4139e4b17023SJohn Marino    */
4140e4b17023SJohn Marino   template<typename _RealType = double>
4141e4b17023SJohn Marino     class exponential_distribution
4142e4b17023SJohn Marino     {
4143e4b17023SJohn Marino       static_assert(std::is_floating_point<_RealType>::value,
4144e4b17023SJohn Marino 		    "template argument not a floating point type");
4145e4b17023SJohn Marino 
4146e4b17023SJohn Marino     public:
4147e4b17023SJohn Marino       /** The type of the range of the distribution. */
4148e4b17023SJohn Marino       typedef _RealType result_type;
4149e4b17023SJohn Marino       /** Parameter type. */
4150e4b17023SJohn Marino       struct param_type
4151e4b17023SJohn Marino       {
4152e4b17023SJohn Marino 	typedef exponential_distribution<_RealType> distribution_type;
4153e4b17023SJohn Marino 
4154e4b17023SJohn Marino 	explicit
4155e4b17023SJohn Marino 	param_type(_RealType __lambda = _RealType(1))
4156e4b17023SJohn Marino 	: _M_lambda(__lambda)
4157e4b17023SJohn Marino 	{
4158e4b17023SJohn Marino 	  _GLIBCXX_DEBUG_ASSERT(_M_lambda > _RealType(0));
4159e4b17023SJohn Marino 	}
4160e4b17023SJohn Marino 
4161e4b17023SJohn Marino 	_RealType
4162e4b17023SJohn Marino 	lambda() const
4163e4b17023SJohn Marino 	{ return _M_lambda; }
4164e4b17023SJohn Marino 
4165e4b17023SJohn Marino 	friend bool
4166e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
4167e4b17023SJohn Marino 	{ return __p1._M_lambda == __p2._M_lambda; }
4168e4b17023SJohn Marino 
4169e4b17023SJohn Marino       private:
4170e4b17023SJohn Marino 	_RealType _M_lambda;
4171e4b17023SJohn Marino       };
4172e4b17023SJohn Marino 
4173e4b17023SJohn Marino     public:
4174e4b17023SJohn Marino       /**
4175e4b17023SJohn Marino        * @brief Constructs an exponential distribution with inverse scale
4176e4b17023SJohn Marino        *        parameter @f$\lambda@f$.
4177e4b17023SJohn Marino        */
4178e4b17023SJohn Marino       explicit
4179e4b17023SJohn Marino       exponential_distribution(const result_type& __lambda = result_type(1))
4180e4b17023SJohn Marino       : _M_param(__lambda)
4181e4b17023SJohn Marino       { }
4182e4b17023SJohn Marino 
4183e4b17023SJohn Marino       explicit
4184e4b17023SJohn Marino       exponential_distribution(const param_type& __p)
4185e4b17023SJohn Marino       : _M_param(__p)
4186e4b17023SJohn Marino       { }
4187e4b17023SJohn Marino 
4188e4b17023SJohn Marino       /**
4189e4b17023SJohn Marino        * @brief Resets the distribution state.
4190e4b17023SJohn Marino        *
4191e4b17023SJohn Marino        * Has no effect on exponential distributions.
4192e4b17023SJohn Marino        */
4193e4b17023SJohn Marino       void
4194e4b17023SJohn Marino       reset() { }
4195e4b17023SJohn Marino 
4196e4b17023SJohn Marino       /**
4197e4b17023SJohn Marino        * @brief Returns the inverse scale parameter of the distribution.
4198e4b17023SJohn Marino        */
4199e4b17023SJohn Marino       _RealType
4200e4b17023SJohn Marino       lambda() const
4201e4b17023SJohn Marino       { return _M_param.lambda(); }
4202e4b17023SJohn Marino 
4203e4b17023SJohn Marino       /**
4204e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
4205e4b17023SJohn Marino        */
4206e4b17023SJohn Marino       param_type
4207e4b17023SJohn Marino       param() const
4208e4b17023SJohn Marino       { return _M_param; }
4209e4b17023SJohn Marino 
4210e4b17023SJohn Marino       /**
4211e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
4212e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
4213e4b17023SJohn Marino        */
4214e4b17023SJohn Marino       void
4215e4b17023SJohn Marino       param(const param_type& __param)
4216e4b17023SJohn Marino       { _M_param = __param; }
4217e4b17023SJohn Marino 
4218e4b17023SJohn Marino       /**
4219e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
4220e4b17023SJohn Marino        */
4221e4b17023SJohn Marino       result_type
4222e4b17023SJohn Marino       min() const
4223e4b17023SJohn Marino       { return result_type(0); }
4224e4b17023SJohn Marino 
4225e4b17023SJohn Marino       /**
4226e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
4227e4b17023SJohn Marino        */
4228e4b17023SJohn Marino       result_type
4229e4b17023SJohn Marino       max() const
4230e4b17023SJohn Marino       { return std::numeric_limits<result_type>::max(); }
4231e4b17023SJohn Marino 
4232e4b17023SJohn Marino       /**
4233e4b17023SJohn Marino        * @brief Generating functions.
4234e4b17023SJohn Marino        */
4235e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
4236e4b17023SJohn Marino 	result_type
4237e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
4238*5ce9237cSJohn Marino         { return this->operator()(__urng, _M_param); }
4239e4b17023SJohn Marino 
4240e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
4241e4b17023SJohn Marino 	result_type
4242e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
4243e4b17023SJohn Marino 		   const param_type& __p)
4244e4b17023SJohn Marino 	{
4245e4b17023SJohn Marino 	  __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
4246e4b17023SJohn Marino 	    __aurng(__urng);
4247*5ce9237cSJohn Marino 	  return -std::log(result_type(1) - __aurng()) / __p.lambda();
4248e4b17023SJohn Marino 	}
4249e4b17023SJohn Marino 
4250e4b17023SJohn Marino       /**
4251e4b17023SJohn Marino        * @brief Return true if two exponential distributions have the same
4252e4b17023SJohn Marino        *        parameters.
4253e4b17023SJohn Marino        */
4254*5ce9237cSJohn Marino       friend bool
4255*5ce9237cSJohn Marino       operator==(const exponential_distribution& __d1,
4256*5ce9237cSJohn Marino 		 const exponential_distribution& __d2)
4257*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param; }
4258*5ce9237cSJohn Marino 
4259*5ce9237cSJohn Marino     private:
4260*5ce9237cSJohn Marino       param_type _M_param;
4261*5ce9237cSJohn Marino     };
4262e4b17023SJohn Marino 
4263e4b17023SJohn Marino   /**
4264e4b17023SJohn Marino    * @brief Return true if two exponential distributions have different
4265e4b17023SJohn Marino    *        parameters.
4266e4b17023SJohn Marino    */
4267e4b17023SJohn Marino   template<typename _RealType>
4268e4b17023SJohn Marino     inline bool
4269e4b17023SJohn Marino     operator!=(const std::exponential_distribution<_RealType>& __d1,
4270e4b17023SJohn Marino 	       const std::exponential_distribution<_RealType>& __d2)
4271e4b17023SJohn Marino     { return !(__d1 == __d2); }
4272e4b17023SJohn Marino 
4273e4b17023SJohn Marino   /**
4274e4b17023SJohn Marino    * @brief Inserts a %exponential_distribution random number distribution
4275e4b17023SJohn Marino    * @p __x into the output stream @p __os.
4276e4b17023SJohn Marino    *
4277e4b17023SJohn Marino    * @param __os An output stream.
4278e4b17023SJohn Marino    * @param __x  A %exponential_distribution random number distribution.
4279e4b17023SJohn Marino    *
4280e4b17023SJohn Marino    * @returns The output stream with the state of @p __x inserted or in
4281e4b17023SJohn Marino    * an error state.
4282e4b17023SJohn Marino    */
4283e4b17023SJohn Marino   template<typename _RealType, typename _CharT, typename _Traits>
4284e4b17023SJohn Marino     std::basic_ostream<_CharT, _Traits>&
4285e4b17023SJohn Marino     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4286e4b17023SJohn Marino 	       const std::exponential_distribution<_RealType>& __x);
4287e4b17023SJohn Marino 
4288e4b17023SJohn Marino   /**
4289e4b17023SJohn Marino    * @brief Extracts a %exponential_distribution random number distribution
4290e4b17023SJohn Marino    * @p __x from the input stream @p __is.
4291e4b17023SJohn Marino    *
4292e4b17023SJohn Marino    * @param __is An input stream.
4293e4b17023SJohn Marino    * @param __x A %exponential_distribution random number
4294e4b17023SJohn Marino    *            generator engine.
4295e4b17023SJohn Marino    *
4296e4b17023SJohn Marino    * @returns The input stream with @p __x extracted or in an error state.
4297e4b17023SJohn Marino    */
4298e4b17023SJohn Marino   template<typename _RealType, typename _CharT, typename _Traits>
4299e4b17023SJohn Marino     std::basic_istream<_CharT, _Traits>&
4300e4b17023SJohn Marino     operator>>(std::basic_istream<_CharT, _Traits>& __is,
4301e4b17023SJohn Marino 	       std::exponential_distribution<_RealType>& __x);
4302e4b17023SJohn Marino 
4303e4b17023SJohn Marino 
4304e4b17023SJohn Marino   /**
4305e4b17023SJohn Marino    * @brief A weibull_distribution random number distribution.
4306e4b17023SJohn Marino    *
4307e4b17023SJohn Marino    * The formula for the normal probability density function is:
4308e4b17023SJohn Marino    * @f[
4309e4b17023SJohn Marino    *     p(x|\alpha,\beta) = \frac{\alpha}{\beta} (\frac{x}{\beta})^{\alpha-1}
4310e4b17023SJohn Marino    *                         \exp{(-(\frac{x}{\beta})^\alpha)}
4311e4b17023SJohn Marino    * @f]
4312e4b17023SJohn Marino    */
4313e4b17023SJohn Marino   template<typename _RealType = double>
4314e4b17023SJohn Marino     class weibull_distribution
4315e4b17023SJohn Marino     {
4316e4b17023SJohn Marino       static_assert(std::is_floating_point<_RealType>::value,
4317e4b17023SJohn Marino 		    "template argument not a floating point type");
4318e4b17023SJohn Marino 
4319e4b17023SJohn Marino     public:
4320e4b17023SJohn Marino       /** The type of the range of the distribution. */
4321e4b17023SJohn Marino       typedef _RealType result_type;
4322e4b17023SJohn Marino       /** Parameter type. */
4323e4b17023SJohn Marino       struct param_type
4324e4b17023SJohn Marino       {
4325e4b17023SJohn Marino 	typedef weibull_distribution<_RealType> distribution_type;
4326e4b17023SJohn Marino 
4327e4b17023SJohn Marino 	explicit
4328e4b17023SJohn Marino 	param_type(_RealType __a = _RealType(1),
4329e4b17023SJohn Marino 		   _RealType __b = _RealType(1))
4330e4b17023SJohn Marino 	: _M_a(__a), _M_b(__b)
4331e4b17023SJohn Marino 	{ }
4332e4b17023SJohn Marino 
4333e4b17023SJohn Marino 	_RealType
4334e4b17023SJohn Marino 	a() const
4335e4b17023SJohn Marino 	{ return _M_a; }
4336e4b17023SJohn Marino 
4337e4b17023SJohn Marino 	_RealType
4338e4b17023SJohn Marino 	b() const
4339e4b17023SJohn Marino 	{ return _M_b; }
4340e4b17023SJohn Marino 
4341e4b17023SJohn Marino 	friend bool
4342e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
4343e4b17023SJohn Marino 	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
4344e4b17023SJohn Marino 
4345e4b17023SJohn Marino       private:
4346e4b17023SJohn Marino 	_RealType _M_a;
4347e4b17023SJohn Marino 	_RealType _M_b;
4348e4b17023SJohn Marino       };
4349e4b17023SJohn Marino 
4350e4b17023SJohn Marino       explicit
4351e4b17023SJohn Marino       weibull_distribution(_RealType __a = _RealType(1),
4352e4b17023SJohn Marino 			   _RealType __b = _RealType(1))
4353e4b17023SJohn Marino       : _M_param(__a, __b)
4354e4b17023SJohn Marino       { }
4355e4b17023SJohn Marino 
4356e4b17023SJohn Marino       explicit
4357e4b17023SJohn Marino       weibull_distribution(const param_type& __p)
4358e4b17023SJohn Marino       : _M_param(__p)
4359e4b17023SJohn Marino       { }
4360e4b17023SJohn Marino 
4361e4b17023SJohn Marino       /**
4362e4b17023SJohn Marino        * @brief Resets the distribution state.
4363e4b17023SJohn Marino        */
4364e4b17023SJohn Marino       void
4365e4b17023SJohn Marino       reset()
4366e4b17023SJohn Marino       { }
4367e4b17023SJohn Marino 
4368e4b17023SJohn Marino       /**
4369e4b17023SJohn Marino        * @brief Return the @f$a@f$ parameter of the distribution.
4370e4b17023SJohn Marino        */
4371e4b17023SJohn Marino       _RealType
4372e4b17023SJohn Marino       a() const
4373e4b17023SJohn Marino       { return _M_param.a(); }
4374e4b17023SJohn Marino 
4375e4b17023SJohn Marino       /**
4376e4b17023SJohn Marino        * @brief Return the @f$b@f$ parameter of the distribution.
4377e4b17023SJohn Marino        */
4378e4b17023SJohn Marino       _RealType
4379e4b17023SJohn Marino       b() const
4380e4b17023SJohn Marino       { return _M_param.b(); }
4381e4b17023SJohn Marino 
4382e4b17023SJohn Marino       /**
4383e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
4384e4b17023SJohn Marino        */
4385e4b17023SJohn Marino       param_type
4386e4b17023SJohn Marino       param() const
4387e4b17023SJohn Marino       { return _M_param; }
4388e4b17023SJohn Marino 
4389e4b17023SJohn Marino       /**
4390e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
4391e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
4392e4b17023SJohn Marino        */
4393e4b17023SJohn Marino       void
4394e4b17023SJohn Marino       param(const param_type& __param)
4395e4b17023SJohn Marino       { _M_param = __param; }
4396e4b17023SJohn Marino 
4397e4b17023SJohn Marino       /**
4398e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
4399e4b17023SJohn Marino        */
4400e4b17023SJohn Marino       result_type
4401e4b17023SJohn Marino       min() const
4402e4b17023SJohn Marino       { return result_type(0); }
4403e4b17023SJohn Marino 
4404e4b17023SJohn Marino       /**
4405e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
4406e4b17023SJohn Marino        */
4407e4b17023SJohn Marino       result_type
4408e4b17023SJohn Marino       max() const
4409e4b17023SJohn Marino       { return std::numeric_limits<result_type>::max(); }
4410e4b17023SJohn Marino 
4411e4b17023SJohn Marino       /**
4412e4b17023SJohn Marino        * @brief Generating functions.
4413e4b17023SJohn Marino        */
4414e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
4415e4b17023SJohn Marino 	result_type
4416e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
4417*5ce9237cSJohn Marino 	{ return this->operator()(__urng, _M_param); }
4418e4b17023SJohn Marino 
4419e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
4420e4b17023SJohn Marino 	result_type
4421e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
4422e4b17023SJohn Marino 		   const param_type& __p);
4423e4b17023SJohn Marino 
4424e4b17023SJohn Marino       /**
4425e4b17023SJohn Marino        * @brief Return true if two Weibull distributions have the same
4426e4b17023SJohn Marino        *        parameters.
4427e4b17023SJohn Marino        */
4428*5ce9237cSJohn Marino       friend bool
4429*5ce9237cSJohn Marino       operator==(const weibull_distribution& __d1,
4430*5ce9237cSJohn Marino 		 const weibull_distribution& __d2)
4431*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param; }
4432*5ce9237cSJohn Marino 
4433*5ce9237cSJohn Marino     private:
4434*5ce9237cSJohn Marino       param_type _M_param;
4435*5ce9237cSJohn Marino     };
4436e4b17023SJohn Marino 
4437e4b17023SJohn Marino    /**
4438e4b17023SJohn Marino     * @brief Return true if two Weibull distributions have different
4439e4b17023SJohn Marino     *        parameters.
4440e4b17023SJohn Marino     */
4441e4b17023SJohn Marino   template<typename _RealType>
4442e4b17023SJohn Marino     inline bool
4443e4b17023SJohn Marino     operator!=(const std::weibull_distribution<_RealType>& __d1,
4444e4b17023SJohn Marino 	       const std::weibull_distribution<_RealType>& __d2)
4445e4b17023SJohn Marino     { return !(__d1 == __d2); }
4446e4b17023SJohn Marino 
4447e4b17023SJohn Marino   /**
4448e4b17023SJohn Marino    * @brief Inserts a %weibull_distribution random number distribution
4449e4b17023SJohn Marino    * @p __x into the output stream @p __os.
4450e4b17023SJohn Marino    *
4451e4b17023SJohn Marino    * @param __os An output stream.
4452e4b17023SJohn Marino    * @param __x  A %weibull_distribution random number distribution.
4453e4b17023SJohn Marino    *
4454e4b17023SJohn Marino    * @returns The output stream with the state of @p __x inserted or in
4455e4b17023SJohn Marino    * an error state.
4456e4b17023SJohn Marino    */
4457e4b17023SJohn Marino   template<typename _RealType, typename _CharT, typename _Traits>
4458e4b17023SJohn Marino     std::basic_ostream<_CharT, _Traits>&
4459e4b17023SJohn Marino     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4460e4b17023SJohn Marino 	       const std::weibull_distribution<_RealType>& __x);
4461e4b17023SJohn Marino 
4462e4b17023SJohn Marino   /**
4463e4b17023SJohn Marino    * @brief Extracts a %weibull_distribution random number distribution
4464e4b17023SJohn Marino    * @p __x from the input stream @p __is.
4465e4b17023SJohn Marino    *
4466e4b17023SJohn Marino    * @param __is An input stream.
4467e4b17023SJohn Marino    * @param __x A %weibull_distribution random number
4468e4b17023SJohn Marino    *            generator engine.
4469e4b17023SJohn Marino    *
4470e4b17023SJohn Marino    * @returns The input stream with @p __x extracted or in an error state.
4471e4b17023SJohn Marino    */
4472e4b17023SJohn Marino   template<typename _RealType, typename _CharT, typename _Traits>
4473e4b17023SJohn Marino     std::basic_istream<_CharT, _Traits>&
4474e4b17023SJohn Marino     operator>>(std::basic_istream<_CharT, _Traits>& __is,
4475e4b17023SJohn Marino 	       std::weibull_distribution<_RealType>& __x);
4476e4b17023SJohn Marino 
4477e4b17023SJohn Marino 
4478e4b17023SJohn Marino   /**
4479e4b17023SJohn Marino    * @brief A extreme_value_distribution random number distribution.
4480e4b17023SJohn Marino    *
4481e4b17023SJohn Marino    * The formula for the normal probability mass function is
4482e4b17023SJohn Marino    * @f[
4483e4b17023SJohn Marino    *     p(x|a,b) = \frac{1}{b}
4484e4b17023SJohn Marino    *                \exp( \frac{a-x}{b} - \exp(\frac{a-x}{b}))
4485e4b17023SJohn Marino    * @f]
4486e4b17023SJohn Marino    */
4487e4b17023SJohn Marino   template<typename _RealType = double>
4488e4b17023SJohn Marino     class extreme_value_distribution
4489e4b17023SJohn Marino     {
4490e4b17023SJohn Marino       static_assert(std::is_floating_point<_RealType>::value,
4491e4b17023SJohn Marino 		    "template argument not a floating point type");
4492e4b17023SJohn Marino 
4493e4b17023SJohn Marino     public:
4494e4b17023SJohn Marino       /** The type of the range of the distribution. */
4495e4b17023SJohn Marino       typedef _RealType result_type;
4496e4b17023SJohn Marino       /** Parameter type. */
4497e4b17023SJohn Marino       struct param_type
4498e4b17023SJohn Marino       {
4499e4b17023SJohn Marino 	typedef extreme_value_distribution<_RealType> distribution_type;
4500e4b17023SJohn Marino 
4501e4b17023SJohn Marino 	explicit
4502e4b17023SJohn Marino 	param_type(_RealType __a = _RealType(0),
4503e4b17023SJohn Marino 		   _RealType __b = _RealType(1))
4504e4b17023SJohn Marino 	: _M_a(__a), _M_b(__b)
4505e4b17023SJohn Marino 	{ }
4506e4b17023SJohn Marino 
4507e4b17023SJohn Marino 	_RealType
4508e4b17023SJohn Marino 	a() const
4509e4b17023SJohn Marino 	{ return _M_a; }
4510e4b17023SJohn Marino 
4511e4b17023SJohn Marino 	_RealType
4512e4b17023SJohn Marino 	b() const
4513e4b17023SJohn Marino 	{ return _M_b; }
4514e4b17023SJohn Marino 
4515e4b17023SJohn Marino 	friend bool
4516e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
4517e4b17023SJohn Marino 	{ return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; }
4518e4b17023SJohn Marino 
4519e4b17023SJohn Marino       private:
4520e4b17023SJohn Marino 	_RealType _M_a;
4521e4b17023SJohn Marino 	_RealType _M_b;
4522e4b17023SJohn Marino       };
4523e4b17023SJohn Marino 
4524e4b17023SJohn Marino       explicit
4525e4b17023SJohn Marino       extreme_value_distribution(_RealType __a = _RealType(0),
4526e4b17023SJohn Marino 				 _RealType __b = _RealType(1))
4527e4b17023SJohn Marino       : _M_param(__a, __b)
4528e4b17023SJohn Marino       { }
4529e4b17023SJohn Marino 
4530e4b17023SJohn Marino       explicit
4531e4b17023SJohn Marino       extreme_value_distribution(const param_type& __p)
4532e4b17023SJohn Marino       : _M_param(__p)
4533e4b17023SJohn Marino       { }
4534e4b17023SJohn Marino 
4535e4b17023SJohn Marino       /**
4536e4b17023SJohn Marino        * @brief Resets the distribution state.
4537e4b17023SJohn Marino        */
4538e4b17023SJohn Marino       void
4539e4b17023SJohn Marino       reset()
4540e4b17023SJohn Marino       { }
4541e4b17023SJohn Marino 
4542e4b17023SJohn Marino       /**
4543e4b17023SJohn Marino        * @brief Return the @f$a@f$ parameter of the distribution.
4544e4b17023SJohn Marino        */
4545e4b17023SJohn Marino       _RealType
4546e4b17023SJohn Marino       a() const
4547e4b17023SJohn Marino       { return _M_param.a(); }
4548e4b17023SJohn Marino 
4549e4b17023SJohn Marino       /**
4550e4b17023SJohn Marino        * @brief Return the @f$b@f$ parameter of the distribution.
4551e4b17023SJohn Marino        */
4552e4b17023SJohn Marino       _RealType
4553e4b17023SJohn Marino       b() const
4554e4b17023SJohn Marino       { return _M_param.b(); }
4555e4b17023SJohn Marino 
4556e4b17023SJohn Marino       /**
4557e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
4558e4b17023SJohn Marino        */
4559e4b17023SJohn Marino       param_type
4560e4b17023SJohn Marino       param() const
4561e4b17023SJohn Marino       { return _M_param; }
4562e4b17023SJohn Marino 
4563e4b17023SJohn Marino       /**
4564e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
4565e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
4566e4b17023SJohn Marino        */
4567e4b17023SJohn Marino       void
4568e4b17023SJohn Marino       param(const param_type& __param)
4569e4b17023SJohn Marino       { _M_param = __param; }
4570e4b17023SJohn Marino 
4571e4b17023SJohn Marino       /**
4572e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
4573e4b17023SJohn Marino        */
4574e4b17023SJohn Marino       result_type
4575e4b17023SJohn Marino       min() const
4576e4b17023SJohn Marino       { return std::numeric_limits<result_type>::min(); }
4577e4b17023SJohn Marino 
4578e4b17023SJohn Marino       /**
4579e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
4580e4b17023SJohn Marino        */
4581e4b17023SJohn Marino       result_type
4582e4b17023SJohn Marino       max() const
4583e4b17023SJohn Marino       { return std::numeric_limits<result_type>::max(); }
4584e4b17023SJohn Marino 
4585e4b17023SJohn Marino       /**
4586e4b17023SJohn Marino        * @brief Generating functions.
4587e4b17023SJohn Marino        */
4588e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
4589e4b17023SJohn Marino 	result_type
4590e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
4591*5ce9237cSJohn Marino 	{ return this->operator()(__urng, _M_param); }
4592e4b17023SJohn Marino 
4593e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
4594e4b17023SJohn Marino 	result_type
4595e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
4596e4b17023SJohn Marino 		   const param_type& __p);
4597e4b17023SJohn Marino 
4598e4b17023SJohn Marino       /**
4599e4b17023SJohn Marino        * @brief Return true if two extreme value distributions have the same
4600e4b17023SJohn Marino        *        parameters.
4601e4b17023SJohn Marino        */
4602*5ce9237cSJohn Marino       friend bool
4603*5ce9237cSJohn Marino       operator==(const extreme_value_distribution& __d1,
4604*5ce9237cSJohn Marino 		 const extreme_value_distribution& __d2)
4605*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param; }
4606*5ce9237cSJohn Marino 
4607*5ce9237cSJohn Marino     private:
4608*5ce9237cSJohn Marino       param_type _M_param;
4609*5ce9237cSJohn Marino     };
4610e4b17023SJohn Marino 
4611e4b17023SJohn Marino   /**
4612e4b17023SJohn Marino     * @brief Return true if two extreme value distributions have different
4613e4b17023SJohn Marino     *        parameters.
4614e4b17023SJohn Marino    */
4615e4b17023SJohn Marino   template<typename _RealType>
4616e4b17023SJohn Marino     inline bool
4617e4b17023SJohn Marino     operator!=(const std::extreme_value_distribution<_RealType>& __d1,
4618e4b17023SJohn Marino 	       const std::extreme_value_distribution<_RealType>& __d2)
4619e4b17023SJohn Marino     { return !(__d1 == __d2); }
4620e4b17023SJohn Marino 
4621e4b17023SJohn Marino   /**
4622e4b17023SJohn Marino    * @brief Inserts a %extreme_value_distribution random number distribution
4623e4b17023SJohn Marino    * @p __x into the output stream @p __os.
4624e4b17023SJohn Marino    *
4625e4b17023SJohn Marino    * @param __os An output stream.
4626e4b17023SJohn Marino    * @param __x  A %extreme_value_distribution random number distribution.
4627e4b17023SJohn Marino    *
4628e4b17023SJohn Marino    * @returns The output stream with the state of @p __x inserted or in
4629e4b17023SJohn Marino    * an error state.
4630e4b17023SJohn Marino    */
4631e4b17023SJohn Marino   template<typename _RealType, typename _CharT, typename _Traits>
4632e4b17023SJohn Marino     std::basic_ostream<_CharT, _Traits>&
4633e4b17023SJohn Marino     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4634e4b17023SJohn Marino 	       const std::extreme_value_distribution<_RealType>& __x);
4635e4b17023SJohn Marino 
4636e4b17023SJohn Marino   /**
4637e4b17023SJohn Marino    * @brief Extracts a %extreme_value_distribution random number
4638e4b17023SJohn Marino    *        distribution @p __x from the input stream @p __is.
4639e4b17023SJohn Marino    *
4640e4b17023SJohn Marino    * @param __is An input stream.
4641e4b17023SJohn Marino    * @param __x A %extreme_value_distribution random number
4642e4b17023SJohn Marino    *            generator engine.
4643e4b17023SJohn Marino    *
4644e4b17023SJohn Marino    * @returns The input stream with @p __x extracted or in an error state.
4645e4b17023SJohn Marino    */
4646e4b17023SJohn Marino   template<typename _RealType, typename _CharT, typename _Traits>
4647e4b17023SJohn Marino     std::basic_istream<_CharT, _Traits>&
4648e4b17023SJohn Marino     operator>>(std::basic_istream<_CharT, _Traits>& __is,
4649e4b17023SJohn Marino 	       std::extreme_value_distribution<_RealType>& __x);
4650e4b17023SJohn Marino 
4651e4b17023SJohn Marino 
4652e4b17023SJohn Marino   /**
4653e4b17023SJohn Marino    * @brief A discrete_distribution random number distribution.
4654e4b17023SJohn Marino    *
4655e4b17023SJohn Marino    * The formula for the discrete probability mass function is
4656e4b17023SJohn Marino    *
4657e4b17023SJohn Marino    */
4658e4b17023SJohn Marino   template<typename _IntType = int>
4659e4b17023SJohn Marino     class discrete_distribution
4660e4b17023SJohn Marino     {
4661e4b17023SJohn Marino       static_assert(std::is_integral<_IntType>::value,
4662e4b17023SJohn Marino 		    "template argument not an integral type");
4663e4b17023SJohn Marino 
4664e4b17023SJohn Marino     public:
4665e4b17023SJohn Marino       /** The type of the range of the distribution. */
4666e4b17023SJohn Marino       typedef _IntType result_type;
4667e4b17023SJohn Marino       /** Parameter type. */
4668e4b17023SJohn Marino       struct param_type
4669e4b17023SJohn Marino       {
4670e4b17023SJohn Marino 	typedef discrete_distribution<_IntType> distribution_type;
4671e4b17023SJohn Marino 	friend class discrete_distribution<_IntType>;
4672e4b17023SJohn Marino 
4673e4b17023SJohn Marino 	param_type()
4674e4b17023SJohn Marino 	: _M_prob(), _M_cp()
4675e4b17023SJohn Marino 	{ }
4676e4b17023SJohn Marino 
4677e4b17023SJohn Marino 	template<typename _InputIterator>
4678e4b17023SJohn Marino 	  param_type(_InputIterator __wbegin,
4679e4b17023SJohn Marino 		     _InputIterator __wend)
4680e4b17023SJohn Marino 	  : _M_prob(__wbegin, __wend), _M_cp()
4681e4b17023SJohn Marino 	  { _M_initialize(); }
4682e4b17023SJohn Marino 
4683e4b17023SJohn Marino 	param_type(initializer_list<double> __wil)
4684e4b17023SJohn Marino 	: _M_prob(__wil.begin(), __wil.end()), _M_cp()
4685e4b17023SJohn Marino 	{ _M_initialize(); }
4686e4b17023SJohn Marino 
4687e4b17023SJohn Marino 	template<typename _Func>
4688e4b17023SJohn Marino 	  param_type(size_t __nw, double __xmin, double __xmax,
4689e4b17023SJohn Marino 		     _Func __fw);
4690e4b17023SJohn Marino 
4691e4b17023SJohn Marino 	// See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
4692e4b17023SJohn Marino 	param_type(const param_type&) = default;
4693e4b17023SJohn Marino 	param_type& operator=(const param_type&) = default;
4694e4b17023SJohn Marino 
4695e4b17023SJohn Marino 	std::vector<double>
4696e4b17023SJohn Marino 	probabilities() const
4697e4b17023SJohn Marino 	{ return _M_prob.empty() ? std::vector<double>(1, 1.0) : _M_prob; }
4698e4b17023SJohn Marino 
4699e4b17023SJohn Marino 	friend bool
4700e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
4701e4b17023SJohn Marino 	{ return __p1._M_prob == __p2._M_prob; }
4702e4b17023SJohn Marino 
4703e4b17023SJohn Marino       private:
4704e4b17023SJohn Marino 	void
4705e4b17023SJohn Marino 	_M_initialize();
4706e4b17023SJohn Marino 
4707e4b17023SJohn Marino 	std::vector<double> _M_prob;
4708e4b17023SJohn Marino 	std::vector<double> _M_cp;
4709e4b17023SJohn Marino       };
4710e4b17023SJohn Marino 
4711e4b17023SJohn Marino       discrete_distribution()
4712e4b17023SJohn Marino       : _M_param()
4713e4b17023SJohn Marino       { }
4714e4b17023SJohn Marino 
4715e4b17023SJohn Marino       template<typename _InputIterator>
4716e4b17023SJohn Marino 	discrete_distribution(_InputIterator __wbegin,
4717e4b17023SJohn Marino 			      _InputIterator __wend)
4718e4b17023SJohn Marino 	: _M_param(__wbegin, __wend)
4719e4b17023SJohn Marino 	{ }
4720e4b17023SJohn Marino 
4721e4b17023SJohn Marino       discrete_distribution(initializer_list<double> __wl)
4722e4b17023SJohn Marino       : _M_param(__wl)
4723e4b17023SJohn Marino       { }
4724e4b17023SJohn Marino 
4725e4b17023SJohn Marino       template<typename _Func>
4726e4b17023SJohn Marino 	discrete_distribution(size_t __nw, double __xmin, double __xmax,
4727e4b17023SJohn Marino 			      _Func __fw)
4728e4b17023SJohn Marino 	: _M_param(__nw, __xmin, __xmax, __fw)
4729e4b17023SJohn Marino 	{ }
4730e4b17023SJohn Marino 
4731e4b17023SJohn Marino       explicit
4732e4b17023SJohn Marino       discrete_distribution(const param_type& __p)
4733e4b17023SJohn Marino       : _M_param(__p)
4734e4b17023SJohn Marino       { }
4735e4b17023SJohn Marino 
4736e4b17023SJohn Marino       /**
4737e4b17023SJohn Marino        * @brief Resets the distribution state.
4738e4b17023SJohn Marino        */
4739e4b17023SJohn Marino       void
4740e4b17023SJohn Marino       reset()
4741e4b17023SJohn Marino       { }
4742e4b17023SJohn Marino 
4743e4b17023SJohn Marino       /**
4744e4b17023SJohn Marino        * @brief Returns the probabilities of the distribution.
4745e4b17023SJohn Marino        */
4746e4b17023SJohn Marino       std::vector<double>
4747e4b17023SJohn Marino       probabilities() const
4748e4b17023SJohn Marino       {
4749e4b17023SJohn Marino 	return _M_param._M_prob.empty()
4750e4b17023SJohn Marino 	  ? std::vector<double>(1, 1.0) : _M_param._M_prob;
4751e4b17023SJohn Marino       }
4752e4b17023SJohn Marino 
4753e4b17023SJohn Marino       /**
4754e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
4755e4b17023SJohn Marino        */
4756e4b17023SJohn Marino       param_type
4757e4b17023SJohn Marino       param() const
4758e4b17023SJohn Marino       { return _M_param; }
4759e4b17023SJohn Marino 
4760e4b17023SJohn Marino       /**
4761e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
4762e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
4763e4b17023SJohn Marino        */
4764e4b17023SJohn Marino       void
4765e4b17023SJohn Marino       param(const param_type& __param)
4766e4b17023SJohn Marino       { _M_param = __param; }
4767e4b17023SJohn Marino 
4768e4b17023SJohn Marino       /**
4769e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
4770e4b17023SJohn Marino        */
4771e4b17023SJohn Marino       result_type
4772e4b17023SJohn Marino       min() const
4773e4b17023SJohn Marino       { return result_type(0); }
4774e4b17023SJohn Marino 
4775e4b17023SJohn Marino       /**
4776e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
4777e4b17023SJohn Marino        */
4778e4b17023SJohn Marino       result_type
4779e4b17023SJohn Marino       max() const
4780e4b17023SJohn Marino       {
4781e4b17023SJohn Marino 	return _M_param._M_prob.empty()
4782e4b17023SJohn Marino 	  ? result_type(0) : result_type(_M_param._M_prob.size() - 1);
4783e4b17023SJohn Marino       }
4784e4b17023SJohn Marino 
4785e4b17023SJohn Marino       /**
4786e4b17023SJohn Marino        * @brief Generating functions.
4787e4b17023SJohn Marino        */
4788e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
4789e4b17023SJohn Marino 	result_type
4790e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
4791*5ce9237cSJohn Marino 	{ return this->operator()(__urng, _M_param); }
4792e4b17023SJohn Marino 
4793e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
4794e4b17023SJohn Marino 	result_type
4795e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
4796e4b17023SJohn Marino 		   const param_type& __p);
4797e4b17023SJohn Marino 
4798e4b17023SJohn Marino       /**
4799*5ce9237cSJohn Marino        * @brief Return true if two discrete distributions have the same
4800*5ce9237cSJohn Marino        *        parameters.
4801*5ce9237cSJohn Marino        */
4802*5ce9237cSJohn Marino       friend bool
4803*5ce9237cSJohn Marino       operator==(const discrete_distribution& __d1,
4804*5ce9237cSJohn Marino 		 const discrete_distribution& __d2)
4805*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param; }
4806*5ce9237cSJohn Marino 
4807*5ce9237cSJohn Marino       /**
4808e4b17023SJohn Marino        * @brief Inserts a %discrete_distribution random number distribution
4809e4b17023SJohn Marino        * @p __x into the output stream @p __os.
4810e4b17023SJohn Marino        *
4811e4b17023SJohn Marino        * @param __os An output stream.
4812e4b17023SJohn Marino        * @param __x  A %discrete_distribution random number distribution.
4813e4b17023SJohn Marino        *
4814e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
4815e4b17023SJohn Marino        * an error state.
4816e4b17023SJohn Marino        */
4817e4b17023SJohn Marino       template<typename _IntType1, typename _CharT, typename _Traits>
4818e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
4819e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
4820e4b17023SJohn Marino 		   const std::discrete_distribution<_IntType1>& __x);
4821e4b17023SJohn Marino 
4822e4b17023SJohn Marino       /**
4823e4b17023SJohn Marino        * @brief Extracts a %discrete_distribution random number distribution
4824e4b17023SJohn Marino        * @p __x from the input stream @p __is.
4825e4b17023SJohn Marino        *
4826e4b17023SJohn Marino        * @param __is An input stream.
4827e4b17023SJohn Marino        * @param __x A %discrete_distribution random number
4828e4b17023SJohn Marino        *            generator engine.
4829e4b17023SJohn Marino        *
4830e4b17023SJohn Marino        * @returns The input stream with @p __x extracted or in an error
4831e4b17023SJohn Marino        *          state.
4832e4b17023SJohn Marino        */
4833e4b17023SJohn Marino       template<typename _IntType1, typename _CharT, typename _Traits>
4834e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
4835e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
4836e4b17023SJohn Marino 		   std::discrete_distribution<_IntType1>& __x);
4837e4b17023SJohn Marino 
4838e4b17023SJohn Marino     private:
4839e4b17023SJohn Marino       param_type _M_param;
4840e4b17023SJohn Marino     };
4841e4b17023SJohn Marino 
4842e4b17023SJohn Marino   /**
4843e4b17023SJohn Marino     * @brief Return true if two discrete distributions have different
4844e4b17023SJohn Marino     *        parameters.
4845e4b17023SJohn Marino     */
4846e4b17023SJohn Marino   template<typename _IntType>
4847e4b17023SJohn Marino     inline bool
4848e4b17023SJohn Marino     operator!=(const std::discrete_distribution<_IntType>& __d1,
4849e4b17023SJohn Marino 	       const std::discrete_distribution<_IntType>& __d2)
4850e4b17023SJohn Marino     { return !(__d1 == __d2); }
4851e4b17023SJohn Marino 
4852e4b17023SJohn Marino 
4853e4b17023SJohn Marino   /**
4854e4b17023SJohn Marino    * @brief A piecewise_constant_distribution random number distribution.
4855e4b17023SJohn Marino    *
4856e4b17023SJohn Marino    * The formula for the piecewise constant probability mass function is
4857e4b17023SJohn Marino    *
4858e4b17023SJohn Marino    */
4859e4b17023SJohn Marino   template<typename _RealType = double>
4860e4b17023SJohn Marino     class piecewise_constant_distribution
4861e4b17023SJohn Marino     {
4862e4b17023SJohn Marino       static_assert(std::is_floating_point<_RealType>::value,
4863e4b17023SJohn Marino 		    "template argument not a floating point type");
4864e4b17023SJohn Marino 
4865e4b17023SJohn Marino     public:
4866e4b17023SJohn Marino       /** The type of the range of the distribution. */
4867e4b17023SJohn Marino       typedef _RealType result_type;
4868e4b17023SJohn Marino       /** Parameter type. */
4869e4b17023SJohn Marino       struct param_type
4870e4b17023SJohn Marino       {
4871e4b17023SJohn Marino 	typedef piecewise_constant_distribution<_RealType> distribution_type;
4872e4b17023SJohn Marino 	friend class piecewise_constant_distribution<_RealType>;
4873e4b17023SJohn Marino 
4874e4b17023SJohn Marino 	param_type()
4875e4b17023SJohn Marino 	: _M_int(), _M_den(), _M_cp()
4876e4b17023SJohn Marino 	{ }
4877e4b17023SJohn Marino 
4878e4b17023SJohn Marino 	template<typename _InputIteratorB, typename _InputIteratorW>
4879e4b17023SJohn Marino 	  param_type(_InputIteratorB __bfirst,
4880e4b17023SJohn Marino 		     _InputIteratorB __bend,
4881e4b17023SJohn Marino 		     _InputIteratorW __wbegin);
4882e4b17023SJohn Marino 
4883e4b17023SJohn Marino 	template<typename _Func>
4884e4b17023SJohn Marino 	  param_type(initializer_list<_RealType> __bi, _Func __fw);
4885e4b17023SJohn Marino 
4886e4b17023SJohn Marino 	template<typename _Func>
4887e4b17023SJohn Marino 	  param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
4888e4b17023SJohn Marino 		     _Func __fw);
4889e4b17023SJohn Marino 
4890e4b17023SJohn Marino 	// See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
4891e4b17023SJohn Marino 	param_type(const param_type&) = default;
4892e4b17023SJohn Marino 	param_type& operator=(const param_type&) = default;
4893e4b17023SJohn Marino 
4894e4b17023SJohn Marino 	std::vector<_RealType>
4895e4b17023SJohn Marino 	intervals() const
4896e4b17023SJohn Marino 	{
4897e4b17023SJohn Marino 	  if (_M_int.empty())
4898e4b17023SJohn Marino 	    {
4899e4b17023SJohn Marino 	      std::vector<_RealType> __tmp(2);
4900e4b17023SJohn Marino 	      __tmp[1] = _RealType(1);
4901e4b17023SJohn Marino 	      return __tmp;
4902e4b17023SJohn Marino 	    }
4903e4b17023SJohn Marino 	  else
4904e4b17023SJohn Marino 	    return _M_int;
4905e4b17023SJohn Marino 	}
4906e4b17023SJohn Marino 
4907e4b17023SJohn Marino 	std::vector<double>
4908e4b17023SJohn Marino 	densities() const
4909e4b17023SJohn Marino 	{ return _M_den.empty() ? std::vector<double>(1, 1.0) : _M_den; }
4910e4b17023SJohn Marino 
4911e4b17023SJohn Marino 	friend bool
4912e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
4913e4b17023SJohn Marino 	{ return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; }
4914e4b17023SJohn Marino 
4915e4b17023SJohn Marino       private:
4916e4b17023SJohn Marino 	void
4917e4b17023SJohn Marino 	_M_initialize();
4918e4b17023SJohn Marino 
4919e4b17023SJohn Marino 	std::vector<_RealType> _M_int;
4920e4b17023SJohn Marino 	std::vector<double> _M_den;
4921e4b17023SJohn Marino 	std::vector<double> _M_cp;
4922e4b17023SJohn Marino       };
4923e4b17023SJohn Marino 
4924e4b17023SJohn Marino       explicit
4925e4b17023SJohn Marino       piecewise_constant_distribution()
4926e4b17023SJohn Marino       : _M_param()
4927e4b17023SJohn Marino       { }
4928e4b17023SJohn Marino 
4929e4b17023SJohn Marino       template<typename _InputIteratorB, typename _InputIteratorW>
4930e4b17023SJohn Marino 	piecewise_constant_distribution(_InputIteratorB __bfirst,
4931e4b17023SJohn Marino 					_InputIteratorB __bend,
4932e4b17023SJohn Marino 					_InputIteratorW __wbegin)
4933e4b17023SJohn Marino 	: _M_param(__bfirst, __bend, __wbegin)
4934e4b17023SJohn Marino 	{ }
4935e4b17023SJohn Marino 
4936e4b17023SJohn Marino       template<typename _Func>
4937e4b17023SJohn Marino 	piecewise_constant_distribution(initializer_list<_RealType> __bl,
4938e4b17023SJohn Marino 					_Func __fw)
4939e4b17023SJohn Marino 	: _M_param(__bl, __fw)
4940e4b17023SJohn Marino 	{ }
4941e4b17023SJohn Marino 
4942e4b17023SJohn Marino       template<typename _Func>
4943e4b17023SJohn Marino 	piecewise_constant_distribution(size_t __nw,
4944e4b17023SJohn Marino 					_RealType __xmin, _RealType __xmax,
4945e4b17023SJohn Marino 					_Func __fw)
4946e4b17023SJohn Marino 	: _M_param(__nw, __xmin, __xmax, __fw)
4947e4b17023SJohn Marino 	{ }
4948e4b17023SJohn Marino 
4949e4b17023SJohn Marino       explicit
4950e4b17023SJohn Marino       piecewise_constant_distribution(const param_type& __p)
4951e4b17023SJohn Marino       : _M_param(__p)
4952e4b17023SJohn Marino       { }
4953e4b17023SJohn Marino 
4954e4b17023SJohn Marino       /**
4955e4b17023SJohn Marino        * @brief Resets the distribution state.
4956e4b17023SJohn Marino        */
4957e4b17023SJohn Marino       void
4958e4b17023SJohn Marino       reset()
4959e4b17023SJohn Marino       { }
4960e4b17023SJohn Marino 
4961e4b17023SJohn Marino       /**
4962e4b17023SJohn Marino        * @brief Returns a vector of the intervals.
4963e4b17023SJohn Marino        */
4964e4b17023SJohn Marino       std::vector<_RealType>
4965e4b17023SJohn Marino       intervals() const
4966e4b17023SJohn Marino       {
4967e4b17023SJohn Marino 	if (_M_param._M_int.empty())
4968e4b17023SJohn Marino 	  {
4969e4b17023SJohn Marino 	    std::vector<_RealType> __tmp(2);
4970e4b17023SJohn Marino 	    __tmp[1] = _RealType(1);
4971e4b17023SJohn Marino 	    return __tmp;
4972e4b17023SJohn Marino 	  }
4973e4b17023SJohn Marino 	else
4974e4b17023SJohn Marino 	  return _M_param._M_int;
4975e4b17023SJohn Marino       }
4976e4b17023SJohn Marino 
4977e4b17023SJohn Marino       /**
4978e4b17023SJohn Marino        * @brief Returns a vector of the probability densities.
4979e4b17023SJohn Marino        */
4980e4b17023SJohn Marino       std::vector<double>
4981e4b17023SJohn Marino       densities() const
4982e4b17023SJohn Marino       {
4983e4b17023SJohn Marino 	return _M_param._M_den.empty()
4984e4b17023SJohn Marino 	  ? std::vector<double>(1, 1.0) : _M_param._M_den;
4985e4b17023SJohn Marino       }
4986e4b17023SJohn Marino 
4987e4b17023SJohn Marino       /**
4988e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
4989e4b17023SJohn Marino        */
4990e4b17023SJohn Marino       param_type
4991e4b17023SJohn Marino       param() const
4992e4b17023SJohn Marino       { return _M_param; }
4993e4b17023SJohn Marino 
4994e4b17023SJohn Marino       /**
4995e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
4996e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
4997e4b17023SJohn Marino        */
4998e4b17023SJohn Marino       void
4999e4b17023SJohn Marino       param(const param_type& __param)
5000e4b17023SJohn Marino       { _M_param = __param; }
5001e4b17023SJohn Marino 
5002e4b17023SJohn Marino       /**
5003e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
5004e4b17023SJohn Marino        */
5005e4b17023SJohn Marino       result_type
5006e4b17023SJohn Marino       min() const
5007e4b17023SJohn Marino       {
5008e4b17023SJohn Marino 	return _M_param._M_int.empty()
5009e4b17023SJohn Marino 	  ? result_type(0) : _M_param._M_int.front();
5010e4b17023SJohn Marino       }
5011e4b17023SJohn Marino 
5012e4b17023SJohn Marino       /**
5013e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
5014e4b17023SJohn Marino        */
5015e4b17023SJohn Marino       result_type
5016e4b17023SJohn Marino       max() const
5017e4b17023SJohn Marino       {
5018e4b17023SJohn Marino 	return _M_param._M_int.empty()
5019e4b17023SJohn Marino 	  ? result_type(1) : _M_param._M_int.back();
5020e4b17023SJohn Marino       }
5021e4b17023SJohn Marino 
5022e4b17023SJohn Marino       /**
5023e4b17023SJohn Marino        * @brief Generating functions.
5024e4b17023SJohn Marino        */
5025e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
5026e4b17023SJohn Marino 	result_type
5027e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
5028*5ce9237cSJohn Marino 	{ return this->operator()(__urng, _M_param); }
5029e4b17023SJohn Marino 
5030e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
5031e4b17023SJohn Marino 	result_type
5032e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
5033e4b17023SJohn Marino 		   const param_type& __p);
5034e4b17023SJohn Marino 
5035e4b17023SJohn Marino       /**
5036*5ce9237cSJohn Marino        * @brief Return true if two piecewise constant distributions have the
5037*5ce9237cSJohn Marino        *        same parameters.
5038*5ce9237cSJohn Marino        */
5039*5ce9237cSJohn Marino       friend bool
5040*5ce9237cSJohn Marino       operator==(const piecewise_constant_distribution& __d1,
5041*5ce9237cSJohn Marino 		 const piecewise_constant_distribution& __d2)
5042*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param; }
5043*5ce9237cSJohn Marino 
5044*5ce9237cSJohn Marino       /**
5045e4b17023SJohn Marino        * @brief Inserts a %piecewise_constan_distribution random
5046e4b17023SJohn Marino        *        number distribution @p __x into the output stream @p __os.
5047e4b17023SJohn Marino        *
5048e4b17023SJohn Marino        * @param __os An output stream.
5049e4b17023SJohn Marino        * @param __x  A %piecewise_constan_distribution random number
5050e4b17023SJohn Marino        *             distribution.
5051e4b17023SJohn Marino        *
5052e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
5053e4b17023SJohn Marino        * an error state.
5054e4b17023SJohn Marino        */
5055e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
5056e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
5057e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5058e4b17023SJohn Marino 		   const std::piecewise_constant_distribution<_RealType1>& __x);
5059e4b17023SJohn Marino 
5060e4b17023SJohn Marino       /**
5061e4b17023SJohn Marino        * @brief Extracts a %piecewise_constan_distribution random
5062e4b17023SJohn Marino        *        number distribution @p __x from the input stream @p __is.
5063e4b17023SJohn Marino        *
5064e4b17023SJohn Marino        * @param __is An input stream.
5065e4b17023SJohn Marino        * @param __x A %piecewise_constan_distribution random number
5066e4b17023SJohn Marino        *            generator engine.
5067e4b17023SJohn Marino        *
5068e4b17023SJohn Marino        * @returns The input stream with @p __x extracted or in an error
5069e4b17023SJohn Marino        *          state.
5070e4b17023SJohn Marino        */
5071e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
5072e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
5073e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
5074e4b17023SJohn Marino 		   std::piecewise_constant_distribution<_RealType1>& __x);
5075e4b17023SJohn Marino 
5076e4b17023SJohn Marino     private:
5077e4b17023SJohn Marino       param_type _M_param;
5078e4b17023SJohn Marino     };
5079e4b17023SJohn Marino 
5080e4b17023SJohn Marino   /**
5081e4b17023SJohn Marino     * @brief Return true if two piecewise constant distributions have
5082e4b17023SJohn Marino     *        different parameters.
5083e4b17023SJohn Marino    */
5084e4b17023SJohn Marino   template<typename _RealType>
5085e4b17023SJohn Marino     inline bool
5086e4b17023SJohn Marino     operator!=(const std::piecewise_constant_distribution<_RealType>& __d1,
5087e4b17023SJohn Marino 	       const std::piecewise_constant_distribution<_RealType>& __d2)
5088e4b17023SJohn Marino     { return !(__d1 == __d2); }
5089e4b17023SJohn Marino 
5090e4b17023SJohn Marino 
5091e4b17023SJohn Marino   /**
5092e4b17023SJohn Marino    * @brief A piecewise_linear_distribution random number distribution.
5093e4b17023SJohn Marino    *
5094e4b17023SJohn Marino    * The formula for the piecewise linear probability mass function is
5095e4b17023SJohn Marino    *
5096e4b17023SJohn Marino    */
5097e4b17023SJohn Marino   template<typename _RealType = double>
5098e4b17023SJohn Marino     class piecewise_linear_distribution
5099e4b17023SJohn Marino     {
5100e4b17023SJohn Marino       static_assert(std::is_floating_point<_RealType>::value,
5101e4b17023SJohn Marino 		    "template argument not a floating point type");
5102e4b17023SJohn Marino 
5103e4b17023SJohn Marino     public:
5104e4b17023SJohn Marino       /** The type of the range of the distribution. */
5105e4b17023SJohn Marino       typedef _RealType result_type;
5106e4b17023SJohn Marino       /** Parameter type. */
5107e4b17023SJohn Marino       struct param_type
5108e4b17023SJohn Marino       {
5109e4b17023SJohn Marino 	typedef piecewise_linear_distribution<_RealType> distribution_type;
5110e4b17023SJohn Marino 	friend class piecewise_linear_distribution<_RealType>;
5111e4b17023SJohn Marino 
5112e4b17023SJohn Marino 	param_type()
5113e4b17023SJohn Marino 	: _M_int(), _M_den(), _M_cp(), _M_m()
5114e4b17023SJohn Marino 	{ }
5115e4b17023SJohn Marino 
5116e4b17023SJohn Marino 	template<typename _InputIteratorB, typename _InputIteratorW>
5117e4b17023SJohn Marino 	  param_type(_InputIteratorB __bfirst,
5118e4b17023SJohn Marino 		     _InputIteratorB __bend,
5119e4b17023SJohn Marino 		     _InputIteratorW __wbegin);
5120e4b17023SJohn Marino 
5121e4b17023SJohn Marino 	template<typename _Func>
5122e4b17023SJohn Marino 	  param_type(initializer_list<_RealType> __bl, _Func __fw);
5123e4b17023SJohn Marino 
5124e4b17023SJohn Marino 	template<typename _Func>
5125e4b17023SJohn Marino 	  param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
5126e4b17023SJohn Marino 		     _Func __fw);
5127e4b17023SJohn Marino 
5128e4b17023SJohn Marino 	// See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/
5129e4b17023SJohn Marino 	param_type(const param_type&) = default;
5130e4b17023SJohn Marino 	param_type& operator=(const param_type&) = default;
5131e4b17023SJohn Marino 
5132e4b17023SJohn Marino 	std::vector<_RealType>
5133e4b17023SJohn Marino 	intervals() const
5134e4b17023SJohn Marino 	{
5135e4b17023SJohn Marino 	  if (_M_int.empty())
5136e4b17023SJohn Marino 	    {
5137e4b17023SJohn Marino 	      std::vector<_RealType> __tmp(2);
5138e4b17023SJohn Marino 	      __tmp[1] = _RealType(1);
5139e4b17023SJohn Marino 	      return __tmp;
5140e4b17023SJohn Marino 	    }
5141e4b17023SJohn Marino 	  else
5142e4b17023SJohn Marino 	    return _M_int;
5143e4b17023SJohn Marino 	}
5144e4b17023SJohn Marino 
5145e4b17023SJohn Marino 	std::vector<double>
5146e4b17023SJohn Marino 	densities() const
5147e4b17023SJohn Marino 	{ return _M_den.empty() ? std::vector<double>(2, 1.0) : _M_den; }
5148e4b17023SJohn Marino 
5149e4b17023SJohn Marino 	friend bool
5150e4b17023SJohn Marino 	operator==(const param_type& __p1, const param_type& __p2)
5151e4b17023SJohn Marino 	{ return (__p1._M_int == __p2._M_int
5152e4b17023SJohn Marino 		  && __p1._M_den == __p2._M_den); }
5153e4b17023SJohn Marino 
5154e4b17023SJohn Marino       private:
5155e4b17023SJohn Marino 	void
5156e4b17023SJohn Marino 	_M_initialize();
5157e4b17023SJohn Marino 
5158e4b17023SJohn Marino 	std::vector<_RealType> _M_int;
5159e4b17023SJohn Marino 	std::vector<double> _M_den;
5160e4b17023SJohn Marino 	std::vector<double> _M_cp;
5161e4b17023SJohn Marino 	std::vector<double> _M_m;
5162e4b17023SJohn Marino       };
5163e4b17023SJohn Marino 
5164e4b17023SJohn Marino       explicit
5165e4b17023SJohn Marino       piecewise_linear_distribution()
5166e4b17023SJohn Marino       : _M_param()
5167e4b17023SJohn Marino       { }
5168e4b17023SJohn Marino 
5169e4b17023SJohn Marino       template<typename _InputIteratorB, typename _InputIteratorW>
5170e4b17023SJohn Marino 	piecewise_linear_distribution(_InputIteratorB __bfirst,
5171e4b17023SJohn Marino 				      _InputIteratorB __bend,
5172e4b17023SJohn Marino 				      _InputIteratorW __wbegin)
5173e4b17023SJohn Marino 	: _M_param(__bfirst, __bend, __wbegin)
5174e4b17023SJohn Marino 	{ }
5175e4b17023SJohn Marino 
5176e4b17023SJohn Marino       template<typename _Func>
5177e4b17023SJohn Marino 	piecewise_linear_distribution(initializer_list<_RealType> __bl,
5178e4b17023SJohn Marino 				      _Func __fw)
5179e4b17023SJohn Marino 	: _M_param(__bl, __fw)
5180e4b17023SJohn Marino 	{ }
5181e4b17023SJohn Marino 
5182e4b17023SJohn Marino       template<typename _Func>
5183e4b17023SJohn Marino 	piecewise_linear_distribution(size_t __nw,
5184e4b17023SJohn Marino 				      _RealType __xmin, _RealType __xmax,
5185e4b17023SJohn Marino 				      _Func __fw)
5186e4b17023SJohn Marino 	: _M_param(__nw, __xmin, __xmax, __fw)
5187e4b17023SJohn Marino 	{ }
5188e4b17023SJohn Marino 
5189e4b17023SJohn Marino       explicit
5190e4b17023SJohn Marino       piecewise_linear_distribution(const param_type& __p)
5191e4b17023SJohn Marino       : _M_param(__p)
5192e4b17023SJohn Marino       { }
5193e4b17023SJohn Marino 
5194e4b17023SJohn Marino       /**
5195e4b17023SJohn Marino        * Resets the distribution state.
5196e4b17023SJohn Marino        */
5197e4b17023SJohn Marino       void
5198e4b17023SJohn Marino       reset()
5199e4b17023SJohn Marino       { }
5200e4b17023SJohn Marino 
5201e4b17023SJohn Marino       /**
5202e4b17023SJohn Marino        * @brief Return the intervals of the distribution.
5203e4b17023SJohn Marino        */
5204e4b17023SJohn Marino       std::vector<_RealType>
5205e4b17023SJohn Marino       intervals() const
5206e4b17023SJohn Marino       {
5207e4b17023SJohn Marino 	if (_M_param._M_int.empty())
5208e4b17023SJohn Marino 	  {
5209e4b17023SJohn Marino 	    std::vector<_RealType> __tmp(2);
5210e4b17023SJohn Marino 	    __tmp[1] = _RealType(1);
5211e4b17023SJohn Marino 	    return __tmp;
5212e4b17023SJohn Marino 	  }
5213e4b17023SJohn Marino 	else
5214e4b17023SJohn Marino 	  return _M_param._M_int;
5215e4b17023SJohn Marino       }
5216e4b17023SJohn Marino 
5217e4b17023SJohn Marino       /**
5218e4b17023SJohn Marino        * @brief Return a vector of the probability densities of the
5219e4b17023SJohn Marino        *        distribution.
5220e4b17023SJohn Marino        */
5221e4b17023SJohn Marino       std::vector<double>
5222e4b17023SJohn Marino       densities() const
5223e4b17023SJohn Marino       {
5224e4b17023SJohn Marino 	return _M_param._M_den.empty()
5225e4b17023SJohn Marino 	  ? std::vector<double>(2, 1.0) : _M_param._M_den;
5226e4b17023SJohn Marino       }
5227e4b17023SJohn Marino 
5228e4b17023SJohn Marino       /**
5229e4b17023SJohn Marino        * @brief Returns the parameter set of the distribution.
5230e4b17023SJohn Marino        */
5231e4b17023SJohn Marino       param_type
5232e4b17023SJohn Marino       param() const
5233e4b17023SJohn Marino       { return _M_param; }
5234e4b17023SJohn Marino 
5235e4b17023SJohn Marino       /**
5236e4b17023SJohn Marino        * @brief Sets the parameter set of the distribution.
5237e4b17023SJohn Marino        * @param __param The new parameter set of the distribution.
5238e4b17023SJohn Marino        */
5239e4b17023SJohn Marino       void
5240e4b17023SJohn Marino       param(const param_type& __param)
5241e4b17023SJohn Marino       { _M_param = __param; }
5242e4b17023SJohn Marino 
5243e4b17023SJohn Marino       /**
5244e4b17023SJohn Marino        * @brief Returns the greatest lower bound value of the distribution.
5245e4b17023SJohn Marino        */
5246e4b17023SJohn Marino       result_type
5247e4b17023SJohn Marino       min() const
5248e4b17023SJohn Marino       {
5249e4b17023SJohn Marino 	return _M_param._M_int.empty()
5250e4b17023SJohn Marino 	  ? result_type(0) : _M_param._M_int.front();
5251e4b17023SJohn Marino       }
5252e4b17023SJohn Marino 
5253e4b17023SJohn Marino       /**
5254e4b17023SJohn Marino        * @brief Returns the least upper bound value of the distribution.
5255e4b17023SJohn Marino        */
5256e4b17023SJohn Marino       result_type
5257e4b17023SJohn Marino       max() const
5258e4b17023SJohn Marino       {
5259e4b17023SJohn Marino 	return _M_param._M_int.empty()
5260e4b17023SJohn Marino 	  ? result_type(1) : _M_param._M_int.back();
5261e4b17023SJohn Marino       }
5262e4b17023SJohn Marino 
5263e4b17023SJohn Marino       /**
5264e4b17023SJohn Marino        * @brief Generating functions.
5265e4b17023SJohn Marino        */
5266e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
5267e4b17023SJohn Marino 	result_type
5268e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng)
5269*5ce9237cSJohn Marino 	{ return this->operator()(__urng, _M_param); }
5270e4b17023SJohn Marino 
5271e4b17023SJohn Marino       template<typename _UniformRandomNumberGenerator>
5272e4b17023SJohn Marino 	result_type
5273e4b17023SJohn Marino 	operator()(_UniformRandomNumberGenerator& __urng,
5274e4b17023SJohn Marino 		   const param_type& __p);
5275e4b17023SJohn Marino 
5276e4b17023SJohn Marino       /**
5277*5ce9237cSJohn Marino        * @brief Return true if two piecewise linear distributions have the
5278*5ce9237cSJohn Marino        *        same parameters.
5279*5ce9237cSJohn Marino        */
5280*5ce9237cSJohn Marino       friend bool
5281*5ce9237cSJohn Marino       operator==(const piecewise_linear_distribution& __d1,
5282*5ce9237cSJohn Marino 		 const piecewise_linear_distribution& __d2)
5283*5ce9237cSJohn Marino       { return __d1._M_param == __d2._M_param; }
5284*5ce9237cSJohn Marino 
5285*5ce9237cSJohn Marino       /**
5286e4b17023SJohn Marino        * @brief Inserts a %piecewise_linear_distribution random number
5287e4b17023SJohn Marino        *        distribution @p __x into the output stream @p __os.
5288e4b17023SJohn Marino        *
5289e4b17023SJohn Marino        * @param __os An output stream.
5290e4b17023SJohn Marino        * @param __x  A %piecewise_linear_distribution random number
5291e4b17023SJohn Marino        *             distribution.
5292e4b17023SJohn Marino        *
5293e4b17023SJohn Marino        * @returns The output stream with the state of @p __x inserted or in
5294e4b17023SJohn Marino        *          an error state.
5295e4b17023SJohn Marino        */
5296e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
5297e4b17023SJohn Marino 	friend std::basic_ostream<_CharT, _Traits>&
5298e4b17023SJohn Marino 	operator<<(std::basic_ostream<_CharT, _Traits>& __os,
5299e4b17023SJohn Marino 		   const std::piecewise_linear_distribution<_RealType1>& __x);
5300e4b17023SJohn Marino 
5301e4b17023SJohn Marino       /**
5302e4b17023SJohn Marino        * @brief Extracts a %piecewise_linear_distribution random number
5303e4b17023SJohn Marino        *        distribution @p __x from the input stream @p __is.
5304e4b17023SJohn Marino        *
5305e4b17023SJohn Marino        * @param __is An input stream.
5306e4b17023SJohn Marino        * @param __x  A %piecewise_linear_distribution random number
5307e4b17023SJohn Marino        *             generator engine.
5308e4b17023SJohn Marino        *
5309e4b17023SJohn Marino        * @returns The input stream with @p __x extracted or in an error
5310e4b17023SJohn Marino        *          state.
5311e4b17023SJohn Marino        */
5312e4b17023SJohn Marino       template<typename _RealType1, typename _CharT, typename _Traits>
5313e4b17023SJohn Marino 	friend std::basic_istream<_CharT, _Traits>&
5314e4b17023SJohn Marino 	operator>>(std::basic_istream<_CharT, _Traits>& __is,
5315e4b17023SJohn Marino 		   std::piecewise_linear_distribution<_RealType1>& __x);
5316e4b17023SJohn Marino 
5317e4b17023SJohn Marino     private:
5318e4b17023SJohn Marino       param_type _M_param;
5319e4b17023SJohn Marino     };
5320e4b17023SJohn Marino 
5321e4b17023SJohn Marino   /**
5322e4b17023SJohn Marino     * @brief Return true if two piecewise linear distributions have
5323e4b17023SJohn Marino     *        different parameters.
5324e4b17023SJohn Marino    */
5325e4b17023SJohn Marino   template<typename _RealType>
5326e4b17023SJohn Marino     inline bool
5327e4b17023SJohn Marino     operator!=(const std::piecewise_linear_distribution<_RealType>& __d1,
5328e4b17023SJohn Marino 	       const std::piecewise_linear_distribution<_RealType>& __d2)
5329e4b17023SJohn Marino     { return !(__d1 == __d2); }
5330e4b17023SJohn Marino 
5331e4b17023SJohn Marino 
5332e4b17023SJohn Marino   /* @} */ // group random_distributions_poisson
5333e4b17023SJohn Marino 
5334e4b17023SJohn Marino   /* @} */ // group random_distributions
5335e4b17023SJohn Marino 
5336e4b17023SJohn Marino   /**
5337e4b17023SJohn Marino    * @addtogroup random_utilities Random Number Utilities
5338e4b17023SJohn Marino    * @ingroup random
5339e4b17023SJohn Marino    * @{
5340e4b17023SJohn Marino    */
5341e4b17023SJohn Marino 
5342e4b17023SJohn Marino   /**
5343e4b17023SJohn Marino    * @brief The seed_seq class generates sequences of seeds for random
5344e4b17023SJohn Marino    *        number generators.
5345e4b17023SJohn Marino    */
5346e4b17023SJohn Marino   class seed_seq
5347e4b17023SJohn Marino   {
5348e4b17023SJohn Marino 
5349e4b17023SJohn Marino   public:
5350e4b17023SJohn Marino     /** The type of the seed vales. */
5351e4b17023SJohn Marino     typedef uint_least32_t result_type;
5352e4b17023SJohn Marino 
5353e4b17023SJohn Marino     /** Default constructor. */
5354e4b17023SJohn Marino     seed_seq()
5355e4b17023SJohn Marino     : _M_v()
5356e4b17023SJohn Marino     { }
5357e4b17023SJohn Marino 
5358e4b17023SJohn Marino     template<typename _IntType>
5359e4b17023SJohn Marino       seed_seq(std::initializer_list<_IntType> il);
5360e4b17023SJohn Marino 
5361e4b17023SJohn Marino     template<typename _InputIterator>
5362e4b17023SJohn Marino       seed_seq(_InputIterator __begin, _InputIterator __end);
5363e4b17023SJohn Marino 
5364e4b17023SJohn Marino     // generating functions
5365e4b17023SJohn Marino     template<typename _RandomAccessIterator>
5366e4b17023SJohn Marino       void
5367e4b17023SJohn Marino       generate(_RandomAccessIterator __begin, _RandomAccessIterator __end);
5368e4b17023SJohn Marino 
5369e4b17023SJohn Marino     // property functions
5370e4b17023SJohn Marino     size_t size() const
5371e4b17023SJohn Marino     { return _M_v.size(); }
5372e4b17023SJohn Marino 
5373e4b17023SJohn Marino     template<typename OutputIterator>
5374e4b17023SJohn Marino       void
5375e4b17023SJohn Marino       param(OutputIterator __dest) const
5376e4b17023SJohn Marino       { std::copy(_M_v.begin(), _M_v.end(), __dest); }
5377e4b17023SJohn Marino 
5378e4b17023SJohn Marino   private:
5379e4b17023SJohn Marino     ///
5380e4b17023SJohn Marino     std::vector<result_type> _M_v;
5381e4b17023SJohn Marino   };
5382e4b17023SJohn Marino 
5383e4b17023SJohn Marino   /* @} */ // group random_utilities
5384e4b17023SJohn Marino 
5385e4b17023SJohn Marino   /* @} */ // group random
5386e4b17023SJohn Marino 
5387e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
5388e4b17023SJohn Marino } // namespace std
5389e4b17023SJohn Marino 
5390e4b17023SJohn Marino #endif
5391