LCOV - code coverage report
Current view: top level - 11/bits - random.tcc (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 95 112 84.8 %
Date: 2025-08-24 09:11:10 Functions: 8 8 100.0 %

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

Generated by: LCOV version 1.14