re PR libstdc++/56202 (SIGFPE (division by zero) in std::binomial_distribution)
[official-gcc.git] / libstdc++-v3 / include / bits / random.tcc
blob6220a5d61d4dea8023150f69db8a2c7e51561007
1 // random number generation (out of line) -*- C++ -*-
3 // Copyright (C) 2009-2013 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file bits/random.tcc
26  *  This is an internal header file, included by other library headers.
27  *  Do not attempt to use it directly. @headername{random}
28  */
30 #ifndef _RANDOM_TCC
31 #define _RANDOM_TCC 1
33 #include <numeric> // std::accumulate and std::partial_sum
35 namespace std _GLIBCXX_VISIBILITY(default)
37   /*
38    * (Further) implementation-space details.
39    */
40   namespace __detail
41   {
42   _GLIBCXX_BEGIN_NAMESPACE_VERSION
44     // General case for x = (ax + c) mod m -- use Schrage's algorithm
45     // to avoid integer overflow.
46     //
47     // Preconditions:  a > 0, m > 0.
48     //
49     // Note: only works correctly for __m % __a < __m / __a.
50     template<typename _Tp, _Tp __m, _Tp __a, _Tp __c>
51       _Tp
52       _Mod<_Tp, __m, __a, __c, false, true>::
53       __calc(_Tp __x)
54       {
55         if (__a == 1)
56           __x %= __m;
57         else
58           {
59             static const _Tp __q = __m / __a;
60             static const _Tp __r = __m % __a;
62             _Tp __t1 = __a * (__x % __q);
63             _Tp __t2 = __r * (__x / __q);
64             if (__t1 >= __t2)
65               __x = __t1 - __t2;
66             else
67               __x = __m - __t2 + __t1;
68           }
70         if (__c != 0)
71           {
72             const _Tp __d = __m - __x;
73             if (__d > __c)
74               __x += __c;
75             else
76               __x = __c - __d;
77           }
78         return __x;
79       }
81     template<typename _InputIterator, typename _OutputIterator,
82              typename _UnaryOperation>
83       _OutputIterator
84       __transform(_InputIterator __first, _InputIterator __last,
85                   _OutputIterator __result, _UnaryOperation __unary_op)
86       {
87         for (; __first != __last; ++__first, ++__result)
88           *__result = __unary_op(*__first);
89         return __result;
90       }
92   _GLIBCXX_END_NAMESPACE_VERSION
93   } // namespace __detail
95 _GLIBCXX_BEGIN_NAMESPACE_VERSION
97   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
98     constexpr _UIntType
99     linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier;
101   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
102     constexpr _UIntType
103     linear_congruential_engine<_UIntType, __a, __c, __m>::increment;
105   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
106     constexpr _UIntType
107     linear_congruential_engine<_UIntType, __a, __c, __m>::modulus;
109   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
110     constexpr _UIntType
111     linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed;
113   /**
114    * Seeds the LCR with integral value @p __s, adjusted so that the
115    * ring identity is never a member of the convergence set.
116    */
117   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
118     void
119     linear_congruential_engine<_UIntType, __a, __c, __m>::
120     seed(result_type __s)
121     {
122       if ((__detail::__mod<_UIntType, __m>(__c) == 0)
123           && (__detail::__mod<_UIntType, __m>(__s) == 0))
124         _M_x = 1;
125       else
126         _M_x = __detail::__mod<_UIntType, __m>(__s);
127     }
129   /**
130    * Seeds the LCR engine with a value generated by @p __q.
131    */
132   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
133     template<typename _Sseq>
134       typename std::enable_if<std::is_class<_Sseq>::value>::type
135       linear_congruential_engine<_UIntType, __a, __c, __m>::
136       seed(_Sseq& __q)
137       {
138         const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits
139                                         : std::__lg(__m);
140         const _UIntType __k = (__k0 + 31) / 32;
141         uint_least32_t __arr[__k + 3];
142         __q.generate(__arr + 0, __arr + __k + 3);
143         _UIntType __factor = 1u;
144         _UIntType __sum = 0u;
145         for (size_t __j = 0; __j < __k; ++__j)
146           {
147             __sum += __arr[__j + 3] * __factor;
148             __factor *= __detail::_Shift<_UIntType, 32>::__value;
149           }
150         seed(__sum);
151       }
153   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
154            typename _CharT, typename _Traits>
155     std::basic_ostream<_CharT, _Traits>&
156     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
157                const linear_congruential_engine<_UIntType,
158                                                 __a, __c, __m>& __lcr)
159     {
160       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
161       typedef typename __ostream_type::ios_base    __ios_base;
163       const typename __ios_base::fmtflags __flags = __os.flags();
164       const _CharT __fill = __os.fill();
165       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
166       __os.fill(__os.widen(' '));
168       __os << __lcr._M_x;
170       __os.flags(__flags);
171       __os.fill(__fill);
172       return __os;
173     }
175   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
176            typename _CharT, typename _Traits>
177     std::basic_istream<_CharT, _Traits>&
178     operator>>(std::basic_istream<_CharT, _Traits>& __is,
179                linear_congruential_engine<_UIntType, __a, __c, __m>& __lcr)
180     {
181       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
182       typedef typename __istream_type::ios_base    __ios_base;
184       const typename __ios_base::fmtflags __flags = __is.flags();
185       __is.flags(__ios_base::dec);
187       __is >> __lcr._M_x;
189       __is.flags(__flags);
190       return __is;
191     }
194   template<typename _UIntType,
195            size_t __w, size_t __n, size_t __m, size_t __r,
196            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
197            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
198            _UIntType __f>
199     constexpr size_t
200     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
201                             __s, __b, __t, __c, __l, __f>::word_size;
203   template<typename _UIntType,
204            size_t __w, size_t __n, size_t __m, size_t __r,
205            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
206            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
207            _UIntType __f>
208     constexpr size_t
209     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
210                             __s, __b, __t, __c, __l, __f>::state_size;
212   template<typename _UIntType,
213            size_t __w, size_t __n, size_t __m, size_t __r,
214            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
215            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
216            _UIntType __f>
217     constexpr size_t
218     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
219                             __s, __b, __t, __c, __l, __f>::shift_size;
221   template<typename _UIntType,
222            size_t __w, size_t __n, size_t __m, size_t __r,
223            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
224            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
225            _UIntType __f>
226     constexpr size_t
227     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
228                             __s, __b, __t, __c, __l, __f>::mask_bits;
230   template<typename _UIntType,
231            size_t __w, size_t __n, size_t __m, size_t __r,
232            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
233            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
234            _UIntType __f>
235     constexpr _UIntType
236     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
237                             __s, __b, __t, __c, __l, __f>::xor_mask;
239   template<typename _UIntType,
240            size_t __w, size_t __n, size_t __m, size_t __r,
241            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
242            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
243            _UIntType __f>
244     constexpr size_t
245     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
246                             __s, __b, __t, __c, __l, __f>::tempering_u;
247    
248   template<typename _UIntType,
249            size_t __w, size_t __n, size_t __m, size_t __r,
250            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
251            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
252            _UIntType __f>
253     constexpr _UIntType
254     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
255                             __s, __b, __t, __c, __l, __f>::tempering_d;
257   template<typename _UIntType,
258            size_t __w, size_t __n, size_t __m, size_t __r,
259            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
260            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
261            _UIntType __f>
262     constexpr size_t
263     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
264                             __s, __b, __t, __c, __l, __f>::tempering_s;
266   template<typename _UIntType,
267            size_t __w, size_t __n, size_t __m, size_t __r,
268            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
269            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
270            _UIntType __f>
271     constexpr _UIntType
272     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
273                             __s, __b, __t, __c, __l, __f>::tempering_b;
275   template<typename _UIntType,
276            size_t __w, size_t __n, size_t __m, size_t __r,
277            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
278            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
279            _UIntType __f>
280     constexpr size_t
281     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
282                             __s, __b, __t, __c, __l, __f>::tempering_t;
284   template<typename _UIntType,
285            size_t __w, size_t __n, size_t __m, size_t __r,
286            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
287            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
288            _UIntType __f>
289     constexpr _UIntType
290     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
291                             __s, __b, __t, __c, __l, __f>::tempering_c;
293   template<typename _UIntType,
294            size_t __w, size_t __n, size_t __m, size_t __r,
295            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
296            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
297            _UIntType __f>
298     constexpr size_t
299     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
300                             __s, __b, __t, __c, __l, __f>::tempering_l;
302   template<typename _UIntType,
303            size_t __w, size_t __n, size_t __m, size_t __r,
304            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
305            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
306            _UIntType __f>
307     constexpr _UIntType
308     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
309                             __s, __b, __t, __c, __l, __f>::
310                                               initialization_multiplier;
312   template<typename _UIntType,
313            size_t __w, size_t __n, size_t __m, size_t __r,
314            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
315            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
316            _UIntType __f>
317     constexpr _UIntType
318     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
319                             __s, __b, __t, __c, __l, __f>::default_seed;
321   template<typename _UIntType,
322            size_t __w, size_t __n, size_t __m, size_t __r,
323            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
324            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
325            _UIntType __f>
326     void
327     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
328                             __s, __b, __t, __c, __l, __f>::
329     seed(result_type __sd)
330     {
331       _M_x[0] = __detail::__mod<_UIntType,
332         __detail::_Shift<_UIntType, __w>::__value>(__sd);
334       for (size_t __i = 1; __i < state_size; ++__i)
335         {
336           _UIntType __x = _M_x[__i - 1];
337           __x ^= __x >> (__w - 2);
338           __x *= __f;
339           __x += __detail::__mod<_UIntType, __n>(__i);
340           _M_x[__i] = __detail::__mod<_UIntType,
341             __detail::_Shift<_UIntType, __w>::__value>(__x);
342         }
343       _M_p = state_size;
344     }
346   template<typename _UIntType,
347            size_t __w, size_t __n, size_t __m, size_t __r,
348            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
349            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
350            _UIntType __f>
351     template<typename _Sseq>
352       typename std::enable_if<std::is_class<_Sseq>::value>::type
353       mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
354                               __s, __b, __t, __c, __l, __f>::
355       seed(_Sseq& __q)
356       {
357         const _UIntType __upper_mask = (~_UIntType()) << __r;
358         const size_t __k = (__w + 31) / 32;
359         uint_least32_t __arr[__n * __k];
360         __q.generate(__arr + 0, __arr + __n * __k);
362         bool __zero = true;
363         for (size_t __i = 0; __i < state_size; ++__i)
364           {
365             _UIntType __factor = 1u;
366             _UIntType __sum = 0u;
367             for (size_t __j = 0; __j < __k; ++__j)
368               {
369                 __sum += __arr[__k * __i + __j] * __factor;
370                 __factor *= __detail::_Shift<_UIntType, 32>::__value;
371               }
372             _M_x[__i] = __detail::__mod<_UIntType,
373               __detail::_Shift<_UIntType, __w>::__value>(__sum);
375             if (__zero)
376               {
377                 if (__i == 0)
378                   {
379                     if ((_M_x[0] & __upper_mask) != 0u)
380                       __zero = false;
381                   }
382                 else if (_M_x[__i] != 0u)
383                   __zero = false;
384               }
385           }
386         if (__zero)
387           _M_x[0] = __detail::_Shift<_UIntType, __w - 1>::__value;
388         _M_p = state_size;
389       }
391   template<typename _UIntType, size_t __w,
392            size_t __n, size_t __m, size_t __r,
393            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
394            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
395            _UIntType __f>
396     void
397     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
398                             __s, __b, __t, __c, __l, __f>::
399     _M_gen_rand(void)
400     {
401       const _UIntType __upper_mask = (~_UIntType()) << __r;
402       const _UIntType __lower_mask = ~__upper_mask;
404       for (size_t __k = 0; __k < (__n - __m); ++__k)
405         {
406           _UIntType __y = ((_M_x[__k] & __upper_mask)
407                            | (_M_x[__k + 1] & __lower_mask));
408           _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1)
409                        ^ ((__y & 0x01) ? __a : 0));
410         }
412       for (size_t __k = (__n - __m); __k < (__n - 1); ++__k)
413         {
414           _UIntType __y = ((_M_x[__k] & __upper_mask)
415                            | (_M_x[__k + 1] & __lower_mask));
416           _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1)
417                        ^ ((__y & 0x01) ? __a : 0));
418         }
420       _UIntType __y = ((_M_x[__n - 1] & __upper_mask)
421                        | (_M_x[0] & __lower_mask));
422       _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1)
423                        ^ ((__y & 0x01) ? __a : 0));
424       _M_p = 0;
425     }
427   template<typename _UIntType, size_t __w,
428            size_t __n, size_t __m, size_t __r,
429            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
430            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
431            _UIntType __f>
432     void
433     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
434                             __s, __b, __t, __c, __l, __f>::
435     discard(unsigned long long __z)
436     {
437       while (__z > state_size - _M_p)
438         {
439           __z -= state_size - _M_p;
440           _M_gen_rand();
441         }
442       _M_p += __z;
443     }
445   template<typename _UIntType, size_t __w,
446            size_t __n, size_t __m, size_t __r,
447            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
448            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
449            _UIntType __f>
450     typename
451     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
452                             __s, __b, __t, __c, __l, __f>::result_type
453     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
454                             __s, __b, __t, __c, __l, __f>::
455     operator()()
456     {
457       // Reload the vector - cost is O(n) amortized over n calls.
458       if (_M_p >= state_size)
459         _M_gen_rand();
461       // Calculate o(x(i)).
462       result_type __z = _M_x[_M_p++];
463       __z ^= (__z >> __u) & __d;
464       __z ^= (__z << __s) & __b;
465       __z ^= (__z << __t) & __c;
466       __z ^= (__z >> __l);
468       return __z;
469     }
471   template<typename _UIntType, size_t __w,
472            size_t __n, size_t __m, size_t __r,
473            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
474            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
475            _UIntType __f, typename _CharT, typename _Traits>
476     std::basic_ostream<_CharT, _Traits>&
477     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
478                const mersenne_twister_engine<_UIntType, __w, __n, __m,
479                __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x)
480     {
481       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
482       typedef typename __ostream_type::ios_base    __ios_base;
484       const typename __ios_base::fmtflags __flags = __os.flags();
485       const _CharT __fill = __os.fill();
486       const _CharT __space = __os.widen(' ');
487       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
488       __os.fill(__space);
490       for (size_t __i = 0; __i < __n; ++__i)
491         __os << __x._M_x[__i] << __space;
492       __os << __x._M_p;
494       __os.flags(__flags);
495       __os.fill(__fill);
496       return __os;
497     }
499   template<typename _UIntType, size_t __w,
500            size_t __n, size_t __m, size_t __r,
501            _UIntType __a, size_t __u, _UIntType __d, size_t __s,
502            _UIntType __b, size_t __t, _UIntType __c, size_t __l,
503            _UIntType __f, typename _CharT, typename _Traits>
504     std::basic_istream<_CharT, _Traits>&
505     operator>>(std::basic_istream<_CharT, _Traits>& __is,
506                mersenne_twister_engine<_UIntType, __w, __n, __m,
507                __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x)
508     {
509       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
510       typedef typename __istream_type::ios_base    __ios_base;
512       const typename __ios_base::fmtflags __flags = __is.flags();
513       __is.flags(__ios_base::dec | __ios_base::skipws);
515       for (size_t __i = 0; __i < __n; ++__i)
516         __is >> __x._M_x[__i];
517       __is >> __x._M_p;
519       __is.flags(__flags);
520       return __is;
521     }
524   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
525     constexpr size_t
526     subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size;
528   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
529     constexpr size_t
530     subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag;
532   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
533     constexpr size_t
534     subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag;
536   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
537     constexpr _UIntType
538     subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed;
540   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
541     void
542     subtract_with_carry_engine<_UIntType, __w, __s, __r>::
543     seed(result_type __value)
544     {
545       std::linear_congruential_engine<result_type, 40014u, 0u, 2147483563u>
546         __lcg(__value == 0u ? default_seed : __value);
548       const size_t __n = (__w + 31) / 32;
550       for (size_t __i = 0; __i < long_lag; ++__i)
551         {
552           _UIntType __sum = 0u;
553           _UIntType __factor = 1u;
554           for (size_t __j = 0; __j < __n; ++__j)
555             {
556               __sum += __detail::__mod<uint_least32_t,
557                        __detail::_Shift<uint_least32_t, 32>::__value>
558                          (__lcg()) * __factor;
559               __factor *= __detail::_Shift<_UIntType, 32>::__value;
560             }
561           _M_x[__i] = __detail::__mod<_UIntType,
562             __detail::_Shift<_UIntType, __w>::__value>(__sum);
563         }
564       _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
565       _M_p = 0;
566     }
568   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
569     template<typename _Sseq>
570       typename std::enable_if<std::is_class<_Sseq>::value>::type
571       subtract_with_carry_engine<_UIntType, __w, __s, __r>::
572       seed(_Sseq& __q)
573       {
574         const size_t __k = (__w + 31) / 32;
575         uint_least32_t __arr[__r * __k];
576         __q.generate(__arr + 0, __arr + __r * __k);
578         for (size_t __i = 0; __i < long_lag; ++__i)
579           {
580             _UIntType __sum = 0u;
581             _UIntType __factor = 1u;
582             for (size_t __j = 0; __j < __k; ++__j)
583               {
584                 __sum += __arr[__k * __i + __j] * __factor;
585                 __factor *= __detail::_Shift<_UIntType, 32>::__value;
586               }
587             _M_x[__i] = __detail::__mod<_UIntType,
588               __detail::_Shift<_UIntType, __w>::__value>(__sum);
589           }
590         _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
591         _M_p = 0;
592       }
594   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
595     typename subtract_with_carry_engine<_UIntType, __w, __s, __r>::
596              result_type
597     subtract_with_carry_engine<_UIntType, __w, __s, __r>::
598     operator()()
599     {
600       // Derive short lag index from current index.
601       long __ps = _M_p - short_lag;
602       if (__ps < 0)
603         __ps += long_lag;
605       // Calculate new x(i) without overflow or division.
606       // NB: Thanks to the requirements for _UIntType, _M_x[_M_p] + _M_carry
607       // cannot overflow.
608       _UIntType __xi;
609       if (_M_x[__ps] >= _M_x[_M_p] + _M_carry)
610         {
611           __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry;
612           _M_carry = 0;
613         }
614       else
615         {
616           __xi = (__detail::_Shift<_UIntType, __w>::__value
617                   - _M_x[_M_p] - _M_carry + _M_x[__ps]);
618           _M_carry = 1;
619         }
620       _M_x[_M_p] = __xi;
622       // Adjust current index to loop around in ring buffer.
623       if (++_M_p >= long_lag)
624         _M_p = 0;
626       return __xi;
627     }
629   template<typename _UIntType, size_t __w, size_t __s, size_t __r,
630            typename _CharT, typename _Traits>
631     std::basic_ostream<_CharT, _Traits>&
632     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
633                const subtract_with_carry_engine<_UIntType,
634                                                 __w, __s, __r>& __x)
635     {
636       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
637       typedef typename __ostream_type::ios_base    __ios_base;
639       const typename __ios_base::fmtflags __flags = __os.flags();
640       const _CharT __fill = __os.fill();
641       const _CharT __space = __os.widen(' ');
642       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
643       __os.fill(__space);
645       for (size_t __i = 0; __i < __r; ++__i)
646         __os << __x._M_x[__i] << __space;
647       __os << __x._M_carry << __space << __x._M_p;
649       __os.flags(__flags);
650       __os.fill(__fill);
651       return __os;
652     }
654   template<typename _UIntType, size_t __w, size_t __s, size_t __r,
655            typename _CharT, typename _Traits>
656     std::basic_istream<_CharT, _Traits>&
657     operator>>(std::basic_istream<_CharT, _Traits>& __is,
658                subtract_with_carry_engine<_UIntType, __w, __s, __r>& __x)
659     {
660       typedef std::basic_ostream<_CharT, _Traits>  __istream_type;
661       typedef typename __istream_type::ios_base    __ios_base;
663       const typename __ios_base::fmtflags __flags = __is.flags();
664       __is.flags(__ios_base::dec | __ios_base::skipws);
666       for (size_t __i = 0; __i < __r; ++__i)
667         __is >> __x._M_x[__i];
668       __is >> __x._M_carry;
669       __is >> __x._M_p;
671       __is.flags(__flags);
672       return __is;
673     }
676   template<typename _RandomNumberEngine, size_t __p, size_t __r>
677     constexpr size_t
678     discard_block_engine<_RandomNumberEngine, __p, __r>::block_size;
680   template<typename _RandomNumberEngine, size_t __p, size_t __r>
681     constexpr size_t
682     discard_block_engine<_RandomNumberEngine, __p, __r>::used_block;
684   template<typename _RandomNumberEngine, size_t __p, size_t __r>
685     typename discard_block_engine<_RandomNumberEngine,
686                            __p, __r>::result_type
687     discard_block_engine<_RandomNumberEngine, __p, __r>::
688     operator()()
689     {
690       if (_M_n >= used_block)
691         {
692           _M_b.discard(block_size - _M_n);
693           _M_n = 0;
694         }
695       ++_M_n;
696       return _M_b();
697     }
699   template<typename _RandomNumberEngine, size_t __p, size_t __r,
700            typename _CharT, typename _Traits>
701     std::basic_ostream<_CharT, _Traits>&
702     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
703                const discard_block_engine<_RandomNumberEngine,
704                __p, __r>& __x)
705     {
706       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
707       typedef typename __ostream_type::ios_base    __ios_base;
709       const typename __ios_base::fmtflags __flags = __os.flags();
710       const _CharT __fill = __os.fill();
711       const _CharT __space = __os.widen(' ');
712       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
713       __os.fill(__space);
715       __os << __x.base() << __space << __x._M_n;
717       __os.flags(__flags);
718       __os.fill(__fill);
719       return __os;
720     }
722   template<typename _RandomNumberEngine, size_t __p, size_t __r,
723            typename _CharT, typename _Traits>
724     std::basic_istream<_CharT, _Traits>&
725     operator>>(std::basic_istream<_CharT, _Traits>& __is,
726                discard_block_engine<_RandomNumberEngine, __p, __r>& __x)
727     {
728       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
729       typedef typename __istream_type::ios_base    __ios_base;
731       const typename __ios_base::fmtflags __flags = __is.flags();
732       __is.flags(__ios_base::dec | __ios_base::skipws);
734       __is >> __x._M_b >> __x._M_n;
736       __is.flags(__flags);
737       return __is;
738     }
741   template<typename _RandomNumberEngine, size_t __w, typename _UIntType>
742     typename independent_bits_engine<_RandomNumberEngine, __w, _UIntType>::
743       result_type
744     independent_bits_engine<_RandomNumberEngine, __w, _UIntType>::
745     operator()()
746     {
747       typedef typename _RandomNumberEngine::result_type _Eresult_type;
748       const _Eresult_type __r
749         = (_M_b.max() - _M_b.min() < std::numeric_limits<_Eresult_type>::max()
750            ? _M_b.max() - _M_b.min() + 1 : 0);
751       const unsigned __edig = std::numeric_limits<_Eresult_type>::digits;
752       const unsigned __m = __r ? std::__lg(__r) : __edig;
754       typedef typename std::common_type<_Eresult_type, result_type>::type
755         __ctype;
756       const unsigned __cdig = std::numeric_limits<__ctype>::digits;
758       unsigned __n, __n0;
759       __ctype __s0, __s1, __y0, __y1;
761       for (size_t __i = 0; __i < 2; ++__i)
762         {
763           __n = (__w + __m - 1) / __m + __i;
764           __n0 = __n - __w % __n;
765           const unsigned __w0 = __w / __n;  // __w0 <= __m
767           __s0 = 0;
768           __s1 = 0;
769           if (__w0 < __cdig)
770             {
771               __s0 = __ctype(1) << __w0;
772               __s1 = __s0 << 1;
773             }
775           __y0 = 0;
776           __y1 = 0;
777           if (__r)
778             {
779               __y0 = __s0 * (__r / __s0);
780               if (__s1)
781                 __y1 = __s1 * (__r / __s1);
783               if (__r - __y0 <= __y0 / __n)
784                 break;
785             }
786           else
787             break;
788         }
790       result_type __sum = 0;
791       for (size_t __k = 0; __k < __n0; ++__k)
792         {
793           __ctype __u;
794           do
795             __u = _M_b() - _M_b.min();
796           while (__y0 && __u >= __y0);
797           __sum = __s0 * __sum + (__s0 ? __u % __s0 : __u);
798         }
799       for (size_t __k = __n0; __k < __n; ++__k)
800         {
801           __ctype __u;
802           do
803             __u = _M_b() - _M_b.min();
804           while (__y1 && __u >= __y1);
805           __sum = __s1 * __sum + (__s1 ? __u % __s1 : __u);
806         }
807       return __sum;
808     }
811   template<typename _RandomNumberEngine, size_t __k>
812     constexpr size_t
813     shuffle_order_engine<_RandomNumberEngine, __k>::table_size;
815   template<typename _RandomNumberEngine, size_t __k>
816     typename shuffle_order_engine<_RandomNumberEngine, __k>::result_type
817     shuffle_order_engine<_RandomNumberEngine, __k>::
818     operator()()
819     {
820       size_t __j = __k * ((_M_y - _M_b.min())
821                           / (_M_b.max() - _M_b.min() + 1.0L));
822       _M_y = _M_v[__j];
823       _M_v[__j] = _M_b();
825       return _M_y;
826     }
828   template<typename _RandomNumberEngine, size_t __k,
829            typename _CharT, typename _Traits>
830     std::basic_ostream<_CharT, _Traits>&
831     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
832                const shuffle_order_engine<_RandomNumberEngine, __k>& __x)
833     {
834       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
835       typedef typename __ostream_type::ios_base    __ios_base;
837       const typename __ios_base::fmtflags __flags = __os.flags();
838       const _CharT __fill = __os.fill();
839       const _CharT __space = __os.widen(' ');
840       __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left);
841       __os.fill(__space);
843       __os << __x.base();
844       for (size_t __i = 0; __i < __k; ++__i)
845         __os << __space << __x._M_v[__i];
846       __os << __space << __x._M_y;
848       __os.flags(__flags);
849       __os.fill(__fill);
850       return __os;
851     }
853   template<typename _RandomNumberEngine, size_t __k,
854            typename _CharT, typename _Traits>
855     std::basic_istream<_CharT, _Traits>&
856     operator>>(std::basic_istream<_CharT, _Traits>& __is,
857                shuffle_order_engine<_RandomNumberEngine, __k>& __x)
858     {
859       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
860       typedef typename __istream_type::ios_base    __ios_base;
862       const typename __ios_base::fmtflags __flags = __is.flags();
863       __is.flags(__ios_base::dec | __ios_base::skipws);
865       __is >> __x._M_b;
866       for (size_t __i = 0; __i < __k; ++__i)
867         __is >> __x._M_v[__i];
868       __is >> __x._M_y;
870       __is.flags(__flags);
871       return __is;
872     }
875   template<typename _IntType>
876     template<typename _UniformRandomNumberGenerator>
877       typename uniform_int_distribution<_IntType>::result_type
878       uniform_int_distribution<_IntType>::
879       operator()(_UniformRandomNumberGenerator& __urng,
880                  const param_type& __param)
881       {
882         typedef typename _UniformRandomNumberGenerator::result_type
883           _Gresult_type;
884         typedef typename std::make_unsigned<result_type>::type __utype;
885         typedef typename std::common_type<_Gresult_type, __utype>::type
886           __uctype;
888         const __uctype __urngmin = __urng.min();
889         const __uctype __urngmax = __urng.max();
890         const __uctype __urngrange = __urngmax - __urngmin;
891         const __uctype __urange
892           = __uctype(__param.b()) - __uctype(__param.a());
894         __uctype __ret;
896         if (__urngrange > __urange)
897           {
898             // downscaling
899             const __uctype __uerange = __urange + 1; // __urange can be zero
900             const __uctype __scaling = __urngrange / __uerange;
901             const __uctype __past = __uerange * __scaling;
902             do
903               __ret = __uctype(__urng()) - __urngmin;
904             while (__ret >= __past);
905             __ret /= __scaling;
906           }
907         else if (__urngrange < __urange)
908           {
909             // upscaling
910             /*
911               Note that every value in [0, urange]
912               can be written uniquely as
914               (urngrange + 1) * high + low
916               where
918               high in [0, urange / (urngrange + 1)]
920               and
921         
922               low in [0, urngrange].
923             */
924             __uctype __tmp; // wraparound control
925             do
926               {
927                 const __uctype __uerngrange = __urngrange + 1;
928                 __tmp = (__uerngrange * operator()
929                          (__urng, param_type(0, __urange / __uerngrange)));
930                 __ret = __tmp + (__uctype(__urng()) - __urngmin);
931               }
932             while (__ret > __urange || __ret < __tmp);
933           }
934         else
935           __ret = __uctype(__urng()) - __urngmin;
937         return __ret + __param.a();
938       }
941   template<typename _IntType>
942     template<typename _ForwardIterator,
943              typename _UniformRandomNumberGenerator>
944       void
945       uniform_int_distribution<_IntType>::
946       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
947                       _UniformRandomNumberGenerator& __urng,
948                       const param_type& __param)
949       {
950         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
951         typedef typename _UniformRandomNumberGenerator::result_type
952           _Gresult_type;
953         typedef typename std::make_unsigned<result_type>::type __utype;
954         typedef typename std::common_type<_Gresult_type, __utype>::type
955           __uctype;
957         const __uctype __urngmin = __urng.min();
958         const __uctype __urngmax = __urng.max();
959         const __uctype __urngrange = __urngmax - __urngmin;
960         const __uctype __urange
961           = __uctype(__param.b()) - __uctype(__param.a());
963         __uctype __ret;
965         if (__urngrange > __urange)
966           {
967             if (__detail::_Power_of_2(__urngrange + 1)
968                 && __detail::_Power_of_2(__urange + 1))
969               {
970                 while (__f != __t)
971                   {
972                     __ret = __uctype(__urng()) - __urngmin;
973                     *__f++ = (__ret & __urange) + __param.a();
974                   }
975               }
976             else
977               {
978                 // downscaling
979                 const __uctype __uerange = __urange + 1; // __urange can be zero
980                 const __uctype __scaling = __urngrange / __uerange;
981                 const __uctype __past = __uerange * __scaling;
982                 while (__f != __t)
983                   {
984                     do
985                       __ret = __uctype(__urng()) - __urngmin;
986                     while (__ret >= __past);
987                     *__f++ = __ret / __scaling + __param.a();
988                   }
989               }
990           }
991         else if (__urngrange < __urange)
992           {
993             // upscaling
994             /*
995               Note that every value in [0, urange]
996               can be written uniquely as
998               (urngrange + 1) * high + low
1000               where
1002               high in [0, urange / (urngrange + 1)]
1004               and
1006               low in [0, urngrange].
1007             */
1008             __uctype __tmp; // wraparound control
1009             while (__f != __t)
1010               {
1011                 do
1012                   {
1013                     const __uctype __uerngrange = __urngrange + 1;
1014                     __tmp = (__uerngrange * operator()
1015                              (__urng, param_type(0, __urange / __uerngrange)));
1016                     __ret = __tmp + (__uctype(__urng()) - __urngmin);
1017                   }
1018                 while (__ret > __urange || __ret < __tmp);
1019                 *__f++ = __ret;
1020               }
1021           }
1022         else
1023           while (__f != __t)
1024             *__f++ = __uctype(__urng()) - __urngmin + __param.a();
1025       }
1027   template<typename _IntType, typename _CharT, typename _Traits>
1028     std::basic_ostream<_CharT, _Traits>&
1029     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1030                const uniform_int_distribution<_IntType>& __x)
1031     {
1032       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1033       typedef typename __ostream_type::ios_base    __ios_base;
1035       const typename __ios_base::fmtflags __flags = __os.flags();
1036       const _CharT __fill = __os.fill();
1037       const _CharT __space = __os.widen(' ');
1038       __os.flags(__ios_base::scientific | __ios_base::left);
1039       __os.fill(__space);
1041       __os << __x.a() << __space << __x.b();
1043       __os.flags(__flags);
1044       __os.fill(__fill);
1045       return __os;
1046     }
1048   template<typename _IntType, typename _CharT, typename _Traits>
1049     std::basic_istream<_CharT, _Traits>&
1050     operator>>(std::basic_istream<_CharT, _Traits>& __is,
1051                uniform_int_distribution<_IntType>& __x)
1052     {
1053       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1054       typedef typename __istream_type::ios_base    __ios_base;
1056       const typename __ios_base::fmtflags __flags = __is.flags();
1057       __is.flags(__ios_base::dec | __ios_base::skipws);
1059       _IntType __a, __b;
1060       __is >> __a >> __b;
1061       __x.param(typename uniform_int_distribution<_IntType>::
1062                 param_type(__a, __b));
1064       __is.flags(__flags);
1065       return __is;
1066     }
1069   template<typename _RealType>
1070     template<typename _ForwardIterator,
1071              typename _UniformRandomNumberGenerator>
1072       void
1073       uniform_real_distribution<_RealType>::
1074       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1075                       _UniformRandomNumberGenerator& __urng,
1076                       const param_type& __p)
1077       {
1078         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1079         __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1080           __aurng(__urng);
1081         auto __range = __p.b() - __p.a();
1082         while (__f != __t)
1083           *__f++ = __aurng() * __range + __p.a();
1084       }
1086   template<typename _RealType, typename _CharT, typename _Traits>
1087     std::basic_ostream<_CharT, _Traits>&
1088     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1089                const uniform_real_distribution<_RealType>& __x)
1090     {
1091       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1092       typedef typename __ostream_type::ios_base    __ios_base;
1094       const typename __ios_base::fmtflags __flags = __os.flags();
1095       const _CharT __fill = __os.fill();
1096       const std::streamsize __precision = __os.precision();
1097       const _CharT __space = __os.widen(' ');
1098       __os.flags(__ios_base::scientific | __ios_base::left);
1099       __os.fill(__space);
1100       __os.precision(std::numeric_limits<_RealType>::max_digits10);
1102       __os << __x.a() << __space << __x.b();
1104       __os.flags(__flags);
1105       __os.fill(__fill);
1106       __os.precision(__precision);
1107       return __os;
1108     }
1110   template<typename _RealType, typename _CharT, typename _Traits>
1111     std::basic_istream<_CharT, _Traits>&
1112     operator>>(std::basic_istream<_CharT, _Traits>& __is,
1113                uniform_real_distribution<_RealType>& __x)
1114     {
1115       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1116       typedef typename __istream_type::ios_base    __ios_base;
1118       const typename __ios_base::fmtflags __flags = __is.flags();
1119       __is.flags(__ios_base::skipws);
1121       _RealType __a, __b;
1122       __is >> __a >> __b;
1123       __x.param(typename uniform_real_distribution<_RealType>::
1124                 param_type(__a, __b));
1126       __is.flags(__flags);
1127       return __is;
1128     }
1131   template<typename _ForwardIterator,
1132            typename _UniformRandomNumberGenerator>
1133     void
1134     std::bernoulli_distribution::
1135     __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1136                     _UniformRandomNumberGenerator& __urng,
1137                     const param_type& __p)
1138     {
1139       __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1140       __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1141         __aurng(__urng);
1142       auto __limit = __p.p() * (__aurng.max() - __aurng.min());
1144       while (__f != __t)
1145         *__f++ = (__aurng() - __aurng.min()) < __limit;
1146     }
1148   template<typename _CharT, typename _Traits>
1149     std::basic_ostream<_CharT, _Traits>&
1150     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1151                const bernoulli_distribution& __x)
1152     {
1153       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1154       typedef typename __ostream_type::ios_base    __ios_base;
1156       const typename __ios_base::fmtflags __flags = __os.flags();
1157       const _CharT __fill = __os.fill();
1158       const std::streamsize __precision = __os.precision();
1159       __os.flags(__ios_base::scientific | __ios_base::left);
1160       __os.fill(__os.widen(' '));
1161       __os.precision(std::numeric_limits<double>::max_digits10);
1163       __os << __x.p();
1165       __os.flags(__flags);
1166       __os.fill(__fill);
1167       __os.precision(__precision);
1168       return __os;
1169     }
1172   template<typename _IntType>
1173     template<typename _UniformRandomNumberGenerator>
1174       typename geometric_distribution<_IntType>::result_type
1175       geometric_distribution<_IntType>::
1176       operator()(_UniformRandomNumberGenerator& __urng,
1177                  const param_type& __param)
1178       {
1179         // About the epsilon thing see this thread:
1180         // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html
1181         const double __naf =
1182           (1 - std::numeric_limits<double>::epsilon()) / 2;
1183         // The largest _RealType convertible to _IntType.
1184         const double __thr =
1185           std::numeric_limits<_IntType>::max() + __naf;
1186         __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1187           __aurng(__urng);
1189         double __cand;
1190         do
1191           __cand = std::floor(std::log(1.0 - __aurng()) / __param._M_log_1_p);
1192         while (__cand >= __thr);
1194         return result_type(__cand + __naf);
1195       }
1197   template<typename _IntType>
1198     template<typename _ForwardIterator,
1199              typename _UniformRandomNumberGenerator>
1200       void
1201       geometric_distribution<_IntType>::
1202       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1203                       _UniformRandomNumberGenerator& __urng,
1204                       const param_type& __param)
1205       {
1206         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1207         // About the epsilon thing see this thread:
1208         // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html
1209         const double __naf =
1210           (1 - std::numeric_limits<double>::epsilon()) / 2;
1211         // The largest _RealType convertible to _IntType.
1212         const double __thr =
1213           std::numeric_limits<_IntType>::max() + __naf;
1214         __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1215           __aurng(__urng);
1217         while (__f != __t)
1218           {
1219             double __cand;
1220             do
1221               __cand = std::floor(std::log(1.0 - __aurng())
1222                                   / __param._M_log_1_p);
1223             while (__cand >= __thr);
1225             *__f++ = __cand + __naf;
1226           }
1227       }
1229   template<typename _IntType,
1230            typename _CharT, typename _Traits>
1231     std::basic_ostream<_CharT, _Traits>&
1232     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1233                const geometric_distribution<_IntType>& __x)
1234     {
1235       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1236       typedef typename __ostream_type::ios_base    __ios_base;
1238       const typename __ios_base::fmtflags __flags = __os.flags();
1239       const _CharT __fill = __os.fill();
1240       const std::streamsize __precision = __os.precision();
1241       __os.flags(__ios_base::scientific | __ios_base::left);
1242       __os.fill(__os.widen(' '));
1243       __os.precision(std::numeric_limits<double>::max_digits10);
1245       __os << __x.p();
1247       __os.flags(__flags);
1248       __os.fill(__fill);
1249       __os.precision(__precision);
1250       return __os;
1251     }
1253   template<typename _IntType,
1254            typename _CharT, typename _Traits>
1255     std::basic_istream<_CharT, _Traits>&
1256     operator>>(std::basic_istream<_CharT, _Traits>& __is,
1257                geometric_distribution<_IntType>& __x)
1258     {
1259       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1260       typedef typename __istream_type::ios_base    __ios_base;
1262       const typename __ios_base::fmtflags __flags = __is.flags();
1263       __is.flags(__ios_base::skipws);
1265       double __p;
1266       __is >> __p;
1267       __x.param(typename geometric_distribution<_IntType>::param_type(__p));
1269       __is.flags(__flags);
1270       return __is;
1271     }
1273   // This is Leger's algorithm, also in Devroye, Ch. X, Example 1.5.
1274   template<typename _IntType>
1275     template<typename _UniformRandomNumberGenerator>
1276       typename negative_binomial_distribution<_IntType>::result_type
1277       negative_binomial_distribution<_IntType>::
1278       operator()(_UniformRandomNumberGenerator& __urng)
1279       {
1280         const double __y = _M_gd(__urng);
1282         // XXX Is the constructor too slow?
1283         std::poisson_distribution<result_type> __poisson(__y);
1284         return __poisson(__urng);
1285       }
1287   template<typename _IntType>
1288     template<typename _UniformRandomNumberGenerator>
1289       typename negative_binomial_distribution<_IntType>::result_type
1290       negative_binomial_distribution<_IntType>::
1291       operator()(_UniformRandomNumberGenerator& __urng,
1292                  const param_type& __p)
1293       {
1294         typedef typename std::gamma_distribution<result_type>::param_type
1295           param_type;
1296         
1297         const double __y =
1298           _M_gd(__urng, param_type(__p.k(), (1.0 - __p.p()) / __p.p()));
1300         std::poisson_distribution<result_type> __poisson(__y);
1301         return __poisson(__urng);
1302       }
1304   template<typename _IntType>
1305     template<typename _ForwardIterator,
1306              typename _UniformRandomNumberGenerator>
1307       void
1308       negative_binomial_distribution<_IntType>::
1309       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1310                       _UniformRandomNumberGenerator& __urng)
1311       {
1312         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1313         while (__f != __t)
1314           {
1315             const double __y = _M_gd(__urng);
1317             // XXX Is the constructor too slow?
1318             std::poisson_distribution<result_type> __poisson(__y);
1319             *__f++ = __poisson(__urng);
1320           }
1321       }
1323   template<typename _IntType>
1324     template<typename _ForwardIterator,
1325              typename _UniformRandomNumberGenerator>
1326       void
1327       negative_binomial_distribution<_IntType>::
1328       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1329                       _UniformRandomNumberGenerator& __urng,
1330                       const param_type& __p)
1331       {
1332         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1333         typename std::gamma_distribution<result_type>::param_type
1334           __p2(__p.k(), (1.0 - __p.p()) / __p.p());
1336         while (__f != __t)
1337           {
1338             const double __y = _M_gd(__urng, __p2);
1340             std::poisson_distribution<result_type> __poisson(__y);
1341             *__f++ = __poisson(__urng);
1342           }
1343       }
1345   template<typename _IntType, typename _CharT, typename _Traits>
1346     std::basic_ostream<_CharT, _Traits>&
1347     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1348                const negative_binomial_distribution<_IntType>& __x)
1349     {
1350       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1351       typedef typename __ostream_type::ios_base    __ios_base;
1353       const typename __ios_base::fmtflags __flags = __os.flags();
1354       const _CharT __fill = __os.fill();
1355       const std::streamsize __precision = __os.precision();
1356       const _CharT __space = __os.widen(' ');
1357       __os.flags(__ios_base::scientific | __ios_base::left);
1358       __os.fill(__os.widen(' '));
1359       __os.precision(std::numeric_limits<double>::max_digits10);
1361       __os << __x.k() << __space << __x.p()
1362            << __space << __x._M_gd;
1364       __os.flags(__flags);
1365       __os.fill(__fill);
1366       __os.precision(__precision);
1367       return __os;
1368     }
1370   template<typename _IntType, typename _CharT, typename _Traits>
1371     std::basic_istream<_CharT, _Traits>&
1372     operator>>(std::basic_istream<_CharT, _Traits>& __is,
1373                negative_binomial_distribution<_IntType>& __x)
1374     {
1375       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1376       typedef typename __istream_type::ios_base    __ios_base;
1378       const typename __ios_base::fmtflags __flags = __is.flags();
1379       __is.flags(__ios_base::skipws);
1381       _IntType __k;
1382       double __p;
1383       __is >> __k >> __p >> __x._M_gd;
1384       __x.param(typename negative_binomial_distribution<_IntType>::
1385                 param_type(__k, __p));
1387       __is.flags(__flags);
1388       return __is;
1389     }
1392   template<typename _IntType>
1393     void
1394     poisson_distribution<_IntType>::param_type::
1395     _M_initialize()
1396     {
1397 #if _GLIBCXX_USE_C99_MATH_TR1
1398       if (_M_mean >= 12)
1399         {
1400           const double __m = std::floor(_M_mean);
1401           _M_lm_thr = std::log(_M_mean);
1402           _M_lfm = std::lgamma(__m + 1);
1403           _M_sm = std::sqrt(__m);
1405           const double __pi_4 = 0.7853981633974483096156608458198757L;
1406           const double __dx = std::sqrt(2 * __m * std::log(32 * __m
1407                                                               / __pi_4));
1408           _M_d = std::round(std::max(6.0, std::min(__m, __dx)));
1409           const double __cx = 2 * __m + _M_d;
1410           _M_scx = std::sqrt(__cx / 2);
1411           _M_1cx = 1 / __cx;
1413           _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx);
1414           _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2))
1415                 / _M_d;
1416         }
1417       else
1418 #endif
1419         _M_lm_thr = std::exp(-_M_mean);
1420       }
1422   /**
1423    * A rejection algorithm when mean >= 12 and a simple method based
1424    * upon the multiplication of uniform random variates otherwise.
1425    * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
1426    * is defined.
1427    *
1428    * Reference:
1429    * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
1430    * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!).
1431    */
1432   template<typename _IntType>
1433     template<typename _UniformRandomNumberGenerator>
1434       typename poisson_distribution<_IntType>::result_type
1435       poisson_distribution<_IntType>::
1436       operator()(_UniformRandomNumberGenerator& __urng,
1437                  const param_type& __param)
1438       {
1439         __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1440           __aurng(__urng);
1441 #if _GLIBCXX_USE_C99_MATH_TR1
1442         if (__param.mean() >= 12)
1443           {
1444             double __x;
1446             // See comments above...
1447             const double __naf =
1448               (1 - std::numeric_limits<double>::epsilon()) / 2;
1449             const double __thr =
1450               std::numeric_limits<_IntType>::max() + __naf;
1452             const double __m = std::floor(__param.mean());
1453             // sqrt(pi / 2)
1454             const double __spi_2 = 1.2533141373155002512078826424055226L;
1455             const double __c1 = __param._M_sm * __spi_2;
1456             const double __c2 = __param._M_c2b + __c1;
1457             const double __c3 = __c2 + 1;
1458             const double __c4 = __c3 + 1;
1459             // e^(1 / 78)
1460             const double __e178 = 1.0129030479320018583185514777512983L;
1461             const double __c5 = __c4 + __e178;
1462             const double __c = __param._M_cb + __c5;
1463             const double __2cx = 2 * (2 * __m + __param._M_d);
1465             bool __reject = true;
1466             do
1467               {
1468                 const double __u = __c * __aurng();
1469                 const double __e = -std::log(1.0 - __aurng());
1471                 double __w = 0.0;
1473                 if (__u <= __c1)
1474                   {
1475                     const double __n = _M_nd(__urng);
1476                     const double __y = -std::abs(__n) * __param._M_sm - 1;
1477                     __x = std::floor(__y);
1478                     __w = -__n * __n / 2;
1479                     if (__x < -__m)
1480                       continue;
1481                   }
1482                 else if (__u <= __c2)
1483                   {
1484                     const double __n = _M_nd(__urng);
1485                     const double __y = 1 + std::abs(__n) * __param._M_scx;
1486                     __x = std::ceil(__y);
1487                     __w = __y * (2 - __y) * __param._M_1cx;
1488                     if (__x > __param._M_d)
1489                       continue;
1490                   }
1491                 else if (__u <= __c3)
1492                   // NB: This case not in the book, nor in the Errata,
1493                   // but should be ok...
1494                   __x = -1;
1495                 else if (__u <= __c4)
1496                   __x = 0;
1497                 else if (__u <= __c5)
1498                   __x = 1;
1499                 else
1500                   {
1501                     const double __v = -std::log(1.0 - __aurng());
1502                     const double __y = __param._M_d
1503                                      + __v * __2cx / __param._M_d;
1504                     __x = std::ceil(__y);
1505                     __w = -__param._M_d * __param._M_1cx * (1 + __y / 2);
1506                   }
1508                 __reject = (__w - __e - __x * __param._M_lm_thr
1509                             > __param._M_lfm - std::lgamma(__x + __m + 1));
1511                 __reject |= __x + __m >= __thr;
1513               } while (__reject);
1515             return result_type(__x + __m + __naf);
1516           }
1517         else
1518 #endif
1519           {
1520             _IntType     __x = 0;
1521             double __prod = 1.0;
1523             do
1524               {
1525                 __prod *= __aurng();
1526                 __x += 1;
1527               }
1528             while (__prod > __param._M_lm_thr);
1530             return __x - 1;
1531           }
1532       }
1534   template<typename _IntType>
1535     template<typename _ForwardIterator,
1536              typename _UniformRandomNumberGenerator>
1537       void
1538       poisson_distribution<_IntType>::
1539       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1540                       _UniformRandomNumberGenerator& __urng,
1541                       const param_type& __param)
1542       {
1543         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1544         // We could duplicate everything from operator()...
1545         while (__f != __t)
1546           *__f++ = this->operator()(__urng, __param);
1547       }
1549   template<typename _IntType,
1550            typename _CharT, typename _Traits>
1551     std::basic_ostream<_CharT, _Traits>&
1552     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1553                const poisson_distribution<_IntType>& __x)
1554     {
1555       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1556       typedef typename __ostream_type::ios_base    __ios_base;
1558       const typename __ios_base::fmtflags __flags = __os.flags();
1559       const _CharT __fill = __os.fill();
1560       const std::streamsize __precision = __os.precision();
1561       const _CharT __space = __os.widen(' ');
1562       __os.flags(__ios_base::scientific | __ios_base::left);
1563       __os.fill(__space);
1564       __os.precision(std::numeric_limits<double>::max_digits10);
1566       __os << __x.mean() << __space << __x._M_nd;
1568       __os.flags(__flags);
1569       __os.fill(__fill);
1570       __os.precision(__precision);
1571       return __os;
1572     }
1574   template<typename _IntType,
1575            typename _CharT, typename _Traits>
1576     std::basic_istream<_CharT, _Traits>&
1577     operator>>(std::basic_istream<_CharT, _Traits>& __is,
1578                poisson_distribution<_IntType>& __x)
1579     {
1580       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1581       typedef typename __istream_type::ios_base    __ios_base;
1583       const typename __ios_base::fmtflags __flags = __is.flags();
1584       __is.flags(__ios_base::skipws);
1586       double __mean;
1587       __is >> __mean >> __x._M_nd;
1588       __x.param(typename poisson_distribution<_IntType>::param_type(__mean));
1590       __is.flags(__flags);
1591       return __is;
1592     }
1595   template<typename _IntType>
1596     void
1597     binomial_distribution<_IntType>::param_type::
1598     _M_initialize()
1599     {
1600       const double __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p;
1602       _M_easy = true;
1604 #if _GLIBCXX_USE_C99_MATH_TR1
1605       if (_M_t * __p12 >= 8)
1606         {
1607           _M_easy = false;
1608           const double __np = std::floor(_M_t * __p12);
1609           const double __pa = __np / _M_t;
1610           const double __1p = 1 - __pa;
1612           const double __pi_4 = 0.7853981633974483096156608458198757L;
1613           const double __d1x =
1614             std::sqrt(__np * __1p * std::log(32 * __np
1615                                              / (81 * __pi_4 * __1p)));
1616           _M_d1 = std::round(std::max(1.0, __d1x));
1617           const double __d2x =
1618             std::sqrt(__np * __1p * std::log(32 * _M_t * __1p
1619                                              / (__pi_4 * __pa)));
1620           _M_d2 = std::round(std::max(1.0, __d2x));
1622           // sqrt(pi / 2)
1623           const double __spi_2 = 1.2533141373155002512078826424055226L;
1624           _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np));
1625           _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p));
1626           _M_c = 2 * _M_d1 / __np;
1627           _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2;
1628           const double __a12 = _M_a1 + _M_s2 * __spi_2;
1629           const double __s1s = _M_s1 * _M_s1;
1630           _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p))
1631                              * 2 * __s1s / _M_d1
1632                              * std::exp(-_M_d1 * _M_d1 / (2 * __s1s)));
1633           const double __s2s = _M_s2 * _M_s2;
1634           _M_s = (_M_a123 + 2 * __s2s / _M_d2
1635                   * std::exp(-_M_d2 * _M_d2 / (2 * __s2s)));
1636           _M_lf = (std::lgamma(__np + 1)
1637                    + std::lgamma(_M_t - __np + 1));
1638           _M_lp1p = std::log(__pa / __1p);
1640           _M_q = -std::log(1 - (__p12 - __pa) / __1p);
1641         }
1642       else
1643 #endif
1644         _M_q = -std::log(1 - __p12);
1645     }
1647   template<typename _IntType>
1648     template<typename _UniformRandomNumberGenerator>
1649       typename binomial_distribution<_IntType>::result_type
1650       binomial_distribution<_IntType>::
1651       _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t)
1652       {
1653         _IntType __x = 0;
1654         double __sum = 0.0;
1655         __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1656           __aurng(__urng);
1658         do
1659           {
1660             const double __e = -std::log(1.0 - __aurng());
1661             if (__t == __x)
1662               {
1663                 if (__e)
1664                   return __x;
1665                 continue;
1666               }
1667             __sum += __e / (__t - __x);
1668             __x += 1;
1669           }
1670         while (__sum <= _M_param._M_q);
1672         return __x - 1;
1673       }
1675   /**
1676    * A rejection algorithm when t * p >= 8 and a simple waiting time
1677    * method - the second in the referenced book - otherwise.
1678    * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1
1679    * is defined.
1680    *
1681    * Reference:
1682    * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
1683    * New York, 1986, Ch. X, Sect. 4 (+ Errata!).
1684    */
1685   template<typename _IntType>
1686     template<typename _UniformRandomNumberGenerator>
1687       typename binomial_distribution<_IntType>::result_type
1688       binomial_distribution<_IntType>::
1689       operator()(_UniformRandomNumberGenerator& __urng,
1690                  const param_type& __param)
1691       {
1692         result_type __ret;
1693         const _IntType __t = __param.t();
1694         const double __p = __param.p();
1695         const double __p12 = __p <= 0.5 ? __p : 1.0 - __p;
1696         __detail::_Adaptor<_UniformRandomNumberGenerator, double>
1697           __aurng(__urng);
1699 #if _GLIBCXX_USE_C99_MATH_TR1
1700         if (!__param._M_easy)
1701           {
1702             double __x;
1704             // See comments above...
1705             const double __naf =
1706               (1 - std::numeric_limits<double>::epsilon()) / 2;
1707             const double __thr =
1708               std::numeric_limits<_IntType>::max() + __naf;
1710             const double __np = std::floor(__t * __p12);
1712             // sqrt(pi / 2)
1713             const double __spi_2 = 1.2533141373155002512078826424055226L;
1714             const double __a1 = __param._M_a1;
1715             const double __a12 = __a1 + __param._M_s2 * __spi_2;
1716             const double __a123 = __param._M_a123;
1717             const double __s1s = __param._M_s1 * __param._M_s1;
1718             const double __s2s = __param._M_s2 * __param._M_s2;
1720             bool __reject;
1721             do
1722               {
1723                 const double __u = __param._M_s * __aurng();
1725                 double __v;
1727                 if (__u <= __a1)
1728                   {
1729                     const double __n = _M_nd(__urng);
1730                     const double __y = __param._M_s1 * std::abs(__n);
1731                     __reject = __y >= __param._M_d1;
1732                     if (!__reject)
1733                       {
1734                         const double __e = -std::log(1.0 - __aurng());
1735                         __x = std::floor(__y);
1736                         __v = -__e - __n * __n / 2 + __param._M_c;
1737                       }
1738                   }
1739                 else if (__u <= __a12)
1740                   {
1741                     const double __n = _M_nd(__urng);
1742                     const double __y = __param._M_s2 * std::abs(__n);
1743                     __reject = __y >= __param._M_d2;
1744                     if (!__reject)
1745                       {
1746                         const double __e = -std::log(1.0 - __aurng());
1747                         __x = std::floor(-__y);
1748                         __v = -__e - __n * __n / 2;
1749                       }
1750                   }
1751                 else if (__u <= __a123)
1752                   {
1753                     const double __e1 = -std::log(1.0 - __aurng());
1754                     const double __e2 = -std::log(1.0 - __aurng());
1756                     const double __y = __param._M_d1
1757                                      + 2 * __s1s * __e1 / __param._M_d1;
1758                     __x = std::floor(__y);
1759                     __v = (-__e2 + __param._M_d1 * (1 / (__t - __np)
1760                                                     -__y / (2 * __s1s)));
1761                     __reject = false;
1762                   }
1763                 else
1764                   {
1765                     const double __e1 = -std::log(1.0 - __aurng());
1766                     const double __e2 = -std::log(1.0 - __aurng());
1768                     const double __y = __param._M_d2
1769                                      + 2 * __s2s * __e1 / __param._M_d2;
1770                     __x = std::floor(-__y);
1771                     __v = -__e2 - __param._M_d2 * __y / (2 * __s2s);
1772                     __reject = false;
1773                   }
1775                 __reject = __reject || __x < -__np || __x > __t - __np;
1776                 if (!__reject)
1777                   {
1778                     const double __lfx =
1779                       std::lgamma(__np + __x + 1)
1780                       + std::lgamma(__t - (__np + __x) + 1);
1781                     __reject = __v > __param._M_lf - __lfx
1782                              + __x * __param._M_lp1p;
1783                   }
1785                 __reject |= __x + __np >= __thr;
1786               }
1787             while (__reject);
1789             __x += __np + __naf;
1791             const _IntType __z = _M_waiting(__urng, __t - _IntType(__x));
1792             __ret = _IntType(__x) + __z;
1793           }
1794         else
1795 #endif
1796           __ret = _M_waiting(__urng, __t);
1798         if (__p12 != __p)
1799           __ret = __t - __ret;
1800         return __ret;
1801       }
1803   template<typename _IntType>
1804     template<typename _ForwardIterator,
1805              typename _UniformRandomNumberGenerator>
1806       void
1807       binomial_distribution<_IntType>::
1808       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1809                       _UniformRandomNumberGenerator& __urng,
1810                       const param_type& __param)
1811       {
1812         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1813         // We could duplicate everything from operator()...
1814         while (__f != __t)
1815           *__f++ = this->operator()(__urng, __param);
1816       }
1818   template<typename _IntType,
1819            typename _CharT, typename _Traits>
1820     std::basic_ostream<_CharT, _Traits>&
1821     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1822                const binomial_distribution<_IntType>& __x)
1823     {
1824       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1825       typedef typename __ostream_type::ios_base    __ios_base;
1827       const typename __ios_base::fmtflags __flags = __os.flags();
1828       const _CharT __fill = __os.fill();
1829       const std::streamsize __precision = __os.precision();
1830       const _CharT __space = __os.widen(' ');
1831       __os.flags(__ios_base::scientific | __ios_base::left);
1832       __os.fill(__space);
1833       __os.precision(std::numeric_limits<double>::max_digits10);
1835       __os << __x.t() << __space << __x.p()
1836            << __space << __x._M_nd;
1838       __os.flags(__flags);
1839       __os.fill(__fill);
1840       __os.precision(__precision);
1841       return __os;
1842     }
1844   template<typename _IntType,
1845            typename _CharT, typename _Traits>
1846     std::basic_istream<_CharT, _Traits>&
1847     operator>>(std::basic_istream<_CharT, _Traits>& __is,
1848                binomial_distribution<_IntType>& __x)
1849     {
1850       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1851       typedef typename __istream_type::ios_base    __ios_base;
1853       const typename __ios_base::fmtflags __flags = __is.flags();
1854       __is.flags(__ios_base::dec | __ios_base::skipws);
1856       _IntType __t;
1857       double __p;
1858       __is >> __t >> __p >> __x._M_nd;
1859       __x.param(typename binomial_distribution<_IntType>::
1860                 param_type(__t, __p));
1862       __is.flags(__flags);
1863       return __is;
1864     }
1867   template<typename _RealType>
1868     template<typename _ForwardIterator,
1869              typename _UniformRandomNumberGenerator>
1870       void
1871       std::exponential_distribution<_RealType>::
1872       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1873                       _UniformRandomNumberGenerator& __urng,
1874                       const param_type& __p)
1875       {
1876         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1877         __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1878           __aurng(__urng);
1879         while (__f != __t)
1880           *__f++ = -std::log(result_type(1) - __aurng()) / __p.lambda();
1881       }
1883   template<typename _RealType, typename _CharT, typename _Traits>
1884     std::basic_ostream<_CharT, _Traits>&
1885     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1886                const exponential_distribution<_RealType>& __x)
1887     {
1888       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
1889       typedef typename __ostream_type::ios_base    __ios_base;
1891       const typename __ios_base::fmtflags __flags = __os.flags();
1892       const _CharT __fill = __os.fill();
1893       const std::streamsize __precision = __os.precision();
1894       __os.flags(__ios_base::scientific | __ios_base::left);
1895       __os.fill(__os.widen(' '));
1896       __os.precision(std::numeric_limits<_RealType>::max_digits10);
1898       __os << __x.lambda();
1900       __os.flags(__flags);
1901       __os.fill(__fill);
1902       __os.precision(__precision);
1903       return __os;
1904     }
1906   template<typename _RealType, typename _CharT, typename _Traits>
1907     std::basic_istream<_CharT, _Traits>&
1908     operator>>(std::basic_istream<_CharT, _Traits>& __is,
1909                exponential_distribution<_RealType>& __x)
1910     {
1911       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
1912       typedef typename __istream_type::ios_base    __ios_base;
1914       const typename __ios_base::fmtflags __flags = __is.flags();
1915       __is.flags(__ios_base::dec | __ios_base::skipws);
1917       _RealType __lambda;
1918       __is >> __lambda;
1919       __x.param(typename exponential_distribution<_RealType>::
1920                 param_type(__lambda));
1922       __is.flags(__flags);
1923       return __is;
1924     }
1927   /**
1928    * Polar method due to Marsaglia.
1929    *
1930    * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag,
1931    * New York, 1986, Ch. V, Sect. 4.4.
1932    */
1933   template<typename _RealType>
1934     template<typename _UniformRandomNumberGenerator>
1935       typename normal_distribution<_RealType>::result_type
1936       normal_distribution<_RealType>::
1937       operator()(_UniformRandomNumberGenerator& __urng,
1938                  const param_type& __param)
1939       {
1940         result_type __ret;
1941         __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1942           __aurng(__urng);
1944         if (_M_saved_available)
1945           {
1946             _M_saved_available = false;
1947             __ret = _M_saved;
1948           }
1949         else
1950           {
1951             result_type __x, __y, __r2;
1952             do
1953               {
1954                 __x = result_type(2.0) * __aurng() - 1.0;
1955                 __y = result_type(2.0) * __aurng() - 1.0;
1956                 __r2 = __x * __x + __y * __y;
1957               }
1958             while (__r2 > 1.0 || __r2 == 0.0);
1960             const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
1961             _M_saved = __x * __mult;
1962             _M_saved_available = true;
1963             __ret = __y * __mult;
1964           }
1966         __ret = __ret * __param.stddev() + __param.mean();
1967         return __ret;
1968       }
1970   template<typename _RealType>
1971     template<typename _ForwardIterator,
1972              typename _UniformRandomNumberGenerator>
1973       void
1974       normal_distribution<_RealType>::
1975       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
1976                       _UniformRandomNumberGenerator& __urng,
1977                       const param_type& __param)
1978       {
1979         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
1981         if (__f == __t)
1982           return;
1984         if (_M_saved_available)
1985           {
1986             _M_saved_available = false;
1987             *__f++ = _M_saved * __param.stddev() + __param.mean();
1989             if (__f == __t)
1990               return;
1991           }
1993         __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
1994           __aurng(__urng);
1996         while (__f + 1 < __t)
1997           {
1998             result_type __x, __y, __r2;
1999             do
2000               {
2001                 __x = result_type(2.0) * __aurng() - 1.0;
2002                 __y = result_type(2.0) * __aurng() - 1.0;
2003                 __r2 = __x * __x + __y * __y;
2004               }
2005             while (__r2 > 1.0 || __r2 == 0.0);
2007             const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
2008             *__f++ = __y * __mult * __param.stddev() + __param.mean();
2009             *__f++ = __x * __mult * __param.stddev() + __param.mean();
2010           }
2012         if (__f != __t)
2013           {
2014             result_type __x, __y, __r2;
2015             do
2016               {
2017                 __x = result_type(2.0) * __aurng() - 1.0;
2018                 __y = result_type(2.0) * __aurng() - 1.0;
2019                 __r2 = __x * __x + __y * __y;
2020               }
2021             while (__r2 > 1.0 || __r2 == 0.0);
2023             const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2);
2024             _M_saved = __x * __mult;
2025             _M_saved_available = true;
2026             *__f = __y * __mult * __param.stddev() + __param.mean();
2027           }
2028       }
2030   template<typename _RealType>
2031     bool
2032     operator==(const std::normal_distribution<_RealType>& __d1,
2033                const std::normal_distribution<_RealType>& __d2)
2034     {
2035       if (__d1._M_param == __d2._M_param
2036           && __d1._M_saved_available == __d2._M_saved_available)
2037         {
2038           if (__d1._M_saved_available
2039               && __d1._M_saved == __d2._M_saved)
2040             return true;
2041           else if(!__d1._M_saved_available)
2042             return true;
2043           else
2044             return false;
2045         }
2046       else
2047         return false;
2048     }
2050   template<typename _RealType, typename _CharT, typename _Traits>
2051     std::basic_ostream<_CharT, _Traits>&
2052     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2053                const normal_distribution<_RealType>& __x)
2054     {
2055       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2056       typedef typename __ostream_type::ios_base    __ios_base;
2058       const typename __ios_base::fmtflags __flags = __os.flags();
2059       const _CharT __fill = __os.fill();
2060       const std::streamsize __precision = __os.precision();
2061       const _CharT __space = __os.widen(' ');
2062       __os.flags(__ios_base::scientific | __ios_base::left);
2063       __os.fill(__space);
2064       __os.precision(std::numeric_limits<_RealType>::max_digits10);
2066       __os << __x.mean() << __space << __x.stddev()
2067            << __space << __x._M_saved_available;
2068       if (__x._M_saved_available)
2069         __os << __space << __x._M_saved;
2071       __os.flags(__flags);
2072       __os.fill(__fill);
2073       __os.precision(__precision);
2074       return __os;
2075     }
2077   template<typename _RealType, typename _CharT, typename _Traits>
2078     std::basic_istream<_CharT, _Traits>&
2079     operator>>(std::basic_istream<_CharT, _Traits>& __is,
2080                normal_distribution<_RealType>& __x)
2081     {
2082       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2083       typedef typename __istream_type::ios_base    __ios_base;
2085       const typename __ios_base::fmtflags __flags = __is.flags();
2086       __is.flags(__ios_base::dec | __ios_base::skipws);
2088       double __mean, __stddev;
2089       __is >> __mean >> __stddev
2090            >> __x._M_saved_available;
2091       if (__x._M_saved_available)
2092         __is >> __x._M_saved;
2093       __x.param(typename normal_distribution<_RealType>::
2094                 param_type(__mean, __stddev));
2096       __is.flags(__flags);
2097       return __is;
2098     }
2101   template<typename _RealType>
2102     template<typename _ForwardIterator,
2103              typename _UniformRandomNumberGenerator>
2104       void
2105       lognormal_distribution<_RealType>::
2106       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2107                       _UniformRandomNumberGenerator& __urng,
2108                       const param_type& __p)
2109       {
2110         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2111           while (__f != __t)
2112             *__f++ = std::exp(__p.s() * _M_nd(__urng) + __p.m());
2113       }
2115   template<typename _RealType, typename _CharT, typename _Traits>
2116     std::basic_ostream<_CharT, _Traits>&
2117     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2118                const lognormal_distribution<_RealType>& __x)
2119     {
2120       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2121       typedef typename __ostream_type::ios_base    __ios_base;
2123       const typename __ios_base::fmtflags __flags = __os.flags();
2124       const _CharT __fill = __os.fill();
2125       const std::streamsize __precision = __os.precision();
2126       const _CharT __space = __os.widen(' ');
2127       __os.flags(__ios_base::scientific | __ios_base::left);
2128       __os.fill(__space);
2129       __os.precision(std::numeric_limits<_RealType>::max_digits10);
2131       __os << __x.m() << __space << __x.s()
2132            << __space << __x._M_nd;
2134       __os.flags(__flags);
2135       __os.fill(__fill);
2136       __os.precision(__precision);
2137       return __os;
2138     }
2140   template<typename _RealType, typename _CharT, typename _Traits>
2141     std::basic_istream<_CharT, _Traits>&
2142     operator>>(std::basic_istream<_CharT, _Traits>& __is,
2143                lognormal_distribution<_RealType>& __x)
2144     {
2145       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2146       typedef typename __istream_type::ios_base    __ios_base;
2148       const typename __ios_base::fmtflags __flags = __is.flags();
2149       __is.flags(__ios_base::dec | __ios_base::skipws);
2151       _RealType __m, __s;
2152       __is >> __m >> __s >> __x._M_nd;
2153       __x.param(typename lognormal_distribution<_RealType>::
2154                 param_type(__m, __s));
2156       __is.flags(__flags);
2157       return __is;
2158     }
2160   template<typename _RealType>
2161     template<typename _ForwardIterator,
2162              typename _UniformRandomNumberGenerator>
2163       void
2164       std::chi_squared_distribution<_RealType>::
2165       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2166                       _UniformRandomNumberGenerator& __urng)
2167       {
2168         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2169         while (__f != __t)
2170           *__f++ = 2 * _M_gd(__urng);
2171       }
2173   template<typename _RealType>
2174     template<typename _ForwardIterator,
2175              typename _UniformRandomNumberGenerator>
2176       void
2177       std::chi_squared_distribution<_RealType>::
2178       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2179                       _UniformRandomNumberGenerator& __urng,
2180                       const typename
2181                       std::gamma_distribution<result_type>::param_type& __p)
2182       {
2183         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2184         while (__f != __t)
2185           *__f++ = 2 * _M_gd(__urng, __p);
2186       }
2188   template<typename _RealType, typename _CharT, typename _Traits>
2189     std::basic_ostream<_CharT, _Traits>&
2190     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2191                const chi_squared_distribution<_RealType>& __x)
2192     {
2193       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2194       typedef typename __ostream_type::ios_base    __ios_base;
2196       const typename __ios_base::fmtflags __flags = __os.flags();
2197       const _CharT __fill = __os.fill();
2198       const std::streamsize __precision = __os.precision();
2199       const _CharT __space = __os.widen(' ');
2200       __os.flags(__ios_base::scientific | __ios_base::left);
2201       __os.fill(__space);
2202       __os.precision(std::numeric_limits<_RealType>::max_digits10);
2204       __os << __x.n() << __space << __x._M_gd;
2206       __os.flags(__flags);
2207       __os.fill(__fill);
2208       __os.precision(__precision);
2209       return __os;
2210     }
2212   template<typename _RealType, typename _CharT, typename _Traits>
2213     std::basic_istream<_CharT, _Traits>&
2214     operator>>(std::basic_istream<_CharT, _Traits>& __is,
2215                chi_squared_distribution<_RealType>& __x)
2216     {
2217       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2218       typedef typename __istream_type::ios_base    __ios_base;
2220       const typename __ios_base::fmtflags __flags = __is.flags();
2221       __is.flags(__ios_base::dec | __ios_base::skipws);
2223       _RealType __n;
2224       __is >> __n >> __x._M_gd;
2225       __x.param(typename chi_squared_distribution<_RealType>::
2226                 param_type(__n));
2228       __is.flags(__flags);
2229       return __is;
2230     }
2233   template<typename _RealType>
2234     template<typename _UniformRandomNumberGenerator>
2235       typename cauchy_distribution<_RealType>::result_type
2236       cauchy_distribution<_RealType>::
2237       operator()(_UniformRandomNumberGenerator& __urng,
2238                  const param_type& __p)
2239       {
2240         __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2241           __aurng(__urng);
2242         _RealType __u;
2243         do
2244           __u = __aurng();
2245         while (__u == 0.5);
2247         const _RealType __pi = 3.1415926535897932384626433832795029L;
2248         return __p.a() + __p.b() * std::tan(__pi * __u);
2249       }
2251   template<typename _RealType>
2252     template<typename _ForwardIterator,
2253              typename _UniformRandomNumberGenerator>
2254       void
2255       cauchy_distribution<_RealType>::
2256       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2257                       _UniformRandomNumberGenerator& __urng,
2258                       const param_type& __p)
2259       {
2260         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2261         const _RealType __pi = 3.1415926535897932384626433832795029L;
2262         __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2263           __aurng(__urng);
2264         while (__f != __t)
2265           {
2266             _RealType __u;
2267             do
2268               __u = __aurng();
2269             while (__u == 0.5);
2271             *__f++ = __p.a() + __p.b() * std::tan(__pi * __u);
2272           }
2273       }
2275   template<typename _RealType, typename _CharT, typename _Traits>
2276     std::basic_ostream<_CharT, _Traits>&
2277     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2278                const cauchy_distribution<_RealType>& __x)
2279     {
2280       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2281       typedef typename __ostream_type::ios_base    __ios_base;
2283       const typename __ios_base::fmtflags __flags = __os.flags();
2284       const _CharT __fill = __os.fill();
2285       const std::streamsize __precision = __os.precision();
2286       const _CharT __space = __os.widen(' ');
2287       __os.flags(__ios_base::scientific | __ios_base::left);
2288       __os.fill(__space);
2289       __os.precision(std::numeric_limits<_RealType>::max_digits10);
2291       __os << __x.a() << __space << __x.b();
2293       __os.flags(__flags);
2294       __os.fill(__fill);
2295       __os.precision(__precision);
2296       return __os;
2297     }
2299   template<typename _RealType, typename _CharT, typename _Traits>
2300     std::basic_istream<_CharT, _Traits>&
2301     operator>>(std::basic_istream<_CharT, _Traits>& __is,
2302                cauchy_distribution<_RealType>& __x)
2303     {
2304       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2305       typedef typename __istream_type::ios_base    __ios_base;
2307       const typename __ios_base::fmtflags __flags = __is.flags();
2308       __is.flags(__ios_base::dec | __ios_base::skipws);
2310       _RealType __a, __b;
2311       __is >> __a >> __b;
2312       __x.param(typename cauchy_distribution<_RealType>::
2313                 param_type(__a, __b));
2315       __is.flags(__flags);
2316       return __is;
2317     }
2320   template<typename _RealType>
2321     template<typename _ForwardIterator,
2322              typename _UniformRandomNumberGenerator>
2323       void
2324       std::fisher_f_distribution<_RealType>::
2325       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2326                       _UniformRandomNumberGenerator& __urng)
2327       {
2328         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2329         while (__f != __t)
2330           *__f++ = ((_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()));
2331       }
2333   template<typename _RealType>
2334     template<typename _ForwardIterator,
2335              typename _UniformRandomNumberGenerator>
2336       void
2337       std::fisher_f_distribution<_RealType>::
2338       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2339                       _UniformRandomNumberGenerator& __urng,
2340                       const param_type& __p)
2341       {
2342         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2343         typedef typename std::gamma_distribution<result_type>::param_type
2344           param_type;
2345         param_type __p1(__p.m() / 2);
2346         param_type __p2(__p.n() / 2);
2347         while (__f != __t)
2348           *__f++ = ((_M_gd_x(__urng, __p1) * n())
2349                     / (_M_gd_y(__urng, __p2) * m()));
2350       }
2352   template<typename _RealType, typename _CharT, typename _Traits>
2353     std::basic_ostream<_CharT, _Traits>&
2354     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2355                const fisher_f_distribution<_RealType>& __x)
2356     {
2357       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2358       typedef typename __ostream_type::ios_base    __ios_base;
2360       const typename __ios_base::fmtflags __flags = __os.flags();
2361       const _CharT __fill = __os.fill();
2362       const std::streamsize __precision = __os.precision();
2363       const _CharT __space = __os.widen(' ');
2364       __os.flags(__ios_base::scientific | __ios_base::left);
2365       __os.fill(__space);
2366       __os.precision(std::numeric_limits<_RealType>::max_digits10);
2368       __os << __x.m() << __space << __x.n()
2369            << __space << __x._M_gd_x << __space << __x._M_gd_y;
2371       __os.flags(__flags);
2372       __os.fill(__fill);
2373       __os.precision(__precision);
2374       return __os;
2375     }
2377   template<typename _RealType, typename _CharT, typename _Traits>
2378     std::basic_istream<_CharT, _Traits>&
2379     operator>>(std::basic_istream<_CharT, _Traits>& __is,
2380                fisher_f_distribution<_RealType>& __x)
2381     {
2382       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2383       typedef typename __istream_type::ios_base    __ios_base;
2385       const typename __ios_base::fmtflags __flags = __is.flags();
2386       __is.flags(__ios_base::dec | __ios_base::skipws);
2388       _RealType __m, __n;
2389       __is >> __m >> __n >> __x._M_gd_x >> __x._M_gd_y;
2390       __x.param(typename fisher_f_distribution<_RealType>::
2391                 param_type(__m, __n));
2393       __is.flags(__flags);
2394       return __is;
2395     }
2398   template<typename _RealType>
2399     template<typename _ForwardIterator,
2400              typename _UniformRandomNumberGenerator>
2401       void
2402       std::student_t_distribution<_RealType>::
2403       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2404                       _UniformRandomNumberGenerator& __urng)
2405       {
2406         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2407         while (__f != __t)
2408           *__f++ = _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng));
2409       }
2411   template<typename _RealType>
2412     template<typename _ForwardIterator,
2413              typename _UniformRandomNumberGenerator>
2414       void
2415       std::student_t_distribution<_RealType>::
2416       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2417                       _UniformRandomNumberGenerator& __urng,
2418                       const param_type& __p)
2419       {
2420         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2421         typename std::gamma_distribution<result_type>::param_type
2422           __p2(__p.n() / 2, 2);
2423         while (__f != __t)
2424           *__f++ =  _M_nd(__urng) * std::sqrt(__p.n() / _M_gd(__urng, __p2));
2425       }
2427   template<typename _RealType, typename _CharT, typename _Traits>
2428     std::basic_ostream<_CharT, _Traits>&
2429     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2430                const student_t_distribution<_RealType>& __x)
2431     {
2432       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2433       typedef typename __ostream_type::ios_base    __ios_base;
2435       const typename __ios_base::fmtflags __flags = __os.flags();
2436       const _CharT __fill = __os.fill();
2437       const std::streamsize __precision = __os.precision();
2438       const _CharT __space = __os.widen(' ');
2439       __os.flags(__ios_base::scientific | __ios_base::left);
2440       __os.fill(__space);
2441       __os.precision(std::numeric_limits<_RealType>::max_digits10);
2443       __os << __x.n() << __space << __x._M_nd << __space << __x._M_gd;
2445       __os.flags(__flags);
2446       __os.fill(__fill);
2447       __os.precision(__precision);
2448       return __os;
2449     }
2451   template<typename _RealType, typename _CharT, typename _Traits>
2452     std::basic_istream<_CharT, _Traits>&
2453     operator>>(std::basic_istream<_CharT, _Traits>& __is,
2454                student_t_distribution<_RealType>& __x)
2455     {
2456       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2457       typedef typename __istream_type::ios_base    __ios_base;
2459       const typename __ios_base::fmtflags __flags = __is.flags();
2460       __is.flags(__ios_base::dec | __ios_base::skipws);
2462       _RealType __n;
2463       __is >> __n >> __x._M_nd >> __x._M_gd;
2464       __x.param(typename student_t_distribution<_RealType>::param_type(__n));
2466       __is.flags(__flags);
2467       return __is;
2468     }
2471   template<typename _RealType>
2472     void
2473     gamma_distribution<_RealType>::param_type::
2474     _M_initialize()
2475     {
2476       _M_malpha = _M_alpha < 1.0 ? _M_alpha + _RealType(1.0) : _M_alpha;
2478       const _RealType __a1 = _M_malpha - _RealType(1.0) / _RealType(3.0);
2479       _M_a2 = _RealType(1.0) / std::sqrt(_RealType(9.0) * __a1);
2480     }
2482   /**
2483    * Marsaglia, G. and Tsang, W. W.
2484    * "A Simple Method for Generating Gamma Variables"
2485    * ACM Transactions on Mathematical Software, 26, 3, 363-372, 2000.
2486    */
2487   template<typename _RealType>
2488     template<typename _UniformRandomNumberGenerator>
2489       typename gamma_distribution<_RealType>::result_type
2490       gamma_distribution<_RealType>::
2491       operator()(_UniformRandomNumberGenerator& __urng,
2492                  const param_type& __param)
2493       {
2494         __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2495           __aurng(__urng);
2497         result_type __u, __v, __n;
2498         const result_type __a1 = (__param._M_malpha
2499                                   - _RealType(1.0) / _RealType(3.0));
2501         do
2502           {
2503             do
2504               {
2505                 __n = _M_nd(__urng);
2506                 __v = result_type(1.0) + __param._M_a2 * __n; 
2507               }
2508             while (__v <= 0.0);
2510             __v = __v * __v * __v;
2511             __u = __aurng();
2512           }
2513         while (__u > result_type(1.0) - 0.331 * __n * __n * __n * __n
2514                && (std::log(__u) > (0.5 * __n * __n + __a1
2515                                     * (1.0 - __v + std::log(__v)))));
2517         if (__param.alpha() == __param._M_malpha)
2518           return __a1 * __v * __param.beta();
2519         else
2520           {
2521             do
2522               __u = __aurng();
2523             while (__u == 0.0);
2524             
2525             return (std::pow(__u, result_type(1.0) / __param.alpha())
2526                     * __a1 * __v * __param.beta());
2527           }
2528       }
2530   template<typename _RealType>
2531     template<typename _ForwardIterator,
2532              typename _UniformRandomNumberGenerator>
2533       void
2534       gamma_distribution<_RealType>::
2535       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2536                       _UniformRandomNumberGenerator& __urng,
2537                       const param_type& __param)
2538       {
2539         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2540         __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2541           __aurng(__urng);
2543         result_type __u, __v, __n;
2544         const result_type __a1 = (__param._M_malpha
2545                                   - _RealType(1.0) / _RealType(3.0));
2547         if (__param.alpha() == __param._M_malpha)
2548           while (__f != __t)
2549             {
2550               do
2551                 {
2552                   do
2553                     {
2554                       __n = _M_nd(__urng);
2555                       __v = result_type(1.0) + __param._M_a2 * __n;
2556                     }
2557                   while (__v <= 0.0);
2559                   __v = __v * __v * __v;
2560                   __u = __aurng();
2561                 }
2562               while (__u > result_type(1.0) - 0.331 * __n * __n * __n * __n
2563                      && (std::log(__u) > (0.5 * __n * __n + __a1
2564                                           * (1.0 - __v + std::log(__v)))));
2566               *__f++ = __a1 * __v * __param.beta();
2567             }
2568         else
2569           while (__f != __t)
2570             {
2571               do
2572                 {
2573                   do
2574                     {
2575                       __n = _M_nd(__urng);
2576                       __v = result_type(1.0) + __param._M_a2 * __n;
2577                     }
2578                   while (__v <= 0.0);
2580                   __v = __v * __v * __v;
2581                   __u = __aurng();
2582                 }
2583               while (__u > result_type(1.0) - 0.331 * __n * __n * __n * __n
2584                      && (std::log(__u) > (0.5 * __n * __n + __a1
2585                                           * (1.0 - __v + std::log(__v)))));
2587               do
2588                 __u = __aurng();
2589               while (__u == 0.0);
2591               *__f++ = (std::pow(__u, result_type(1.0) / __param.alpha())
2592                         * __a1 * __v * __param.beta());
2593             }
2594       }
2596   template<typename _RealType, typename _CharT, typename _Traits>
2597     std::basic_ostream<_CharT, _Traits>&
2598     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2599                const gamma_distribution<_RealType>& __x)
2600     {
2601       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2602       typedef typename __ostream_type::ios_base    __ios_base;
2604       const typename __ios_base::fmtflags __flags = __os.flags();
2605       const _CharT __fill = __os.fill();
2606       const std::streamsize __precision = __os.precision();
2607       const _CharT __space = __os.widen(' ');
2608       __os.flags(__ios_base::scientific | __ios_base::left);
2609       __os.fill(__space);
2610       __os.precision(std::numeric_limits<_RealType>::max_digits10);
2612       __os << __x.alpha() << __space << __x.beta()
2613            << __space << __x._M_nd;
2615       __os.flags(__flags);
2616       __os.fill(__fill);
2617       __os.precision(__precision);
2618       return __os;
2619     }
2621   template<typename _RealType, typename _CharT, typename _Traits>
2622     std::basic_istream<_CharT, _Traits>&
2623     operator>>(std::basic_istream<_CharT, _Traits>& __is,
2624                gamma_distribution<_RealType>& __x)
2625     {
2626       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2627       typedef typename __istream_type::ios_base    __ios_base;
2629       const typename __ios_base::fmtflags __flags = __is.flags();
2630       __is.flags(__ios_base::dec | __ios_base::skipws);
2632       _RealType __alpha_val, __beta_val;
2633       __is >> __alpha_val >> __beta_val >> __x._M_nd;
2634       __x.param(typename gamma_distribution<_RealType>::
2635                 param_type(__alpha_val, __beta_val));
2637       __is.flags(__flags);
2638       return __is;
2639     }
2642   template<typename _RealType>
2643     template<typename _UniformRandomNumberGenerator>
2644       typename weibull_distribution<_RealType>::result_type
2645       weibull_distribution<_RealType>::
2646       operator()(_UniformRandomNumberGenerator& __urng,
2647                  const param_type& __p)
2648       {
2649         __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2650           __aurng(__urng);
2651         return __p.b() * std::pow(-std::log(result_type(1) - __aurng()),
2652                                   result_type(1) / __p.a());
2653       }
2655   template<typename _RealType>
2656     template<typename _ForwardIterator,
2657              typename _UniformRandomNumberGenerator>
2658       void
2659       weibull_distribution<_RealType>::
2660       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2661                       _UniformRandomNumberGenerator& __urng,
2662                       const param_type& __p)
2663       {
2664         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2665         __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2666           __aurng(__urng);
2667         auto __inv_a = result_type(1) / __p.a();
2669         while (__f != __t)
2670           *__f++ = __p.b() * std::pow(-std::log(result_type(1) - __aurng()),
2671                                       __inv_a);
2672       }
2674   template<typename _RealType, typename _CharT, typename _Traits>
2675     std::basic_ostream<_CharT, _Traits>&
2676     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2677                const weibull_distribution<_RealType>& __x)
2678     {
2679       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2680       typedef typename __ostream_type::ios_base    __ios_base;
2682       const typename __ios_base::fmtflags __flags = __os.flags();
2683       const _CharT __fill = __os.fill();
2684       const std::streamsize __precision = __os.precision();
2685       const _CharT __space = __os.widen(' ');
2686       __os.flags(__ios_base::scientific | __ios_base::left);
2687       __os.fill(__space);
2688       __os.precision(std::numeric_limits<_RealType>::max_digits10);
2690       __os << __x.a() << __space << __x.b();
2692       __os.flags(__flags);
2693       __os.fill(__fill);
2694       __os.precision(__precision);
2695       return __os;
2696     }
2698   template<typename _RealType, typename _CharT, typename _Traits>
2699     std::basic_istream<_CharT, _Traits>&
2700     operator>>(std::basic_istream<_CharT, _Traits>& __is,
2701                weibull_distribution<_RealType>& __x)
2702     {
2703       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2704       typedef typename __istream_type::ios_base    __ios_base;
2706       const typename __ios_base::fmtflags __flags = __is.flags();
2707       __is.flags(__ios_base::dec | __ios_base::skipws);
2709       _RealType __a, __b;
2710       __is >> __a >> __b;
2711       __x.param(typename weibull_distribution<_RealType>::
2712                 param_type(__a, __b));
2714       __is.flags(__flags);
2715       return __is;
2716     }
2719   template<typename _RealType>
2720     template<typename _UniformRandomNumberGenerator>
2721       typename extreme_value_distribution<_RealType>::result_type
2722       extreme_value_distribution<_RealType>::
2723       operator()(_UniformRandomNumberGenerator& __urng,
2724                  const param_type& __p)
2725       {
2726         __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2727           __aurng(__urng);
2728         return __p.a() - __p.b() * std::log(-std::log(result_type(1)
2729                                                       - __aurng()));
2730       }
2732   template<typename _RealType>
2733     template<typename _ForwardIterator,
2734              typename _UniformRandomNumberGenerator>
2735       void
2736       extreme_value_distribution<_RealType>::
2737       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2738                       _UniformRandomNumberGenerator& __urng,
2739                       const param_type& __p)
2740       {
2741         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2742         __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
2743           __aurng(__urng);
2745         while (__f != __t)
2746           *__f++ = __p.a() - __p.b() * std::log(-std::log(result_type(1)
2747                                                           - __aurng()));
2748       }
2750   template<typename _RealType, typename _CharT, typename _Traits>
2751     std::basic_ostream<_CharT, _Traits>&
2752     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2753                const extreme_value_distribution<_RealType>& __x)
2754     {
2755       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2756       typedef typename __ostream_type::ios_base    __ios_base;
2758       const typename __ios_base::fmtflags __flags = __os.flags();
2759       const _CharT __fill = __os.fill();
2760       const std::streamsize __precision = __os.precision();
2761       const _CharT __space = __os.widen(' ');
2762       __os.flags(__ios_base::scientific | __ios_base::left);
2763       __os.fill(__space);
2764       __os.precision(std::numeric_limits<_RealType>::max_digits10);
2766       __os << __x.a() << __space << __x.b();
2768       __os.flags(__flags);
2769       __os.fill(__fill);
2770       __os.precision(__precision);
2771       return __os;
2772     }
2774   template<typename _RealType, typename _CharT, typename _Traits>
2775     std::basic_istream<_CharT, _Traits>&
2776     operator>>(std::basic_istream<_CharT, _Traits>& __is,
2777                extreme_value_distribution<_RealType>& __x)
2778     {
2779       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2780       typedef typename __istream_type::ios_base    __ios_base;
2782       const typename __ios_base::fmtflags __flags = __is.flags();
2783       __is.flags(__ios_base::dec | __ios_base::skipws);
2785       _RealType __a, __b;
2786       __is >> __a >> __b;
2787       __x.param(typename extreme_value_distribution<_RealType>::
2788                 param_type(__a, __b));
2790       __is.flags(__flags);
2791       return __is;
2792     }
2795   template<typename _IntType>
2796     void
2797     discrete_distribution<_IntType>::param_type::
2798     _M_initialize()
2799     {
2800       if (_M_prob.size() < 2)
2801         {
2802           _M_prob.clear();
2803           return;
2804         }
2806       const double __sum = std::accumulate(_M_prob.begin(),
2807                                            _M_prob.end(), 0.0);
2808       // Now normalize the probabilites.
2809       __detail::__transform(_M_prob.begin(), _M_prob.end(), _M_prob.begin(),
2810                           std::bind2nd(std::divides<double>(), __sum));
2811       // Accumulate partial sums.
2812       _M_cp.reserve(_M_prob.size());
2813       std::partial_sum(_M_prob.begin(), _M_prob.end(),
2814                        std::back_inserter(_M_cp));
2815       // Make sure the last cumulative probability is one.
2816       _M_cp[_M_cp.size() - 1] = 1.0;
2817     }
2819   template<typename _IntType>
2820     template<typename _Func>
2821       discrete_distribution<_IntType>::param_type::
2822       param_type(size_t __nw, double __xmin, double __xmax, _Func __fw)
2823       : _M_prob(), _M_cp()
2824       {
2825         const size_t __n = __nw == 0 ? 1 : __nw;
2826         const double __delta = (__xmax - __xmin) / __n;
2828         _M_prob.reserve(__n);
2829         for (size_t __k = 0; __k < __nw; ++__k)
2830           _M_prob.push_back(__fw(__xmin + __k * __delta + 0.5 * __delta));
2832         _M_initialize();
2833       }
2835   template<typename _IntType>
2836     template<typename _UniformRandomNumberGenerator>
2837       typename discrete_distribution<_IntType>::result_type
2838       discrete_distribution<_IntType>::
2839       operator()(_UniformRandomNumberGenerator& __urng,
2840                  const param_type& __param)
2841       {
2842         if (__param._M_cp.empty())
2843           return result_type(0);
2845         __detail::_Adaptor<_UniformRandomNumberGenerator, double>
2846           __aurng(__urng);
2848         const double __p = __aurng();
2849         auto __pos = std::lower_bound(__param._M_cp.begin(),
2850                                       __param._M_cp.end(), __p);
2852         return __pos - __param._M_cp.begin();
2853       }
2855   template<typename _IntType>
2856     template<typename _ForwardIterator,
2857              typename _UniformRandomNumberGenerator>
2858       void
2859       discrete_distribution<_IntType>::
2860       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
2861                       _UniformRandomNumberGenerator& __urng,
2862                       const param_type& __param)
2863       {
2864         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
2866         if (__param._M_cp.empty())
2867           {
2868             while (__f != __t)
2869               *__f++ = result_type(0);
2870             return;
2871           }
2873         __detail::_Adaptor<_UniformRandomNumberGenerator, double>
2874           __aurng(__urng);
2876         while (__f != __t)
2877           {
2878             const double __p = __aurng();
2879             auto __pos = std::lower_bound(__param._M_cp.begin(),
2880                                           __param._M_cp.end(), __p);
2882             *__f++ = __pos - __param._M_cp.begin();
2883           }
2884       }
2886   template<typename _IntType, typename _CharT, typename _Traits>
2887     std::basic_ostream<_CharT, _Traits>&
2888     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2889                const discrete_distribution<_IntType>& __x)
2890     {
2891       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
2892       typedef typename __ostream_type::ios_base    __ios_base;
2894       const typename __ios_base::fmtflags __flags = __os.flags();
2895       const _CharT __fill = __os.fill();
2896       const std::streamsize __precision = __os.precision();
2897       const _CharT __space = __os.widen(' ');
2898       __os.flags(__ios_base::scientific | __ios_base::left);
2899       __os.fill(__space);
2900       __os.precision(std::numeric_limits<double>::max_digits10);
2902       std::vector<double> __prob = __x.probabilities();
2903       __os << __prob.size();
2904       for (auto __dit = __prob.begin(); __dit != __prob.end(); ++__dit)
2905         __os << __space << *__dit;
2907       __os.flags(__flags);
2908       __os.fill(__fill);
2909       __os.precision(__precision);
2910       return __os;
2911     }
2913   template<typename _IntType, typename _CharT, typename _Traits>
2914     std::basic_istream<_CharT, _Traits>&
2915     operator>>(std::basic_istream<_CharT, _Traits>& __is,
2916                discrete_distribution<_IntType>& __x)
2917     {
2918       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
2919       typedef typename __istream_type::ios_base    __ios_base;
2921       const typename __ios_base::fmtflags __flags = __is.flags();
2922       __is.flags(__ios_base::dec | __ios_base::skipws);
2924       size_t __n;
2925       __is >> __n;
2927       std::vector<double> __prob_vec;
2928       __prob_vec.reserve(__n);
2929       for (; __n != 0; --__n)
2930         {
2931           double __prob;
2932           __is >> __prob;
2933           __prob_vec.push_back(__prob);
2934         }
2936       __x.param(typename discrete_distribution<_IntType>::
2937                 param_type(__prob_vec.begin(), __prob_vec.end()));
2939       __is.flags(__flags);
2940       return __is;
2941     }
2944   template<typename _RealType>
2945     void
2946     piecewise_constant_distribution<_RealType>::param_type::
2947     _M_initialize()
2948     {
2949       if (_M_int.size() < 2
2950           || (_M_int.size() == 2
2951               && _M_int[0] == _RealType(0)
2952               && _M_int[1] == _RealType(1)))
2953         {
2954           _M_int.clear();
2955           _M_den.clear();
2956           return;
2957         }
2959       const double __sum = std::accumulate(_M_den.begin(),
2960                                            _M_den.end(), 0.0);
2962       __detail::__transform(_M_den.begin(), _M_den.end(), _M_den.begin(),
2963                             std::bind2nd(std::divides<double>(), __sum));
2965       _M_cp.reserve(_M_den.size());
2966       std::partial_sum(_M_den.begin(), _M_den.end(),
2967                        std::back_inserter(_M_cp));
2969       // Make sure the last cumulative probability is one.
2970       _M_cp[_M_cp.size() - 1] = 1.0;
2972       for (size_t __k = 0; __k < _M_den.size(); ++__k)
2973         _M_den[__k] /= _M_int[__k + 1] - _M_int[__k];
2974     }
2976   template<typename _RealType>
2977     template<typename _InputIteratorB, typename _InputIteratorW>
2978       piecewise_constant_distribution<_RealType>::param_type::
2979       param_type(_InputIteratorB __bbegin,
2980                  _InputIteratorB __bend,
2981                  _InputIteratorW __wbegin)
2982       : _M_int(), _M_den(), _M_cp()
2983       {
2984         if (__bbegin != __bend)
2985           {
2986             for (;;)
2987               {
2988                 _M_int.push_back(*__bbegin);
2989                 ++__bbegin;
2990                 if (__bbegin == __bend)
2991                   break;
2993                 _M_den.push_back(*__wbegin);
2994                 ++__wbegin;
2995               }
2996           }
2998         _M_initialize();
2999       }
3001   template<typename _RealType>
3002     template<typename _Func>
3003       piecewise_constant_distribution<_RealType>::param_type::
3004       param_type(initializer_list<_RealType> __bl, _Func __fw)
3005       : _M_int(), _M_den(), _M_cp()
3006       {
3007         _M_int.reserve(__bl.size());
3008         for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter)
3009           _M_int.push_back(*__biter);
3011         _M_den.reserve(_M_int.size() - 1);
3012         for (size_t __k = 0; __k < _M_int.size() - 1; ++__k)
3013           _M_den.push_back(__fw(0.5 * (_M_int[__k + 1] + _M_int[__k])));
3015         _M_initialize();
3016       }
3018   template<typename _RealType>
3019     template<typename _Func>
3020       piecewise_constant_distribution<_RealType>::param_type::
3021       param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw)
3022       : _M_int(), _M_den(), _M_cp()
3023       {
3024         const size_t __n = __nw == 0 ? 1 : __nw;
3025         const _RealType __delta = (__xmax - __xmin) / __n;
3027         _M_int.reserve(__n + 1);
3028         for (size_t __k = 0; __k <= __nw; ++__k)
3029           _M_int.push_back(__xmin + __k * __delta);
3031         _M_den.reserve(__n);
3032         for (size_t __k = 0; __k < __nw; ++__k)
3033           _M_den.push_back(__fw(_M_int[__k] + 0.5 * __delta));
3035         _M_initialize();
3036       }
3038   template<typename _RealType>
3039     template<typename _UniformRandomNumberGenerator>
3040       typename piecewise_constant_distribution<_RealType>::result_type
3041       piecewise_constant_distribution<_RealType>::
3042       operator()(_UniformRandomNumberGenerator& __urng,
3043                  const param_type& __param)
3044       {
3045         __detail::_Adaptor<_UniformRandomNumberGenerator, double>
3046           __aurng(__urng);
3048         const double __p = __aurng();
3049         if (__param._M_cp.empty())
3050           return __p;
3052         auto __pos = std::lower_bound(__param._M_cp.begin(),
3053                                       __param._M_cp.end(), __p);
3054         const size_t __i = __pos - __param._M_cp.begin();
3056         const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
3058         return __param._M_int[__i] + (__p - __pref) / __param._M_den[__i];
3059       }
3061   template<typename _RealType>
3062     template<typename _ForwardIterator,
3063              typename _UniformRandomNumberGenerator>
3064       void
3065       piecewise_constant_distribution<_RealType>::
3066       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3067                       _UniformRandomNumberGenerator& __urng,
3068                       const param_type& __param)
3069       {
3070         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
3071         __detail::_Adaptor<_UniformRandomNumberGenerator, double>
3072           __aurng(__urng);
3074         if (__param._M_cp.empty())
3075           {
3076             while (__f != __t)
3077               *__f++ = __aurng();
3078             return;
3079           }
3081         while (__f != __t)
3082           {
3083             const double __p = __aurng();
3085             auto __pos = std::lower_bound(__param._M_cp.begin(),
3086                                           __param._M_cp.end(), __p);
3087             const size_t __i = __pos - __param._M_cp.begin();
3089             const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
3091             *__f++ = (__param._M_int[__i]
3092                       + (__p - __pref) / __param._M_den[__i]);
3093           }
3094       }
3096   template<typename _RealType, typename _CharT, typename _Traits>
3097     std::basic_ostream<_CharT, _Traits>&
3098     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3099                const piecewise_constant_distribution<_RealType>& __x)
3100     {
3101       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
3102       typedef typename __ostream_type::ios_base    __ios_base;
3104       const typename __ios_base::fmtflags __flags = __os.flags();
3105       const _CharT __fill = __os.fill();
3106       const std::streamsize __precision = __os.precision();
3107       const _CharT __space = __os.widen(' ');
3108       __os.flags(__ios_base::scientific | __ios_base::left);
3109       __os.fill(__space);
3110       __os.precision(std::numeric_limits<_RealType>::max_digits10);
3112       std::vector<_RealType> __int = __x.intervals();
3113       __os << __int.size() - 1;
3115       for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit)
3116         __os << __space << *__xit;
3118       std::vector<double> __den = __x.densities();
3119       for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit)
3120         __os << __space << *__dit;
3122       __os.flags(__flags);
3123       __os.fill(__fill);
3124       __os.precision(__precision);
3125       return __os;
3126     }
3128   template<typename _RealType, typename _CharT, typename _Traits>
3129     std::basic_istream<_CharT, _Traits>&
3130     operator>>(std::basic_istream<_CharT, _Traits>& __is,
3131                piecewise_constant_distribution<_RealType>& __x)
3132     {
3133       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
3134       typedef typename __istream_type::ios_base    __ios_base;
3136       const typename __ios_base::fmtflags __flags = __is.flags();
3137       __is.flags(__ios_base::dec | __ios_base::skipws);
3139       size_t __n;
3140       __is >> __n;
3142       std::vector<_RealType> __int_vec;
3143       __int_vec.reserve(__n + 1);
3144       for (size_t __i = 0; __i <= __n; ++__i)
3145         {
3146           _RealType __int;
3147           __is >> __int;
3148           __int_vec.push_back(__int);
3149         }
3151       std::vector<double> __den_vec;
3152       __den_vec.reserve(__n);
3153       for (size_t __i = 0; __i < __n; ++__i)
3154         {
3155           double __den;
3156           __is >> __den;
3157           __den_vec.push_back(__den);
3158         }
3160       __x.param(typename piecewise_constant_distribution<_RealType>::
3161           param_type(__int_vec.begin(), __int_vec.end(), __den_vec.begin()));
3163       __is.flags(__flags);
3164       return __is;
3165     }
3168   template<typename _RealType>
3169     void
3170     piecewise_linear_distribution<_RealType>::param_type::
3171     _M_initialize()
3172     {
3173       if (_M_int.size() < 2
3174           || (_M_int.size() == 2
3175               && _M_int[0] == _RealType(0)
3176               && _M_int[1] == _RealType(1)
3177               && _M_den[0] == _M_den[1]))
3178         {
3179           _M_int.clear();
3180           _M_den.clear();
3181           return;
3182         }
3184       double __sum = 0.0;
3185       _M_cp.reserve(_M_int.size() - 1);
3186       _M_m.reserve(_M_int.size() - 1);
3187       for (size_t __k = 0; __k < _M_int.size() - 1; ++__k)
3188         {
3189           const _RealType __delta = _M_int[__k + 1] - _M_int[__k];
3190           __sum += 0.5 * (_M_den[__k + 1] + _M_den[__k]) * __delta;
3191           _M_cp.push_back(__sum);
3192           _M_m.push_back((_M_den[__k + 1] - _M_den[__k]) / __delta);
3193         }
3195       //  Now normalize the densities...
3196       __detail::__transform(_M_den.begin(), _M_den.end(), _M_den.begin(),
3197                           std::bind2nd(std::divides<double>(), __sum));
3198       //  ... and partial sums... 
3199       __detail::__transform(_M_cp.begin(), _M_cp.end(), _M_cp.begin(),
3200                             std::bind2nd(std::divides<double>(), __sum));
3201       //  ... and slopes.
3202       __detail::__transform(_M_m.begin(), _M_m.end(), _M_m.begin(),
3203                             std::bind2nd(std::divides<double>(), __sum));
3204       //  Make sure the last cumulative probablility is one.
3205       _M_cp[_M_cp.size() - 1] = 1.0;
3206      }
3208   template<typename _RealType>
3209     template<typename _InputIteratorB, typename _InputIteratorW>
3210       piecewise_linear_distribution<_RealType>::param_type::
3211       param_type(_InputIteratorB __bbegin,
3212                  _InputIteratorB __bend,
3213                  _InputIteratorW __wbegin)
3214       : _M_int(), _M_den(), _M_cp(), _M_m()
3215       {
3216         for (; __bbegin != __bend; ++__bbegin, ++__wbegin)
3217           {
3218             _M_int.push_back(*__bbegin);
3219             _M_den.push_back(*__wbegin);
3220           }
3222         _M_initialize();
3223       }
3225   template<typename _RealType>
3226     template<typename _Func>
3227       piecewise_linear_distribution<_RealType>::param_type::
3228       param_type(initializer_list<_RealType> __bl, _Func __fw)
3229       : _M_int(), _M_den(), _M_cp(), _M_m()
3230       {
3231         _M_int.reserve(__bl.size());
3232         _M_den.reserve(__bl.size());
3233         for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter)
3234           {
3235             _M_int.push_back(*__biter);
3236             _M_den.push_back(__fw(*__biter));
3237           }
3239         _M_initialize();
3240       }
3242   template<typename _RealType>
3243     template<typename _Func>
3244       piecewise_linear_distribution<_RealType>::param_type::
3245       param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw)
3246       : _M_int(), _M_den(), _M_cp(), _M_m()
3247       {
3248         const size_t __n = __nw == 0 ? 1 : __nw;
3249         const _RealType __delta = (__xmax - __xmin) / __n;
3251         _M_int.reserve(__n + 1);
3252         _M_den.reserve(__n + 1);
3253         for (size_t __k = 0; __k <= __nw; ++__k)
3254           {
3255             _M_int.push_back(__xmin + __k * __delta);
3256             _M_den.push_back(__fw(_M_int[__k] + __delta));
3257           }
3259         _M_initialize();
3260       }
3262   template<typename _RealType>
3263     template<typename _UniformRandomNumberGenerator>
3264       typename piecewise_linear_distribution<_RealType>::result_type
3265       piecewise_linear_distribution<_RealType>::
3266       operator()(_UniformRandomNumberGenerator& __urng,
3267                  const param_type& __param)
3268       {
3269         __detail::_Adaptor<_UniformRandomNumberGenerator, double>
3270           __aurng(__urng);
3272         const double __p = __aurng();
3273         if (__param._M_cp.empty())
3274           return __p;
3276         auto __pos = std::lower_bound(__param._M_cp.begin(),
3277                                       __param._M_cp.end(), __p);
3278         const size_t __i = __pos - __param._M_cp.begin();
3280         const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
3282         const double __a = 0.5 * __param._M_m[__i];
3283         const double __b = __param._M_den[__i];
3284         const double __cm = __p - __pref;
3286         _RealType __x = __param._M_int[__i];
3287         if (__a == 0)
3288           __x += __cm / __b;
3289         else
3290           {
3291             const double __d = __b * __b + 4.0 * __a * __cm;
3292             __x += 0.5 * (std::sqrt(__d) - __b) / __a;
3293           }
3295         return __x;
3296       }
3298   template<typename _RealType>
3299     template<typename _ForwardIterator,
3300              typename _UniformRandomNumberGenerator>
3301       void
3302       piecewise_linear_distribution<_RealType>::
3303       __generate_impl(_ForwardIterator __f, _ForwardIterator __t,
3304                       _UniformRandomNumberGenerator& __urng,
3305                       const param_type& __param)
3306       {
3307         __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
3308         // We could duplicate everything from operator()...
3309         while (__f != __t)
3310           *__f++ = this->operator()(__urng, __param);
3311       }
3313   template<typename _RealType, typename _CharT, typename _Traits>
3314     std::basic_ostream<_CharT, _Traits>&
3315     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
3316                const piecewise_linear_distribution<_RealType>& __x)
3317     {
3318       typedef std::basic_ostream<_CharT, _Traits>  __ostream_type;
3319       typedef typename __ostream_type::ios_base    __ios_base;
3321       const typename __ios_base::fmtflags __flags = __os.flags();
3322       const _CharT __fill = __os.fill();
3323       const std::streamsize __precision = __os.precision();
3324       const _CharT __space = __os.widen(' ');
3325       __os.flags(__ios_base::scientific | __ios_base::left);
3326       __os.fill(__space);
3327       __os.precision(std::numeric_limits<_RealType>::max_digits10);
3329       std::vector<_RealType> __int = __x.intervals();
3330       __os << __int.size() - 1;
3332       for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit)
3333         __os << __space << *__xit;
3335       std::vector<double> __den = __x.densities();
3336       for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit)
3337         __os << __space << *__dit;
3339       __os.flags(__flags);
3340       __os.fill(__fill);
3341       __os.precision(__precision);
3342       return __os;
3343     }
3345   template<typename _RealType, typename _CharT, typename _Traits>
3346     std::basic_istream<_CharT, _Traits>&
3347     operator>>(std::basic_istream<_CharT, _Traits>& __is,
3348                piecewise_linear_distribution<_RealType>& __x)
3349     {
3350       typedef std::basic_istream<_CharT, _Traits>  __istream_type;
3351       typedef typename __istream_type::ios_base    __ios_base;
3353       const typename __ios_base::fmtflags __flags = __is.flags();
3354       __is.flags(__ios_base::dec | __ios_base::skipws);
3356       size_t __n;
3357       __is >> __n;
3359       std::vector<_RealType> __int_vec;
3360       __int_vec.reserve(__n + 1);
3361       for (size_t __i = 0; __i <= __n; ++__i)
3362         {
3363           _RealType __int;
3364           __is >> __int;
3365           __int_vec.push_back(__int);
3366         }
3368       std::vector<double> __den_vec;
3369       __den_vec.reserve(__n + 1);
3370       for (size_t __i = 0; __i <= __n; ++__i)
3371         {
3372           double __den;
3373           __is >> __den;
3374           __den_vec.push_back(__den);
3375         }
3377       __x.param(typename piecewise_linear_distribution<_RealType>::
3378           param_type(__int_vec.begin(), __int_vec.end(), __den_vec.begin()));
3380       __is.flags(__flags);
3381       return __is;
3382     }
3385   template<typename _IntType>
3386     seed_seq::seed_seq(std::initializer_list<_IntType> __il)
3387     {
3388       for (auto __iter = __il.begin(); __iter != __il.end(); ++__iter)
3389         _M_v.push_back(__detail::__mod<result_type,
3390                        __detail::_Shift<result_type, 32>::__value>(*__iter));
3391     }
3393   template<typename _InputIterator>
3394     seed_seq::seed_seq(_InputIterator __begin, _InputIterator __end)
3395     {
3396       for (_InputIterator __iter = __begin; __iter != __end; ++__iter)
3397         _M_v.push_back(__detail::__mod<result_type,
3398                        __detail::_Shift<result_type, 32>::__value>(*__iter));
3399     }
3401   template<typename _RandomAccessIterator>
3402     void
3403     seed_seq::generate(_RandomAccessIterator __begin,
3404                        _RandomAccessIterator __end)
3405     {
3406       typedef typename iterator_traits<_RandomAccessIterator>::value_type
3407         _Type;
3409       if (__begin == __end)
3410         return;
3412       std::fill(__begin, __end, _Type(0x8b8b8b8bu));
3414       const size_t __n = __end - __begin;
3415       const size_t __s = _M_v.size();
3416       const size_t __t = (__n >= 623) ? 11
3417                        : (__n >=  68) ? 7
3418                        : (__n >=  39) ? 5
3419                        : (__n >=   7) ? 3
3420                        : (__n - 1) / 2;
3421       const size_t __p = (__n - __t) / 2;
3422       const size_t __q = __p + __t;
3423       const size_t __m = std::max(size_t(__s + 1), __n);
3425       for (size_t __k = 0; __k < __m; ++__k)
3426         {
3427           _Type __arg = (__begin[__k % __n]
3428                          ^ __begin[(__k + __p) % __n]
3429                          ^ __begin[(__k - 1) % __n]);
3430           _Type __r1 = __arg ^ (__arg >> 27);
3431           __r1 = __detail::__mod<_Type,
3432                     __detail::_Shift<_Type, 32>::__value>(1664525u * __r1);
3433           _Type __r2 = __r1;
3434           if (__k == 0)
3435             __r2 += __s;
3436           else if (__k <= __s)
3437             __r2 += __k % __n + _M_v[__k - 1];
3438           else
3439             __r2 += __k % __n;
3440           __r2 = __detail::__mod<_Type,
3441                    __detail::_Shift<_Type, 32>::__value>(__r2);
3442           __begin[(__k + __p) % __n] += __r1;
3443           __begin[(__k + __q) % __n] += __r2;
3444           __begin[__k % __n] = __r2;
3445         }
3447       for (size_t __k = __m; __k < __m + __n; ++__k)
3448         {
3449           _Type __arg = (__begin[__k % __n]
3450                          + __begin[(__k + __p) % __n]
3451                          + __begin[(__k - 1) % __n]);
3452           _Type __r3 = __arg ^ (__arg >> 27);
3453           __r3 = __detail::__mod<_Type,
3454                    __detail::_Shift<_Type, 32>::__value>(1566083941u * __r3);
3455           _Type __r4 = __r3 - __k % __n;
3456           __r4 = __detail::__mod<_Type,
3457                    __detail::_Shift<_Type, 32>::__value>(__r4);
3458           __begin[(__k + __p) % __n] ^= __r3;
3459           __begin[(__k + __q) % __n] ^= __r4;
3460           __begin[__k % __n] = __r4;
3461         }
3462     }
3464   template<typename _RealType, size_t __bits,
3465            typename _UniformRandomNumberGenerator>
3466     _RealType
3467     generate_canonical(_UniformRandomNumberGenerator& __urng)
3468     {
3469       const size_t __b
3470         = std::min(static_cast<size_t>(std::numeric_limits<_RealType>::digits),
3471                    __bits);
3472       const long double __r = static_cast<long double>(__urng.max())
3473                             - static_cast<long double>(__urng.min()) + 1.0L;
3474       const size_t __log2r = std::log(__r) / std::log(2.0L);
3475       size_t __k = std::max<size_t>(1UL, (__b + __log2r - 1UL) / __log2r);
3476       _RealType __sum = _RealType(0);
3477       _RealType __tmp = _RealType(1);
3478       for (; __k != 0; --__k)
3479         {
3480           __sum += _RealType(__urng() - __urng.min()) * __tmp;
3481           __tmp *= __r;
3482         }
3483       return __sum / __tmp;
3484     }
3486 _GLIBCXX_END_NAMESPACE_VERSION
3487 } // namespace
3489 #endif