1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H
10 #define _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H
12 #include <__algorithm/equal.h>
13 #include <__algorithm/min.h>
15 #include <__cstddef/size_t.h>
16 #include <__random/is_seed_sequence.h>
17 #include <__type_traits/enable_if.h>
22 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23 # pragma GCC system_header
27 #include <__undef_macros>
29 _LIBCPP_BEGIN_NAMESPACE_STD
31 template <class _UIntType
,
45 class _LIBCPP_TEMPLATE_VIS mersenne_twister_engine
;
47 template <class _UInt
,
61 _LIBCPP_HIDE_FROM_ABI
bool
62 operator==(const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
,
63 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __y
);
65 template <class _UInt
,
79 _LIBCPP_HIDE_FROM_ABI
bool
80 operator!=(const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
,
81 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __y
);
83 template <class _CharT
,
99 _LIBCPP_HIDE_FROM_ABI basic_ostream
<_CharT
, _Traits
>&
100 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
,
101 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
);
103 template <class _CharT
,
119 _LIBCPP_HIDE_FROM_ABI basic_istream
<_CharT
, _Traits
>&
120 operator>>(basic_istream
<_CharT
, _Traits
>& __is
,
121 mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
);
123 template <class _UIntType
,
137 class _LIBCPP_TEMPLATE_VIS mersenne_twister_engine
{
140 typedef _UIntType result_type
;
143 result_type __x_
[__n
];
146 static_assert(0 < __m
, "mersenne_twister_engine invalid parameters");
147 static_assert(__m
<= __n
, "mersenne_twister_engine invalid parameters");
148 static _LIBCPP_CONSTEXPR
const result_type _Dt
= numeric_limits
<result_type
>::digits
;
149 static_assert(__w
<= _Dt
, "mersenne_twister_engine invalid parameters");
150 static_assert(2 <= __w
, "mersenne_twister_engine invalid parameters");
151 static_assert(__r
<= __w
, "mersenne_twister_engine invalid parameters");
152 static_assert(__u
<= __w
, "mersenne_twister_engine invalid parameters");
153 static_assert(__s
<= __w
, "mersenne_twister_engine invalid parameters");
154 static_assert(__t
<= __w
, "mersenne_twister_engine invalid parameters");
155 static_assert(__l
<= __w
, "mersenne_twister_engine invalid parameters");
158 static _LIBCPP_CONSTEXPR
const result_type _Min
= 0;
159 static _LIBCPP_CONSTEXPR
const result_type _Max
=
160 __w
== _Dt
? result_type(~0) : (result_type(1) << __w
) - result_type(1);
161 static_assert(_Min
< _Max
, "mersenne_twister_engine invalid parameters");
162 static_assert(__a
<= _Max
, "mersenne_twister_engine invalid parameters");
163 static_assert(__b
<= _Max
, "mersenne_twister_engine invalid parameters");
164 static_assert(__c
<= _Max
, "mersenne_twister_engine invalid parameters");
165 static_assert(__d
<= _Max
, "mersenne_twister_engine invalid parameters");
166 static_assert(__f
<= _Max
, "mersenne_twister_engine invalid parameters");
168 // engine characteristics
169 static inline _LIBCPP_CONSTEXPR
const size_t word_size
= __w
;
170 static inline _LIBCPP_CONSTEXPR
const size_t state_size
= __n
;
171 static inline _LIBCPP_CONSTEXPR
const size_t shift_size
= __m
;
172 static inline _LIBCPP_CONSTEXPR
const size_t mask_bits
= __r
;
173 static inline _LIBCPP_CONSTEXPR
const result_type xor_mask
= __a
;
174 static inline _LIBCPP_CONSTEXPR
const size_t tempering_u
= __u
;
175 static inline _LIBCPP_CONSTEXPR
const result_type tempering_d
= __d
;
176 static inline _LIBCPP_CONSTEXPR
const size_t tempering_s
= __s
;
177 static inline _LIBCPP_CONSTEXPR
const result_type tempering_b
= __b
;
178 static inline _LIBCPP_CONSTEXPR
const size_t tempering_t
= __t
;
179 static inline _LIBCPP_CONSTEXPR
const result_type tempering_c
= __c
;
180 static inline _LIBCPP_CONSTEXPR
const size_t tempering_l
= __l
;
181 static inline _LIBCPP_CONSTEXPR
const result_type initialization_multiplier
= __f
;
182 _LIBCPP_HIDE_FROM_ABI
static _LIBCPP_CONSTEXPR result_type
min() { return _Min
; }
183 _LIBCPP_HIDE_FROM_ABI
static _LIBCPP_CONSTEXPR result_type
max() { return _Max
; }
184 static inline _LIBCPP_CONSTEXPR
const result_type default_seed
= 5489u;
186 // constructors and seeding functions
187 #ifndef _LIBCPP_CXX03_LANG
188 _LIBCPP_HIDE_FROM_ABI
mersenne_twister_engine() : mersenne_twister_engine(default_seed
) {}
189 _LIBCPP_HIDE_FROM_ABI
explicit mersenne_twister_engine(result_type __sd
) { seed(__sd
); }
191 _LIBCPP_HIDE_FROM_ABI
explicit mersenne_twister_engine(result_type __sd
= default_seed
) { seed(__sd
); }
193 template <class _Sseq
, __enable_if_t
<__is_seed_sequence
<_Sseq
, mersenne_twister_engine
>::value
, int> = 0>
194 _LIBCPP_HIDE_FROM_ABI
explicit mersenne_twister_engine(_Sseq
& __q
) {
197 _LIBCPP_HIDE_FROM_ABI
void seed(result_type __sd
= default_seed
);
198 template <class _Sseq
, __enable_if_t
<__is_seed_sequence
<_Sseq
, mersenne_twister_engine
>::value
, int> = 0>
199 _LIBCPP_HIDE_FROM_ABI
void seed(_Sseq
& __q
) {
200 __seed(__q
, integral_constant
<unsigned, 1 + (__w
- 1) / 32>());
203 // generating functions
204 _LIBCPP_HIDE_FROM_ABI result_type
operator()();
205 _LIBCPP_HIDE_FROM_ABI
void discard(unsigned long long __z
) {
210 template <class _UInt
,
224 friend bool operator==(
225 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
,
226 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __y
);
228 template <class _UInt
,
242 friend bool operator!=(
243 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
,
244 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __y
);
246 template <class _CharT
,
262 friend basic_ostream
<_CharT
, _Traits
>& operator<<(
263 basic_ostream
<_CharT
, _Traits
>& __os
,
264 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
);
266 template <class _CharT
,
282 friend basic_istream
<_CharT
, _Traits
>&
283 operator>>(basic_istream
<_CharT
, _Traits
>& __is
,
284 mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
);
287 template <class _Sseq
>
288 _LIBCPP_HIDE_FROM_ABI
void __seed(_Sseq
& __q
, integral_constant
<unsigned, 1>);
289 template <class _Sseq
>
290 _LIBCPP_HIDE_FROM_ABI
void __seed(_Sseq
& __q
, integral_constant
<unsigned, 2>);
292 template <size_t __count
,
293 __enable_if_t
<__count
< __w
, int> = 0> _LIBCPP_HIDE_FROM_ABI
static result_type
__lshift(result_type __x
) {
294 return (__x
<< __count
) & _Max
;
297 template <size_t __count
, __enable_if_t
<(__count
>= __w
), int> = 0>
298 _LIBCPP_HIDE_FROM_ABI
static result_type
__lshift(result_type
) {
299 return result_type(0);
302 template <size_t __count
,
303 __enable_if_t
<__count
< _Dt
, int> = 0> _LIBCPP_HIDE_FROM_ABI
static result_type
__rshift(result_type __x
) {
304 return __x
>> __count
;
307 template <size_t __count
, __enable_if_t
<(__count
>= _Dt
), int> = 0>
308 _LIBCPP_HIDE_FROM_ABI
static result_type
__rshift(result_type
) {
309 return result_type(0);
313 template <class _UIntType
,
327 void mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::seed(
328 result_type __sd
) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
{ // __w >= 2
329 __x_
[0] = __sd
& _Max
;
330 for (size_t __i
= 1; __i
< __n
; ++__i
)
331 __x_
[__i
] = (__f
* (__x_
[__i
- 1] ^ __rshift
<__w
- 2>(__x_
[__i
- 1])) + __i
) & _Max
;
335 template <class _UIntType
,
349 template <class _Sseq
>
350 void mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::__seed(
351 _Sseq
& __q
, integral_constant
<unsigned, 1>) {
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) : (result_type(1) << __r
) - result_type(1);
359 if ((__x_
[0] & ~__mask
) == 0) {
360 for (size_t __i
= 1; __i
< __n
; ++__i
)
363 __x_
[0] = result_type(1) << (__w
- 1);
367 template <class _UIntType
,
381 template <class _Sseq
>
382 void mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::__seed(
383 _Sseq
& __q
, integral_constant
<unsigned, 2>) {
384 const unsigned __k
= 2;
385 uint32_t __ar
[__n
* __k
];
386 __q
.generate(__ar
, __ar
+ __n
* __k
);
387 for (size_t __i
= 0; __i
< __n
; ++__i
)
388 __x_
[__i
] = static_cast<result_type
>((__ar
[2 * __i
] + ((uint64_t)__ar
[2 * __i
+ 1] << 32)) & _Max
);
389 const result_type __mask
= __r
== _Dt
? result_type(~0) : (result_type(1) << __r
) - result_type(1);
391 if ((__x_
[0] & ~__mask
) == 0) {
392 for (size_t __i
= 1; __i
< __n
; ++__i
)
395 __x_
[0] = result_type(1) << (__w
- 1);
399 template <class _UIntType
,
414 mersenne_twister_engine
<_UIntType
, __w
, __n
, __m
, __r
, __a
, __u
, __d
, __s
, __b
, __t
, __c
, __l
, __f
>::operator()() {
415 const size_t __j
= (__i_
+ 1) % __n
;
416 const result_type __mask
= __r
== _Dt
? result_type(~0) : (result_type(1) << __r
) - result_type(1);
417 const result_type __yp
= (__x_
[__i_
] & ~__mask
) | (__x_
[__j
] & __mask
);
418 const size_t __k
= (__i_
+ __m
) % __n
;
419 __x_
[__i_
] = __x_
[__k
] ^ __rshift
<1>(__yp
) ^ (__a
* (__yp
& 1));
420 result_type __z
= __x_
[__i_
] ^ (__rshift
<__u
>(__x_
[__i_
]) & __d
);
422 __z
^= __lshift
<__s
>(__z
) & __b
;
423 __z
^= __lshift
<__t
>(__z
) & __c
;
424 return __z
^ __rshift
<__l
>(__z
);
427 template <class _UInt
,
441 _LIBCPP_HIDE_FROM_ABI
bool
442 operator==(const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
,
443 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __y
) {
444 if (__x
.__i_
== __y
.__i_
)
445 return std::equal(__x
.__x_
, __x
.__x_
+ _Np
, __y
.__x_
);
446 if (__x
.__i_
== 0 || __y
.__i_
== 0) {
447 size_t __j
= std::min(_Np
- __x
.__i_
, _Np
- __y
.__i_
);
448 if (!std::equal(__x
.__x_
+ __x
.__i_
, __x
.__x_
+ __x
.__i_
+ __j
, __y
.__x_
+ __y
.__i_
))
451 return std::equal(__x
.__x_
+ __j
, __x
.__x_
+ _Np
, __y
.__x_
);
452 return std::equal(__x
.__x_
, __x
.__x_
+ (_Np
- __j
), __y
.__x_
+ __j
);
454 if (__x
.__i_
< __y
.__i_
) {
455 size_t __j
= _Np
- __y
.__i_
;
456 if (!std::equal(__x
.__x_
+ __x
.__i_
, __x
.__x_
+ (__x
.__i_
+ __j
), __y
.__x_
+ __y
.__i_
))
458 if (!std::equal(__x
.__x_
+ (__x
.__i_
+ __j
), __x
.__x_
+ _Np
, __y
.__x_
))
460 return std::equal(__x
.__x_
, __x
.__x_
+ __x
.__i_
, __y
.__x_
+ (_Np
- (__x
.__i_
+ __j
)));
462 size_t __j
= _Np
- __x
.__i_
;
463 if (!std::equal(__y
.__x_
+ __y
.__i_
, __y
.__x_
+ (__y
.__i_
+ __j
), __x
.__x_
+ __x
.__i_
))
465 if (!std::equal(__y
.__x_
+ (__y
.__i_
+ __j
), __y
.__x_
+ _Np
, __x
.__x_
))
467 return std::equal(__y
.__x_
, __y
.__x_
+ __y
.__i_
, __x
.__x_
+ (_Np
- (__y
.__i_
+ __j
)));
470 template <class _UInt
,
484 inline _LIBCPP_HIDE_FROM_ABI
bool
485 operator!=(const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
,
486 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __y
) {
487 return !(__x
== __y
);
490 template <class _CharT
,
506 _LIBCPP_HIDE_FROM_ABI basic_ostream
<_CharT
, _Traits
>&
507 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
,
508 const mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
) {
509 __save_flags
<_CharT
, _Traits
> __lx(__os
);
510 typedef basic_ostream
<_CharT
, _Traits
> _Ostream
;
511 __os
.flags(_Ostream::dec
| _Ostream::left
);
512 _CharT __sp
= __os
.widen(' ');
514 __os
<< __x
.__x_
[__x
.__i_
];
515 for (size_t __j
= __x
.__i_
+ 1; __j
< _Np
; ++__j
)
516 __os
<< __sp
<< __x
.__x_
[__j
];
517 for (size_t __j
= 0; __j
< __x
.__i_
; ++__j
)
518 __os
<< __sp
<< __x
.__x_
[__j
];
522 template <class _CharT
,
538 _LIBCPP_HIDE_FROM_ABI basic_istream
<_CharT
, _Traits
>&
539 operator>>(basic_istream
<_CharT
, _Traits
>& __is
,
540 mersenne_twister_engine
<_UInt
, _Wp
, _Np
, _Mp
, _Rp
, _Ap
, _Up
, _Dp
, _Sp
, _Bp
, _Tp
, _Cp
, _Lp
, _Fp
>& __x
) {
541 __save_flags
<_CharT
, _Traits
> __lx(__is
);
542 typedef basic_istream
<_CharT
, _Traits
> _Istream
;
543 __is
.flags(_Istream::dec
| _Istream::skipws
);
545 for (size_t __i
= 0; __i
< _Np
; ++__i
)
548 for (size_t __i
= 0; __i
< _Np
; ++__i
)
549 __x
.__x_
[__i
] = __t
[__i
];
555 typedef mersenne_twister_engine
<
571 typedef mersenne_twister_engine
<
577 0xb5026f5aa96619e9ULL
,
579 0x5555555555555555ULL
,
581 0x71d67fffeda60000ULL
,
583 0xfff7eee000000000ULL
,
585 6364136223846793005ULL>
588 _LIBCPP_END_NAMESPACE_STD
592 #endif // _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H