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