xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/random.tcc (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj // random number generation (out of line) -*- C++ -*-
238fd1498Szrj 
338fd1498Szrj // Copyright (C) 2009-2018 Free Software Foundation, Inc.
438fd1498Szrj //
538fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
638fd1498Szrj // software; you can redistribute it and/or modify it under the
738fd1498Szrj // terms of the GNU General Public License as published by the
838fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj // any later version.
1038fd1498Szrj 
1138fd1498Szrj // This library is distributed in the hope that it will be useful,
1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1438fd1498Szrj // GNU General Public License for more details.
1538fd1498Szrj 
1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj // 3.1, as published by the Free Software Foundation.
1938fd1498Szrj 
2038fd1498Szrj // You should have received a copy of the GNU General Public License and
2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2338fd1498Szrj // <http://www.gnu.org/licenses/>.
2438fd1498Szrj 
2538fd1498Szrj /** @file bits/random.tcc
2638fd1498Szrj  *  This is an internal header file, included by other library headers.
2738fd1498Szrj  *  Do not attempt to use it directly. @headername{random}
2838fd1498Szrj  */
2938fd1498Szrj 
3038fd1498Szrj #ifndef _RANDOM_TCC
3138fd1498Szrj #define _RANDOM_TCC 1
3238fd1498Szrj 
3338fd1498Szrj #include <numeric> // std::accumulate and std::partial_sum
3438fd1498Szrj 
3538fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
3638fd1498Szrj {
3738fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
3838fd1498Szrj 
3938fd1498Szrj   /*
4038fd1498Szrj    * (Further) implementation-space details.
4138fd1498Szrj    */
4238fd1498Szrj   namespace __detail
4338fd1498Szrj   {
4438fd1498Szrj     // General case for x = (ax + c) mod m -- use Schrage's algorithm
4538fd1498Szrj     // to avoid integer overflow.
4638fd1498Szrj     //
4738fd1498Szrj     // Preconditions:  a > 0, m > 0.
4838fd1498Szrj     //
4938fd1498Szrj     // Note: only works correctly for __m % __a < __m / __a.
5038fd1498Szrj     template<typename _Tp, _Tp __m, _Tp __a, _Tp __c>
5138fd1498Szrj       _Tp
5238fd1498Szrj       _Mod<_Tp, __m, __a, __c, false, true>::
__calc(_Tp __x)5338fd1498Szrj       __calc(_Tp __x)
5438fd1498Szrj       {
5538fd1498Szrj 	if (__a == 1)
5638fd1498Szrj 	  __x %= __m;
5738fd1498Szrj 	else
5838fd1498Szrj 	  {
5938fd1498Szrj 	    static const _Tp __q = __m / __a;
6038fd1498Szrj 	    static const _Tp __r = __m % __a;
6138fd1498Szrj 
6238fd1498Szrj 	    _Tp __t1 = __a * (__x % __q);
6338fd1498Szrj 	    _Tp __t2 = __r * (__x / __q);
6438fd1498Szrj 	    if (__t1 >= __t2)
6538fd1498Szrj 	      __x = __t1 - __t2;
6638fd1498Szrj 	    else
6738fd1498Szrj 	      __x = __m - __t2 + __t1;
6838fd1498Szrj 	  }
6938fd1498Szrj 
7038fd1498Szrj 	if (__c != 0)
7138fd1498Szrj 	  {
7238fd1498Szrj 	    const _Tp __d = __m - __x;
7338fd1498Szrj 	    if (__d > __c)
7438fd1498Szrj 	      __x += __c;
7538fd1498Szrj 	    else
7638fd1498Szrj 	      __x = __c - __d;
7738fd1498Szrj 	  }
7838fd1498Szrj 	return __x;
7938fd1498Szrj       }
8038fd1498Szrj 
8138fd1498Szrj     template<typename _InputIterator, typename _OutputIterator,
8238fd1498Szrj 	     typename _Tp>
8338fd1498Szrj       _OutputIterator
__normalize(_InputIterator __first,_InputIterator __last,_OutputIterator __result,const _Tp & __factor)8438fd1498Szrj       __normalize(_InputIterator __first, _InputIterator __last,
8538fd1498Szrj 		  _OutputIterator __result, const _Tp& __factor)
8638fd1498Szrj       {
8738fd1498Szrj 	for (; __first != __last; ++__first, ++__result)
8838fd1498Szrj 	  *__result = *__first / __factor;
8938fd1498Szrj 	return __result;
9038fd1498Szrj       }
9138fd1498Szrj 
9238fd1498Szrj   } // namespace __detail
9338fd1498Szrj 
9438fd1498Szrj   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
9538fd1498Szrj     constexpr _UIntType
9638fd1498Szrj     linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier;
9738fd1498Szrj 
9838fd1498Szrj   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
9938fd1498Szrj     constexpr _UIntType
10038fd1498Szrj     linear_congruential_engine<_UIntType, __a, __c, __m>::increment;
10138fd1498Szrj 
10238fd1498Szrj   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
10338fd1498Szrj     constexpr _UIntType
10438fd1498Szrj     linear_congruential_engine<_UIntType, __a, __c, __m>::modulus;
10538fd1498Szrj 
10638fd1498Szrj   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
10738fd1498Szrj     constexpr _UIntType
10838fd1498Szrj     linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed;
10938fd1498Szrj 
11038fd1498Szrj   /**
11138fd1498Szrj    * Seeds the LCR with integral value @p __s, adjusted so that the
11238fd1498Szrj    * ring identity is never a member of the convergence set.
11338fd1498Szrj    */
11438fd1498Szrj   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
11538fd1498Szrj     void
11638fd1498Szrj     linear_congruential_engine<_UIntType, __a, __c, __m>::
seed(result_type __s)11738fd1498Szrj     seed(result_type __s)
11838fd1498Szrj     {
11938fd1498Szrj       if ((__detail::__mod<_UIntType, __m>(__c) == 0)
12038fd1498Szrj 	  && (__detail::__mod<_UIntType, __m>(__s) == 0))
12138fd1498Szrj 	_M_x = 1;
12238fd1498Szrj       else
12338fd1498Szrj 	_M_x = __detail::__mod<_UIntType, __m>(__s);
12438fd1498Szrj     }
12538fd1498Szrj 
12638fd1498Szrj   /**
12738fd1498Szrj    * Seeds the LCR engine with a value generated by @p __q.
12838fd1498Szrj    */
12938fd1498Szrj   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
13038fd1498Szrj     template<typename _Sseq>
13138fd1498Szrj       typename std::enable_if<std::is_class<_Sseq>::value>::type
13238fd1498Szrj       linear_congruential_engine<_UIntType, __a, __c, __m>::
seed(_Sseq & __q)13338fd1498Szrj       seed(_Sseq& __q)
13438fd1498Szrj       {
13538fd1498Szrj 	const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits
13638fd1498Szrj 	                                : std::__lg(__m);
13738fd1498Szrj 	const _UIntType __k = (__k0 + 31) / 32;
13838fd1498Szrj 	uint_least32_t __arr[__k + 3];
13938fd1498Szrj 	__q.generate(__arr + 0, __arr + __k + 3);
14038fd1498Szrj 	_UIntType __factor = 1u;
14138fd1498Szrj 	_UIntType __sum = 0u;
14238fd1498Szrj 	for (size_t __j = 0; __j < __k; ++__j)
14338fd1498Szrj 	  {
14438fd1498Szrj 	    __sum += __arr[__j + 3] * __factor;
14538fd1498Szrj 	    __factor *= __detail::_Shift<_UIntType, 32>::__value;
14638fd1498Szrj 	  }
14738fd1498Szrj 	seed(__sum);
14838fd1498Szrj       }
14938fd1498Szrj 
15038fd1498Szrj   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
15138fd1498Szrj 	   typename _CharT, typename _Traits>
15238fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const linear_congruential_engine<_UIntType,__a,__c,__m> & __lcr)15338fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
15438fd1498Szrj 	       const linear_congruential_engine<_UIntType,
15538fd1498Szrj 						__a, __c, __m>& __lcr)
15638fd1498Szrj     {
15738fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
15838fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
15938fd1498Szrj 
16038fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
16138fd1498Szrj       const _CharT __fill = __os.fill();
16238fd1498Szrj       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
16338fd1498Szrj       __os.fill(__os.widen(' '));
16438fd1498Szrj 
16538fd1498Szrj       __os << __lcr._M_x;
16638fd1498Szrj 
16738fd1498Szrj       __os.flags(__flags);
16838fd1498Szrj       __os.fill(__fill);
16938fd1498Szrj       return __os;
17038fd1498Szrj     }
17138fd1498Szrj 
17238fd1498Szrj   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
17338fd1498Szrj 	   typename _CharT, typename _Traits>
17438fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,linear_congruential_engine<_UIntType,__a,__c,__m> & __lcr)17538fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
17638fd1498Szrj 	       linear_congruential_engine<_UIntType, __a, __c, __m>& __lcr)
17738fd1498Szrj     {
17838fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
17938fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
18038fd1498Szrj 
18138fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
18238fd1498Szrj       __is.flags(__ios_base::dec);
18338fd1498Szrj 
18438fd1498Szrj       __is >> __lcr._M_x;
18538fd1498Szrj 
18638fd1498Szrj       __is.flags(__flags);
18738fd1498Szrj       return __is;
18838fd1498Szrj     }
18938fd1498Szrj 
19038fd1498Szrj 
19138fd1498Szrj   template<typename _UIntType,
19238fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
19338fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
19438fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
19538fd1498Szrj 	   _UIntType __f>
19638fd1498Szrj     constexpr size_t
19738fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
19838fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::word_size;
19938fd1498Szrj 
20038fd1498Szrj   template<typename _UIntType,
20138fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
20238fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
20338fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
20438fd1498Szrj 	   _UIntType __f>
20538fd1498Szrj     constexpr size_t
20638fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
20738fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::state_size;
20838fd1498Szrj 
20938fd1498Szrj   template<typename _UIntType,
21038fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
21138fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
21238fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
21338fd1498Szrj 	   _UIntType __f>
21438fd1498Szrj     constexpr size_t
21538fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
21638fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::shift_size;
21738fd1498Szrj 
21838fd1498Szrj   template<typename _UIntType,
21938fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
22038fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
22138fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
22238fd1498Szrj 	   _UIntType __f>
22338fd1498Szrj     constexpr size_t
22438fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
22538fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::mask_bits;
22638fd1498Szrj 
22738fd1498Szrj   template<typename _UIntType,
22838fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
22938fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23038fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
23138fd1498Szrj 	   _UIntType __f>
23238fd1498Szrj     constexpr _UIntType
23338fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
23438fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::xor_mask;
23538fd1498Szrj 
23638fd1498Szrj   template<typename _UIntType,
23738fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
23838fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23938fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
24038fd1498Szrj 	   _UIntType __f>
24138fd1498Szrj     constexpr size_t
24238fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
24338fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::tempering_u;
24438fd1498Szrj 
24538fd1498Szrj   template<typename _UIntType,
24638fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
24738fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
24838fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
24938fd1498Szrj 	   _UIntType __f>
25038fd1498Szrj     constexpr _UIntType
25138fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
25238fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::tempering_d;
25338fd1498Szrj 
25438fd1498Szrj   template<typename _UIntType,
25538fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
25638fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
25738fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
25838fd1498Szrj 	   _UIntType __f>
25938fd1498Szrj     constexpr size_t
26038fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
26138fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::tempering_s;
26238fd1498Szrj 
26338fd1498Szrj   template<typename _UIntType,
26438fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
26538fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
26638fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
26738fd1498Szrj 	   _UIntType __f>
26838fd1498Szrj     constexpr _UIntType
26938fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
27038fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::tempering_b;
27138fd1498Szrj 
27238fd1498Szrj   template<typename _UIntType,
27338fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
27438fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
27538fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
27638fd1498Szrj 	   _UIntType __f>
27738fd1498Szrj     constexpr size_t
27838fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
27938fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::tempering_t;
28038fd1498Szrj 
28138fd1498Szrj   template<typename _UIntType,
28238fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
28338fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
28438fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
28538fd1498Szrj 	   _UIntType __f>
28638fd1498Szrj     constexpr _UIntType
28738fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
28838fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::tempering_c;
28938fd1498Szrj 
29038fd1498Szrj   template<typename _UIntType,
29138fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
29238fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
29338fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
29438fd1498Szrj 	   _UIntType __f>
29538fd1498Szrj     constexpr size_t
29638fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
29738fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::tempering_l;
29838fd1498Szrj 
29938fd1498Szrj   template<typename _UIntType,
30038fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
30138fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
30238fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
30338fd1498Szrj 	   _UIntType __f>
30438fd1498Szrj     constexpr _UIntType
30538fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
30638fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::
30738fd1498Szrj                                               initialization_multiplier;
30838fd1498Szrj 
30938fd1498Szrj   template<typename _UIntType,
31038fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
31138fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
31238fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
31338fd1498Szrj 	   _UIntType __f>
31438fd1498Szrj     constexpr _UIntType
31538fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
31638fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::default_seed;
31738fd1498Szrj 
31838fd1498Szrj   template<typename _UIntType,
31938fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
32038fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
32138fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
32238fd1498Szrj 	   _UIntType __f>
32338fd1498Szrj     void
32438fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
32538fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::
seed(result_type __sd)32638fd1498Szrj     seed(result_type __sd)
32738fd1498Szrj     {
32838fd1498Szrj       _M_x[0] = __detail::__mod<_UIntType,
32938fd1498Szrj 	__detail::_Shift<_UIntType, __w>::__value>(__sd);
33038fd1498Szrj 
33138fd1498Szrj       for (size_t __i = 1; __i < state_size; ++__i)
33238fd1498Szrj 	{
33338fd1498Szrj 	  _UIntType __x = _M_x[__i - 1];
33438fd1498Szrj 	  __x ^= __x >> (__w - 2);
33538fd1498Szrj 	  __x *= __f;
33638fd1498Szrj 	  __x += __detail::__mod<_UIntType, __n>(__i);
33738fd1498Szrj 	  _M_x[__i] = __detail::__mod<_UIntType,
33838fd1498Szrj 	    __detail::_Shift<_UIntType, __w>::__value>(__x);
33938fd1498Szrj 	}
34038fd1498Szrj       _M_p = state_size;
34138fd1498Szrj     }
34238fd1498Szrj 
34338fd1498Szrj   template<typename _UIntType,
34438fd1498Szrj 	   size_t __w, size_t __n, size_t __m, size_t __r,
34538fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
34638fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
34738fd1498Szrj 	   _UIntType __f>
34838fd1498Szrj     template<typename _Sseq>
34938fd1498Szrj       typename std::enable_if<std::is_class<_Sseq>::value>::type
35038fd1498Szrj       mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
35138fd1498Szrj 			      __s, __b, __t, __c, __l, __f>::
seed(_Sseq & __q)35238fd1498Szrj       seed(_Sseq& __q)
35338fd1498Szrj       {
35438fd1498Szrj 	const _UIntType __upper_mask = (~_UIntType()) << __r;
35538fd1498Szrj 	const size_t __k = (__w + 31) / 32;
35638fd1498Szrj 	uint_least32_t __arr[__n * __k];
35738fd1498Szrj 	__q.generate(__arr + 0, __arr + __n * __k);
35838fd1498Szrj 
35938fd1498Szrj 	bool __zero = true;
36038fd1498Szrj 	for (size_t __i = 0; __i < state_size; ++__i)
36138fd1498Szrj 	  {
36238fd1498Szrj 	    _UIntType __factor = 1u;
36338fd1498Szrj 	    _UIntType __sum = 0u;
36438fd1498Szrj 	    for (size_t __j = 0; __j < __k; ++__j)
36538fd1498Szrj 	      {
36638fd1498Szrj 		__sum += __arr[__k * __i + __j] * __factor;
36738fd1498Szrj 		__factor *= __detail::_Shift<_UIntType, 32>::__value;
36838fd1498Szrj 	      }
36938fd1498Szrj 	    _M_x[__i] = __detail::__mod<_UIntType,
37038fd1498Szrj 	      __detail::_Shift<_UIntType, __w>::__value>(__sum);
37138fd1498Szrj 
37238fd1498Szrj 	    if (__zero)
37338fd1498Szrj 	      {
37438fd1498Szrj 		if (__i == 0)
37538fd1498Szrj 		  {
37638fd1498Szrj 		    if ((_M_x[0] & __upper_mask) != 0u)
37738fd1498Szrj 		      __zero = false;
37838fd1498Szrj 		  }
37938fd1498Szrj 		else if (_M_x[__i] != 0u)
38038fd1498Szrj 		  __zero = false;
38138fd1498Szrj 	      }
38238fd1498Szrj 	  }
38338fd1498Szrj         if (__zero)
38438fd1498Szrj           _M_x[0] = __detail::_Shift<_UIntType, __w - 1>::__value;
38538fd1498Szrj 	_M_p = state_size;
38638fd1498Szrj       }
38738fd1498Szrj 
38838fd1498Szrj   template<typename _UIntType, size_t __w,
38938fd1498Szrj 	   size_t __n, size_t __m, size_t __r,
39038fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
39138fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
39238fd1498Szrj 	   _UIntType __f>
39338fd1498Szrj     void
39438fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
39538fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::
_M_gen_rand(void)39638fd1498Szrj     _M_gen_rand(void)
39738fd1498Szrj     {
39838fd1498Szrj       const _UIntType __upper_mask = (~_UIntType()) << __r;
39938fd1498Szrj       const _UIntType __lower_mask = ~__upper_mask;
40038fd1498Szrj 
40138fd1498Szrj       for (size_t __k = 0; __k < (__n - __m); ++__k)
40238fd1498Szrj         {
40338fd1498Szrj 	  _UIntType __y = ((_M_x[__k] & __upper_mask)
40438fd1498Szrj 			   | (_M_x[__k + 1] & __lower_mask));
40538fd1498Szrj 	  _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1)
40638fd1498Szrj 		       ^ ((__y & 0x01) ? __a : 0));
40738fd1498Szrj         }
40838fd1498Szrj 
40938fd1498Szrj       for (size_t __k = (__n - __m); __k < (__n - 1); ++__k)
41038fd1498Szrj 	{
41138fd1498Szrj 	  _UIntType __y = ((_M_x[__k] & __upper_mask)
41238fd1498Szrj 			   | (_M_x[__k + 1] & __lower_mask));
41338fd1498Szrj 	  _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1)
41438fd1498Szrj 		       ^ ((__y & 0x01) ? __a : 0));
41538fd1498Szrj 	}
41638fd1498Szrj 
41738fd1498Szrj       _UIntType __y = ((_M_x[__n - 1] & __upper_mask)
41838fd1498Szrj 		       | (_M_x[0] & __lower_mask));
41938fd1498Szrj       _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1)
42038fd1498Szrj 		       ^ ((__y & 0x01) ? __a : 0));
42138fd1498Szrj       _M_p = 0;
42238fd1498Szrj     }
42338fd1498Szrj 
42438fd1498Szrj   template<typename _UIntType, size_t __w,
42538fd1498Szrj 	   size_t __n, size_t __m, size_t __r,
42638fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
42738fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
42838fd1498Szrj 	   _UIntType __f>
42938fd1498Szrj     void
43038fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
43138fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::
discard(unsigned long long __z)43238fd1498Szrj     discard(unsigned long long __z)
43338fd1498Szrj     {
43438fd1498Szrj       while (__z > state_size - _M_p)
43538fd1498Szrj 	{
43638fd1498Szrj 	  __z -= state_size - _M_p;
43738fd1498Szrj 	  _M_gen_rand();
43838fd1498Szrj 	}
43938fd1498Szrj       _M_p += __z;
44038fd1498Szrj     }
44138fd1498Szrj 
44238fd1498Szrj   template<typename _UIntType, size_t __w,
44338fd1498Szrj 	   size_t __n, size_t __m, size_t __r,
44438fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
44538fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
44638fd1498Szrj 	   _UIntType __f>
44738fd1498Szrj     typename
44838fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
44938fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::result_type
45038fd1498Szrj     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
45138fd1498Szrj 			    __s, __b, __t, __c, __l, __f>::
operator ()()45238fd1498Szrj     operator()()
45338fd1498Szrj     {
45438fd1498Szrj       // Reload the vector - cost is O(n) amortized over n calls.
45538fd1498Szrj       if (_M_p >= state_size)
45638fd1498Szrj 	_M_gen_rand();
45738fd1498Szrj 
45838fd1498Szrj       // Calculate o(x(i)).
45938fd1498Szrj       result_type __z = _M_x[_M_p++];
46038fd1498Szrj       __z ^= (__z >> __u) & __d;
46138fd1498Szrj       __z ^= (__z << __s) & __b;
46238fd1498Szrj       __z ^= (__z << __t) & __c;
46338fd1498Szrj       __z ^= (__z >> __l);
46438fd1498Szrj 
46538fd1498Szrj       return __z;
46638fd1498Szrj     }
46738fd1498Szrj 
46838fd1498Szrj   template<typename _UIntType, size_t __w,
46938fd1498Szrj 	   size_t __n, size_t __m, size_t __r,
47038fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
47138fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
47238fd1498Szrj 	   _UIntType __f, typename _CharT, typename _Traits>
47338fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const mersenne_twister_engine<_UIntType,__w,__n,__m,__r,__a,__u,__d,__s,__b,__t,__c,__l,__f> & __x)47438fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
47538fd1498Szrj 	       const mersenne_twister_engine<_UIntType, __w, __n, __m,
47638fd1498Szrj 	       __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x)
47738fd1498Szrj     {
47838fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
47938fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
48038fd1498Szrj 
48138fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
48238fd1498Szrj       const _CharT __fill = __os.fill();
48338fd1498Szrj       const _CharT __space = __os.widen(' ');
48438fd1498Szrj       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
48538fd1498Szrj       __os.fill(__space);
48638fd1498Szrj 
48738fd1498Szrj       for (size_t __i = 0; __i < __n; ++__i)
48838fd1498Szrj 	__os << __x._M_x[__i] << __space;
48938fd1498Szrj       __os << __x._M_p;
49038fd1498Szrj 
49138fd1498Szrj       __os.flags(__flags);
49238fd1498Szrj       __os.fill(__fill);
49338fd1498Szrj       return __os;
49438fd1498Szrj     }
49538fd1498Szrj 
49638fd1498Szrj   template<typename _UIntType, size_t __w,
49738fd1498Szrj 	   size_t __n, size_t __m, size_t __r,
49838fd1498Szrj 	   _UIntType __a, size_t __u, _UIntType __d, size_t __s,
49938fd1498Szrj 	   _UIntType __b, size_t __t, _UIntType __c, size_t __l,
50038fd1498Szrj 	   _UIntType __f, typename _CharT, typename _Traits>
50138fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,mersenne_twister_engine<_UIntType,__w,__n,__m,__r,__a,__u,__d,__s,__b,__t,__c,__l,__f> & __x)50238fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
50338fd1498Szrj 	       mersenne_twister_engine<_UIntType, __w, __n, __m,
50438fd1498Szrj 	       __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x)
50538fd1498Szrj     {
50638fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
50738fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
50838fd1498Szrj 
50938fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
51038fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
51138fd1498Szrj 
51238fd1498Szrj       for (size_t __i = 0; __i < __n; ++__i)
51338fd1498Szrj 	__is >> __x._M_x[__i];
51438fd1498Szrj       __is >> __x._M_p;
51538fd1498Szrj 
51638fd1498Szrj       __is.flags(__flags);
51738fd1498Szrj       return __is;
51838fd1498Szrj     }
51938fd1498Szrj 
52038fd1498Szrj 
52138fd1498Szrj   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
52238fd1498Szrj     constexpr size_t
52338fd1498Szrj     subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size;
52438fd1498Szrj 
52538fd1498Szrj   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
52638fd1498Szrj     constexpr size_t
52738fd1498Szrj     subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag;
52838fd1498Szrj 
52938fd1498Szrj   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
53038fd1498Szrj     constexpr size_t
53138fd1498Szrj     subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag;
53238fd1498Szrj 
53338fd1498Szrj   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
53438fd1498Szrj     constexpr _UIntType
53538fd1498Szrj     subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed;
53638fd1498Szrj 
53738fd1498Szrj   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
53838fd1498Szrj     void
53938fd1498Szrj     subtract_with_carry_engine<_UIntType, __w, __s, __r>::
seed(result_type __value)54038fd1498Szrj     seed(result_type __value)
54138fd1498Szrj     {
54238fd1498Szrj       std::linear_congruential_engine<result_type, 40014u, 0u, 2147483563u>
54338fd1498Szrj 	__lcg(__value == 0u ? default_seed : __value);
54438fd1498Szrj 
54538fd1498Szrj       const size_t __n = (__w + 31) / 32;
54638fd1498Szrj 
54738fd1498Szrj       for (size_t __i = 0; __i < long_lag; ++__i)
54838fd1498Szrj 	{
54938fd1498Szrj 	  _UIntType __sum = 0u;
55038fd1498Szrj 	  _UIntType __factor = 1u;
55138fd1498Szrj 	  for (size_t __j = 0; __j < __n; ++__j)
55238fd1498Szrj 	    {
55338fd1498Szrj 	      __sum += __detail::__mod<uint_least32_t,
55438fd1498Szrj 		       __detail::_Shift<uint_least32_t, 32>::__value>
55538fd1498Szrj 			 (__lcg()) * __factor;
55638fd1498Szrj 	      __factor *= __detail::_Shift<_UIntType, 32>::__value;
55738fd1498Szrj 	    }
55838fd1498Szrj 	  _M_x[__i] = __detail::__mod<_UIntType,
55938fd1498Szrj 	    __detail::_Shift<_UIntType, __w>::__value>(__sum);
56038fd1498Szrj 	}
56138fd1498Szrj       _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
56238fd1498Szrj       _M_p = 0;
56338fd1498Szrj     }
56438fd1498Szrj 
56538fd1498Szrj   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
56638fd1498Szrj     template<typename _Sseq>
56738fd1498Szrj       typename std::enable_if<std::is_class<_Sseq>::value>::type
56838fd1498Szrj       subtract_with_carry_engine<_UIntType, __w, __s, __r>::
seed(_Sseq & __q)56938fd1498Szrj       seed(_Sseq& __q)
57038fd1498Szrj       {
57138fd1498Szrj 	const size_t __k = (__w + 31) / 32;
57238fd1498Szrj 	uint_least32_t __arr[__r * __k];
57338fd1498Szrj 	__q.generate(__arr + 0, __arr + __r * __k);
57438fd1498Szrj 
57538fd1498Szrj 	for (size_t __i = 0; __i < long_lag; ++__i)
57638fd1498Szrj 	  {
57738fd1498Szrj 	    _UIntType __sum = 0u;
57838fd1498Szrj 	    _UIntType __factor = 1u;
57938fd1498Szrj 	    for (size_t __j = 0; __j < __k; ++__j)
58038fd1498Szrj 	      {
58138fd1498Szrj 		__sum += __arr[__k * __i + __j] * __factor;
58238fd1498Szrj 		__factor *= __detail::_Shift<_UIntType, 32>::__value;
58338fd1498Szrj 	      }
58438fd1498Szrj 	    _M_x[__i] = __detail::__mod<_UIntType,
58538fd1498Szrj 	      __detail::_Shift<_UIntType, __w>::__value>(__sum);
58638fd1498Szrj 	  }
58738fd1498Szrj 	_M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
58838fd1498Szrj 	_M_p = 0;
58938fd1498Szrj       }
59038fd1498Szrj 
59138fd1498Szrj   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
59238fd1498Szrj     typename subtract_with_carry_engine<_UIntType, __w, __s, __r>::
59338fd1498Szrj 	     result_type
59438fd1498Szrj     subtract_with_carry_engine<_UIntType, __w, __s, __r>::
operator ()()59538fd1498Szrj     operator()()
59638fd1498Szrj     {
59738fd1498Szrj       // Derive short lag index from current index.
59838fd1498Szrj       long __ps = _M_p - short_lag;
59938fd1498Szrj       if (__ps < 0)
60038fd1498Szrj 	__ps += long_lag;
60138fd1498Szrj 
60238fd1498Szrj       // Calculate new x(i) without overflow or division.
60338fd1498Szrj       // NB: Thanks to the requirements for _UIntType, _M_x[_M_p] + _M_carry
60438fd1498Szrj       // cannot overflow.
60538fd1498Szrj       _UIntType __xi;
60638fd1498Szrj       if (_M_x[__ps] >= _M_x[_M_p] + _M_carry)
60738fd1498Szrj 	{
60838fd1498Szrj 	  __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry;
60938fd1498Szrj 	  _M_carry = 0;
61038fd1498Szrj 	}
61138fd1498Szrj       else
61238fd1498Szrj 	{
61338fd1498Szrj 	  __xi = (__detail::_Shift<_UIntType, __w>::__value
61438fd1498Szrj 		  - _M_x[_M_p] - _M_carry + _M_x[__ps]);
61538fd1498Szrj 	  _M_carry = 1;
61638fd1498Szrj 	}
61738fd1498Szrj       _M_x[_M_p] = __xi;
61838fd1498Szrj 
61938fd1498Szrj       // Adjust current index to loop around in ring buffer.
62038fd1498Szrj       if (++_M_p >= long_lag)
62138fd1498Szrj 	_M_p = 0;
62238fd1498Szrj 
62338fd1498Szrj       return __xi;
62438fd1498Szrj     }
62538fd1498Szrj 
62638fd1498Szrj   template<typename _UIntType, size_t __w, size_t __s, size_t __r,
62738fd1498Szrj 	   typename _CharT, typename _Traits>
62838fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const subtract_with_carry_engine<_UIntType,__w,__s,__r> & __x)62938fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
63038fd1498Szrj 	       const subtract_with_carry_engine<_UIntType,
63138fd1498Szrj 						__w, __s, __r>& __x)
63238fd1498Szrj     {
63338fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
63438fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
63538fd1498Szrj 
63638fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
63738fd1498Szrj       const _CharT __fill = __os.fill();
63838fd1498Szrj       const _CharT __space = __os.widen(' ');
63938fd1498Szrj       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
64038fd1498Szrj       __os.fill(__space);
64138fd1498Szrj 
64238fd1498Szrj       for (size_t __i = 0; __i < __r; ++__i)
64338fd1498Szrj 	__os << __x._M_x[__i] << __space;
64438fd1498Szrj       __os << __x._M_carry << __space << __x._M_p;
64538fd1498Szrj 
64638fd1498Szrj       __os.flags(__flags);
64738fd1498Szrj       __os.fill(__fill);
64838fd1498Szrj       return __os;
64938fd1498Szrj     }
65038fd1498Szrj 
65138fd1498Szrj   template<typename _UIntType, size_t __w, size_t __s, size_t __r,
65238fd1498Szrj 	   typename _CharT, typename _Traits>
65338fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,subtract_with_carry_engine<_UIntType,__w,__s,__r> & __x)65438fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
65538fd1498Szrj 	       subtract_with_carry_engine<_UIntType, __w, __s, __r>& __x)
65638fd1498Szrj     {
65738fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __istream_type;
65838fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
65938fd1498Szrj 
66038fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
66138fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
66238fd1498Szrj 
66338fd1498Szrj       for (size_t __i = 0; __i < __r; ++__i)
66438fd1498Szrj 	__is >> __x._M_x[__i];
66538fd1498Szrj       __is >> __x._M_carry;
66638fd1498Szrj       __is >> __x._M_p;
66738fd1498Szrj 
66838fd1498Szrj       __is.flags(__flags);
66938fd1498Szrj       return __is;
67038fd1498Szrj     }
67138fd1498Szrj 
67238fd1498Szrj 
67338fd1498Szrj   template<typename _RandomNumberEngine, size_t __p, size_t __r>
67438fd1498Szrj     constexpr size_t
67538fd1498Szrj     discard_block_engine<_RandomNumberEngine, __p, __r>::block_size;
67638fd1498Szrj 
67738fd1498Szrj   template<typename _RandomNumberEngine, size_t __p, size_t __r>
67838fd1498Szrj     constexpr size_t
67938fd1498Szrj     discard_block_engine<_RandomNumberEngine, __p, __r>::used_block;
68038fd1498Szrj 
68138fd1498Szrj   template<typename _RandomNumberEngine, size_t __p, size_t __r>
68238fd1498Szrj     typename discard_block_engine<_RandomNumberEngine,
68338fd1498Szrj 			   __p, __r>::result_type
68438fd1498Szrj     discard_block_engine<_RandomNumberEngine, __p, __r>::
operator ()()68538fd1498Szrj     operator()()
68638fd1498Szrj     {
68738fd1498Szrj       if (_M_n >= used_block)
68838fd1498Szrj 	{
68938fd1498Szrj 	  _M_b.discard(block_size - _M_n);
69038fd1498Szrj 	  _M_n = 0;
69138fd1498Szrj 	}
69238fd1498Szrj       ++_M_n;
69338fd1498Szrj       return _M_b();
69438fd1498Szrj     }
69538fd1498Szrj 
69638fd1498Szrj   template<typename _RandomNumberEngine, size_t __p, size_t __r,
69738fd1498Szrj 	   typename _CharT, typename _Traits>
69838fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const discard_block_engine<_RandomNumberEngine,__p,__r> & __x)69938fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
70038fd1498Szrj 	       const discard_block_engine<_RandomNumberEngine,
70138fd1498Szrj 	       __p, __r>& __x)
70238fd1498Szrj     {
70338fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
70438fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
70538fd1498Szrj 
70638fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
70738fd1498Szrj       const _CharT __fill = __os.fill();
70838fd1498Szrj       const _CharT __space = __os.widen(' ');
70938fd1498Szrj       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
71038fd1498Szrj       __os.fill(__space);
71138fd1498Szrj 
71238fd1498Szrj       __os << __x.base() << __space << __x._M_n;
71338fd1498Szrj 
71438fd1498Szrj       __os.flags(__flags);
71538fd1498Szrj       __os.fill(__fill);
71638fd1498Szrj       return __os;
71738fd1498Szrj     }
71838fd1498Szrj 
71938fd1498Szrj   template<typename _RandomNumberEngine, size_t __p, size_t __r,
72038fd1498Szrj 	   typename _CharT, typename _Traits>
72138fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,discard_block_engine<_RandomNumberEngine,__p,__r> & __x)72238fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
72338fd1498Szrj 	       discard_block_engine<_RandomNumberEngine, __p, __r>& __x)
72438fd1498Szrj     {
72538fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
72638fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
72738fd1498Szrj 
72838fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
72938fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
73038fd1498Szrj 
73138fd1498Szrj       __is >> __x._M_b >> __x._M_n;
73238fd1498Szrj 
73338fd1498Szrj       __is.flags(__flags);
73438fd1498Szrj       return __is;
73538fd1498Szrj     }
73638fd1498Szrj 
73738fd1498Szrj 
73838fd1498Szrj   template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
73938fd1498Szrj     typename independent_bits_engine<_RandomNumberEngine, __w, _UIntType>::
74038fd1498Szrj       result_type
74138fd1498Szrj     independent_bits_engine<_RandomNumberEngine, __w, _UIntType>::
operator ()()74238fd1498Szrj     operator()()
74338fd1498Szrj     {
74438fd1498Szrj       typedef typename _RandomNumberEngine::result_type _Eresult_type;
74538fd1498Szrj       const _Eresult_type __r
74638fd1498Szrj 	= (_M_b.max() - _M_b.min() < std::numeric_limits<_Eresult_type>::max()
74738fd1498Szrj 	   ? _M_b.max() - _M_b.min() + 1 : 0);
74838fd1498Szrj       const unsigned __edig = std::numeric_limits<_Eresult_type>::digits;
74938fd1498Szrj       const unsigned __m = __r ? std::__lg(__r) : __edig;
75038fd1498Szrj 
75138fd1498Szrj       typedef typename std::common_type<_Eresult_type, result_type>::type
75238fd1498Szrj 	__ctype;
75338fd1498Szrj       const unsigned __cdig = std::numeric_limits<__ctype>::digits;
75438fd1498Szrj 
75538fd1498Szrj       unsigned __n, __n0;
75638fd1498Szrj       __ctype __s0, __s1, __y0, __y1;
75738fd1498Szrj 
75838fd1498Szrj       for (size_t __i = 0; __i < 2; ++__i)
75938fd1498Szrj 	{
76038fd1498Szrj 	  __n = (__w + __m - 1) / __m + __i;
76138fd1498Szrj 	  __n0 = __n - __w % __n;
76238fd1498Szrj 	  const unsigned __w0 = __w / __n;  // __w0 <= __m
76338fd1498Szrj 
76438fd1498Szrj 	  __s0 = 0;
76538fd1498Szrj 	  __s1 = 0;
76638fd1498Szrj 	  if (__w0 < __cdig)
76738fd1498Szrj 	    {
76838fd1498Szrj 	      __s0 = __ctype(1) << __w0;
76938fd1498Szrj 	      __s1 = __s0 << 1;
77038fd1498Szrj 	    }
77138fd1498Szrj 
77238fd1498Szrj 	  __y0 = 0;
77338fd1498Szrj 	  __y1 = 0;
77438fd1498Szrj 	  if (__r)
77538fd1498Szrj 	    {
77638fd1498Szrj 	      __y0 = __s0 * (__r / __s0);
77738fd1498Szrj 	      if (__s1)
77838fd1498Szrj 		__y1 = __s1 * (__r / __s1);
77938fd1498Szrj 
78038fd1498Szrj 	      if (__r - __y0 <= __y0 / __n)
78138fd1498Szrj 		break;
78238fd1498Szrj 	    }
78338fd1498Szrj 	  else
78438fd1498Szrj 	    break;
78538fd1498Szrj 	}
78638fd1498Szrj 
78738fd1498Szrj       result_type __sum = 0;
78838fd1498Szrj       for (size_t __k = 0; __k < __n0; ++__k)
78938fd1498Szrj 	{
79038fd1498Szrj 	  __ctype __u;
79138fd1498Szrj 	  do
79238fd1498Szrj 	    __u = _M_b() - _M_b.min();
79338fd1498Szrj 	  while (__y0 && __u >= __y0);
79438fd1498Szrj 	  __sum = __s0 * __sum + (__s0 ? __u % __s0 : __u);
79538fd1498Szrj 	}
79638fd1498Szrj       for (size_t __k = __n0; __k < __n; ++__k)
79738fd1498Szrj 	{
79838fd1498Szrj 	  __ctype __u;
79938fd1498Szrj 	  do
80038fd1498Szrj 	    __u = _M_b() - _M_b.min();
80138fd1498Szrj 	  while (__y1 && __u >= __y1);
80238fd1498Szrj 	  __sum = __s1 * __sum + (__s1 ? __u % __s1 : __u);
80338fd1498Szrj 	}
80438fd1498Szrj       return __sum;
80538fd1498Szrj     }
80638fd1498Szrj 
80738fd1498Szrj 
80838fd1498Szrj   template<typename _RandomNumberEngine, size_t __k>
80938fd1498Szrj     constexpr size_t
81038fd1498Szrj     shuffle_order_engine<_RandomNumberEngine, __k>::table_size;
81138fd1498Szrj 
81238fd1498Szrj   template<typename _RandomNumberEngine, size_t __k>
81338fd1498Szrj     typename shuffle_order_engine<_RandomNumberEngine, __k>::result_type
81438fd1498Szrj     shuffle_order_engine<_RandomNumberEngine, __k>::
operator ()()81538fd1498Szrj     operator()()
81638fd1498Szrj     {
81738fd1498Szrj       size_t __j = __k * ((_M_y - _M_b.min())
81838fd1498Szrj 			  / (_M_b.max() - _M_b.min() + 1.0L));
81938fd1498Szrj       _M_y = _M_v[__j];
82038fd1498Szrj       _M_v[__j] = _M_b();
82138fd1498Szrj 
82238fd1498Szrj       return _M_y;
82338fd1498Szrj     }
82438fd1498Szrj 
82538fd1498Szrj   template<typename _RandomNumberEngine, size_t __k,
82638fd1498Szrj 	   typename _CharT, typename _Traits>
82738fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const shuffle_order_engine<_RandomNumberEngine,__k> & __x)82838fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
82938fd1498Szrj 	       const shuffle_order_engine<_RandomNumberEngine, __k>& __x)
83038fd1498Szrj     {
83138fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
83238fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
83338fd1498Szrj 
83438fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
83538fd1498Szrj       const _CharT __fill = __os.fill();
83638fd1498Szrj       const _CharT __space = __os.widen(' ');
83738fd1498Szrj       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
83838fd1498Szrj       __os.fill(__space);
83938fd1498Szrj 
84038fd1498Szrj       __os << __x.base();
84138fd1498Szrj       for (size_t __i = 0; __i < __k; ++__i)
84238fd1498Szrj 	__os << __space << __x._M_v[__i];
84338fd1498Szrj       __os << __space << __x._M_y;
84438fd1498Szrj 
84538fd1498Szrj       __os.flags(__flags);
84638fd1498Szrj       __os.fill(__fill);
84738fd1498Szrj       return __os;
84838fd1498Szrj     }
84938fd1498Szrj 
85038fd1498Szrj   template<typename _RandomNumberEngine, size_t __k,
85138fd1498Szrj 	   typename _CharT, typename _Traits>
85238fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,shuffle_order_engine<_RandomNumberEngine,__k> & __x)85338fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
85438fd1498Szrj 	       shuffle_order_engine<_RandomNumberEngine, __k>& __x)
85538fd1498Szrj     {
85638fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
85738fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
85838fd1498Szrj 
85938fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
86038fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
86138fd1498Szrj 
86238fd1498Szrj       __is >> __x._M_b;
86338fd1498Szrj       for (size_t __i = 0; __i < __k; ++__i)
86438fd1498Szrj 	__is >> __x._M_v[__i];
86538fd1498Szrj       __is >> __x._M_y;
86638fd1498Szrj 
86738fd1498Szrj       __is.flags(__flags);
86838fd1498Szrj       return __is;
86938fd1498Szrj     }
87038fd1498Szrj 
87138fd1498Szrj 
87238fd1498Szrj   template<typename _IntType, typename _CharT, typename _Traits>
87338fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const uniform_int_distribution<_IntType> & __x)87438fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
87538fd1498Szrj 	       const uniform_int_distribution<_IntType>& __x)
87638fd1498Szrj     {
87738fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
87838fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
87938fd1498Szrj 
88038fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
88138fd1498Szrj       const _CharT __fill = __os.fill();
88238fd1498Szrj       const _CharT __space = __os.widen(' ');
88338fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
88438fd1498Szrj       __os.fill(__space);
88538fd1498Szrj 
88638fd1498Szrj       __os << __x.a() << __space << __x.b();
88738fd1498Szrj 
88838fd1498Szrj       __os.flags(__flags);
88938fd1498Szrj       __os.fill(__fill);
89038fd1498Szrj       return __os;
89138fd1498Szrj     }
89238fd1498Szrj 
89338fd1498Szrj   template<typename _IntType, typename _CharT, typename _Traits>
89438fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,uniform_int_distribution<_IntType> & __x)89538fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
89638fd1498Szrj 	       uniform_int_distribution<_IntType>& __x)
89738fd1498Szrj     {
89838fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
89938fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
90038fd1498Szrj 
90138fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
90238fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
90338fd1498Szrj 
90438fd1498Szrj       _IntType __a, __b;
90538fd1498Szrj       __is >> __a >> __b;
90638fd1498Szrj       __x.param(typename uniform_int_distribution<_IntType>::
90738fd1498Szrj 		param_type(__a, __b));
90838fd1498Szrj 
90938fd1498Szrj       __is.flags(__flags);
91038fd1498Szrj       return __is;
91138fd1498Szrj     }
91238fd1498Szrj 
91338fd1498Szrj 
91438fd1498Szrj   template<typename _RealType>
91538fd1498Szrj     template<typename _ForwardIterator,
91638fd1498Szrj 	     typename _UniformRandomNumberGenerator>
91738fd1498Szrj       void
91838fd1498Szrj       uniform_real_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)91938fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
92038fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
92138fd1498Szrj 		      const param_type& __p)
92238fd1498Szrj       {
92338fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
92438fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
92538fd1498Szrj 	  __aurng(__urng);
92638fd1498Szrj 	auto __range = __p.b() - __p.a();
92738fd1498Szrj 	while (__f != __t)
92838fd1498Szrj 	  *__f++ = __aurng() * __range + __p.a();
92938fd1498Szrj       }
93038fd1498Szrj 
93138fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
93238fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const uniform_real_distribution<_RealType> & __x)93338fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
93438fd1498Szrj 	       const uniform_real_distribution<_RealType>& __x)
93538fd1498Szrj     {
93638fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
93738fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
93838fd1498Szrj 
93938fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
94038fd1498Szrj       const _CharT __fill = __os.fill();
94138fd1498Szrj       const std::streamsize __precision = __os.precision();
94238fd1498Szrj       const _CharT __space = __os.widen(' ');
94338fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
94438fd1498Szrj       __os.fill(__space);
94538fd1498Szrj       __os.precision(std::numeric_limits<_RealType>::max_digits10);
94638fd1498Szrj 
94738fd1498Szrj       __os << __x.a() << __space << __x.b();
94838fd1498Szrj 
94938fd1498Szrj       __os.flags(__flags);
95038fd1498Szrj       __os.fill(__fill);
95138fd1498Szrj       __os.precision(__precision);
95238fd1498Szrj       return __os;
95338fd1498Szrj     }
95438fd1498Szrj 
95538fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
95638fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,uniform_real_distribution<_RealType> & __x)95738fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
95838fd1498Szrj 	       uniform_real_distribution<_RealType>& __x)
95938fd1498Szrj     {
96038fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
96138fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
96238fd1498Szrj 
96338fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
96438fd1498Szrj       __is.flags(__ios_base::skipws);
96538fd1498Szrj 
96638fd1498Szrj       _RealType __a, __b;
96738fd1498Szrj       __is >> __a >> __b;
96838fd1498Szrj       __x.param(typename uniform_real_distribution<_RealType>::
96938fd1498Szrj 		param_type(__a, __b));
97038fd1498Szrj 
97138fd1498Szrj       __is.flags(__flags);
97238fd1498Szrj       return __is;
97338fd1498Szrj     }
97438fd1498Szrj 
97538fd1498Szrj 
97638fd1498Szrj   template<typename _ForwardIterator,
97738fd1498Szrj 	   typename _UniformRandomNumberGenerator>
97838fd1498Szrj     void
97938fd1498Szrj     std::bernoulli_distribution::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)98038fd1498Szrj     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
98138fd1498Szrj 		    _UniformRandomNumberGenerator& __urng,
98238fd1498Szrj 		    const param_type& __p)
98338fd1498Szrj     {
98438fd1498Szrj       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
98538fd1498Szrj       __detail::_Adaptor<_UniformRandomNumberGenerator, double>
98638fd1498Szrj 	__aurng(__urng);
98738fd1498Szrj       auto __limit = __p.p() * (__aurng.max() - __aurng.min());
98838fd1498Szrj 
98938fd1498Szrj       while (__f != __t)
99038fd1498Szrj 	*__f++ = (__aurng() - __aurng.min()) < __limit;
99138fd1498Szrj     }
99238fd1498Szrj 
99338fd1498Szrj   template<typename _CharT, typename _Traits>
99438fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const bernoulli_distribution & __x)99538fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
99638fd1498Szrj 	       const bernoulli_distribution& __x)
99738fd1498Szrj     {
99838fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
99938fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
100038fd1498Szrj 
100138fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
100238fd1498Szrj       const _CharT __fill = __os.fill();
100338fd1498Szrj       const std::streamsize __precision = __os.precision();
100438fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
100538fd1498Szrj       __os.fill(__os.widen(' '));
100638fd1498Szrj       __os.precision(std::numeric_limits<double>::max_digits10);
100738fd1498Szrj 
100838fd1498Szrj       __os << __x.p();
100938fd1498Szrj 
101038fd1498Szrj       __os.flags(__flags);
101138fd1498Szrj       __os.fill(__fill);
101238fd1498Szrj       __os.precision(__precision);
101338fd1498Szrj       return __os;
101438fd1498Szrj     }
101538fd1498Szrj 
101638fd1498Szrj 
101738fd1498Szrj   template<typename _IntType>
101838fd1498Szrj     template<typename _UniformRandomNumberGenerator>
101938fd1498Szrj       typename geometric_distribution<_IntType>::result_type
102038fd1498Szrj       geometric_distribution<_IntType>::
operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)102138fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng,
102238fd1498Szrj 		 const param_type& __param)
102338fd1498Szrj       {
102438fd1498Szrj 	// About the epsilon thing see this thread:
102538fd1498Szrj 	// http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html
102638fd1498Szrj 	const double __naf =
102738fd1498Szrj 	  (1 - std::numeric_limits<double>::epsilon()) / 2;
102838fd1498Szrj 	// The largest _RealType convertible to _IntType.
102938fd1498Szrj 	const double __thr =
103038fd1498Szrj 	  std::numeric_limits<_IntType>::max() + __naf;
103138fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
103238fd1498Szrj 	  __aurng(__urng);
103338fd1498Szrj 
103438fd1498Szrj 	double __cand;
103538fd1498Szrj 	do
103638fd1498Szrj 	  __cand = std::floor(std::log(1.0 - __aurng()) / __param._M_log_1_p);
103738fd1498Szrj 	while (__cand >= __thr);
103838fd1498Szrj 
103938fd1498Szrj 	return result_type(__cand + __naf);
104038fd1498Szrj       }
104138fd1498Szrj 
104238fd1498Szrj   template<typename _IntType>
104338fd1498Szrj     template<typename _ForwardIterator,
104438fd1498Szrj 	     typename _UniformRandomNumberGenerator>
104538fd1498Szrj       void
104638fd1498Szrj       geometric_distribution<_IntType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)104738fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
104838fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
104938fd1498Szrj 		      const param_type& __param)
105038fd1498Szrj       {
105138fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
105238fd1498Szrj 	// About the epsilon thing see this thread:
105338fd1498Szrj 	// http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html
105438fd1498Szrj 	const double __naf =
105538fd1498Szrj 	  (1 - std::numeric_limits<double>::epsilon()) / 2;
105638fd1498Szrj 	// The largest _RealType convertible to _IntType.
105738fd1498Szrj 	const double __thr =
105838fd1498Szrj 	  std::numeric_limits<_IntType>::max() + __naf;
105938fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
106038fd1498Szrj 	  __aurng(__urng);
106138fd1498Szrj 
106238fd1498Szrj 	while (__f != __t)
106338fd1498Szrj 	  {
106438fd1498Szrj 	    double __cand;
106538fd1498Szrj 	    do
106638fd1498Szrj 	      __cand = std::floor(std::log(1.0 - __aurng())
106738fd1498Szrj 				  / __param._M_log_1_p);
106838fd1498Szrj 	    while (__cand >= __thr);
106938fd1498Szrj 
107038fd1498Szrj 	    *__f++ = __cand + __naf;
107138fd1498Szrj 	  }
107238fd1498Szrj       }
107338fd1498Szrj 
107438fd1498Szrj   template<typename _IntType,
107538fd1498Szrj 	   typename _CharT, typename _Traits>
107638fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const geometric_distribution<_IntType> & __x)107738fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
107838fd1498Szrj 	       const geometric_distribution<_IntType>& __x)
107938fd1498Szrj     {
108038fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
108138fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
108238fd1498Szrj 
108338fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
108438fd1498Szrj       const _CharT __fill = __os.fill();
108538fd1498Szrj       const std::streamsize __precision = __os.precision();
108638fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
108738fd1498Szrj       __os.fill(__os.widen(' '));
108838fd1498Szrj       __os.precision(std::numeric_limits<double>::max_digits10);
108938fd1498Szrj 
109038fd1498Szrj       __os << __x.p();
109138fd1498Szrj 
109238fd1498Szrj       __os.flags(__flags);
109338fd1498Szrj       __os.fill(__fill);
109438fd1498Szrj       __os.precision(__precision);
109538fd1498Szrj       return __os;
109638fd1498Szrj     }
109738fd1498Szrj 
109838fd1498Szrj   template<typename _IntType,
109938fd1498Szrj 	   typename _CharT, typename _Traits>
110038fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,geometric_distribution<_IntType> & __x)110138fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
110238fd1498Szrj 	       geometric_distribution<_IntType>& __x)
110338fd1498Szrj     {
110438fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
110538fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
110638fd1498Szrj 
110738fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
110838fd1498Szrj       __is.flags(__ios_base::skipws);
110938fd1498Szrj 
111038fd1498Szrj       double __p;
111138fd1498Szrj       __is >> __p;
111238fd1498Szrj       __x.param(typename geometric_distribution<_IntType>::param_type(__p));
111338fd1498Szrj 
111438fd1498Szrj       __is.flags(__flags);
111538fd1498Szrj       return __is;
111638fd1498Szrj     }
111738fd1498Szrj 
111838fd1498Szrj   // This is Leger's algorithm, also in Devroye, Ch. X, Example 1.5.
111938fd1498Szrj   template<typename _IntType>
112038fd1498Szrj     template<typename _UniformRandomNumberGenerator>
112138fd1498Szrj       typename negative_binomial_distribution<_IntType>::result_type
112238fd1498Szrj       negative_binomial_distribution<_IntType>::
operator ()(_UniformRandomNumberGenerator & __urng)112338fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng)
112438fd1498Szrj       {
112538fd1498Szrj 	const double __y = _M_gd(__urng);
112638fd1498Szrj 
112738fd1498Szrj 	// XXX Is the constructor too slow?
112838fd1498Szrj 	std::poisson_distribution<result_type> __poisson(__y);
112938fd1498Szrj 	return __poisson(__urng);
113038fd1498Szrj       }
113138fd1498Szrj 
113238fd1498Szrj   template<typename _IntType>
113338fd1498Szrj     template<typename _UniformRandomNumberGenerator>
113438fd1498Szrj       typename negative_binomial_distribution<_IntType>::result_type
113538fd1498Szrj       negative_binomial_distribution<_IntType>::
operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __p)113638fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng,
113738fd1498Szrj 		 const param_type& __p)
113838fd1498Szrj       {
113938fd1498Szrj 	typedef typename std::gamma_distribution<double>::param_type
114038fd1498Szrj 	  param_type;
114138fd1498Szrj 
114238fd1498Szrj 	const double __y =
114338fd1498Szrj 	  _M_gd(__urng, param_type(__p.k(), (1.0 - __p.p()) / __p.p()));
114438fd1498Szrj 
114538fd1498Szrj 	std::poisson_distribution<result_type> __poisson(__y);
114638fd1498Szrj 	return __poisson(__urng);
114738fd1498Szrj       }
114838fd1498Szrj 
114938fd1498Szrj   template<typename _IntType>
115038fd1498Szrj     template<typename _ForwardIterator,
115138fd1498Szrj 	     typename _UniformRandomNumberGenerator>
115238fd1498Szrj       void
115338fd1498Szrj       negative_binomial_distribution<_IntType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng)115438fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
115538fd1498Szrj 		      _UniformRandomNumberGenerator& __urng)
115638fd1498Szrj       {
115738fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
115838fd1498Szrj 	while (__f != __t)
115938fd1498Szrj 	  {
116038fd1498Szrj 	    const double __y = _M_gd(__urng);
116138fd1498Szrj 
116238fd1498Szrj 	    // XXX Is the constructor too slow?
116338fd1498Szrj 	    std::poisson_distribution<result_type> __poisson(__y);
116438fd1498Szrj 	    *__f++ = __poisson(__urng);
116538fd1498Szrj 	  }
116638fd1498Szrj       }
116738fd1498Szrj 
116838fd1498Szrj   template<typename _IntType>
116938fd1498Szrj     template<typename _ForwardIterator,
117038fd1498Szrj 	     typename _UniformRandomNumberGenerator>
117138fd1498Szrj       void
117238fd1498Szrj       negative_binomial_distribution<_IntType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)117338fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
117438fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
117538fd1498Szrj 		      const param_type& __p)
117638fd1498Szrj       {
117738fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
117838fd1498Szrj 	typename std::gamma_distribution<result_type>::param_type
117938fd1498Szrj 	  __p2(__p.k(), (1.0 - __p.p()) / __p.p());
118038fd1498Szrj 
118138fd1498Szrj 	while (__f != __t)
118238fd1498Szrj 	  {
118338fd1498Szrj 	    const double __y = _M_gd(__urng, __p2);
118438fd1498Szrj 
118538fd1498Szrj 	    std::poisson_distribution<result_type> __poisson(__y);
118638fd1498Szrj 	    *__f++ = __poisson(__urng);
118738fd1498Szrj 	  }
118838fd1498Szrj       }
118938fd1498Szrj 
119038fd1498Szrj   template<typename _IntType, typename _CharT, typename _Traits>
119138fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const negative_binomial_distribution<_IntType> & __x)119238fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
119338fd1498Szrj 	       const negative_binomial_distribution<_IntType>& __x)
119438fd1498Szrj     {
119538fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
119638fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
119738fd1498Szrj 
119838fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
119938fd1498Szrj       const _CharT __fill = __os.fill();
120038fd1498Szrj       const std::streamsize __precision = __os.precision();
120138fd1498Szrj       const _CharT __space = __os.widen(' ');
120238fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
120338fd1498Szrj       __os.fill(__os.widen(' '));
120438fd1498Szrj       __os.precision(std::numeric_limits<double>::max_digits10);
120538fd1498Szrj 
120638fd1498Szrj       __os << __x.k() << __space << __x.p()
120738fd1498Szrj 	   << __space << __x._M_gd;
120838fd1498Szrj 
120938fd1498Szrj       __os.flags(__flags);
121038fd1498Szrj       __os.fill(__fill);
121138fd1498Szrj       __os.precision(__precision);
121238fd1498Szrj       return __os;
121338fd1498Szrj     }
121438fd1498Szrj 
121538fd1498Szrj   template<typename _IntType, typename _CharT, typename _Traits>
121638fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,negative_binomial_distribution<_IntType> & __x)121738fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
121838fd1498Szrj 	       negative_binomial_distribution<_IntType>& __x)
121938fd1498Szrj     {
122038fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
122138fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
122238fd1498Szrj 
122338fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
122438fd1498Szrj       __is.flags(__ios_base::skipws);
122538fd1498Szrj 
122638fd1498Szrj       _IntType __k;
122738fd1498Szrj       double __p;
122838fd1498Szrj       __is >> __k >> __p >> __x._M_gd;
122938fd1498Szrj       __x.param(typename negative_binomial_distribution<_IntType>::
123038fd1498Szrj 		param_type(__k, __p));
123138fd1498Szrj 
123238fd1498Szrj       __is.flags(__flags);
123338fd1498Szrj       return __is;
123438fd1498Szrj     }
123538fd1498Szrj 
123638fd1498Szrj 
123738fd1498Szrj   template<typename _IntType>
123838fd1498Szrj     void
123938fd1498Szrj     poisson_distribution<_IntType>::param_type::
_M_initialize()124038fd1498Szrj     _M_initialize()
124138fd1498Szrj     {
124238fd1498Szrj #if _GLIBCXX_USE_C99_MATH_TR1
124338fd1498Szrj       if (_M_mean >= 12)
124438fd1498Szrj 	{
124538fd1498Szrj 	  const double __m = std::floor(_M_mean);
124638fd1498Szrj 	  _M_lm_thr = std::log(_M_mean);
124738fd1498Szrj 	  _M_lfm = std::lgamma(__m + 1);
124838fd1498Szrj 	  _M_sm = std::sqrt(__m);
124938fd1498Szrj 
125038fd1498Szrj 	  const double __pi_4 = 0.7853981633974483096156608458198757L;
125138fd1498Szrj 	  const double __dx = std::sqrt(2 * __m * std::log(32 * __m
125238fd1498Szrj 							      / __pi_4));
125338fd1498Szrj 	  _M_d = std::round(std::max<double>(6.0, std::min(__m, __dx)));
125438fd1498Szrj 	  const double __cx = 2 * __m + _M_d;
125538fd1498Szrj 	  _M_scx = std::sqrt(__cx / 2);
125638fd1498Szrj 	  _M_1cx = 1 / __cx;
125738fd1498Szrj 
125838fd1498Szrj 	  _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx);
125938fd1498Szrj 	  _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2))
126038fd1498Szrj 		/ _M_d;
126138fd1498Szrj 	}
126238fd1498Szrj       else
126338fd1498Szrj #endif
126438fd1498Szrj 	_M_lm_thr = std::exp(-_M_mean);
126538fd1498Szrj       }
126638fd1498Szrj 
126738fd1498Szrj   /**
126838fd1498Szrj    * A rejection algorithm when mean >= 12 and a simple method based
126938fd1498Szrj    * upon the multiplication of uniform random variates otherwise.
127038fd1498Szrj    * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
127138fd1498Szrj    * is defined.
127238fd1498Szrj    *
127338fd1498Szrj    * Reference:
127438fd1498Szrj    * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
127538fd1498Szrj    * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!).
127638fd1498Szrj    */
127738fd1498Szrj   template<typename _IntType>
127838fd1498Szrj     template<typename _UniformRandomNumberGenerator>
127938fd1498Szrj       typename poisson_distribution<_IntType>::result_type
128038fd1498Szrj       poisson_distribution<_IntType>::
operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)128138fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng,
128238fd1498Szrj 		 const param_type& __param)
128338fd1498Szrj       {
128438fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
128538fd1498Szrj 	  __aurng(__urng);
128638fd1498Szrj #if _GLIBCXX_USE_C99_MATH_TR1
128738fd1498Szrj 	if (__param.mean() >= 12)
128838fd1498Szrj 	  {
128938fd1498Szrj 	    double __x;
129038fd1498Szrj 
129138fd1498Szrj 	    // See comments above...
129238fd1498Szrj 	    const double __naf =
129338fd1498Szrj 	      (1 - std::numeric_limits<double>::epsilon()) / 2;
129438fd1498Szrj 	    const double __thr =
129538fd1498Szrj 	      std::numeric_limits<_IntType>::max() + __naf;
129638fd1498Szrj 
129738fd1498Szrj 	    const double __m = std::floor(__param.mean());
129838fd1498Szrj 	    // sqrt(pi / 2)
129938fd1498Szrj 	    const double __spi_2 = 1.2533141373155002512078826424055226L;
130038fd1498Szrj 	    const double __c1 = __param._M_sm * __spi_2;
130138fd1498Szrj 	    const double __c2 = __param._M_c2b + __c1;
130238fd1498Szrj 	    const double __c3 = __c2 + 1;
130338fd1498Szrj 	    const double __c4 = __c3 + 1;
130438fd1498Szrj 	    // 1 / 78
130538fd1498Szrj 	    const double __178 = 0.0128205128205128205128205128205128L;
130638fd1498Szrj 	    // e^(1 / 78)
130738fd1498Szrj 	    const double __e178 = 1.0129030479320018583185514777512983L;
130838fd1498Szrj 	    const double __c5 = __c4 + __e178;
130938fd1498Szrj 	    const double __c = __param._M_cb + __c5;
131038fd1498Szrj 	    const double __2cx = 2 * (2 * __m + __param._M_d);
131138fd1498Szrj 
131238fd1498Szrj 	    bool __reject = true;
131338fd1498Szrj 	    do
131438fd1498Szrj 	      {
131538fd1498Szrj 		const double __u = __c * __aurng();
131638fd1498Szrj 		const double __e = -std::log(1.0 - __aurng());
131738fd1498Szrj 
131838fd1498Szrj 		double __w = 0.0;
131938fd1498Szrj 
132038fd1498Szrj 		if (__u <= __c1)
132138fd1498Szrj 		  {
132238fd1498Szrj 		    const double __n = _M_nd(__urng);
132338fd1498Szrj 		    const double __y = -std::abs(__n) * __param._M_sm - 1;
132438fd1498Szrj 		    __x = std::floor(__y);
132538fd1498Szrj 		    __w = -__n * __n / 2;
132638fd1498Szrj 		    if (__x < -__m)
132738fd1498Szrj 		      continue;
132838fd1498Szrj 		  }
132938fd1498Szrj 		else if (__u <= __c2)
133038fd1498Szrj 		  {
133138fd1498Szrj 		    const double __n = _M_nd(__urng);
133238fd1498Szrj 		    const double __y = 1 + std::abs(__n) * __param._M_scx;
133338fd1498Szrj 		    __x = std::ceil(__y);
133438fd1498Szrj 		    __w = __y * (2 - __y) * __param._M_1cx;
133538fd1498Szrj 		    if (__x > __param._M_d)
133638fd1498Szrj 		      continue;
133738fd1498Szrj 		  }
133838fd1498Szrj 		else if (__u <= __c3)
133938fd1498Szrj 		  // NB: This case not in the book, nor in the Errata,
134038fd1498Szrj 		  // but should be ok...
134138fd1498Szrj 		  __x = -1;
134238fd1498Szrj 		else if (__u <= __c4)
134338fd1498Szrj 		  __x = 0;
134438fd1498Szrj 		else if (__u <= __c5)
134538fd1498Szrj 		  {
134638fd1498Szrj 		    __x = 1;
134738fd1498Szrj 		    // Only in the Errata, see libstdc++/83237.
134838fd1498Szrj 		    __w = __178;
134938fd1498Szrj 		  }
135038fd1498Szrj 		else
135138fd1498Szrj 		  {
135238fd1498Szrj 		    const double __v = -std::log(1.0 - __aurng());
135338fd1498Szrj 		    const double __y = __param._M_d
135438fd1498Szrj 				     + __v * __2cx / __param._M_d;
135538fd1498Szrj 		    __x = std::ceil(__y);
135638fd1498Szrj 		    __w = -__param._M_d * __param._M_1cx * (1 + __y / 2);
135738fd1498Szrj 		  }
135838fd1498Szrj 
135938fd1498Szrj 		__reject = (__w - __e - __x * __param._M_lm_thr
136038fd1498Szrj 			    > __param._M_lfm - std::lgamma(__x + __m + 1));
136138fd1498Szrj 
136238fd1498Szrj 		__reject |= __x + __m >= __thr;
136338fd1498Szrj 
136438fd1498Szrj 	      } while (__reject);
136538fd1498Szrj 
136638fd1498Szrj 	    return result_type(__x + __m + __naf);
136738fd1498Szrj 	  }
136838fd1498Szrj 	else
136938fd1498Szrj #endif
137038fd1498Szrj 	  {
137138fd1498Szrj 	    _IntType     __x = 0;
137238fd1498Szrj 	    double __prod = 1.0;
137338fd1498Szrj 
137438fd1498Szrj 	    do
137538fd1498Szrj 	      {
137638fd1498Szrj 		__prod *= __aurng();
137738fd1498Szrj 		__x += 1;
137838fd1498Szrj 	      }
137938fd1498Szrj 	    while (__prod > __param._M_lm_thr);
138038fd1498Szrj 
138138fd1498Szrj 	    return __x - 1;
138238fd1498Szrj 	  }
138338fd1498Szrj       }
138438fd1498Szrj 
138538fd1498Szrj   template<typename _IntType>
138638fd1498Szrj     template<typename _ForwardIterator,
138738fd1498Szrj 	     typename _UniformRandomNumberGenerator>
138838fd1498Szrj       void
138938fd1498Szrj       poisson_distribution<_IntType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)139038fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
139138fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
139238fd1498Szrj 		      const param_type& __param)
139338fd1498Szrj       {
139438fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
139538fd1498Szrj 	// We could duplicate everything from operator()...
139638fd1498Szrj 	while (__f != __t)
139738fd1498Szrj 	  *__f++ = this->operator()(__urng, __param);
139838fd1498Szrj       }
139938fd1498Szrj 
140038fd1498Szrj   template<typename _IntType,
140138fd1498Szrj 	   typename _CharT, typename _Traits>
140238fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const poisson_distribution<_IntType> & __x)140338fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
140438fd1498Szrj 	       const poisson_distribution<_IntType>& __x)
140538fd1498Szrj     {
140638fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
140738fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
140838fd1498Szrj 
140938fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
141038fd1498Szrj       const _CharT __fill = __os.fill();
141138fd1498Szrj       const std::streamsize __precision = __os.precision();
141238fd1498Szrj       const _CharT __space = __os.widen(' ');
141338fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
141438fd1498Szrj       __os.fill(__space);
141538fd1498Szrj       __os.precision(std::numeric_limits<double>::max_digits10);
141638fd1498Szrj 
141738fd1498Szrj       __os << __x.mean() << __space << __x._M_nd;
141838fd1498Szrj 
141938fd1498Szrj       __os.flags(__flags);
142038fd1498Szrj       __os.fill(__fill);
142138fd1498Szrj       __os.precision(__precision);
142238fd1498Szrj       return __os;
142338fd1498Szrj     }
142438fd1498Szrj 
142538fd1498Szrj   template<typename _IntType,
142638fd1498Szrj 	   typename _CharT, typename _Traits>
142738fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,poisson_distribution<_IntType> & __x)142838fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
142938fd1498Szrj 	       poisson_distribution<_IntType>& __x)
143038fd1498Szrj     {
143138fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
143238fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
143338fd1498Szrj 
143438fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
143538fd1498Szrj       __is.flags(__ios_base::skipws);
143638fd1498Szrj 
143738fd1498Szrj       double __mean;
143838fd1498Szrj       __is >> __mean >> __x._M_nd;
143938fd1498Szrj       __x.param(typename poisson_distribution<_IntType>::param_type(__mean));
144038fd1498Szrj 
144138fd1498Szrj       __is.flags(__flags);
144238fd1498Szrj       return __is;
144338fd1498Szrj     }
144438fd1498Szrj 
144538fd1498Szrj 
144638fd1498Szrj   template<typename _IntType>
144738fd1498Szrj     void
144838fd1498Szrj     binomial_distribution<_IntType>::param_type::
_M_initialize()144938fd1498Szrj     _M_initialize()
145038fd1498Szrj     {
145138fd1498Szrj       const double __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p;
145238fd1498Szrj 
145338fd1498Szrj       _M_easy = true;
145438fd1498Szrj 
145538fd1498Szrj #if _GLIBCXX_USE_C99_MATH_TR1
145638fd1498Szrj       if (_M_t * __p12 >= 8)
145738fd1498Szrj 	{
145838fd1498Szrj 	  _M_easy = false;
145938fd1498Szrj 	  const double __np = std::floor(_M_t * __p12);
146038fd1498Szrj 	  const double __pa = __np / _M_t;
146138fd1498Szrj 	  const double __1p = 1 - __pa;
146238fd1498Szrj 
146338fd1498Szrj 	  const double __pi_4 = 0.7853981633974483096156608458198757L;
146438fd1498Szrj 	  const double __d1x =
146538fd1498Szrj 	    std::sqrt(__np * __1p * std::log(32 * __np
146638fd1498Szrj 					     / (81 * __pi_4 * __1p)));
146738fd1498Szrj 	  _M_d1 = std::round(std::max<double>(1.0, __d1x));
146838fd1498Szrj 	  const double __d2x =
146938fd1498Szrj 	    std::sqrt(__np * __1p * std::log(32 * _M_t * __1p
147038fd1498Szrj 					     / (__pi_4 * __pa)));
147138fd1498Szrj 	  _M_d2 = std::round(std::max<double>(1.0, __d2x));
147238fd1498Szrj 
147338fd1498Szrj 	  // sqrt(pi / 2)
147438fd1498Szrj 	  const double __spi_2 = 1.2533141373155002512078826424055226L;
147538fd1498Szrj 	  _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np));
147638fd1498Szrj 	  _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p));
147738fd1498Szrj 	  _M_c = 2 * _M_d1 / __np;
147838fd1498Szrj 	  _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2;
147938fd1498Szrj 	  const double __a12 = _M_a1 + _M_s2 * __spi_2;
148038fd1498Szrj 	  const double __s1s = _M_s1 * _M_s1;
148138fd1498Szrj 	  _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p))
148238fd1498Szrj 			     * 2 * __s1s / _M_d1
148338fd1498Szrj 			     * std::exp(-_M_d1 * _M_d1 / (2 * __s1s)));
148438fd1498Szrj 	  const double __s2s = _M_s2 * _M_s2;
148538fd1498Szrj 	  _M_s = (_M_a123 + 2 * __s2s / _M_d2
148638fd1498Szrj 		  * std::exp(-_M_d2 * _M_d2 / (2 * __s2s)));
148738fd1498Szrj 	  _M_lf = (std::lgamma(__np + 1)
148838fd1498Szrj 		   + std::lgamma(_M_t - __np + 1));
148938fd1498Szrj 	  _M_lp1p = std::log(__pa / __1p);
149038fd1498Szrj 
149138fd1498Szrj 	  _M_q = -std::log(1 - (__p12 - __pa) / __1p);
149238fd1498Szrj 	}
149338fd1498Szrj       else
149438fd1498Szrj #endif
149538fd1498Szrj 	_M_q = -std::log(1 - __p12);
149638fd1498Szrj     }
149738fd1498Szrj 
149838fd1498Szrj   template<typename _IntType>
149938fd1498Szrj     template<typename _UniformRandomNumberGenerator>
150038fd1498Szrj       typename binomial_distribution<_IntType>::result_type
150138fd1498Szrj       binomial_distribution<_IntType>::
_M_waiting(_UniformRandomNumberGenerator & __urng,_IntType __t,double __q)150238fd1498Szrj       _M_waiting(_UniformRandomNumberGenerator& __urng,
150338fd1498Szrj 		 _IntType __t, double __q)
150438fd1498Szrj       {
150538fd1498Szrj 	_IntType __x = 0;
150638fd1498Szrj 	double __sum = 0.0;
150738fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
150838fd1498Szrj 	  __aurng(__urng);
150938fd1498Szrj 
151038fd1498Szrj 	do
151138fd1498Szrj 	  {
151238fd1498Szrj 	    if (__t == __x)
151338fd1498Szrj 	      return __x;
151438fd1498Szrj 	    const double __e = -std::log(1.0 - __aurng());
151538fd1498Szrj 	    __sum += __e / (__t - __x);
151638fd1498Szrj 	    __x += 1;
151738fd1498Szrj 	  }
151838fd1498Szrj 	while (__sum <= __q);
151938fd1498Szrj 
152038fd1498Szrj 	return __x - 1;
152138fd1498Szrj       }
152238fd1498Szrj 
152338fd1498Szrj   /**
152438fd1498Szrj    * A rejection algorithm when t * p >= 8 and a simple waiting time
152538fd1498Szrj    * method - the second in the referenced book - otherwise.
152638fd1498Szrj    * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
152738fd1498Szrj    * is defined.
152838fd1498Szrj    *
152938fd1498Szrj    * Reference:
153038fd1498Szrj    * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
153138fd1498Szrj    * New York, 1986, Ch. X, Sect. 4 (+ Errata!).
153238fd1498Szrj    */
153338fd1498Szrj   template<typename _IntType>
153438fd1498Szrj     template<typename _UniformRandomNumberGenerator>
153538fd1498Szrj       typename binomial_distribution<_IntType>::result_type
153638fd1498Szrj       binomial_distribution<_IntType>::
operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)153738fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng,
153838fd1498Szrj 		 const param_type& __param)
153938fd1498Szrj       {
154038fd1498Szrj 	result_type __ret;
154138fd1498Szrj 	const _IntType __t = __param.t();
154238fd1498Szrj 	const double __p = __param.p();
154338fd1498Szrj 	const double __p12 = __p <= 0.5 ? __p : 1.0 - __p;
154438fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
154538fd1498Szrj 	  __aurng(__urng);
154638fd1498Szrj 
154738fd1498Szrj #if _GLIBCXX_USE_C99_MATH_TR1
154838fd1498Szrj 	if (!__param._M_easy)
154938fd1498Szrj 	  {
155038fd1498Szrj 	    double __x;
155138fd1498Szrj 
155238fd1498Szrj 	    // See comments above...
155338fd1498Szrj 	    const double __naf =
155438fd1498Szrj 	      (1 - std::numeric_limits<double>::epsilon()) / 2;
155538fd1498Szrj 	    const double __thr =
155638fd1498Szrj 	      std::numeric_limits<_IntType>::max() + __naf;
155738fd1498Szrj 
155838fd1498Szrj 	    const double __np = std::floor(__t * __p12);
155938fd1498Szrj 
156038fd1498Szrj 	    // sqrt(pi / 2)
156138fd1498Szrj 	    const double __spi_2 = 1.2533141373155002512078826424055226L;
156238fd1498Szrj 	    const double __a1 = __param._M_a1;
156338fd1498Szrj 	    const double __a12 = __a1 + __param._M_s2 * __spi_2;
156438fd1498Szrj 	    const double __a123 = __param._M_a123;
156538fd1498Szrj 	    const double __s1s = __param._M_s1 * __param._M_s1;
156638fd1498Szrj 	    const double __s2s = __param._M_s2 * __param._M_s2;
156738fd1498Szrj 
156838fd1498Szrj 	    bool __reject;
156938fd1498Szrj 	    do
157038fd1498Szrj 	      {
157138fd1498Szrj 		const double __u = __param._M_s * __aurng();
157238fd1498Szrj 
157338fd1498Szrj 		double __v;
157438fd1498Szrj 
157538fd1498Szrj 		if (__u <= __a1)
157638fd1498Szrj 		  {
157738fd1498Szrj 		    const double __n = _M_nd(__urng);
157838fd1498Szrj 		    const double __y = __param._M_s1 * std::abs(__n);
157938fd1498Szrj 		    __reject = __y >= __param._M_d1;
158038fd1498Szrj 		    if (!__reject)
158138fd1498Szrj 		      {
158238fd1498Szrj 			const double __e = -std::log(1.0 - __aurng());
158338fd1498Szrj 			__x = std::floor(__y);
158438fd1498Szrj 			__v = -__e - __n * __n / 2 + __param._M_c;
158538fd1498Szrj 		      }
158638fd1498Szrj 		  }
158738fd1498Szrj 		else if (__u <= __a12)
158838fd1498Szrj 		  {
158938fd1498Szrj 		    const double __n = _M_nd(__urng);
159038fd1498Szrj 		    const double __y = __param._M_s2 * std::abs(__n);
159138fd1498Szrj 		    __reject = __y >= __param._M_d2;
159238fd1498Szrj 		    if (!__reject)
159338fd1498Szrj 		      {
159438fd1498Szrj 			const double __e = -std::log(1.0 - __aurng());
159538fd1498Szrj 			__x = std::floor(-__y);
159638fd1498Szrj 			__v = -__e - __n * __n / 2;
159738fd1498Szrj 		      }
159838fd1498Szrj 		  }
159938fd1498Szrj 		else if (__u <= __a123)
160038fd1498Szrj 		  {
160138fd1498Szrj 		    const double __e1 = -std::log(1.0 - __aurng());
160238fd1498Szrj 		    const double __e2 = -std::log(1.0 - __aurng());
160338fd1498Szrj 
160438fd1498Szrj 		    const double __y = __param._M_d1
160538fd1498Szrj 				     + 2 * __s1s * __e1 / __param._M_d1;
160638fd1498Szrj 		    __x = std::floor(__y);
160738fd1498Szrj 		    __v = (-__e2 + __param._M_d1 * (1 / (__t - __np)
160838fd1498Szrj 						    -__y / (2 * __s1s)));
160938fd1498Szrj 		    __reject = false;
161038fd1498Szrj 		  }
161138fd1498Szrj 		else
161238fd1498Szrj 		  {
161338fd1498Szrj 		    const double __e1 = -std::log(1.0 - __aurng());
161438fd1498Szrj 		    const double __e2 = -std::log(1.0 - __aurng());
161538fd1498Szrj 
161638fd1498Szrj 		    const double __y = __param._M_d2
161738fd1498Szrj 				     + 2 * __s2s * __e1 / __param._M_d2;
161838fd1498Szrj 		    __x = std::floor(-__y);
161938fd1498Szrj 		    __v = -__e2 - __param._M_d2 * __y / (2 * __s2s);
162038fd1498Szrj 		    __reject = false;
162138fd1498Szrj 		  }
162238fd1498Szrj 
162338fd1498Szrj 		__reject = __reject || __x < -__np || __x > __t - __np;
162438fd1498Szrj 		if (!__reject)
162538fd1498Szrj 		  {
162638fd1498Szrj 		    const double __lfx =
162738fd1498Szrj 		      std::lgamma(__np + __x + 1)
162838fd1498Szrj 		      + std::lgamma(__t - (__np + __x) + 1);
162938fd1498Szrj 		    __reject = __v > __param._M_lf - __lfx
163038fd1498Szrj 			     + __x * __param._M_lp1p;
163138fd1498Szrj 		  }
163238fd1498Szrj 
163338fd1498Szrj 		__reject |= __x + __np >= __thr;
163438fd1498Szrj 	      }
163538fd1498Szrj 	    while (__reject);
163638fd1498Szrj 
163738fd1498Szrj 	    __x += __np + __naf;
163838fd1498Szrj 
163938fd1498Szrj 	    const _IntType __z = _M_waiting(__urng, __t - _IntType(__x),
164038fd1498Szrj 					    __param._M_q);
164138fd1498Szrj 	    __ret = _IntType(__x) + __z;
164238fd1498Szrj 	  }
164338fd1498Szrj 	else
164438fd1498Szrj #endif
164538fd1498Szrj 	  __ret = _M_waiting(__urng, __t, __param._M_q);
164638fd1498Szrj 
164738fd1498Szrj 	if (__p12 != __p)
164838fd1498Szrj 	  __ret = __t - __ret;
164938fd1498Szrj 	return __ret;
165038fd1498Szrj       }
165138fd1498Szrj 
165238fd1498Szrj   template<typename _IntType>
165338fd1498Szrj     template<typename _ForwardIterator,
165438fd1498Szrj 	     typename _UniformRandomNumberGenerator>
165538fd1498Szrj       void
165638fd1498Szrj       binomial_distribution<_IntType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)165738fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
165838fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
165938fd1498Szrj 		      const param_type& __param)
166038fd1498Szrj       {
166138fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
166238fd1498Szrj 	// We could duplicate everything from operator()...
166338fd1498Szrj 	while (__f != __t)
166438fd1498Szrj 	  *__f++ = this->operator()(__urng, __param);
166538fd1498Szrj       }
166638fd1498Szrj 
166738fd1498Szrj   template<typename _IntType,
166838fd1498Szrj 	   typename _CharT, typename _Traits>
166938fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const binomial_distribution<_IntType> & __x)167038fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
167138fd1498Szrj 	       const binomial_distribution<_IntType>& __x)
167238fd1498Szrj     {
167338fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
167438fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
167538fd1498Szrj 
167638fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
167738fd1498Szrj       const _CharT __fill = __os.fill();
167838fd1498Szrj       const std::streamsize __precision = __os.precision();
167938fd1498Szrj       const _CharT __space = __os.widen(' ');
168038fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
168138fd1498Szrj       __os.fill(__space);
168238fd1498Szrj       __os.precision(std::numeric_limits<double>::max_digits10);
168338fd1498Szrj 
168438fd1498Szrj       __os << __x.t() << __space << __x.p()
168538fd1498Szrj 	   << __space << __x._M_nd;
168638fd1498Szrj 
168738fd1498Szrj       __os.flags(__flags);
168838fd1498Szrj       __os.fill(__fill);
168938fd1498Szrj       __os.precision(__precision);
169038fd1498Szrj       return __os;
169138fd1498Szrj     }
169238fd1498Szrj 
169338fd1498Szrj   template<typename _IntType,
169438fd1498Szrj 	   typename _CharT, typename _Traits>
169538fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,binomial_distribution<_IntType> & __x)169638fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
169738fd1498Szrj 	       binomial_distribution<_IntType>& __x)
169838fd1498Szrj     {
169938fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
170038fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
170138fd1498Szrj 
170238fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
170338fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
170438fd1498Szrj 
170538fd1498Szrj       _IntType __t;
170638fd1498Szrj       double __p;
170738fd1498Szrj       __is >> __t >> __p >> __x._M_nd;
170838fd1498Szrj       __x.param(typename binomial_distribution<_IntType>::
170938fd1498Szrj 		param_type(__t, __p));
171038fd1498Szrj 
171138fd1498Szrj       __is.flags(__flags);
171238fd1498Szrj       return __is;
171338fd1498Szrj     }
171438fd1498Szrj 
171538fd1498Szrj 
171638fd1498Szrj   template<typename _RealType>
171738fd1498Szrj     template<typename _ForwardIterator,
171838fd1498Szrj 	     typename _UniformRandomNumberGenerator>
171938fd1498Szrj       void
172038fd1498Szrj       std::exponential_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)172138fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
172238fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
172338fd1498Szrj 		      const param_type& __p)
172438fd1498Szrj       {
172538fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
172638fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
172738fd1498Szrj 	  __aurng(__urng);
172838fd1498Szrj 	while (__f != __t)
172938fd1498Szrj 	  *__f++ = -std::log(result_type(1) - __aurng()) / __p.lambda();
173038fd1498Szrj       }
173138fd1498Szrj 
173238fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
173338fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const exponential_distribution<_RealType> & __x)173438fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
173538fd1498Szrj 	       const exponential_distribution<_RealType>& __x)
173638fd1498Szrj     {
173738fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
173838fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
173938fd1498Szrj 
174038fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
174138fd1498Szrj       const _CharT __fill = __os.fill();
174238fd1498Szrj       const std::streamsize __precision = __os.precision();
174338fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
174438fd1498Szrj       __os.fill(__os.widen(' '));
174538fd1498Szrj       __os.precision(std::numeric_limits<_RealType>::max_digits10);
174638fd1498Szrj 
174738fd1498Szrj       __os << __x.lambda();
174838fd1498Szrj 
174938fd1498Szrj       __os.flags(__flags);
175038fd1498Szrj       __os.fill(__fill);
175138fd1498Szrj       __os.precision(__precision);
175238fd1498Szrj       return __os;
175338fd1498Szrj     }
175438fd1498Szrj 
175538fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
175638fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,exponential_distribution<_RealType> & __x)175738fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
175838fd1498Szrj 	       exponential_distribution<_RealType>& __x)
175938fd1498Szrj     {
176038fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
176138fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
176238fd1498Szrj 
176338fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
176438fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
176538fd1498Szrj 
176638fd1498Szrj       _RealType __lambda;
176738fd1498Szrj       __is >> __lambda;
176838fd1498Szrj       __x.param(typename exponential_distribution<_RealType>::
176938fd1498Szrj 		param_type(__lambda));
177038fd1498Szrj 
177138fd1498Szrj       __is.flags(__flags);
177238fd1498Szrj       return __is;
177338fd1498Szrj     }
177438fd1498Szrj 
177538fd1498Szrj 
177638fd1498Szrj   /**
177738fd1498Szrj    * Polar method due to Marsaglia.
177838fd1498Szrj    *
177938fd1498Szrj    * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
178038fd1498Szrj    * New York, 1986, Ch. V, Sect. 4.4.
178138fd1498Szrj    */
178238fd1498Szrj   template<typename _RealType>
178338fd1498Szrj     template<typename _UniformRandomNumberGenerator>
178438fd1498Szrj       typename normal_distribution<_RealType>::result_type
178538fd1498Szrj       normal_distribution<_RealType>::
operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)178638fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng,
178738fd1498Szrj 		 const param_type& __param)
178838fd1498Szrj       {
178938fd1498Szrj 	result_type __ret;
179038fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
179138fd1498Szrj 	  __aurng(__urng);
179238fd1498Szrj 
179338fd1498Szrj 	if (_M_saved_available)
179438fd1498Szrj 	  {
179538fd1498Szrj 	    _M_saved_available = false;
179638fd1498Szrj 	    __ret = _M_saved;
179738fd1498Szrj 	  }
179838fd1498Szrj 	else
179938fd1498Szrj 	  {
180038fd1498Szrj 	    result_type __x, __y, __r2;
180138fd1498Szrj 	    do
180238fd1498Szrj 	      {
180338fd1498Szrj 		__x = result_type(2.0) * __aurng() - 1.0;
180438fd1498Szrj 		__y = result_type(2.0) * __aurng() - 1.0;
180538fd1498Szrj 		__r2 = __x * __x + __y * __y;
180638fd1498Szrj 	      }
180738fd1498Szrj 	    while (__r2 > 1.0 || __r2 == 0.0);
180838fd1498Szrj 
180938fd1498Szrj 	    const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
181038fd1498Szrj 	    _M_saved = __x * __mult;
181138fd1498Szrj 	    _M_saved_available = true;
181238fd1498Szrj 	    __ret = __y * __mult;
181338fd1498Szrj 	  }
181438fd1498Szrj 
181538fd1498Szrj 	__ret = __ret * __param.stddev() + __param.mean();
181638fd1498Szrj 	return __ret;
181738fd1498Szrj       }
181838fd1498Szrj 
181938fd1498Szrj   template<typename _RealType>
182038fd1498Szrj     template<typename _ForwardIterator,
182138fd1498Szrj 	     typename _UniformRandomNumberGenerator>
182238fd1498Szrj       void
182338fd1498Szrj       normal_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)182438fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
182538fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
182638fd1498Szrj 		      const param_type& __param)
182738fd1498Szrj       {
182838fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
182938fd1498Szrj 
183038fd1498Szrj 	if (__f == __t)
183138fd1498Szrj 	  return;
183238fd1498Szrj 
183338fd1498Szrj 	if (_M_saved_available)
183438fd1498Szrj 	  {
183538fd1498Szrj 	    _M_saved_available = false;
183638fd1498Szrj 	    *__f++ = _M_saved * __param.stddev() + __param.mean();
183738fd1498Szrj 
183838fd1498Szrj 	    if (__f == __t)
183938fd1498Szrj 	      return;
184038fd1498Szrj 	  }
184138fd1498Szrj 
184238fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
184338fd1498Szrj 	  __aurng(__urng);
184438fd1498Szrj 
184538fd1498Szrj 	while (__f + 1 < __t)
184638fd1498Szrj 	  {
184738fd1498Szrj 	    result_type __x, __y, __r2;
184838fd1498Szrj 	    do
184938fd1498Szrj 	      {
185038fd1498Szrj 		__x = result_type(2.0) * __aurng() - 1.0;
185138fd1498Szrj 		__y = result_type(2.0) * __aurng() - 1.0;
185238fd1498Szrj 		__r2 = __x * __x + __y * __y;
185338fd1498Szrj 	      }
185438fd1498Szrj 	    while (__r2 > 1.0 || __r2 == 0.0);
185538fd1498Szrj 
185638fd1498Szrj 	    const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
185738fd1498Szrj 	    *__f++ = __y * __mult * __param.stddev() + __param.mean();
185838fd1498Szrj 	    *__f++ = __x * __mult * __param.stddev() + __param.mean();
185938fd1498Szrj 	  }
186038fd1498Szrj 
186138fd1498Szrj 	if (__f != __t)
186238fd1498Szrj 	  {
186338fd1498Szrj 	    result_type __x, __y, __r2;
186438fd1498Szrj 	    do
186538fd1498Szrj 	      {
186638fd1498Szrj 		__x = result_type(2.0) * __aurng() - 1.0;
186738fd1498Szrj 		__y = result_type(2.0) * __aurng() - 1.0;
186838fd1498Szrj 		__r2 = __x * __x + __y * __y;
186938fd1498Szrj 	      }
187038fd1498Szrj 	    while (__r2 > 1.0 || __r2 == 0.0);
187138fd1498Szrj 
187238fd1498Szrj 	    const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
187338fd1498Szrj 	    _M_saved = __x * __mult;
187438fd1498Szrj 	    _M_saved_available = true;
187538fd1498Szrj 	    *__f = __y * __mult * __param.stddev() + __param.mean();
187638fd1498Szrj 	  }
187738fd1498Szrj       }
187838fd1498Szrj 
187938fd1498Szrj   template<typename _RealType>
188038fd1498Szrj     bool
operator ==(const std::normal_distribution<_RealType> & __d1,const std::normal_distribution<_RealType> & __d2)188138fd1498Szrj     operator==(const std::normal_distribution<_RealType>& __d1,
188238fd1498Szrj 	       const std::normal_distribution<_RealType>& __d2)
188338fd1498Szrj     {
188438fd1498Szrj       if (__d1._M_param == __d2._M_param
188538fd1498Szrj 	  && __d1._M_saved_available == __d2._M_saved_available)
188638fd1498Szrj 	{
188738fd1498Szrj 	  if (__d1._M_saved_available
188838fd1498Szrj 	      && __d1._M_saved == __d2._M_saved)
188938fd1498Szrj 	    return true;
189038fd1498Szrj 	  else if(!__d1._M_saved_available)
189138fd1498Szrj 	    return true;
189238fd1498Szrj 	  else
189338fd1498Szrj 	    return false;
189438fd1498Szrj 	}
189538fd1498Szrj       else
189638fd1498Szrj 	return false;
189738fd1498Szrj     }
189838fd1498Szrj 
189938fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
190038fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const normal_distribution<_RealType> & __x)190138fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
190238fd1498Szrj 	       const normal_distribution<_RealType>& __x)
190338fd1498Szrj     {
190438fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
190538fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
190638fd1498Szrj 
190738fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
190838fd1498Szrj       const _CharT __fill = __os.fill();
190938fd1498Szrj       const std::streamsize __precision = __os.precision();
191038fd1498Szrj       const _CharT __space = __os.widen(' ');
191138fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
191238fd1498Szrj       __os.fill(__space);
191338fd1498Szrj       __os.precision(std::numeric_limits<_RealType>::max_digits10);
191438fd1498Szrj 
191538fd1498Szrj       __os << __x.mean() << __space << __x.stddev()
191638fd1498Szrj 	   << __space << __x._M_saved_available;
191738fd1498Szrj       if (__x._M_saved_available)
191838fd1498Szrj 	__os << __space << __x._M_saved;
191938fd1498Szrj 
192038fd1498Szrj       __os.flags(__flags);
192138fd1498Szrj       __os.fill(__fill);
192238fd1498Szrj       __os.precision(__precision);
192338fd1498Szrj       return __os;
192438fd1498Szrj     }
192538fd1498Szrj 
192638fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
192738fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,normal_distribution<_RealType> & __x)192838fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
192938fd1498Szrj 	       normal_distribution<_RealType>& __x)
193038fd1498Szrj     {
193138fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
193238fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
193338fd1498Szrj 
193438fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
193538fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
193638fd1498Szrj 
193738fd1498Szrj       double __mean, __stddev;
193838fd1498Szrj       __is >> __mean >> __stddev
193938fd1498Szrj 	   >> __x._M_saved_available;
194038fd1498Szrj       if (__x._M_saved_available)
194138fd1498Szrj 	__is >> __x._M_saved;
194238fd1498Szrj       __x.param(typename normal_distribution<_RealType>::
194338fd1498Szrj 		param_type(__mean, __stddev));
194438fd1498Szrj 
194538fd1498Szrj       __is.flags(__flags);
194638fd1498Szrj       return __is;
194738fd1498Szrj     }
194838fd1498Szrj 
194938fd1498Szrj 
195038fd1498Szrj   template<typename _RealType>
195138fd1498Szrj     template<typename _ForwardIterator,
195238fd1498Szrj 	     typename _UniformRandomNumberGenerator>
195338fd1498Szrj       void
195438fd1498Szrj       lognormal_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)195538fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
195638fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
195738fd1498Szrj 		      const param_type& __p)
195838fd1498Szrj       {
195938fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
196038fd1498Szrj 	  while (__f != __t)
196138fd1498Szrj 	    *__f++ = std::exp(__p.s() * _M_nd(__urng) + __p.m());
196238fd1498Szrj       }
196338fd1498Szrj 
196438fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
196538fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const lognormal_distribution<_RealType> & __x)196638fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
196738fd1498Szrj 	       const lognormal_distribution<_RealType>& __x)
196838fd1498Szrj     {
196938fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
197038fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
197138fd1498Szrj 
197238fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
197338fd1498Szrj       const _CharT __fill = __os.fill();
197438fd1498Szrj       const std::streamsize __precision = __os.precision();
197538fd1498Szrj       const _CharT __space = __os.widen(' ');
197638fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
197738fd1498Szrj       __os.fill(__space);
197838fd1498Szrj       __os.precision(std::numeric_limits<_RealType>::max_digits10);
197938fd1498Szrj 
198038fd1498Szrj       __os << __x.m() << __space << __x.s()
198138fd1498Szrj 	   << __space << __x._M_nd;
198238fd1498Szrj 
198338fd1498Szrj       __os.flags(__flags);
198438fd1498Szrj       __os.fill(__fill);
198538fd1498Szrj       __os.precision(__precision);
198638fd1498Szrj       return __os;
198738fd1498Szrj     }
198838fd1498Szrj 
198938fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
199038fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,lognormal_distribution<_RealType> & __x)199138fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
199238fd1498Szrj 	       lognormal_distribution<_RealType>& __x)
199338fd1498Szrj     {
199438fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
199538fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
199638fd1498Szrj 
199738fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
199838fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
199938fd1498Szrj 
200038fd1498Szrj       _RealType __m, __s;
200138fd1498Szrj       __is >> __m >> __s >> __x._M_nd;
200238fd1498Szrj       __x.param(typename lognormal_distribution<_RealType>::
200338fd1498Szrj 		param_type(__m, __s));
200438fd1498Szrj 
200538fd1498Szrj       __is.flags(__flags);
200638fd1498Szrj       return __is;
200738fd1498Szrj     }
200838fd1498Szrj 
200938fd1498Szrj   template<typename _RealType>
201038fd1498Szrj     template<typename _ForwardIterator,
201138fd1498Szrj 	     typename _UniformRandomNumberGenerator>
201238fd1498Szrj       void
201338fd1498Szrj       std::chi_squared_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng)201438fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
201538fd1498Szrj 		      _UniformRandomNumberGenerator& __urng)
201638fd1498Szrj       {
201738fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
201838fd1498Szrj 	while (__f != __t)
201938fd1498Szrj 	  *__f++ = 2 * _M_gd(__urng);
202038fd1498Szrj       }
202138fd1498Szrj 
202238fd1498Szrj   template<typename _RealType>
202338fd1498Szrj     template<typename _ForwardIterator,
202438fd1498Szrj 	     typename _UniformRandomNumberGenerator>
202538fd1498Szrj       void
202638fd1498Szrj       std::chi_squared_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const typename std::gamma_distribution<result_type>::param_type & __p)202738fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
202838fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
202938fd1498Szrj 		      const typename
203038fd1498Szrj 		      std::gamma_distribution<result_type>::param_type& __p)
203138fd1498Szrj       {
203238fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
203338fd1498Szrj 	while (__f != __t)
203438fd1498Szrj 	  *__f++ = 2 * _M_gd(__urng, __p);
203538fd1498Szrj       }
203638fd1498Szrj 
203738fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
203838fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const chi_squared_distribution<_RealType> & __x)203938fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
204038fd1498Szrj 	       const chi_squared_distribution<_RealType>& __x)
204138fd1498Szrj     {
204238fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
204338fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
204438fd1498Szrj 
204538fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
204638fd1498Szrj       const _CharT __fill = __os.fill();
204738fd1498Szrj       const std::streamsize __precision = __os.precision();
204838fd1498Szrj       const _CharT __space = __os.widen(' ');
204938fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
205038fd1498Szrj       __os.fill(__space);
205138fd1498Szrj       __os.precision(std::numeric_limits<_RealType>::max_digits10);
205238fd1498Szrj 
205338fd1498Szrj       __os << __x.n() << __space << __x._M_gd;
205438fd1498Szrj 
205538fd1498Szrj       __os.flags(__flags);
205638fd1498Szrj       __os.fill(__fill);
205738fd1498Szrj       __os.precision(__precision);
205838fd1498Szrj       return __os;
205938fd1498Szrj     }
206038fd1498Szrj 
206138fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
206238fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,chi_squared_distribution<_RealType> & __x)206338fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
206438fd1498Szrj 	       chi_squared_distribution<_RealType>& __x)
206538fd1498Szrj     {
206638fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
206738fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
206838fd1498Szrj 
206938fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
207038fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
207138fd1498Szrj 
207238fd1498Szrj       _RealType __n;
207338fd1498Szrj       __is >> __n >> __x._M_gd;
207438fd1498Szrj       __x.param(typename chi_squared_distribution<_RealType>::
207538fd1498Szrj 		param_type(__n));
207638fd1498Szrj 
207738fd1498Szrj       __is.flags(__flags);
207838fd1498Szrj       return __is;
207938fd1498Szrj     }
208038fd1498Szrj 
208138fd1498Szrj 
208238fd1498Szrj   template<typename _RealType>
208338fd1498Szrj     template<typename _UniformRandomNumberGenerator>
208438fd1498Szrj       typename cauchy_distribution<_RealType>::result_type
208538fd1498Szrj       cauchy_distribution<_RealType>::
operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __p)208638fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng,
208738fd1498Szrj 		 const param_type& __p)
208838fd1498Szrj       {
208938fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
209038fd1498Szrj 	  __aurng(__urng);
209138fd1498Szrj 	_RealType __u;
209238fd1498Szrj 	do
209338fd1498Szrj 	  __u = __aurng();
209438fd1498Szrj 	while (__u == 0.5);
209538fd1498Szrj 
209638fd1498Szrj 	const _RealType __pi = 3.1415926535897932384626433832795029L;
209738fd1498Szrj 	return __p.a() + __p.b() * std::tan(__pi * __u);
209838fd1498Szrj       }
209938fd1498Szrj 
210038fd1498Szrj   template<typename _RealType>
210138fd1498Szrj     template<typename _ForwardIterator,
210238fd1498Szrj 	     typename _UniformRandomNumberGenerator>
210338fd1498Szrj       void
210438fd1498Szrj       cauchy_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)210538fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
210638fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
210738fd1498Szrj 		      const param_type& __p)
210838fd1498Szrj       {
210938fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
211038fd1498Szrj 	const _RealType __pi = 3.1415926535897932384626433832795029L;
211138fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
211238fd1498Szrj 	  __aurng(__urng);
211338fd1498Szrj 	while (__f != __t)
211438fd1498Szrj 	  {
211538fd1498Szrj 	    _RealType __u;
211638fd1498Szrj 	    do
211738fd1498Szrj 	      __u = __aurng();
211838fd1498Szrj 	    while (__u == 0.5);
211938fd1498Szrj 
212038fd1498Szrj 	    *__f++ = __p.a() + __p.b() * std::tan(__pi * __u);
212138fd1498Szrj 	  }
212238fd1498Szrj       }
212338fd1498Szrj 
212438fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
212538fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const cauchy_distribution<_RealType> & __x)212638fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
212738fd1498Szrj 	       const cauchy_distribution<_RealType>& __x)
212838fd1498Szrj     {
212938fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
213038fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
213138fd1498Szrj 
213238fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
213338fd1498Szrj       const _CharT __fill = __os.fill();
213438fd1498Szrj       const std::streamsize __precision = __os.precision();
213538fd1498Szrj       const _CharT __space = __os.widen(' ');
213638fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
213738fd1498Szrj       __os.fill(__space);
213838fd1498Szrj       __os.precision(std::numeric_limits<_RealType>::max_digits10);
213938fd1498Szrj 
214038fd1498Szrj       __os << __x.a() << __space << __x.b();
214138fd1498Szrj 
214238fd1498Szrj       __os.flags(__flags);
214338fd1498Szrj       __os.fill(__fill);
214438fd1498Szrj       __os.precision(__precision);
214538fd1498Szrj       return __os;
214638fd1498Szrj     }
214738fd1498Szrj 
214838fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
214938fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,cauchy_distribution<_RealType> & __x)215038fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
215138fd1498Szrj 	       cauchy_distribution<_RealType>& __x)
215238fd1498Szrj     {
215338fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
215438fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
215538fd1498Szrj 
215638fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
215738fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
215838fd1498Szrj 
215938fd1498Szrj       _RealType __a, __b;
216038fd1498Szrj       __is >> __a >> __b;
216138fd1498Szrj       __x.param(typename cauchy_distribution<_RealType>::
216238fd1498Szrj 		param_type(__a, __b));
216338fd1498Szrj 
216438fd1498Szrj       __is.flags(__flags);
216538fd1498Szrj       return __is;
216638fd1498Szrj     }
216738fd1498Szrj 
216838fd1498Szrj 
216938fd1498Szrj   template<typename _RealType>
217038fd1498Szrj     template<typename _ForwardIterator,
217138fd1498Szrj 	     typename _UniformRandomNumberGenerator>
217238fd1498Szrj       void
217338fd1498Szrj       std::fisher_f_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng)217438fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
217538fd1498Szrj 		      _UniformRandomNumberGenerator& __urng)
217638fd1498Szrj       {
217738fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
217838fd1498Szrj 	while (__f != __t)
217938fd1498Szrj 	  *__f++ = ((_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()));
218038fd1498Szrj       }
218138fd1498Szrj 
218238fd1498Szrj   template<typename _RealType>
218338fd1498Szrj     template<typename _ForwardIterator,
218438fd1498Szrj 	     typename _UniformRandomNumberGenerator>
218538fd1498Szrj       void
218638fd1498Szrj       std::fisher_f_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)218738fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
218838fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
218938fd1498Szrj 		      const param_type& __p)
219038fd1498Szrj       {
219138fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
219238fd1498Szrj 	typedef typename std::gamma_distribution<result_type>::param_type
219338fd1498Szrj 	  param_type;
219438fd1498Szrj 	param_type __p1(__p.m() / 2);
219538fd1498Szrj 	param_type __p2(__p.n() / 2);
219638fd1498Szrj 	while (__f != __t)
219738fd1498Szrj 	  *__f++ = ((_M_gd_x(__urng, __p1) * n())
219838fd1498Szrj 		    / (_M_gd_y(__urng, __p2) * m()));
219938fd1498Szrj       }
220038fd1498Szrj 
220138fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
220238fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const fisher_f_distribution<_RealType> & __x)220338fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
220438fd1498Szrj 	       const fisher_f_distribution<_RealType>& __x)
220538fd1498Szrj     {
220638fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
220738fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
220838fd1498Szrj 
220938fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
221038fd1498Szrj       const _CharT __fill = __os.fill();
221138fd1498Szrj       const std::streamsize __precision = __os.precision();
221238fd1498Szrj       const _CharT __space = __os.widen(' ');
221338fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
221438fd1498Szrj       __os.fill(__space);
221538fd1498Szrj       __os.precision(std::numeric_limits<_RealType>::max_digits10);
221638fd1498Szrj 
221738fd1498Szrj       __os << __x.m() << __space << __x.n()
221838fd1498Szrj 	   << __space << __x._M_gd_x << __space << __x._M_gd_y;
221938fd1498Szrj 
222038fd1498Szrj       __os.flags(__flags);
222138fd1498Szrj       __os.fill(__fill);
222238fd1498Szrj       __os.precision(__precision);
222338fd1498Szrj       return __os;
222438fd1498Szrj     }
222538fd1498Szrj 
222638fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
222738fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,fisher_f_distribution<_RealType> & __x)222838fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
222938fd1498Szrj 	       fisher_f_distribution<_RealType>& __x)
223038fd1498Szrj     {
223138fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
223238fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
223338fd1498Szrj 
223438fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
223538fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
223638fd1498Szrj 
223738fd1498Szrj       _RealType __m, __n;
223838fd1498Szrj       __is >> __m >> __n >> __x._M_gd_x >> __x._M_gd_y;
223938fd1498Szrj       __x.param(typename fisher_f_distribution<_RealType>::
224038fd1498Szrj 		param_type(__m, __n));
224138fd1498Szrj 
224238fd1498Szrj       __is.flags(__flags);
224338fd1498Szrj       return __is;
224438fd1498Szrj     }
224538fd1498Szrj 
224638fd1498Szrj 
224738fd1498Szrj   template<typename _RealType>
224838fd1498Szrj     template<typename _ForwardIterator,
224938fd1498Szrj 	     typename _UniformRandomNumberGenerator>
225038fd1498Szrj       void
225138fd1498Szrj       std::student_t_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng)225238fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
225338fd1498Szrj 		      _UniformRandomNumberGenerator& __urng)
225438fd1498Szrj       {
225538fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
225638fd1498Szrj 	while (__f != __t)
225738fd1498Szrj 	  *__f++ = _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng));
225838fd1498Szrj       }
225938fd1498Szrj 
226038fd1498Szrj   template<typename _RealType>
226138fd1498Szrj     template<typename _ForwardIterator,
226238fd1498Szrj 	     typename _UniformRandomNumberGenerator>
226338fd1498Szrj       void
226438fd1498Szrj       std::student_t_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)226538fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
226638fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
226738fd1498Szrj 		      const param_type& __p)
226838fd1498Szrj       {
226938fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
227038fd1498Szrj 	typename std::gamma_distribution<result_type>::param_type
227138fd1498Szrj 	  __p2(__p.n() / 2, 2);
227238fd1498Szrj 	while (__f != __t)
227338fd1498Szrj 	  *__f++ =  _M_nd(__urng) * std::sqrt(__p.n() / _M_gd(__urng, __p2));
227438fd1498Szrj       }
227538fd1498Szrj 
227638fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
227738fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const student_t_distribution<_RealType> & __x)227838fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
227938fd1498Szrj 	       const student_t_distribution<_RealType>& __x)
228038fd1498Szrj     {
228138fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
228238fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
228338fd1498Szrj 
228438fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
228538fd1498Szrj       const _CharT __fill = __os.fill();
228638fd1498Szrj       const std::streamsize __precision = __os.precision();
228738fd1498Szrj       const _CharT __space = __os.widen(' ');
228838fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
228938fd1498Szrj       __os.fill(__space);
229038fd1498Szrj       __os.precision(std::numeric_limits<_RealType>::max_digits10);
229138fd1498Szrj 
229238fd1498Szrj       __os << __x.n() << __space << __x._M_nd << __space << __x._M_gd;
229338fd1498Szrj 
229438fd1498Szrj       __os.flags(__flags);
229538fd1498Szrj       __os.fill(__fill);
229638fd1498Szrj       __os.precision(__precision);
229738fd1498Szrj       return __os;
229838fd1498Szrj     }
229938fd1498Szrj 
230038fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
230138fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,student_t_distribution<_RealType> & __x)230238fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
230338fd1498Szrj 	       student_t_distribution<_RealType>& __x)
230438fd1498Szrj     {
230538fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
230638fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
230738fd1498Szrj 
230838fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
230938fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
231038fd1498Szrj 
231138fd1498Szrj       _RealType __n;
231238fd1498Szrj       __is >> __n >> __x._M_nd >> __x._M_gd;
231338fd1498Szrj       __x.param(typename student_t_distribution<_RealType>::param_type(__n));
231438fd1498Szrj 
231538fd1498Szrj       __is.flags(__flags);
231638fd1498Szrj       return __is;
231738fd1498Szrj     }
231838fd1498Szrj 
231938fd1498Szrj 
232038fd1498Szrj   template<typename _RealType>
232138fd1498Szrj     void
232238fd1498Szrj     gamma_distribution<_RealType>::param_type::
_M_initialize()232338fd1498Szrj     _M_initialize()
232438fd1498Szrj     {
232538fd1498Szrj       _M_malpha = _M_alpha < 1.0 ? _M_alpha + _RealType(1.0) : _M_alpha;
232638fd1498Szrj 
232738fd1498Szrj       const _RealType __a1 = _M_malpha - _RealType(1.0) / _RealType(3.0);
232838fd1498Szrj       _M_a2 = _RealType(1.0) / std::sqrt(_RealType(9.0) * __a1);
232938fd1498Szrj     }
233038fd1498Szrj 
233138fd1498Szrj   /**
233238fd1498Szrj    * Marsaglia, G. and Tsang, W. W.
233338fd1498Szrj    * "A Simple Method for Generating Gamma Variables"
233438fd1498Szrj    * ACM Transactions on Mathematical Software, 26, 3, 363-372, 2000.
233538fd1498Szrj    */
233638fd1498Szrj   template<typename _RealType>
233738fd1498Szrj     template<typename _UniformRandomNumberGenerator>
233838fd1498Szrj       typename gamma_distribution<_RealType>::result_type
233938fd1498Szrj       gamma_distribution<_RealType>::
operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)234038fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng,
234138fd1498Szrj 		 const param_type& __param)
234238fd1498Szrj       {
234338fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
234438fd1498Szrj 	  __aurng(__urng);
234538fd1498Szrj 
234638fd1498Szrj 	result_type __u, __v, __n;
234738fd1498Szrj 	const result_type __a1 = (__param._M_malpha
234838fd1498Szrj 				  - _RealType(1.0) / _RealType(3.0));
234938fd1498Szrj 
235038fd1498Szrj 	do
235138fd1498Szrj 	  {
235238fd1498Szrj 	    do
235338fd1498Szrj 	      {
235438fd1498Szrj 		__n = _M_nd(__urng);
235538fd1498Szrj 		__v = result_type(1.0) + __param._M_a2 * __n;
235638fd1498Szrj 	      }
235738fd1498Szrj 	    while (__v <= 0.0);
235838fd1498Szrj 
235938fd1498Szrj 	    __v = __v * __v * __v;
236038fd1498Szrj 	    __u = __aurng();
236138fd1498Szrj 	  }
236238fd1498Szrj 	while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n
236338fd1498Szrj 	       && (std::log(__u) > (0.5 * __n * __n + __a1
236438fd1498Szrj 				    * (1.0 - __v + std::log(__v)))));
236538fd1498Szrj 
236638fd1498Szrj 	if (__param.alpha() == __param._M_malpha)
236738fd1498Szrj 	  return __a1 * __v * __param.beta();
236838fd1498Szrj 	else
236938fd1498Szrj 	  {
237038fd1498Szrj 	    do
237138fd1498Szrj 	      __u = __aurng();
237238fd1498Szrj 	    while (__u == 0.0);
237338fd1498Szrj 
237438fd1498Szrj 	    return (std::pow(__u, result_type(1.0) / __param.alpha())
237538fd1498Szrj 		    * __a1 * __v * __param.beta());
237638fd1498Szrj 	  }
237738fd1498Szrj       }
237838fd1498Szrj 
237938fd1498Szrj   template<typename _RealType>
238038fd1498Szrj     template<typename _ForwardIterator,
238138fd1498Szrj 	     typename _UniformRandomNumberGenerator>
238238fd1498Szrj       void
238338fd1498Szrj       gamma_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)238438fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
238538fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
238638fd1498Szrj 		      const param_type& __param)
238738fd1498Szrj       {
238838fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
238938fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
239038fd1498Szrj 	  __aurng(__urng);
239138fd1498Szrj 
239238fd1498Szrj 	result_type __u, __v, __n;
239338fd1498Szrj 	const result_type __a1 = (__param._M_malpha
239438fd1498Szrj 				  - _RealType(1.0) / _RealType(3.0));
239538fd1498Szrj 
239638fd1498Szrj 	if (__param.alpha() == __param._M_malpha)
239738fd1498Szrj 	  while (__f != __t)
239838fd1498Szrj 	    {
239938fd1498Szrj 	      do
240038fd1498Szrj 		{
240138fd1498Szrj 		  do
240238fd1498Szrj 		    {
240338fd1498Szrj 		      __n = _M_nd(__urng);
240438fd1498Szrj 		      __v = result_type(1.0) + __param._M_a2 * __n;
240538fd1498Szrj 		    }
240638fd1498Szrj 		  while (__v <= 0.0);
240738fd1498Szrj 
240838fd1498Szrj 		  __v = __v * __v * __v;
240938fd1498Szrj 		  __u = __aurng();
241038fd1498Szrj 		}
2411*58e805e6Szrj 	      while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n
241238fd1498Szrj 		     && (std::log(__u) > (0.5 * __n * __n + __a1
241338fd1498Szrj 					  * (1.0 - __v + std::log(__v)))));
241438fd1498Szrj 
241538fd1498Szrj 	      *__f++ = __a1 * __v * __param.beta();
241638fd1498Szrj 	    }
241738fd1498Szrj 	else
241838fd1498Szrj 	  while (__f != __t)
241938fd1498Szrj 	    {
242038fd1498Szrj 	      do
242138fd1498Szrj 		{
242238fd1498Szrj 		  do
242338fd1498Szrj 		    {
242438fd1498Szrj 		      __n = _M_nd(__urng);
242538fd1498Szrj 		      __v = result_type(1.0) + __param._M_a2 * __n;
242638fd1498Szrj 		    }
242738fd1498Szrj 		  while (__v <= 0.0);
242838fd1498Szrj 
242938fd1498Szrj 		  __v = __v * __v * __v;
243038fd1498Szrj 		  __u = __aurng();
243138fd1498Szrj 		}
2432*58e805e6Szrj 	      while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n
243338fd1498Szrj 		     && (std::log(__u) > (0.5 * __n * __n + __a1
243438fd1498Szrj 					  * (1.0 - __v + std::log(__v)))));
243538fd1498Szrj 
243638fd1498Szrj 	      do
243738fd1498Szrj 		__u = __aurng();
243838fd1498Szrj 	      while (__u == 0.0);
243938fd1498Szrj 
244038fd1498Szrj 	      *__f++ = (std::pow(__u, result_type(1.0) / __param.alpha())
244138fd1498Szrj 			* __a1 * __v * __param.beta());
244238fd1498Szrj 	    }
244338fd1498Szrj       }
244438fd1498Szrj 
244538fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
244638fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const gamma_distribution<_RealType> & __x)244738fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
244838fd1498Szrj 	       const gamma_distribution<_RealType>& __x)
244938fd1498Szrj     {
245038fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
245138fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
245238fd1498Szrj 
245338fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
245438fd1498Szrj       const _CharT __fill = __os.fill();
245538fd1498Szrj       const std::streamsize __precision = __os.precision();
245638fd1498Szrj       const _CharT __space = __os.widen(' ');
245738fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
245838fd1498Szrj       __os.fill(__space);
245938fd1498Szrj       __os.precision(std::numeric_limits<_RealType>::max_digits10);
246038fd1498Szrj 
246138fd1498Szrj       __os << __x.alpha() << __space << __x.beta()
246238fd1498Szrj 	   << __space << __x._M_nd;
246338fd1498Szrj 
246438fd1498Szrj       __os.flags(__flags);
246538fd1498Szrj       __os.fill(__fill);
246638fd1498Szrj       __os.precision(__precision);
246738fd1498Szrj       return __os;
246838fd1498Szrj     }
246938fd1498Szrj 
247038fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
247138fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,gamma_distribution<_RealType> & __x)247238fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
247338fd1498Szrj 	       gamma_distribution<_RealType>& __x)
247438fd1498Szrj     {
247538fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
247638fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
247738fd1498Szrj 
247838fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
247938fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
248038fd1498Szrj 
248138fd1498Szrj       _RealType __alpha_val, __beta_val;
248238fd1498Szrj       __is >> __alpha_val >> __beta_val >> __x._M_nd;
248338fd1498Szrj       __x.param(typename gamma_distribution<_RealType>::
248438fd1498Szrj 		param_type(__alpha_val, __beta_val));
248538fd1498Szrj 
248638fd1498Szrj       __is.flags(__flags);
248738fd1498Szrj       return __is;
248838fd1498Szrj     }
248938fd1498Szrj 
249038fd1498Szrj 
249138fd1498Szrj   template<typename _RealType>
249238fd1498Szrj     template<typename _UniformRandomNumberGenerator>
249338fd1498Szrj       typename weibull_distribution<_RealType>::result_type
249438fd1498Szrj       weibull_distribution<_RealType>::
operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __p)249538fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng,
249638fd1498Szrj 		 const param_type& __p)
249738fd1498Szrj       {
249838fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
249938fd1498Szrj 	  __aurng(__urng);
250038fd1498Szrj 	return __p.b() * std::pow(-std::log(result_type(1) - __aurng()),
250138fd1498Szrj 				  result_type(1) / __p.a());
250238fd1498Szrj       }
250338fd1498Szrj 
250438fd1498Szrj   template<typename _RealType>
250538fd1498Szrj     template<typename _ForwardIterator,
250638fd1498Szrj 	     typename _UniformRandomNumberGenerator>
250738fd1498Szrj       void
250838fd1498Szrj       weibull_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)250938fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
251038fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
251138fd1498Szrj 		      const param_type& __p)
251238fd1498Szrj       {
251338fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
251438fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
251538fd1498Szrj 	  __aurng(__urng);
251638fd1498Szrj 	auto __inv_a = result_type(1) / __p.a();
251738fd1498Szrj 
251838fd1498Szrj 	while (__f != __t)
251938fd1498Szrj 	  *__f++ = __p.b() * std::pow(-std::log(result_type(1) - __aurng()),
252038fd1498Szrj 				      __inv_a);
252138fd1498Szrj       }
252238fd1498Szrj 
252338fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
252438fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const weibull_distribution<_RealType> & __x)252538fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
252638fd1498Szrj 	       const weibull_distribution<_RealType>& __x)
252738fd1498Szrj     {
252838fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
252938fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
253038fd1498Szrj 
253138fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
253238fd1498Szrj       const _CharT __fill = __os.fill();
253338fd1498Szrj       const std::streamsize __precision = __os.precision();
253438fd1498Szrj       const _CharT __space = __os.widen(' ');
253538fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
253638fd1498Szrj       __os.fill(__space);
253738fd1498Szrj       __os.precision(std::numeric_limits<_RealType>::max_digits10);
253838fd1498Szrj 
253938fd1498Szrj       __os << __x.a() << __space << __x.b();
254038fd1498Szrj 
254138fd1498Szrj       __os.flags(__flags);
254238fd1498Szrj       __os.fill(__fill);
254338fd1498Szrj       __os.precision(__precision);
254438fd1498Szrj       return __os;
254538fd1498Szrj     }
254638fd1498Szrj 
254738fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
254838fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,weibull_distribution<_RealType> & __x)254938fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
255038fd1498Szrj 	       weibull_distribution<_RealType>& __x)
255138fd1498Szrj     {
255238fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
255338fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
255438fd1498Szrj 
255538fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
255638fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
255738fd1498Szrj 
255838fd1498Szrj       _RealType __a, __b;
255938fd1498Szrj       __is >> __a >> __b;
256038fd1498Szrj       __x.param(typename weibull_distribution<_RealType>::
256138fd1498Szrj 		param_type(__a, __b));
256238fd1498Szrj 
256338fd1498Szrj       __is.flags(__flags);
256438fd1498Szrj       return __is;
256538fd1498Szrj     }
256638fd1498Szrj 
256738fd1498Szrj 
256838fd1498Szrj   template<typename _RealType>
256938fd1498Szrj     template<typename _UniformRandomNumberGenerator>
257038fd1498Szrj       typename extreme_value_distribution<_RealType>::result_type
257138fd1498Szrj       extreme_value_distribution<_RealType>::
operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __p)257238fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng,
257338fd1498Szrj 		 const param_type& __p)
257438fd1498Szrj       {
257538fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
257638fd1498Szrj 	  __aurng(__urng);
257738fd1498Szrj 	return __p.a() - __p.b() * std::log(-std::log(result_type(1)
257838fd1498Szrj 						      - __aurng()));
257938fd1498Szrj       }
258038fd1498Szrj 
258138fd1498Szrj   template<typename _RealType>
258238fd1498Szrj     template<typename _ForwardIterator,
258338fd1498Szrj 	     typename _UniformRandomNumberGenerator>
258438fd1498Szrj       void
258538fd1498Szrj       extreme_value_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __p)258638fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
258738fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
258838fd1498Szrj 		      const param_type& __p)
258938fd1498Szrj       {
259038fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
259138fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
259238fd1498Szrj 	  __aurng(__urng);
259338fd1498Szrj 
259438fd1498Szrj 	while (__f != __t)
259538fd1498Szrj 	  *__f++ = __p.a() - __p.b() * std::log(-std::log(result_type(1)
259638fd1498Szrj 							  - __aurng()));
259738fd1498Szrj       }
259838fd1498Szrj 
259938fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
260038fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const extreme_value_distribution<_RealType> & __x)260138fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
260238fd1498Szrj 	       const extreme_value_distribution<_RealType>& __x)
260338fd1498Szrj     {
260438fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
260538fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
260638fd1498Szrj 
260738fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
260838fd1498Szrj       const _CharT __fill = __os.fill();
260938fd1498Szrj       const std::streamsize __precision = __os.precision();
261038fd1498Szrj       const _CharT __space = __os.widen(' ');
261138fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
261238fd1498Szrj       __os.fill(__space);
261338fd1498Szrj       __os.precision(std::numeric_limits<_RealType>::max_digits10);
261438fd1498Szrj 
261538fd1498Szrj       __os << __x.a() << __space << __x.b();
261638fd1498Szrj 
261738fd1498Szrj       __os.flags(__flags);
261838fd1498Szrj       __os.fill(__fill);
261938fd1498Szrj       __os.precision(__precision);
262038fd1498Szrj       return __os;
262138fd1498Szrj     }
262238fd1498Szrj 
262338fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
262438fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,extreme_value_distribution<_RealType> & __x)262538fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
262638fd1498Szrj 	       extreme_value_distribution<_RealType>& __x)
262738fd1498Szrj     {
262838fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
262938fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
263038fd1498Szrj 
263138fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
263238fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
263338fd1498Szrj 
263438fd1498Szrj       _RealType __a, __b;
263538fd1498Szrj       __is >> __a >> __b;
263638fd1498Szrj       __x.param(typename extreme_value_distribution<_RealType>::
263738fd1498Szrj 		param_type(__a, __b));
263838fd1498Szrj 
263938fd1498Szrj       __is.flags(__flags);
264038fd1498Szrj       return __is;
264138fd1498Szrj     }
264238fd1498Szrj 
264338fd1498Szrj 
264438fd1498Szrj   template<typename _IntType>
264538fd1498Szrj     void
264638fd1498Szrj     discrete_distribution<_IntType>::param_type::
_M_initialize()264738fd1498Szrj     _M_initialize()
264838fd1498Szrj     {
264938fd1498Szrj       if (_M_prob.size() < 2)
265038fd1498Szrj 	{
265138fd1498Szrj 	  _M_prob.clear();
265238fd1498Szrj 	  return;
265338fd1498Szrj 	}
265438fd1498Szrj 
265538fd1498Szrj       const double __sum = std::accumulate(_M_prob.begin(),
265638fd1498Szrj 					   _M_prob.end(), 0.0);
265738fd1498Szrj       // Now normalize the probabilites.
265838fd1498Szrj       __detail::__normalize(_M_prob.begin(), _M_prob.end(), _M_prob.begin(),
265938fd1498Szrj 			    __sum);
266038fd1498Szrj       // Accumulate partial sums.
266138fd1498Szrj       _M_cp.reserve(_M_prob.size());
266238fd1498Szrj       std::partial_sum(_M_prob.begin(), _M_prob.end(),
266338fd1498Szrj 		       std::back_inserter(_M_cp));
266438fd1498Szrj       // Make sure the last cumulative probability is one.
266538fd1498Szrj       _M_cp[_M_cp.size() - 1] = 1.0;
266638fd1498Szrj     }
266738fd1498Szrj 
266838fd1498Szrj   template<typename _IntType>
266938fd1498Szrj     template<typename _Func>
267038fd1498Szrj       discrete_distribution<_IntType>::param_type::
param_type(size_t __nw,double __xmin,double __xmax,_Func __fw)267138fd1498Szrj       param_type(size_t __nw, double __xmin, double __xmax, _Func __fw)
267238fd1498Szrj       : _M_prob(), _M_cp()
267338fd1498Szrj       {
267438fd1498Szrj 	const size_t __n = __nw == 0 ? 1 : __nw;
267538fd1498Szrj 	const double __delta = (__xmax - __xmin) / __n;
267638fd1498Szrj 
267738fd1498Szrj 	_M_prob.reserve(__n);
267838fd1498Szrj 	for (size_t __k = 0; __k < __nw; ++__k)
267938fd1498Szrj 	  _M_prob.push_back(__fw(__xmin + __k * __delta + 0.5 * __delta));
268038fd1498Szrj 
268138fd1498Szrj 	_M_initialize();
268238fd1498Szrj       }
268338fd1498Szrj 
268438fd1498Szrj   template<typename _IntType>
268538fd1498Szrj     template<typename _UniformRandomNumberGenerator>
268638fd1498Szrj       typename discrete_distribution<_IntType>::result_type
268738fd1498Szrj       discrete_distribution<_IntType>::
operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)268838fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng,
268938fd1498Szrj 		 const param_type& __param)
269038fd1498Szrj       {
269138fd1498Szrj 	if (__param._M_cp.empty())
269238fd1498Szrj 	  return result_type(0);
269338fd1498Szrj 
269438fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
269538fd1498Szrj 	  __aurng(__urng);
269638fd1498Szrj 
269738fd1498Szrj 	const double __p = __aurng();
269838fd1498Szrj 	auto __pos = std::lower_bound(__param._M_cp.begin(),
269938fd1498Szrj 				      __param._M_cp.end(), __p);
270038fd1498Szrj 
270138fd1498Szrj 	return __pos - __param._M_cp.begin();
270238fd1498Szrj       }
270338fd1498Szrj 
270438fd1498Szrj   template<typename _IntType>
270538fd1498Szrj     template<typename _ForwardIterator,
270638fd1498Szrj 	     typename _UniformRandomNumberGenerator>
270738fd1498Szrj       void
270838fd1498Szrj       discrete_distribution<_IntType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)270938fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
271038fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
271138fd1498Szrj 		      const param_type& __param)
271238fd1498Szrj       {
271338fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
271438fd1498Szrj 
271538fd1498Szrj 	if (__param._M_cp.empty())
271638fd1498Szrj 	  {
271738fd1498Szrj 	    while (__f != __t)
271838fd1498Szrj 	      *__f++ = result_type(0);
271938fd1498Szrj 	    return;
272038fd1498Szrj 	  }
272138fd1498Szrj 
272238fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
272338fd1498Szrj 	  __aurng(__urng);
272438fd1498Szrj 
272538fd1498Szrj 	while (__f != __t)
272638fd1498Szrj 	  {
272738fd1498Szrj 	    const double __p = __aurng();
272838fd1498Szrj 	    auto __pos = std::lower_bound(__param._M_cp.begin(),
272938fd1498Szrj 					  __param._M_cp.end(), __p);
273038fd1498Szrj 
273138fd1498Szrj 	    *__f++ = __pos - __param._M_cp.begin();
273238fd1498Szrj 	  }
273338fd1498Szrj       }
273438fd1498Szrj 
273538fd1498Szrj   template<typename _IntType, typename _CharT, typename _Traits>
273638fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const discrete_distribution<_IntType> & __x)273738fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
273838fd1498Szrj 	       const discrete_distribution<_IntType>& __x)
273938fd1498Szrj     {
274038fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
274138fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
274238fd1498Szrj 
274338fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
274438fd1498Szrj       const _CharT __fill = __os.fill();
274538fd1498Szrj       const std::streamsize __precision = __os.precision();
274638fd1498Szrj       const _CharT __space = __os.widen(' ');
274738fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
274838fd1498Szrj       __os.fill(__space);
274938fd1498Szrj       __os.precision(std::numeric_limits<double>::max_digits10);
275038fd1498Szrj 
275138fd1498Szrj       std::vector<double> __prob = __x.probabilities();
275238fd1498Szrj       __os << __prob.size();
275338fd1498Szrj       for (auto __dit = __prob.begin(); __dit != __prob.end(); ++__dit)
275438fd1498Szrj 	__os << __space << *__dit;
275538fd1498Szrj 
275638fd1498Szrj       __os.flags(__flags);
275738fd1498Szrj       __os.fill(__fill);
275838fd1498Szrj       __os.precision(__precision);
275938fd1498Szrj       return __os;
276038fd1498Szrj     }
276138fd1498Szrj 
276238fd1498Szrj   template<typename _IntType, typename _CharT, typename _Traits>
276338fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,discrete_distribution<_IntType> & __x)276438fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
276538fd1498Szrj 	       discrete_distribution<_IntType>& __x)
276638fd1498Szrj     {
276738fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
276838fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
276938fd1498Szrj 
277038fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
277138fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
277238fd1498Szrj 
277338fd1498Szrj       size_t __n;
277438fd1498Szrj       __is >> __n;
277538fd1498Szrj 
277638fd1498Szrj       std::vector<double> __prob_vec;
277738fd1498Szrj       __prob_vec.reserve(__n);
277838fd1498Szrj       for (; __n != 0; --__n)
277938fd1498Szrj 	{
278038fd1498Szrj 	  double __prob;
278138fd1498Szrj 	  __is >> __prob;
278238fd1498Szrj 	  __prob_vec.push_back(__prob);
278338fd1498Szrj 	}
278438fd1498Szrj 
278538fd1498Szrj       __x.param(typename discrete_distribution<_IntType>::
278638fd1498Szrj 		param_type(__prob_vec.begin(), __prob_vec.end()));
278738fd1498Szrj 
278838fd1498Szrj       __is.flags(__flags);
278938fd1498Szrj       return __is;
279038fd1498Szrj     }
279138fd1498Szrj 
279238fd1498Szrj 
279338fd1498Szrj   template<typename _RealType>
279438fd1498Szrj     void
279538fd1498Szrj     piecewise_constant_distribution<_RealType>::param_type::
_M_initialize()279638fd1498Szrj     _M_initialize()
279738fd1498Szrj     {
279838fd1498Szrj       if (_M_int.size() < 2
279938fd1498Szrj 	  || (_M_int.size() == 2
280038fd1498Szrj 	      && _M_int[0] == _RealType(0)
280138fd1498Szrj 	      && _M_int[1] == _RealType(1)))
280238fd1498Szrj 	{
280338fd1498Szrj 	  _M_int.clear();
280438fd1498Szrj 	  _M_den.clear();
280538fd1498Szrj 	  return;
280638fd1498Szrj 	}
280738fd1498Szrj 
280838fd1498Szrj       const double __sum = std::accumulate(_M_den.begin(),
280938fd1498Szrj 					   _M_den.end(), 0.0);
281038fd1498Szrj 
281138fd1498Szrj       __detail::__normalize(_M_den.begin(), _M_den.end(), _M_den.begin(),
281238fd1498Szrj 			    __sum);
281338fd1498Szrj 
281438fd1498Szrj       _M_cp.reserve(_M_den.size());
281538fd1498Szrj       std::partial_sum(_M_den.begin(), _M_den.end(),
281638fd1498Szrj 		       std::back_inserter(_M_cp));
281738fd1498Szrj 
281838fd1498Szrj       // Make sure the last cumulative probability is one.
281938fd1498Szrj       _M_cp[_M_cp.size() - 1] = 1.0;
282038fd1498Szrj 
282138fd1498Szrj       for (size_t __k = 0; __k < _M_den.size(); ++__k)
282238fd1498Szrj 	_M_den[__k] /= _M_int[__k + 1] - _M_int[__k];
282338fd1498Szrj     }
282438fd1498Szrj 
282538fd1498Szrj   template<typename _RealType>
282638fd1498Szrj     template<typename _InputIteratorB, typename _InputIteratorW>
282738fd1498Szrj       piecewise_constant_distribution<_RealType>::param_type::
param_type(_InputIteratorB __bbegin,_InputIteratorB __bend,_InputIteratorW __wbegin)282838fd1498Szrj       param_type(_InputIteratorB __bbegin,
282938fd1498Szrj 		 _InputIteratorB __bend,
283038fd1498Szrj 		 _InputIteratorW __wbegin)
283138fd1498Szrj       : _M_int(), _M_den(), _M_cp()
283238fd1498Szrj       {
283338fd1498Szrj 	if (__bbegin != __bend)
283438fd1498Szrj 	  {
283538fd1498Szrj 	    for (;;)
283638fd1498Szrj 	      {
283738fd1498Szrj 		_M_int.push_back(*__bbegin);
283838fd1498Szrj 		++__bbegin;
283938fd1498Szrj 		if (__bbegin == __bend)
284038fd1498Szrj 		  break;
284138fd1498Szrj 
284238fd1498Szrj 		_M_den.push_back(*__wbegin);
284338fd1498Szrj 		++__wbegin;
284438fd1498Szrj 	      }
284538fd1498Szrj 	  }
284638fd1498Szrj 
284738fd1498Szrj 	_M_initialize();
284838fd1498Szrj       }
284938fd1498Szrj 
285038fd1498Szrj   template<typename _RealType>
285138fd1498Szrj     template<typename _Func>
285238fd1498Szrj       piecewise_constant_distribution<_RealType>::param_type::
param_type(initializer_list<_RealType> __bl,_Func __fw)285338fd1498Szrj       param_type(initializer_list<_RealType> __bl, _Func __fw)
285438fd1498Szrj       : _M_int(), _M_den(), _M_cp()
285538fd1498Szrj       {
285638fd1498Szrj 	_M_int.reserve(__bl.size());
285738fd1498Szrj 	for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter)
285838fd1498Szrj 	  _M_int.push_back(*__biter);
285938fd1498Szrj 
286038fd1498Szrj 	_M_den.reserve(_M_int.size() - 1);
286138fd1498Szrj 	for (size_t __k = 0; __k < _M_int.size() - 1; ++__k)
286238fd1498Szrj 	  _M_den.push_back(__fw(0.5 * (_M_int[__k + 1] + _M_int[__k])));
286338fd1498Szrj 
286438fd1498Szrj 	_M_initialize();
286538fd1498Szrj       }
286638fd1498Szrj 
286738fd1498Szrj   template<typename _RealType>
286838fd1498Szrj     template<typename _Func>
286938fd1498Szrj       piecewise_constant_distribution<_RealType>::param_type::
param_type(size_t __nw,_RealType __xmin,_RealType __xmax,_Func __fw)287038fd1498Szrj       param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw)
287138fd1498Szrj       : _M_int(), _M_den(), _M_cp()
287238fd1498Szrj       {
287338fd1498Szrj 	const size_t __n = __nw == 0 ? 1 : __nw;
287438fd1498Szrj 	const _RealType __delta = (__xmax - __xmin) / __n;
287538fd1498Szrj 
287638fd1498Szrj 	_M_int.reserve(__n + 1);
287738fd1498Szrj 	for (size_t __k = 0; __k <= __nw; ++__k)
287838fd1498Szrj 	  _M_int.push_back(__xmin + __k * __delta);
287938fd1498Szrj 
288038fd1498Szrj 	_M_den.reserve(__n);
288138fd1498Szrj 	for (size_t __k = 0; __k < __nw; ++__k)
288238fd1498Szrj 	  _M_den.push_back(__fw(_M_int[__k] + 0.5 * __delta));
288338fd1498Szrj 
288438fd1498Szrj 	_M_initialize();
288538fd1498Szrj       }
288638fd1498Szrj 
288738fd1498Szrj   template<typename _RealType>
288838fd1498Szrj     template<typename _UniformRandomNumberGenerator>
288938fd1498Szrj       typename piecewise_constant_distribution<_RealType>::result_type
289038fd1498Szrj       piecewise_constant_distribution<_RealType>::
operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)289138fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng,
289238fd1498Szrj 		 const param_type& __param)
289338fd1498Szrj       {
289438fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
289538fd1498Szrj 	  __aurng(__urng);
289638fd1498Szrj 
289738fd1498Szrj 	const double __p = __aurng();
289838fd1498Szrj 	if (__param._M_cp.empty())
289938fd1498Szrj 	  return __p;
290038fd1498Szrj 
290138fd1498Szrj 	auto __pos = std::lower_bound(__param._M_cp.begin(),
290238fd1498Szrj 				      __param._M_cp.end(), __p);
290338fd1498Szrj 	const size_t __i = __pos - __param._M_cp.begin();
290438fd1498Szrj 
290538fd1498Szrj 	const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
290638fd1498Szrj 
290738fd1498Szrj 	return __param._M_int[__i] + (__p - __pref) / __param._M_den[__i];
290838fd1498Szrj       }
290938fd1498Szrj 
291038fd1498Szrj   template<typename _RealType>
291138fd1498Szrj     template<typename _ForwardIterator,
291238fd1498Szrj 	     typename _UniformRandomNumberGenerator>
291338fd1498Szrj       void
291438fd1498Szrj       piecewise_constant_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)291538fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
291638fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
291738fd1498Szrj 		      const param_type& __param)
291838fd1498Szrj       {
291938fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
292038fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
292138fd1498Szrj 	  __aurng(__urng);
292238fd1498Szrj 
292338fd1498Szrj 	if (__param._M_cp.empty())
292438fd1498Szrj 	  {
292538fd1498Szrj 	    while (__f != __t)
292638fd1498Szrj 	      *__f++ = __aurng();
292738fd1498Szrj 	    return;
292838fd1498Szrj 	  }
292938fd1498Szrj 
293038fd1498Szrj 	while (__f != __t)
293138fd1498Szrj 	  {
293238fd1498Szrj 	    const double __p = __aurng();
293338fd1498Szrj 
293438fd1498Szrj 	    auto __pos = std::lower_bound(__param._M_cp.begin(),
293538fd1498Szrj 					  __param._M_cp.end(), __p);
293638fd1498Szrj 	    const size_t __i = __pos - __param._M_cp.begin();
293738fd1498Szrj 
293838fd1498Szrj 	    const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
293938fd1498Szrj 
294038fd1498Szrj 	    *__f++ = (__param._M_int[__i]
294138fd1498Szrj 		      + (__p - __pref) / __param._M_den[__i]);
294238fd1498Szrj 	  }
294338fd1498Szrj       }
294438fd1498Szrj 
294538fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
294638fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const piecewise_constant_distribution<_RealType> & __x)294738fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
294838fd1498Szrj 	       const piecewise_constant_distribution<_RealType>& __x)
294938fd1498Szrj     {
295038fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
295138fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
295238fd1498Szrj 
295338fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
295438fd1498Szrj       const _CharT __fill = __os.fill();
295538fd1498Szrj       const std::streamsize __precision = __os.precision();
295638fd1498Szrj       const _CharT __space = __os.widen(' ');
295738fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
295838fd1498Szrj       __os.fill(__space);
295938fd1498Szrj       __os.precision(std::numeric_limits<_RealType>::max_digits10);
296038fd1498Szrj 
296138fd1498Szrj       std::vector<_RealType> __int = __x.intervals();
296238fd1498Szrj       __os << __int.size() - 1;
296338fd1498Szrj 
296438fd1498Szrj       for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit)
296538fd1498Szrj 	__os << __space << *__xit;
296638fd1498Szrj 
296738fd1498Szrj       std::vector<double> __den = __x.densities();
296838fd1498Szrj       for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit)
296938fd1498Szrj 	__os << __space << *__dit;
297038fd1498Szrj 
297138fd1498Szrj       __os.flags(__flags);
297238fd1498Szrj       __os.fill(__fill);
297338fd1498Szrj       __os.precision(__precision);
297438fd1498Szrj       return __os;
297538fd1498Szrj     }
297638fd1498Szrj 
297738fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
297838fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,piecewise_constant_distribution<_RealType> & __x)297938fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
298038fd1498Szrj 	       piecewise_constant_distribution<_RealType>& __x)
298138fd1498Szrj     {
298238fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
298338fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
298438fd1498Szrj 
298538fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
298638fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
298738fd1498Szrj 
298838fd1498Szrj       size_t __n;
298938fd1498Szrj       __is >> __n;
299038fd1498Szrj 
299138fd1498Szrj       std::vector<_RealType> __int_vec;
299238fd1498Szrj       __int_vec.reserve(__n + 1);
299338fd1498Szrj       for (size_t __i = 0; __i <= __n; ++__i)
299438fd1498Szrj 	{
299538fd1498Szrj 	  _RealType __int;
299638fd1498Szrj 	  __is >> __int;
299738fd1498Szrj 	  __int_vec.push_back(__int);
299838fd1498Szrj 	}
299938fd1498Szrj 
300038fd1498Szrj       std::vector<double> __den_vec;
300138fd1498Szrj       __den_vec.reserve(__n);
300238fd1498Szrj       for (size_t __i = 0; __i < __n; ++__i)
300338fd1498Szrj 	{
300438fd1498Szrj 	  double __den;
300538fd1498Szrj 	  __is >> __den;
300638fd1498Szrj 	  __den_vec.push_back(__den);
300738fd1498Szrj 	}
300838fd1498Szrj 
300938fd1498Szrj       __x.param(typename piecewise_constant_distribution<_RealType>::
301038fd1498Szrj 	  param_type(__int_vec.begin(), __int_vec.end(), __den_vec.begin()));
301138fd1498Szrj 
301238fd1498Szrj       __is.flags(__flags);
301338fd1498Szrj       return __is;
301438fd1498Szrj     }
301538fd1498Szrj 
301638fd1498Szrj 
301738fd1498Szrj   template<typename _RealType>
301838fd1498Szrj     void
301938fd1498Szrj     piecewise_linear_distribution<_RealType>::param_type::
_M_initialize()302038fd1498Szrj     _M_initialize()
302138fd1498Szrj     {
302238fd1498Szrj       if (_M_int.size() < 2
302338fd1498Szrj 	  || (_M_int.size() == 2
302438fd1498Szrj 	      && _M_int[0] == _RealType(0)
302538fd1498Szrj 	      && _M_int[1] == _RealType(1)
302638fd1498Szrj 	      && _M_den[0] == _M_den[1]))
302738fd1498Szrj 	{
302838fd1498Szrj 	  _M_int.clear();
302938fd1498Szrj 	  _M_den.clear();
303038fd1498Szrj 	  return;
303138fd1498Szrj 	}
303238fd1498Szrj 
303338fd1498Szrj       double __sum = 0.0;
303438fd1498Szrj       _M_cp.reserve(_M_int.size() - 1);
303538fd1498Szrj       _M_m.reserve(_M_int.size() - 1);
303638fd1498Szrj       for (size_t __k = 0; __k < _M_int.size() - 1; ++__k)
303738fd1498Szrj 	{
303838fd1498Szrj 	  const _RealType __delta = _M_int[__k + 1] - _M_int[__k];
303938fd1498Szrj 	  __sum += 0.5 * (_M_den[__k + 1] + _M_den[__k]) * __delta;
304038fd1498Szrj 	  _M_cp.push_back(__sum);
304138fd1498Szrj 	  _M_m.push_back((_M_den[__k + 1] - _M_den[__k]) / __delta);
304238fd1498Szrj 	}
304338fd1498Szrj 
304438fd1498Szrj       //  Now normalize the densities...
304538fd1498Szrj       __detail::__normalize(_M_den.begin(), _M_den.end(), _M_den.begin(),
304638fd1498Szrj 			    __sum);
304738fd1498Szrj       //  ... and partial sums...
304838fd1498Szrj       __detail::__normalize(_M_cp.begin(), _M_cp.end(), _M_cp.begin(), __sum);
304938fd1498Szrj       //  ... and slopes.
305038fd1498Szrj       __detail::__normalize(_M_m.begin(), _M_m.end(), _M_m.begin(), __sum);
305138fd1498Szrj 
305238fd1498Szrj       //  Make sure the last cumulative probablility is one.
305338fd1498Szrj       _M_cp[_M_cp.size() - 1] = 1.0;
305438fd1498Szrj      }
305538fd1498Szrj 
305638fd1498Szrj   template<typename _RealType>
305738fd1498Szrj     template<typename _InputIteratorB, typename _InputIteratorW>
305838fd1498Szrj       piecewise_linear_distribution<_RealType>::param_type::
param_type(_InputIteratorB __bbegin,_InputIteratorB __bend,_InputIteratorW __wbegin)305938fd1498Szrj       param_type(_InputIteratorB __bbegin,
306038fd1498Szrj 		 _InputIteratorB __bend,
306138fd1498Szrj 		 _InputIteratorW __wbegin)
306238fd1498Szrj       : _M_int(), _M_den(), _M_cp(), _M_m()
306338fd1498Szrj       {
306438fd1498Szrj 	for (; __bbegin != __bend; ++__bbegin, ++__wbegin)
306538fd1498Szrj 	  {
306638fd1498Szrj 	    _M_int.push_back(*__bbegin);
306738fd1498Szrj 	    _M_den.push_back(*__wbegin);
306838fd1498Szrj 	  }
306938fd1498Szrj 
307038fd1498Szrj 	_M_initialize();
307138fd1498Szrj       }
307238fd1498Szrj 
307338fd1498Szrj   template<typename _RealType>
307438fd1498Szrj     template<typename _Func>
307538fd1498Szrj       piecewise_linear_distribution<_RealType>::param_type::
param_type(initializer_list<_RealType> __bl,_Func __fw)307638fd1498Szrj       param_type(initializer_list<_RealType> __bl, _Func __fw)
307738fd1498Szrj       : _M_int(), _M_den(), _M_cp(), _M_m()
307838fd1498Szrj       {
307938fd1498Szrj 	_M_int.reserve(__bl.size());
308038fd1498Szrj 	_M_den.reserve(__bl.size());
308138fd1498Szrj 	for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter)
308238fd1498Szrj 	  {
308338fd1498Szrj 	    _M_int.push_back(*__biter);
308438fd1498Szrj 	    _M_den.push_back(__fw(*__biter));
308538fd1498Szrj 	  }
308638fd1498Szrj 
308738fd1498Szrj 	_M_initialize();
308838fd1498Szrj       }
308938fd1498Szrj 
309038fd1498Szrj   template<typename _RealType>
309138fd1498Szrj     template<typename _Func>
309238fd1498Szrj       piecewise_linear_distribution<_RealType>::param_type::
param_type(size_t __nw,_RealType __xmin,_RealType __xmax,_Func __fw)309338fd1498Szrj       param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw)
309438fd1498Szrj       : _M_int(), _M_den(), _M_cp(), _M_m()
309538fd1498Szrj       {
309638fd1498Szrj 	const size_t __n = __nw == 0 ? 1 : __nw;
309738fd1498Szrj 	const _RealType __delta = (__xmax - __xmin) / __n;
309838fd1498Szrj 
309938fd1498Szrj 	_M_int.reserve(__n + 1);
310038fd1498Szrj 	_M_den.reserve(__n + 1);
310138fd1498Szrj 	for (size_t __k = 0; __k <= __nw; ++__k)
310238fd1498Szrj 	  {
310338fd1498Szrj 	    _M_int.push_back(__xmin + __k * __delta);
310438fd1498Szrj 	    _M_den.push_back(__fw(_M_int[__k] + __delta));
310538fd1498Szrj 	  }
310638fd1498Szrj 
310738fd1498Szrj 	_M_initialize();
310838fd1498Szrj       }
310938fd1498Szrj 
311038fd1498Szrj   template<typename _RealType>
311138fd1498Szrj     template<typename _UniformRandomNumberGenerator>
311238fd1498Szrj       typename piecewise_linear_distribution<_RealType>::result_type
311338fd1498Szrj       piecewise_linear_distribution<_RealType>::
operator ()(_UniformRandomNumberGenerator & __urng,const param_type & __param)311438fd1498Szrj       operator()(_UniformRandomNumberGenerator& __urng,
311538fd1498Szrj 		 const param_type& __param)
311638fd1498Szrj       {
311738fd1498Szrj 	__detail::_Adaptor<_UniformRandomNumberGenerator, double>
311838fd1498Szrj 	  __aurng(__urng);
311938fd1498Szrj 
312038fd1498Szrj 	const double __p = __aurng();
312138fd1498Szrj 	if (__param._M_cp.empty())
312238fd1498Szrj 	  return __p;
312338fd1498Szrj 
312438fd1498Szrj 	auto __pos = std::lower_bound(__param._M_cp.begin(),
312538fd1498Szrj 				      __param._M_cp.end(), __p);
312638fd1498Szrj 	const size_t __i = __pos - __param._M_cp.begin();
312738fd1498Szrj 
312838fd1498Szrj 	const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
312938fd1498Szrj 
313038fd1498Szrj 	const double __a = 0.5 * __param._M_m[__i];
313138fd1498Szrj 	const double __b = __param._M_den[__i];
313238fd1498Szrj 	const double __cm = __p - __pref;
313338fd1498Szrj 
313438fd1498Szrj 	_RealType __x = __param._M_int[__i];
313538fd1498Szrj 	if (__a == 0)
313638fd1498Szrj 	  __x += __cm / __b;
313738fd1498Szrj 	else
313838fd1498Szrj 	  {
313938fd1498Szrj 	    const double __d = __b * __b + 4.0 * __a * __cm;
314038fd1498Szrj 	    __x += 0.5 * (std::sqrt(__d) - __b) / __a;
314138fd1498Szrj           }
314238fd1498Szrj 
314338fd1498Szrj         return __x;
314438fd1498Szrj       }
314538fd1498Szrj 
314638fd1498Szrj   template<typename _RealType>
314738fd1498Szrj     template<typename _ForwardIterator,
314838fd1498Szrj 	     typename _UniformRandomNumberGenerator>
314938fd1498Szrj       void
315038fd1498Szrj       piecewise_linear_distribution<_RealType>::
__generate_impl(_ForwardIterator __f,_ForwardIterator __t,_UniformRandomNumberGenerator & __urng,const param_type & __param)315138fd1498Szrj       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
315238fd1498Szrj 		      _UniformRandomNumberGenerator& __urng,
315338fd1498Szrj 		      const param_type& __param)
315438fd1498Szrj       {
315538fd1498Szrj 	__glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
315638fd1498Szrj 	// We could duplicate everything from operator()...
315738fd1498Szrj 	while (__f != __t)
315838fd1498Szrj 	  *__f++ = this->operator()(__urng, __param);
315938fd1498Szrj       }
316038fd1498Szrj 
316138fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
316238fd1498Szrj     std::basic_ostream<_CharT, _Traits>&
operator <<(std::basic_ostream<_CharT,_Traits> & __os,const piecewise_linear_distribution<_RealType> & __x)316338fd1498Szrj     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
316438fd1498Szrj 	       const piecewise_linear_distribution<_RealType>& __x)
316538fd1498Szrj     {
316638fd1498Szrj       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
316738fd1498Szrj       typedef typename __ostream_type::ios_base    __ios_base;
316838fd1498Szrj 
316938fd1498Szrj       const typename __ios_base::fmtflags __flags = __os.flags();
317038fd1498Szrj       const _CharT __fill = __os.fill();
317138fd1498Szrj       const std::streamsize __precision = __os.precision();
317238fd1498Szrj       const _CharT __space = __os.widen(' ');
317338fd1498Szrj       __os.flags(__ios_base::scientific | __ios_base::left);
317438fd1498Szrj       __os.fill(__space);
317538fd1498Szrj       __os.precision(std::numeric_limits<_RealType>::max_digits10);
317638fd1498Szrj 
317738fd1498Szrj       std::vector<_RealType> __int = __x.intervals();
317838fd1498Szrj       __os << __int.size() - 1;
317938fd1498Szrj 
318038fd1498Szrj       for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit)
318138fd1498Szrj 	__os << __space << *__xit;
318238fd1498Szrj 
318338fd1498Szrj       std::vector<double> __den = __x.densities();
318438fd1498Szrj       for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit)
318538fd1498Szrj 	__os << __space << *__dit;
318638fd1498Szrj 
318738fd1498Szrj       __os.flags(__flags);
318838fd1498Szrj       __os.fill(__fill);
318938fd1498Szrj       __os.precision(__precision);
319038fd1498Szrj       return __os;
319138fd1498Szrj     }
319238fd1498Szrj 
319338fd1498Szrj   template<typename _RealType, typename _CharT, typename _Traits>
319438fd1498Szrj     std::basic_istream<_CharT, _Traits>&
operator >>(std::basic_istream<_CharT,_Traits> & __is,piecewise_linear_distribution<_RealType> & __x)319538fd1498Szrj     operator>>(std::basic_istream<_CharT, _Traits>& __is,
319638fd1498Szrj 	       piecewise_linear_distribution<_RealType>& __x)
319738fd1498Szrj     {
319838fd1498Szrj       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
319938fd1498Szrj       typedef typename __istream_type::ios_base    __ios_base;
320038fd1498Szrj 
320138fd1498Szrj       const typename __ios_base::fmtflags __flags = __is.flags();
320238fd1498Szrj       __is.flags(__ios_base::dec | __ios_base::skipws);
320338fd1498Szrj 
320438fd1498Szrj       size_t __n;
320538fd1498Szrj       __is >> __n;
320638fd1498Szrj 
320738fd1498Szrj       std::vector<_RealType> __int_vec;
320838fd1498Szrj       __int_vec.reserve(__n + 1);
320938fd1498Szrj       for (size_t __i = 0; __i <= __n; ++__i)
321038fd1498Szrj 	{
321138fd1498Szrj 	  _RealType __int;
321238fd1498Szrj 	  __is >> __int;
321338fd1498Szrj 	  __int_vec.push_back(__int);
321438fd1498Szrj 	}
321538fd1498Szrj 
321638fd1498Szrj       std::vector<double> __den_vec;
321738fd1498Szrj       __den_vec.reserve(__n + 1);
321838fd1498Szrj       for (size_t __i = 0; __i <= __n; ++__i)
321938fd1498Szrj 	{
322038fd1498Szrj 	  double __den;
322138fd1498Szrj 	  __is >> __den;
322238fd1498Szrj 	  __den_vec.push_back(__den);
322338fd1498Szrj 	}
322438fd1498Szrj 
322538fd1498Szrj       __x.param(typename piecewise_linear_distribution<_RealType>::
322638fd1498Szrj 	  param_type(__int_vec.begin(), __int_vec.end(), __den_vec.begin()));
322738fd1498Szrj 
322838fd1498Szrj       __is.flags(__flags);
322938fd1498Szrj       return __is;
323038fd1498Szrj     }
323138fd1498Szrj 
323238fd1498Szrj 
323338fd1498Szrj   template<typename _IntType>
seed_seq(std::initializer_list<_IntType> __il)323438fd1498Szrj     seed_seq::seed_seq(std::initializer_list<_IntType> __il)
323538fd1498Szrj     {
323638fd1498Szrj       for (auto __iter = __il.begin(); __iter != __il.end(); ++__iter)
323738fd1498Szrj 	_M_v.push_back(__detail::__mod<result_type,
323838fd1498Szrj 		       __detail::_Shift<result_type, 32>::__value>(*__iter));
323938fd1498Szrj     }
324038fd1498Szrj 
324138fd1498Szrj   template<typename _InputIterator>
seed_seq(_InputIterator __begin,_InputIterator __end)324238fd1498Szrj     seed_seq::seed_seq(_InputIterator __begin, _InputIterator __end)
324338fd1498Szrj     {
324438fd1498Szrj       for (_InputIterator __iter = __begin; __iter != __end; ++__iter)
324538fd1498Szrj 	_M_v.push_back(__detail::__mod<result_type,
324638fd1498Szrj 		       __detail::_Shift<result_type, 32>::__value>(*__iter));
324738fd1498Szrj     }
324838fd1498Szrj 
324938fd1498Szrj   template<typename _RandomAccessIterator>
325038fd1498Szrj     void
generate(_RandomAccessIterator __begin,_RandomAccessIterator __end)325138fd1498Szrj     seed_seq::generate(_RandomAccessIterator __begin,
325238fd1498Szrj 		       _RandomAccessIterator __end)
325338fd1498Szrj     {
325438fd1498Szrj       typedef typename iterator_traits<_RandomAccessIterator>::value_type
325538fd1498Szrj         _Type;
325638fd1498Szrj 
325738fd1498Szrj       if (__begin == __end)
325838fd1498Szrj 	return;
325938fd1498Szrj 
326038fd1498Szrj       std::fill(__begin, __end, _Type(0x8b8b8b8bu));
326138fd1498Szrj 
326238fd1498Szrj       const size_t __n = __end - __begin;
326338fd1498Szrj       const size_t __s = _M_v.size();
326438fd1498Szrj       const size_t __t = (__n >= 623) ? 11
326538fd1498Szrj 		       : (__n >=  68) ? 7
326638fd1498Szrj 		       : (__n >=  39) ? 5
326738fd1498Szrj 		       : (__n >=   7) ? 3
326838fd1498Szrj 		       : (__n - 1) / 2;
326938fd1498Szrj       const size_t __p = (__n - __t) / 2;
327038fd1498Szrj       const size_t __q = __p + __t;
327138fd1498Szrj       const size_t __m = std::max(size_t(__s + 1), __n);
327238fd1498Szrj 
327338fd1498Szrj       for (size_t __k = 0; __k < __m; ++__k)
327438fd1498Szrj 	{
327538fd1498Szrj 	  _Type __arg = (__begin[__k % __n]
327638fd1498Szrj 			 ^ __begin[(__k + __p) % __n]
327738fd1498Szrj 			 ^ __begin[(__k - 1) % __n]);
327838fd1498Szrj 	  _Type __r1 = __arg ^ (__arg >> 27);
327938fd1498Szrj 	  __r1 = __detail::__mod<_Type,
328038fd1498Szrj 		    __detail::_Shift<_Type, 32>::__value>(1664525u * __r1);
328138fd1498Szrj 	  _Type __r2 = __r1;
328238fd1498Szrj 	  if (__k == 0)
328338fd1498Szrj 	    __r2 += __s;
328438fd1498Szrj 	  else if (__k <= __s)
328538fd1498Szrj 	    __r2 += __k % __n + _M_v[__k - 1];
328638fd1498Szrj 	  else
328738fd1498Szrj 	    __r2 += __k % __n;
328838fd1498Szrj 	  __r2 = __detail::__mod<_Type,
328938fd1498Szrj 	           __detail::_Shift<_Type, 32>::__value>(__r2);
329038fd1498Szrj 	  __begin[(__k + __p) % __n] += __r1;
329138fd1498Szrj 	  __begin[(__k + __q) % __n] += __r2;
329238fd1498Szrj 	  __begin[__k % __n] = __r2;
329338fd1498Szrj 	}
329438fd1498Szrj 
329538fd1498Szrj       for (size_t __k = __m; __k < __m + __n; ++__k)
329638fd1498Szrj 	{
329738fd1498Szrj 	  _Type __arg = (__begin[__k % __n]
329838fd1498Szrj 			 + __begin[(__k + __p) % __n]
329938fd1498Szrj 			 + __begin[(__k - 1) % __n]);
330038fd1498Szrj 	  _Type __r3 = __arg ^ (__arg >> 27);
330138fd1498Szrj 	  __r3 = __detail::__mod<_Type,
330238fd1498Szrj 		   __detail::_Shift<_Type, 32>::__value>(1566083941u * __r3);
330338fd1498Szrj 	  _Type __r4 = __r3 - __k % __n;
330438fd1498Szrj 	  __r4 = __detail::__mod<_Type,
330538fd1498Szrj 	           __detail::_Shift<_Type, 32>::__value>(__r4);
330638fd1498Szrj 	  __begin[(__k + __p) % __n] ^= __r3;
330738fd1498Szrj 	  __begin[(__k + __q) % __n] ^= __r4;
330838fd1498Szrj 	  __begin[__k % __n] = __r4;
330938fd1498Szrj 	}
331038fd1498Szrj     }
331138fd1498Szrj 
331238fd1498Szrj   template<typename _RealType, size_t __bits,
331338fd1498Szrj 	   typename _UniformRandomNumberGenerator>
331438fd1498Szrj     _RealType
generate_canonical(_UniformRandomNumberGenerator & __urng)331538fd1498Szrj     generate_canonical(_UniformRandomNumberGenerator& __urng)
331638fd1498Szrj     {
331738fd1498Szrj       static_assert(std::is_floating_point<_RealType>::value,
331838fd1498Szrj 		    "template argument must be a floating point type");
331938fd1498Szrj 
332038fd1498Szrj       const size_t __b
332138fd1498Szrj 	= std::min(static_cast<size_t>(std::numeric_limits<_RealType>::digits),
332238fd1498Szrj                    __bits);
332338fd1498Szrj       const long double __r = static_cast<long double>(__urng.max())
332438fd1498Szrj 			    - static_cast<long double>(__urng.min()) + 1.0L;
332538fd1498Szrj       const size_t __log2r = std::log(__r) / std::log(2.0L);
332638fd1498Szrj       const size_t __m = std::max<size_t>(1UL,
332738fd1498Szrj 					  (__b + __log2r - 1UL) / __log2r);
332838fd1498Szrj       _RealType __ret;
332938fd1498Szrj       _RealType __sum = _RealType(0);
333038fd1498Szrj       _RealType __tmp = _RealType(1);
333138fd1498Szrj       for (size_t __k = __m; __k != 0; --__k)
333238fd1498Szrj 	{
333338fd1498Szrj 	  __sum += _RealType(__urng() - __urng.min()) * __tmp;
333438fd1498Szrj 	  __tmp *= __r;
333538fd1498Szrj 	}
333638fd1498Szrj       __ret = __sum / __tmp;
333738fd1498Szrj       if (__builtin_expect(__ret >= _RealType(1), 0))
333838fd1498Szrj 	{
333938fd1498Szrj #if _GLIBCXX_USE_C99_MATH_TR1
334038fd1498Szrj 	  __ret = std::nextafter(_RealType(1), _RealType(0));
334138fd1498Szrj #else
334238fd1498Szrj 	  __ret = _RealType(1)
334338fd1498Szrj 	    - std::numeric_limits<_RealType>::epsilon() / _RealType(2);
334438fd1498Szrj #endif
334538fd1498Szrj 	}
334638fd1498Szrj       return __ret;
334738fd1498Szrj     }
334838fd1498Szrj 
334938fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
335038fd1498Szrj } // namespace
335138fd1498Szrj 
335238fd1498Szrj #endif
3353