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