xref: /openbsd-src/gnu/llvm/libcxx/include/__random/linear_congruential_engine.h (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
1*4bdff4beSrobert //===----------------------------------------------------------------------===//
2*4bdff4beSrobert //
3*4bdff4beSrobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*4bdff4beSrobert // See https://llvm.org/LICENSE.txt for license information.
5*4bdff4beSrobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*4bdff4beSrobert //
7*4bdff4beSrobert //===----------------------------------------------------------------------===//
8*4bdff4beSrobert 
9*4bdff4beSrobert #ifndef _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H
10*4bdff4beSrobert #define _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H
11*4bdff4beSrobert 
12*4bdff4beSrobert #include <__config>
13*4bdff4beSrobert #include <__random/is_seed_sequence.h>
14*4bdff4beSrobert #include <cstdint>
15*4bdff4beSrobert #include <iosfwd>
16*4bdff4beSrobert #include <type_traits>
17*4bdff4beSrobert 
18*4bdff4beSrobert #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19*4bdff4beSrobert #  pragma GCC system_header
20*4bdff4beSrobert #endif
21*4bdff4beSrobert 
22*4bdff4beSrobert _LIBCPP_PUSH_MACROS
23*4bdff4beSrobert #include <__undef_macros>
24*4bdff4beSrobert 
25*4bdff4beSrobert _LIBCPP_BEGIN_NAMESPACE_STD
26*4bdff4beSrobert 
27*4bdff4beSrobert template <unsigned long long __a, unsigned long long __c,
28*4bdff4beSrobert           unsigned long long __m, unsigned long long _Mp,
29*4bdff4beSrobert           bool _MightOverflow = (__a != 0 && __m != 0 && __m-1 > (_Mp-__c)/__a),
30*4bdff4beSrobert           bool _OverflowOK = ((__m | (__m-1)) > __m), // m = 2^n
31*4bdff4beSrobert           bool _SchrageOK = (__a != 0 && __m != 0 && __m % __a <= __m / __a)> // r <= q
32*4bdff4beSrobert struct __lce_alg_picker
33*4bdff4beSrobert {
34*4bdff4beSrobert     static_assert(__a != 0 || __m != 0 || !_MightOverflow || _OverflowOK || _SchrageOK,
35*4bdff4beSrobert                   "The current values of a, c, and m cannot generate a number "
36*4bdff4beSrobert                   "within bounds of linear_congruential_engine.");
37*4bdff4beSrobert 
38*4bdff4beSrobert     static _LIBCPP_CONSTEXPR const bool __use_schrage = _MightOverflow &&
39*4bdff4beSrobert                                                         !_OverflowOK &&
40*4bdff4beSrobert                                                         _SchrageOK;
41*4bdff4beSrobert };
42*4bdff4beSrobert 
43*4bdff4beSrobert template <unsigned long long __a, unsigned long long __c,
44*4bdff4beSrobert           unsigned long long __m, unsigned long long _Mp,
45*4bdff4beSrobert           bool _UseSchrage = __lce_alg_picker<__a, __c, __m, _Mp>::__use_schrage>
46*4bdff4beSrobert struct __lce_ta;
47*4bdff4beSrobert 
48*4bdff4beSrobert // 64
49*4bdff4beSrobert 
50*4bdff4beSrobert template <unsigned long long __a, unsigned long long __c, unsigned long long __m>
51*4bdff4beSrobert struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), true>
52*4bdff4beSrobert {
53*4bdff4beSrobert     typedef unsigned long long result_type;
54*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
55*4bdff4beSrobert     static result_type next(result_type __x)
56*4bdff4beSrobert     {
57*4bdff4beSrobert         // Schrage's algorithm
58*4bdff4beSrobert         const result_type __q = __m / __a;
59*4bdff4beSrobert         const result_type __r = __m % __a;
60*4bdff4beSrobert         const result_type __t0 = __a * (__x % __q);
61*4bdff4beSrobert         const result_type __t1 = __r * (__x / __q);
62*4bdff4beSrobert         __x = __t0 + (__t0 < __t1) * __m - __t1;
63*4bdff4beSrobert         __x += __c - (__x >= __m - __c) * __m;
64*4bdff4beSrobert         return __x;
65*4bdff4beSrobert     }
66*4bdff4beSrobert };
67*4bdff4beSrobert 
68*4bdff4beSrobert template <unsigned long long __a, unsigned long long __m>
69*4bdff4beSrobert struct __lce_ta<__a, 0, __m, (unsigned long long)(~0), true>
70*4bdff4beSrobert {
71*4bdff4beSrobert     typedef unsigned long long result_type;
72*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
73*4bdff4beSrobert     static result_type next(result_type __x)
74*4bdff4beSrobert     {
75*4bdff4beSrobert         // Schrage's algorithm
76*4bdff4beSrobert         const result_type __q = __m / __a;
77*4bdff4beSrobert         const result_type __r = __m % __a;
78*4bdff4beSrobert         const result_type __t0 = __a * (__x % __q);
79*4bdff4beSrobert         const result_type __t1 = __r * (__x / __q);
80*4bdff4beSrobert         __x = __t0 + (__t0 < __t1) * __m - __t1;
81*4bdff4beSrobert         return __x;
82*4bdff4beSrobert     }
83*4bdff4beSrobert };
84*4bdff4beSrobert 
85*4bdff4beSrobert template <unsigned long long __a, unsigned long long __c, unsigned long long __m>
86*4bdff4beSrobert struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), false>
87*4bdff4beSrobert {
88*4bdff4beSrobert     typedef unsigned long long result_type;
89*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
90*4bdff4beSrobert     static result_type next(result_type __x)
91*4bdff4beSrobert     {
92*4bdff4beSrobert         return (__a * __x + __c) % __m;
93*4bdff4beSrobert     }
94*4bdff4beSrobert };
95*4bdff4beSrobert 
96*4bdff4beSrobert template <unsigned long long __a, unsigned long long __c>
97*4bdff4beSrobert struct __lce_ta<__a, __c, 0, (unsigned long long)(~0), false>
98*4bdff4beSrobert {
99*4bdff4beSrobert     typedef unsigned long long result_type;
100*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
101*4bdff4beSrobert     static result_type next(result_type __x)
102*4bdff4beSrobert     {
103*4bdff4beSrobert         return __a * __x + __c;
104*4bdff4beSrobert     }
105*4bdff4beSrobert };
106*4bdff4beSrobert 
107*4bdff4beSrobert // 32
108*4bdff4beSrobert 
109*4bdff4beSrobert template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>
110*4bdff4beSrobert struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), true>
111*4bdff4beSrobert {
112*4bdff4beSrobert     typedef unsigned result_type;
113*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
114*4bdff4beSrobert     static result_type next(result_type __x)
115*4bdff4beSrobert     {
116*4bdff4beSrobert         const result_type __a = static_cast<result_type>(_Ap);
117*4bdff4beSrobert         const result_type __c = static_cast<result_type>(_Cp);
118*4bdff4beSrobert         const result_type __m = static_cast<result_type>(_Mp);
119*4bdff4beSrobert         // Schrage's algorithm
120*4bdff4beSrobert         const result_type __q = __m / __a;
121*4bdff4beSrobert         const result_type __r = __m % __a;
122*4bdff4beSrobert         const result_type __t0 = __a * (__x % __q);
123*4bdff4beSrobert         const result_type __t1 = __r * (__x / __q);
124*4bdff4beSrobert         __x = __t0 + (__t0 < __t1) * __m - __t1;
125*4bdff4beSrobert         __x += __c - (__x >= __m - __c) * __m;
126*4bdff4beSrobert         return __x;
127*4bdff4beSrobert     }
128*4bdff4beSrobert };
129*4bdff4beSrobert 
130*4bdff4beSrobert template <unsigned long long _Ap, unsigned long long _Mp>
131*4bdff4beSrobert struct __lce_ta<_Ap, 0, _Mp, unsigned(~0), true>
132*4bdff4beSrobert {
133*4bdff4beSrobert     typedef unsigned result_type;
134*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
135*4bdff4beSrobert     static result_type next(result_type __x)
136*4bdff4beSrobert     {
137*4bdff4beSrobert         const result_type __a = static_cast<result_type>(_Ap);
138*4bdff4beSrobert         const result_type __m = static_cast<result_type>(_Mp);
139*4bdff4beSrobert         // Schrage's algorithm
140*4bdff4beSrobert         const result_type __q = __m / __a;
141*4bdff4beSrobert         const result_type __r = __m % __a;
142*4bdff4beSrobert         const result_type __t0 = __a * (__x % __q);
143*4bdff4beSrobert         const result_type __t1 = __r * (__x / __q);
144*4bdff4beSrobert         __x = __t0 + (__t0 < __t1) * __m - __t1;
145*4bdff4beSrobert         return __x;
146*4bdff4beSrobert     }
147*4bdff4beSrobert };
148*4bdff4beSrobert 
149*4bdff4beSrobert template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>
150*4bdff4beSrobert struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), false>
151*4bdff4beSrobert {
152*4bdff4beSrobert     typedef unsigned result_type;
153*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
154*4bdff4beSrobert     static result_type next(result_type __x)
155*4bdff4beSrobert     {
156*4bdff4beSrobert         const result_type __a = static_cast<result_type>(_Ap);
157*4bdff4beSrobert         const result_type __c = static_cast<result_type>(_Cp);
158*4bdff4beSrobert         const result_type __m = static_cast<result_type>(_Mp);
159*4bdff4beSrobert         return (__a * __x + __c) % __m;
160*4bdff4beSrobert     }
161*4bdff4beSrobert };
162*4bdff4beSrobert 
163*4bdff4beSrobert template <unsigned long long _Ap, unsigned long long _Cp>
164*4bdff4beSrobert struct __lce_ta<_Ap, _Cp, 0, unsigned(~0), false>
165*4bdff4beSrobert {
166*4bdff4beSrobert     typedef unsigned result_type;
167*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
168*4bdff4beSrobert     static result_type next(result_type __x)
169*4bdff4beSrobert     {
170*4bdff4beSrobert         const result_type __a = static_cast<result_type>(_Ap);
171*4bdff4beSrobert         const result_type __c = static_cast<result_type>(_Cp);
172*4bdff4beSrobert         return __a * __x + __c;
173*4bdff4beSrobert     }
174*4bdff4beSrobert };
175*4bdff4beSrobert 
176*4bdff4beSrobert // 16
177*4bdff4beSrobert 
178*4bdff4beSrobert template <unsigned long long __a, unsigned long long __c, unsigned long long __m, bool __b>
179*4bdff4beSrobert struct __lce_ta<__a, __c, __m, (unsigned short)(~0), __b>
180*4bdff4beSrobert {
181*4bdff4beSrobert     typedef unsigned short result_type;
182*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
183*4bdff4beSrobert     static result_type next(result_type __x)
184*4bdff4beSrobert     {
185*4bdff4beSrobert         return static_cast<result_type>(__lce_ta<__a, __c, __m, unsigned(~0)>::next(__x));
186*4bdff4beSrobert     }
187*4bdff4beSrobert };
188*4bdff4beSrobert 
189*4bdff4beSrobert template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
190*4bdff4beSrobert class _LIBCPP_TEMPLATE_VIS linear_congruential_engine;
191*4bdff4beSrobert 
192*4bdff4beSrobert template <class _CharT, class _Traits,
193*4bdff4beSrobert           class _Up, _Up _Ap, _Up _Cp, _Up _Np>
194*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY
195*4bdff4beSrobert basic_ostream<_CharT, _Traits>&
196*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os,
197*4bdff4beSrobert            const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&);
198*4bdff4beSrobert 
199*4bdff4beSrobert template <class _CharT, class _Traits,
200*4bdff4beSrobert           class _Up, _Up _Ap, _Up _Cp, _Up _Np>
201*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
202*4bdff4beSrobert operator>>(basic_istream<_CharT, _Traits>& __is,
203*4bdff4beSrobert            linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x);
204*4bdff4beSrobert 
205*4bdff4beSrobert template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
206*4bdff4beSrobert class _LIBCPP_TEMPLATE_VIS linear_congruential_engine
207*4bdff4beSrobert {
208*4bdff4beSrobert public:
209*4bdff4beSrobert     // types
210*4bdff4beSrobert     typedef _UIntType result_type;
211*4bdff4beSrobert 
212*4bdff4beSrobert private:
213*4bdff4beSrobert     result_type __x_;
214*4bdff4beSrobert 
215*4bdff4beSrobert     static _LIBCPP_CONSTEXPR const result_type _Mp = result_type(~0);
216*4bdff4beSrobert 
217*4bdff4beSrobert     static_assert(__m == 0 || __a < __m, "linear_congruential_engine invalid parameters");
218*4bdff4beSrobert     static_assert(__m == 0 || __c < __m, "linear_congruential_engine invalid parameters");
219*4bdff4beSrobert     static_assert(is_unsigned<_UIntType>::value, "_UIntType must be unsigned type");
220*4bdff4beSrobert public:
221*4bdff4beSrobert     static _LIBCPP_CONSTEXPR const result_type _Min = __c == 0u ? 1u : 0u;
222*4bdff4beSrobert     static _LIBCPP_CONSTEXPR const result_type _Max = __m - _UIntType(1u);
223*4bdff4beSrobert     static_assert(_Min < _Max,           "linear_congruential_engine invalid parameters");
224*4bdff4beSrobert 
225*4bdff4beSrobert     // engine characteristics
226*4bdff4beSrobert     static _LIBCPP_CONSTEXPR const result_type multiplier = __a;
227*4bdff4beSrobert     static _LIBCPP_CONSTEXPR const result_type increment = __c;
228*4bdff4beSrobert     static _LIBCPP_CONSTEXPR const result_type modulus = __m;
229*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
230*4bdff4beSrobert     static _LIBCPP_CONSTEXPR result_type min() {return _Min;}
231*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
232*4bdff4beSrobert     static _LIBCPP_CONSTEXPR result_type max() {return _Max;}
233*4bdff4beSrobert     static _LIBCPP_CONSTEXPR const result_type default_seed = 1u;
234*4bdff4beSrobert 
235*4bdff4beSrobert     // constructors and seeding functions
236*4bdff4beSrobert #ifndef _LIBCPP_CXX03_LANG
237*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
238*4bdff4beSrobert     linear_congruential_engine() : linear_congruential_engine(default_seed) {}
239*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
240*4bdff4beSrobert     explicit linear_congruential_engine(result_type __s) { seed(__s); }
241*4bdff4beSrobert #else
242*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
243*4bdff4beSrobert     explicit linear_congruential_engine(result_type __s = default_seed) {
244*4bdff4beSrobert       seed(__s);
245*4bdff4beSrobert     }
246*4bdff4beSrobert #endif
247*4bdff4beSrobert     template<class _Sseq>
248*4bdff4beSrobert         _LIBCPP_INLINE_VISIBILITY
249*4bdff4beSrobert         explicit linear_congruential_engine(_Sseq& __q,
250*4bdff4beSrobert         typename enable_if<__is_seed_sequence<_Sseq, linear_congruential_engine>::value>::type* = 0)
251*4bdff4beSrobert         {seed(__q);}
252*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
253*4bdff4beSrobert     void seed(result_type __s = default_seed)
254*4bdff4beSrobert         {seed(integral_constant<bool, __m == 0>(),
255*4bdff4beSrobert               integral_constant<bool, __c == 0>(), __s);}
256*4bdff4beSrobert     template<class _Sseq>
257*4bdff4beSrobert         _LIBCPP_INLINE_VISIBILITY
258*4bdff4beSrobert         typename enable_if
259*4bdff4beSrobert         <
260*4bdff4beSrobert             __is_seed_sequence<_Sseq, linear_congruential_engine>::value,
261*4bdff4beSrobert             void
262*4bdff4beSrobert         >::type
263*4bdff4beSrobert         seed(_Sseq& __q)
264*4bdff4beSrobert             {__seed(__q, integral_constant<unsigned,
265*4bdff4beSrobert                 1 + (__m == 0 ? (sizeof(result_type) * __CHAR_BIT__ - 1)/32
266*4bdff4beSrobert                              :  (__m > 0x100000000ull))>());}
267*4bdff4beSrobert 
268*4bdff4beSrobert     // generating functions
269*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
270*4bdff4beSrobert     result_type operator()()
271*4bdff4beSrobert         {return __x_ = static_cast<result_type>(__lce_ta<__a, __c, __m, _Mp>::next(__x_));}
272*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
273*4bdff4beSrobert     void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
274*4bdff4beSrobert 
275*4bdff4beSrobert     friend _LIBCPP_INLINE_VISIBILITY
276*4bdff4beSrobert     bool operator==(const linear_congruential_engine& __x,
277*4bdff4beSrobert                     const linear_congruential_engine& __y)
278*4bdff4beSrobert         {return __x.__x_ == __y.__x_;}
279*4bdff4beSrobert     friend _LIBCPP_INLINE_VISIBILITY
280*4bdff4beSrobert     bool operator!=(const linear_congruential_engine& __x,
281*4bdff4beSrobert                     const linear_congruential_engine& __y)
282*4bdff4beSrobert         {return !(__x == __y);}
283*4bdff4beSrobert 
284*4bdff4beSrobert private:
285*4bdff4beSrobert 
286*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
287*4bdff4beSrobert     void seed(true_type, true_type, result_type __s) {__x_ = __s == 0 ? 1 : __s;}
288*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
289*4bdff4beSrobert     void seed(true_type, false_type, result_type __s) {__x_ = __s;}
290*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
291*4bdff4beSrobert     void seed(false_type, true_type, result_type __s) {__x_ = __s % __m == 0 ?
292*4bdff4beSrobert                                                                  1 : __s % __m;}
293*4bdff4beSrobert     _LIBCPP_INLINE_VISIBILITY
294*4bdff4beSrobert     void seed(false_type, false_type, result_type __s) {__x_ = __s % __m;}
295*4bdff4beSrobert 
296*4bdff4beSrobert     template<class _Sseq>
297*4bdff4beSrobert         void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
298*4bdff4beSrobert     template<class _Sseq>
299*4bdff4beSrobert         void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
300*4bdff4beSrobert 
301*4bdff4beSrobert     template <class _CharT, class _Traits,
302*4bdff4beSrobert               class _Up, _Up _Ap, _Up _Cp, _Up _Np>
303*4bdff4beSrobert     friend
304*4bdff4beSrobert     basic_ostream<_CharT, _Traits>&
305*4bdff4beSrobert     operator<<(basic_ostream<_CharT, _Traits>& __os,
306*4bdff4beSrobert                const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&);
307*4bdff4beSrobert 
308*4bdff4beSrobert     template <class _CharT, class _Traits,
309*4bdff4beSrobert               class _Up, _Up _Ap, _Up _Cp, _Up _Np>
310*4bdff4beSrobert     friend
311*4bdff4beSrobert     basic_istream<_CharT, _Traits>&
312*4bdff4beSrobert     operator>>(basic_istream<_CharT, _Traits>& __is,
313*4bdff4beSrobert                linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x);
314*4bdff4beSrobert };
315*4bdff4beSrobert 
316*4bdff4beSrobert template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
317*4bdff4beSrobert     _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
318*4bdff4beSrobert     linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier;
319*4bdff4beSrobert 
320*4bdff4beSrobert template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
321*4bdff4beSrobert     _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
322*4bdff4beSrobert     linear_congruential_engine<_UIntType, __a, __c, __m>::increment;
323*4bdff4beSrobert 
324*4bdff4beSrobert template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
325*4bdff4beSrobert     _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
326*4bdff4beSrobert     linear_congruential_engine<_UIntType, __a, __c, __m>::modulus;
327*4bdff4beSrobert 
328*4bdff4beSrobert template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
329*4bdff4beSrobert     _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
330*4bdff4beSrobert     linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed;
331*4bdff4beSrobert 
332*4bdff4beSrobert template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
333*4bdff4beSrobert template<class _Sseq>
334*4bdff4beSrobert void
335*4bdff4beSrobert linear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q,
336*4bdff4beSrobert                                                  integral_constant<unsigned, 1>)
337*4bdff4beSrobert {
338*4bdff4beSrobert     const unsigned __k = 1;
339*4bdff4beSrobert     uint32_t __ar[__k+3];
340*4bdff4beSrobert     __q.generate(__ar, __ar + __k + 3);
341*4bdff4beSrobert     result_type __s = static_cast<result_type>(__ar[3] % __m);
342*4bdff4beSrobert     __x_ = __c == 0 && __s == 0 ? result_type(1) : __s;
343*4bdff4beSrobert }
344*4bdff4beSrobert 
345*4bdff4beSrobert template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
346*4bdff4beSrobert template<class _Sseq>
347*4bdff4beSrobert void
348*4bdff4beSrobert linear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q,
349*4bdff4beSrobert                                                  integral_constant<unsigned, 2>)
350*4bdff4beSrobert {
351*4bdff4beSrobert     const unsigned __k = 2;
352*4bdff4beSrobert     uint32_t __ar[__k+3];
353*4bdff4beSrobert     __q.generate(__ar, __ar + __k + 3);
354*4bdff4beSrobert     result_type __s = static_cast<result_type>((__ar[3] +
355*4bdff4beSrobert                                               ((uint64_t)__ar[4] << 32)) % __m);
356*4bdff4beSrobert     __x_ = __c == 0 && __s == 0 ? result_type(1) : __s;
357*4bdff4beSrobert }
358*4bdff4beSrobert 
359*4bdff4beSrobert template <class _CharT, class _Traits,
360*4bdff4beSrobert           class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
361*4bdff4beSrobert inline _LIBCPP_INLINE_VISIBILITY
362*4bdff4beSrobert basic_ostream<_CharT, _Traits>&
363*4bdff4beSrobert operator<<(basic_ostream<_CharT, _Traits>& __os,
364*4bdff4beSrobert            const linear_congruential_engine<_UIntType, __a, __c, __m>& __x)
365*4bdff4beSrobert {
366*4bdff4beSrobert     __save_flags<_CharT, _Traits> __lx(__os);
367*4bdff4beSrobert     typedef basic_ostream<_CharT, _Traits> _Ostream;
368*4bdff4beSrobert     __os.flags(_Ostream::dec | _Ostream::left);
369*4bdff4beSrobert     __os.fill(__os.widen(' '));
370*4bdff4beSrobert     return __os << __x.__x_;
371*4bdff4beSrobert }
372*4bdff4beSrobert 
373*4bdff4beSrobert template <class _CharT, class _Traits,
374*4bdff4beSrobert           class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
375*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
376*4bdff4beSrobert operator>>(basic_istream<_CharT, _Traits>& __is,
377*4bdff4beSrobert            linear_congruential_engine<_UIntType, __a, __c, __m>& __x)
378*4bdff4beSrobert {
379*4bdff4beSrobert     __save_flags<_CharT, _Traits> __lx(__is);
380*4bdff4beSrobert     typedef basic_istream<_CharT, _Traits> _Istream;
381*4bdff4beSrobert     __is.flags(_Istream::dec | _Istream::skipws);
382*4bdff4beSrobert     _UIntType __t;
383*4bdff4beSrobert     __is >> __t;
384*4bdff4beSrobert     if (!__is.fail())
385*4bdff4beSrobert         __x.__x_ = __t;
386*4bdff4beSrobert     return __is;
387*4bdff4beSrobert }
388*4bdff4beSrobert 
389*4bdff4beSrobert typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>
390*4bdff4beSrobert                                                                    minstd_rand0;
391*4bdff4beSrobert typedef linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>
392*4bdff4beSrobert                                                                     minstd_rand;
393*4bdff4beSrobert 
394*4bdff4beSrobert _LIBCPP_END_NAMESPACE_STD
395*4bdff4beSrobert 
396*4bdff4beSrobert _LIBCPP_POP_MACROS
397*4bdff4beSrobert 
398*4bdff4beSrobert #endif // _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H
399