xref: /freebsd/contrib/llvm-project/libcxx/include/__random/mersenne_twister_engine.h (revision f126890ac5386406dadf7c4cfa9566cbb56537c5)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H
10 #define _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H
11 
12 #include <__algorithm/equal.h>
13 #include <__algorithm/min.h>
14 #include <__config>
15 #include <__random/is_seed_sequence.h>
16 #include <cstddef>
17 #include <cstdint>
18 #include <iosfwd>
19 #include <limits>
20 
21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22 #  pragma GCC system_header
23 #endif
24 
25 _LIBCPP_PUSH_MACROS
26 #include <__undef_macros>
27 
28 _LIBCPP_BEGIN_NAMESPACE_STD
29 
30 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
31           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
32           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
33 class _LIBCPP_TEMPLATE_VIS mersenne_twister_engine;
34 
35 template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
36           _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
37           _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
38 _LIBCPP_HIDE_FROM_ABI bool
39 operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
40                                          _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
41            const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
42                                          _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
43 
44 template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
45           _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
46           _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
47 _LIBCPP_INLINE_VISIBILITY
48 bool
49 operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
50                                          _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
51            const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
52                                          _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
53 
54 template <class _CharT, class _Traits,
55           class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
56           _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
57           _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
58 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
59 operator<<(basic_ostream<_CharT, _Traits>& __os,
60            const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
61                                          _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
62 
63 template <class _CharT, class _Traits,
64           class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
65           _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
66           _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
67 _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
68 operator>>(basic_istream<_CharT, _Traits>& __is,
69            mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
70                                    _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
71 
72 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
73           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
74           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
75 class _LIBCPP_TEMPLATE_VIS mersenne_twister_engine
76 {
77 public:
78     // types
79     typedef _UIntType result_type;
80 
81 private:
82     result_type __x_[__n];
83     size_t      __i_;
84 
85     static_assert(  0 <  __m, "mersenne_twister_engine invalid parameters");
86     static_assert(__m <= __n, "mersenne_twister_engine invalid parameters");
87     static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits<result_type>::digits;
88     static_assert(__w <= _Dt, "mersenne_twister_engine invalid parameters");
89     static_assert(  2 <= __w, "mersenne_twister_engine invalid parameters");
90     static_assert(__r <= __w, "mersenne_twister_engine invalid parameters");
91     static_assert(__u <= __w, "mersenne_twister_engine invalid parameters");
92     static_assert(__s <= __w, "mersenne_twister_engine invalid parameters");
93     static_assert(__t <= __w, "mersenne_twister_engine invalid parameters");
94     static_assert(__l <= __w, "mersenne_twister_engine invalid parameters");
95 public:
96     static _LIBCPP_CONSTEXPR const result_type _Min = 0;
97     static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) :
98                                                       (result_type(1) << __w) - result_type(1);
99     static_assert(_Min < _Max, "mersenne_twister_engine invalid parameters");
100     static_assert(__a <= _Max, "mersenne_twister_engine invalid parameters");
101     static_assert(__b <= _Max, "mersenne_twister_engine invalid parameters");
102     static_assert(__c <= _Max, "mersenne_twister_engine invalid parameters");
103     static_assert(__d <= _Max, "mersenne_twister_engine invalid parameters");
104     static_assert(__f <= _Max, "mersenne_twister_engine invalid parameters");
105 
106     // engine characteristics
107     static _LIBCPP_CONSTEXPR const size_t word_size = __w;
108     static _LIBCPP_CONSTEXPR const size_t state_size = __n;
109     static _LIBCPP_CONSTEXPR const size_t shift_size = __m;
110     static _LIBCPP_CONSTEXPR const size_t mask_bits = __r;
111     static _LIBCPP_CONSTEXPR const result_type xor_mask = __a;
112     static _LIBCPP_CONSTEXPR const size_t tempering_u = __u;
113     static _LIBCPP_CONSTEXPR const result_type tempering_d = __d;
114     static _LIBCPP_CONSTEXPR const size_t tempering_s = __s;
115     static _LIBCPP_CONSTEXPR const result_type tempering_b = __b;
116     static _LIBCPP_CONSTEXPR const size_t tempering_t = __t;
117     static _LIBCPP_CONSTEXPR const result_type tempering_c = __c;
118     static _LIBCPP_CONSTEXPR const size_t tempering_l = __l;
119     static _LIBCPP_CONSTEXPR const result_type initialization_multiplier = __f;
120     _LIBCPP_INLINE_VISIBILITY
121     static _LIBCPP_CONSTEXPR result_type min() { return _Min; }
122     _LIBCPP_INLINE_VISIBILITY
123     static _LIBCPP_CONSTEXPR result_type max() { return _Max; }
124     static _LIBCPP_CONSTEXPR const result_type default_seed = 5489u;
125 
126     // constructors and seeding functions
127 #ifndef _LIBCPP_CXX03_LANG
128     _LIBCPP_INLINE_VISIBILITY
129     mersenne_twister_engine() : mersenne_twister_engine(default_seed) {}
130     _LIBCPP_INLINE_VISIBILITY
131     explicit mersenne_twister_engine(result_type __sd) { seed(__sd); }
132 #else
133     _LIBCPP_INLINE_VISIBILITY
134     explicit mersenne_twister_engine(result_type __sd = default_seed) {
135       seed(__sd);
136     }
137 #endif
138     template<class _Sseq>
139         _LIBCPP_INLINE_VISIBILITY
140         explicit mersenne_twister_engine(_Sseq& __q,
141         typename enable_if<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value>::type* = 0)
142         {seed(__q);}
143     _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd = default_seed);
144     template<class _Sseq>
145         _LIBCPP_INLINE_VISIBILITY
146         typename enable_if
147         <
148             __is_seed_sequence<_Sseq, mersenne_twister_engine>::value,
149             void
150         >::type
151         seed(_Sseq& __q)
152             {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());}
153 
154     // generating functions
155     _LIBCPP_HIDE_FROM_ABI result_type operator()();
156     _LIBCPP_INLINE_VISIBILITY
157     void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
158 
159     template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
160               _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
161               _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
162     friend
163     bool
164     operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
165                                              _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
166                const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
167                                              _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
168 
169     template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
170               _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
171               _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
172     friend
173     bool
174     operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
175                                              _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
176                const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
177                                              _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
178 
179     template <class _CharT, class _Traits,
180               class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
181               _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
182               _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
183     friend
184     basic_ostream<_CharT, _Traits>&
185     operator<<(basic_ostream<_CharT, _Traits>& __os,
186                const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
187                                              _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
188 
189     template <class _CharT, class _Traits,
190               class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
191               _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
192               _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
193     friend
194     basic_istream<_CharT, _Traits>&
195     operator>>(basic_istream<_CharT, _Traits>& __is,
196                mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
197                                        _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
198 private:
199 
200     template<class _Sseq>
201     _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
202     template<class _Sseq>
203     _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
204 
205     template <size_t __count>
206         _LIBCPP_INLINE_VISIBILITY
207         static
208         typename enable_if
209         <
210             __count < __w,
211             result_type
212         >::type
213         __lshift(result_type __x) {return (__x << __count) & _Max;}
214 
215     template <size_t __count>
216         _LIBCPP_INLINE_VISIBILITY
217         static
218         typename enable_if
219         <
220             (__count >= __w),
221             result_type
222         >::type
223         __lshift(result_type) {return result_type(0);}
224 
225     template <size_t __count>
226         _LIBCPP_INLINE_VISIBILITY
227         static
228         typename enable_if
229         <
230             __count < _Dt,
231             result_type
232         >::type
233         __rshift(result_type __x) {return __x >> __count;}
234 
235     template <size_t __count>
236         _LIBCPP_INLINE_VISIBILITY
237         static
238         typename enable_if
239         <
240             (__count >= _Dt),
241             result_type
242         >::type
243         __rshift(result_type) {return result_type(0);}
244 };
245 
246 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
247           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
248           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
249     _LIBCPP_CONSTEXPR const size_t
250     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::word_size;
251 
252 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
253           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
254           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
255     _LIBCPP_CONSTEXPR const size_t
256     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::state_size;
257 
258 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
259           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
260           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
261     _LIBCPP_CONSTEXPR const size_t
262     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::shift_size;
263 
264 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
265           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
266           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
267     _LIBCPP_CONSTEXPR const size_t
268     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::mask_bits;
269 
270 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
271           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
272           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
273     _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
274     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::xor_mask;
275 
276 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
277           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
278           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
279     _LIBCPP_CONSTEXPR const size_t
280     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_u;
281 
282 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
283           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
284           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
285     _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
286     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_d;
287 
288 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
289           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
290           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
291     _LIBCPP_CONSTEXPR const size_t
292     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_s;
293 
294 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
295           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
296           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
297     _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
298     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_b;
299 
300 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
301           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
302           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
303     _LIBCPP_CONSTEXPR const size_t
304     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_t;
305 
306 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
307           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
308           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
309     _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
310     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_c;
311 
312 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
313           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
314           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
315     _LIBCPP_CONSTEXPR const size_t
316     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_l;
317 
318 template <class _UIntType, 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, _UIntType __f>
321     _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
322     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::initialization_multiplier;
323 
324 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
325           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
326           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
327     _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
328     mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::default_seed;
329 
330 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
331           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
332           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
333 void
334 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
335     __t, __c, __l, __f>::seed(result_type __sd)
336     _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
337 {   // __w >= 2
338     __x_[0] = __sd & _Max;
339     for (size_t __i = 1; __i < __n; ++__i)
340         __x_[__i] = (__f * (__x_[__i-1] ^ __rshift<__w - 2>(__x_[__i-1])) + __i) & _Max;
341     __i_ = 0;
342 }
343 
344 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
345           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
346           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
347 template<class _Sseq>
348 void
349 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
350     __t, __c, __l, __f>::__seed(_Sseq& __q, integral_constant<unsigned, 1>)
351 {
352     const unsigned __k = 1;
353     uint32_t __ar[__n * __k];
354     __q.generate(__ar, __ar + __n * __k);
355     for (size_t __i = 0; __i < __n; ++__i)
356         __x_[__i] = static_cast<result_type>(__ar[__i] & _Max);
357     const result_type __mask = __r == _Dt ? result_type(~0) :
358                                        (result_type(1) << __r) - result_type(1);
359     __i_ = 0;
360     if ((__x_[0] & ~__mask) == 0)
361     {
362         for (size_t __i = 1; __i < __n; ++__i)
363             if (__x_[__i] != 0)
364                 return;
365         __x_[0] = result_type(1) << (__w - 1);
366     }
367 }
368 
369 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
370           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
371           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
372 template<class _Sseq>
373 void
374 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
375     __t, __c, __l, __f>::__seed(_Sseq& __q, integral_constant<unsigned, 2>)
376 {
377     const unsigned __k = 2;
378     uint32_t __ar[__n * __k];
379     __q.generate(__ar, __ar + __n * __k);
380     for (size_t __i = 0; __i < __n; ++__i)
381         __x_[__i] = static_cast<result_type>(
382             (__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max);
383     const result_type __mask = __r == _Dt ? result_type(~0) :
384                                        (result_type(1) << __r) - result_type(1);
385     __i_ = 0;
386     if ((__x_[0] & ~__mask) == 0)
387     {
388         for (size_t __i = 1; __i < __n; ++__i)
389             if (__x_[__i] != 0)
390                 return;
391         __x_[0] = result_type(1) << (__w - 1);
392     }
393 }
394 
395 template <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
396           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
397           _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
398 _UIntType
399 mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
400     __t, __c, __l, __f>::operator()()
401 {
402     const size_t __j = (__i_ + 1) % __n;
403     const result_type __mask = __r == _Dt ? result_type(~0) :
404                                        (result_type(1) << __r) - result_type(1);
405     const result_type __yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask);
406     const size_t __k = (__i_ + __m) % __n;
407     __x_[__i_] = __x_[__k] ^ __rshift<1>(__yp) ^ (__a * (__yp & 1));
408     result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d);
409     __i_ = __j;
410     __z ^= __lshift<__s>(__z) & __b;
411     __z ^= __lshift<__t>(__z) & __c;
412     return __z ^ __rshift<__l>(__z);
413 }
414 
415 template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
416           _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
417           _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
418 _LIBCPP_HIDE_FROM_ABI bool
419 operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
420                                          _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
421            const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
422                                          _Bp, _Tp, _Cp, _Lp, _Fp>& __y)
423 {
424     if (__x.__i_ == __y.__i_)
425         return _VSTD::equal(__x.__x_, __x.__x_ + _Np, __y.__x_);
426     if (__x.__i_ == 0 || __y.__i_ == 0)
427     {
428         size_t __j = _VSTD::min(_Np - __x.__i_, _Np - __y.__i_);
429         if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + __x.__i_ + __j,
430                          __y.__x_ + __y.__i_))
431             return false;
432         if (__x.__i_ == 0)
433             return _VSTD::equal(__x.__x_ + __j, __x.__x_ + _Np, __y.__x_);
434         return _VSTD::equal(__x.__x_, __x.__x_ + (_Np - __j), __y.__x_ + __j);
435     }
436     if (__x.__i_ < __y.__i_)
437     {
438         size_t __j = _Np - __y.__i_;
439         if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + (__x.__i_ + __j),
440                          __y.__x_ + __y.__i_))
441             return false;
442         if (!_VSTD::equal(__x.__x_ + (__x.__i_ + __j), __x.__x_ + _Np,
443                          __y.__x_))
444             return false;
445         return _VSTD::equal(__x.__x_, __x.__x_ + __x.__i_,
446                            __y.__x_ + (_Np - (__x.__i_ + __j)));
447     }
448     size_t __j = _Np - __x.__i_;
449     if (!_VSTD::equal(__y.__x_ + __y.__i_, __y.__x_ + (__y.__i_ + __j),
450                      __x.__x_ + __x.__i_))
451         return false;
452     if (!_VSTD::equal(__y.__x_ + (__y.__i_ + __j), __y.__x_ + _Np,
453                      __x.__x_))
454         return false;
455     return _VSTD::equal(__y.__x_, __y.__x_ + __y.__i_,
456                        __x.__x_ + (_Np - (__y.__i_ + __j)));
457 }
458 
459 template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
460           _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
461           _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
462 inline _LIBCPP_INLINE_VISIBILITY
463 bool
464 operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
465                                          _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
466            const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
467                                          _Bp, _Tp, _Cp, _Lp, _Fp>& __y)
468 {
469     return !(__x == __y);
470 }
471 
472 template <class _CharT, class _Traits,
473           class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
474           _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
475           _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
476 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
477 operator<<(basic_ostream<_CharT, _Traits>& __os,
478            const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
479                                          _Bp, _Tp, _Cp, _Lp, _Fp>& __x)
480 {
481     __save_flags<_CharT, _Traits> __lx(__os);
482     typedef basic_ostream<_CharT, _Traits> _Ostream;
483     __os.flags(_Ostream::dec | _Ostream::left);
484     _CharT __sp = __os.widen(' ');
485     __os.fill(__sp);
486     __os << __x.__x_[__x.__i_];
487     for (size_t __j = __x.__i_ + 1; __j < _Np; ++__j)
488         __os << __sp << __x.__x_[__j];
489     for (size_t __j = 0; __j < __x.__i_; ++__j)
490         __os << __sp << __x.__x_[__j];
491     return __os;
492 }
493 
494 template <class _CharT, class _Traits,
495           class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
496           _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
497           _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
498 _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
499 operator>>(basic_istream<_CharT, _Traits>& __is,
500            mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
501                                    _Bp, _Tp, _Cp, _Lp, _Fp>& __x)
502 {
503     __save_flags<_CharT, _Traits> __lx(__is);
504     typedef basic_istream<_CharT, _Traits> _Istream;
505     __is.flags(_Istream::dec | _Istream::skipws);
506     _UInt __t[_Np];
507     for (size_t __i = 0; __i < _Np; ++__i)
508         __is >> __t[__i];
509     if (!__is.fail())
510     {
511         for (size_t __i = 0; __i < _Np; ++__i)
512             __x.__x_[__i] = __t[__i];
513         __x.__i_ = 0;
514     }
515     return __is;
516 }
517 
518 typedef mersenne_twister_engine<uint_fast32_t, 32, 624, 397, 31,
519                                 0x9908b0df, 11, 0xffffffff,
520                                 7,  0x9d2c5680,
521                                 15, 0xefc60000,
522                                 18, 1812433253>                         mt19937;
523 typedef mersenne_twister_engine<uint_fast64_t, 64, 312, 156, 31,
524                                 0xb5026f5aa96619e9ULL, 29, 0x5555555555555555ULL,
525                                 17, 0x71d67fffeda60000ULL,
526                                 37, 0xfff7eee000000000ULL,
527                                 43, 6364136223846793005ULL>          mt19937_64;
528 
529 _LIBCPP_END_NAMESPACE_STD
530 
531 _LIBCPP_POP_MACROS
532 
533 #endif // _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H
534