xref: /llvm-project/libcxx/include/__random/mersenne_twister_engine.h (revision b69ddbc62838f23ace237c206676b1ed1c882638)
1344cef66SArthur O'Dwyer //===----------------------------------------------------------------------===//
2344cef66SArthur O'Dwyer //
3344cef66SArthur O'Dwyer // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4344cef66SArthur O'Dwyer // See https://llvm.org/LICENSE.txt for license information.
5344cef66SArthur O'Dwyer // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6344cef66SArthur O'Dwyer //
7344cef66SArthur O'Dwyer //===----------------------------------------------------------------------===//
8344cef66SArthur O'Dwyer 
9344cef66SArthur O'Dwyer #ifndef _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H
10344cef66SArthur O'Dwyer #define _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H
11344cef66SArthur O'Dwyer 
12344cef66SArthur O'Dwyer #include <__algorithm/equal.h>
13344cef66SArthur O'Dwyer #include <__algorithm/min.h>
14344cef66SArthur O'Dwyer #include <__config>
15e99c4906SNikolas Klauser #include <__cstddef/size_t.h>
16344cef66SArthur O'Dwyer #include <__random/is_seed_sequence.h>
17d6832a61SLouis Dionne #include <__type_traits/enable_if.h>
18344cef66SArthur O'Dwyer #include <cstdint>
19344cef66SArthur O'Dwyer #include <iosfwd>
20344cef66SArthur O'Dwyer #include <limits>
21344cef66SArthur O'Dwyer 
22344cef66SArthur O'Dwyer #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23344cef66SArthur O'Dwyer #  pragma GCC system_header
24344cef66SArthur O'Dwyer #endif
25344cef66SArthur O'Dwyer 
26344cef66SArthur O'Dwyer _LIBCPP_PUSH_MACROS
27344cef66SArthur O'Dwyer #include <__undef_macros>
28344cef66SArthur O'Dwyer 
29344cef66SArthur O'Dwyer _LIBCPP_BEGIN_NAMESPACE_STD
30344cef66SArthur O'Dwyer 
319783f28cSLouis Dionne template <class _UIntType,
329783f28cSLouis Dionne           size_t __w,
339783f28cSLouis Dionne           size_t __n,
349783f28cSLouis Dionne           size_t __m,
359783f28cSLouis Dionne           size_t __r,
369783f28cSLouis Dionne           _UIntType __a,
379783f28cSLouis Dionne           size_t __u,
389783f28cSLouis Dionne           _UIntType __d,
399783f28cSLouis Dionne           size_t __s,
409783f28cSLouis Dionne           _UIntType __b,
419783f28cSLouis Dionne           size_t __t,
429783f28cSLouis Dionne           _UIntType __c,
439783f28cSLouis Dionne           size_t __l,
449783f28cSLouis Dionne           _UIntType __f>
45344cef66SArthur O'Dwyer class _LIBCPP_TEMPLATE_VIS mersenne_twister_engine;
46344cef66SArthur O'Dwyer 
479783f28cSLouis Dionne template <class _UInt,
489783f28cSLouis Dionne           size_t _Wp,
499783f28cSLouis Dionne           size_t _Np,
509783f28cSLouis Dionne           size_t _Mp,
519783f28cSLouis Dionne           size_t _Rp,
529783f28cSLouis Dionne           _UInt _Ap,
539783f28cSLouis Dionne           size_t _Up,
549783f28cSLouis Dionne           _UInt _Dp,
559783f28cSLouis Dionne           size_t _Sp,
569783f28cSLouis Dionne           _UInt _Bp,
579783f28cSLouis Dionne           size_t _Tp,
589783f28cSLouis Dionne           _UInt _Cp,
599783f28cSLouis Dionne           size_t _Lp,
609783f28cSLouis Dionne           _UInt _Fp>
6180c7e93aSNikolas Klauser _LIBCPP_HIDE_FROM_ABI bool
629783f28cSLouis Dionne operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
639783f28cSLouis Dionne            const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
64344cef66SArthur O'Dwyer 
659783f28cSLouis Dionne template <class _UInt,
669783f28cSLouis Dionne           size_t _Wp,
679783f28cSLouis Dionne           size_t _Np,
689783f28cSLouis Dionne           size_t _Mp,
699783f28cSLouis Dionne           size_t _Rp,
709783f28cSLouis Dionne           _UInt _Ap,
719783f28cSLouis Dionne           size_t _Up,
729783f28cSLouis Dionne           _UInt _Dp,
739783f28cSLouis Dionne           size_t _Sp,
749783f28cSLouis Dionne           _UInt _Bp,
759783f28cSLouis Dionne           size_t _Tp,
769783f28cSLouis Dionne           _UInt _Cp,
779783f28cSLouis Dionne           size_t _Lp,
789783f28cSLouis Dionne           _UInt _Fp>
799783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI bool
809783f28cSLouis Dionne operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
819783f28cSLouis Dionne            const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
82344cef66SArthur O'Dwyer 
839783f28cSLouis Dionne template <class _CharT,
849783f28cSLouis Dionne           class _Traits,
859783f28cSLouis Dionne           class _UInt,
869783f28cSLouis Dionne           size_t _Wp,
879783f28cSLouis Dionne           size_t _Np,
889783f28cSLouis Dionne           size_t _Mp,
899783f28cSLouis Dionne           size_t _Rp,
909783f28cSLouis Dionne           _UInt _Ap,
919783f28cSLouis Dionne           size_t _Up,
929783f28cSLouis Dionne           _UInt _Dp,
939783f28cSLouis Dionne           size_t _Sp,
949783f28cSLouis Dionne           _UInt _Bp,
959783f28cSLouis Dionne           size_t _Tp,
969783f28cSLouis Dionne           _UInt _Cp,
979783f28cSLouis Dionne           size_t _Lp,
989783f28cSLouis Dionne           _UInt _Fp>
9980c7e93aSNikolas Klauser _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
100344cef66SArthur O'Dwyer operator<<(basic_ostream<_CharT, _Traits>& __os,
1019783f28cSLouis Dionne            const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
102344cef66SArthur O'Dwyer 
1039783f28cSLouis Dionne template <class _CharT,
1049783f28cSLouis Dionne           class _Traits,
1059783f28cSLouis Dionne           class _UInt,
1069783f28cSLouis Dionne           size_t _Wp,
1079783f28cSLouis Dionne           size_t _Np,
1089783f28cSLouis Dionne           size_t _Mp,
1099783f28cSLouis Dionne           size_t _Rp,
1109783f28cSLouis Dionne           _UInt _Ap,
1119783f28cSLouis Dionne           size_t _Up,
1129783f28cSLouis Dionne           _UInt _Dp,
1139783f28cSLouis Dionne           size_t _Sp,
1149783f28cSLouis Dionne           _UInt _Bp,
1159783f28cSLouis Dionne           size_t _Tp,
1169783f28cSLouis Dionne           _UInt _Cp,
1179783f28cSLouis Dionne           size_t _Lp,
1189783f28cSLouis Dionne           _UInt _Fp>
11980c7e93aSNikolas Klauser _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
120344cef66SArthur O'Dwyer operator>>(basic_istream<_CharT, _Traits>& __is,
1219783f28cSLouis Dionne            mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
122344cef66SArthur O'Dwyer 
1239783f28cSLouis Dionne template <class _UIntType,
1249783f28cSLouis Dionne           size_t __w,
1259783f28cSLouis Dionne           size_t __n,
1269783f28cSLouis Dionne           size_t __m,
1279783f28cSLouis Dionne           size_t __r,
1289783f28cSLouis Dionne           _UIntType __a,
1299783f28cSLouis Dionne           size_t __u,
1309783f28cSLouis Dionne           _UIntType __d,
1319783f28cSLouis Dionne           size_t __s,
1329783f28cSLouis Dionne           _UIntType __b,
1339783f28cSLouis Dionne           size_t __t,
1349783f28cSLouis Dionne           _UIntType __c,
1359783f28cSLouis Dionne           size_t __l,
1369783f28cSLouis Dionne           _UIntType __f>
1379783f28cSLouis Dionne class _LIBCPP_TEMPLATE_VIS mersenne_twister_engine {
138344cef66SArthur O'Dwyer public:
139344cef66SArthur O'Dwyer   // types
140344cef66SArthur O'Dwyer   typedef _UIntType result_type;
141344cef66SArthur O'Dwyer 
142344cef66SArthur O'Dwyer private:
143344cef66SArthur O'Dwyer   result_type __x_[__n];
144344cef66SArthur O'Dwyer   size_t __i_;
145344cef66SArthur O'Dwyer 
146344cef66SArthur O'Dwyer   static_assert(0 < __m, "mersenne_twister_engine invalid parameters");
147344cef66SArthur O'Dwyer   static_assert(__m <= __n, "mersenne_twister_engine invalid parameters");
148344cef66SArthur O'Dwyer   static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits<result_type>::digits;
149344cef66SArthur O'Dwyer   static_assert(__w <= _Dt, "mersenne_twister_engine invalid parameters");
150344cef66SArthur O'Dwyer   static_assert(2 <= __w, "mersenne_twister_engine invalid parameters");
151344cef66SArthur O'Dwyer   static_assert(__r <= __w, "mersenne_twister_engine invalid parameters");
152344cef66SArthur O'Dwyer   static_assert(__u <= __w, "mersenne_twister_engine invalid parameters");
153344cef66SArthur O'Dwyer   static_assert(__s <= __w, "mersenne_twister_engine invalid parameters");
154344cef66SArthur O'Dwyer   static_assert(__t <= __w, "mersenne_twister_engine invalid parameters");
155344cef66SArthur O'Dwyer   static_assert(__l <= __w, "mersenne_twister_engine invalid parameters");
1569783f28cSLouis Dionne 
157344cef66SArthur O'Dwyer public:
158344cef66SArthur O'Dwyer   static _LIBCPP_CONSTEXPR const result_type _Min = 0;
1599783f28cSLouis Dionne   static _LIBCPP_CONSTEXPR const result_type _Max =
1609783f28cSLouis Dionne       __w == _Dt ? result_type(~0) : (result_type(1) << __w) - result_type(1);
161344cef66SArthur O'Dwyer   static_assert(_Min < _Max, "mersenne_twister_engine invalid parameters");
162344cef66SArthur O'Dwyer   static_assert(__a <= _Max, "mersenne_twister_engine invalid parameters");
163344cef66SArthur O'Dwyer   static_assert(__b <= _Max, "mersenne_twister_engine invalid parameters");
164344cef66SArthur O'Dwyer   static_assert(__c <= _Max, "mersenne_twister_engine invalid parameters");
165344cef66SArthur O'Dwyer   static_assert(__d <= _Max, "mersenne_twister_engine invalid parameters");
166344cef66SArthur O'Dwyer   static_assert(__f <= _Max, "mersenne_twister_engine invalid parameters");
167344cef66SArthur O'Dwyer 
168344cef66SArthur O'Dwyer   // engine characteristics
169*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const size_t word_size                      = __w;
170*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const size_t state_size                     = __n;
171*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const size_t shift_size                     = __m;
172*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const size_t mask_bits                      = __r;
173*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const result_type xor_mask                  = __a;
174*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const size_t tempering_u                    = __u;
175*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const result_type tempering_d               = __d;
176*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const size_t tempering_s                    = __s;
177*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const result_type tempering_b               = __b;
178*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const size_t tempering_t                    = __t;
179*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const result_type tempering_c               = __c;
180*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const size_t tempering_l                    = __l;
181*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const result_type initialization_multiplier = __f;
1829783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR result_type min() { return _Min; }
1839783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR result_type max() { return _Max; }
184*b69ddbc6SNikolas Klauser   static inline _LIBCPP_CONSTEXPR const result_type default_seed = 5489u;
185344cef66SArthur O'Dwyer 
186344cef66SArthur O'Dwyer   // constructors and seeding functions
187344cef66SArthur O'Dwyer #ifndef _LIBCPP_CXX03_LANG
1889783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI mersenne_twister_engine() : mersenne_twister_engine(default_seed) {}
1899783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI explicit mersenne_twister_engine(result_type __sd) { seed(__sd); }
190344cef66SArthur O'Dwyer #else
1919783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI explicit mersenne_twister_engine(result_type __sd = default_seed) { seed(__sd); }
192344cef66SArthur O'Dwyer #endif
1934da76ea7SNikolas Klauser   template <class _Sseq, __enable_if_t<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value, int> = 0>
1949783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI explicit mersenne_twister_engine(_Sseq& __q) {
1959783f28cSLouis Dionne     seed(__q);
1969783f28cSLouis Dionne   }
19783ce1397SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd = default_seed);
198475bd19eSNikolas Klauser   template <class _Sseq, __enable_if_t<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value, int> = 0>
1999783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI void seed(_Sseq& __q) {
2009783f28cSLouis Dionne     __seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());
2019783f28cSLouis Dionne   }
202344cef66SArthur O'Dwyer 
203344cef66SArthur O'Dwyer   // generating functions
20483ce1397SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI result_type operator()();
2059783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI void discard(unsigned long long __z) {
2069783f28cSLouis Dionne     for (; __z; --__z)
2079783f28cSLouis Dionne       operator()();
2089783f28cSLouis Dionne   }
209344cef66SArthur O'Dwyer 
2109783f28cSLouis Dionne   template <class _UInt,
2119783f28cSLouis Dionne             size_t _Wp,
2129783f28cSLouis Dionne             size_t _Np,
2139783f28cSLouis Dionne             size_t _Mp,
2149783f28cSLouis Dionne             size_t _Rp,
2159783f28cSLouis Dionne             _UInt _Ap,
2169783f28cSLouis Dionne             size_t _Up,
2179783f28cSLouis Dionne             _UInt _Dp,
2189783f28cSLouis Dionne             size_t _Sp,
2199783f28cSLouis Dionne             _UInt _Bp,
2209783f28cSLouis Dionne             size_t _Tp,
2219783f28cSLouis Dionne             _UInt _Cp,
2229783f28cSLouis Dionne             size_t _Lp,
2239783f28cSLouis Dionne             _UInt _Fp>
2249783f28cSLouis Dionne   friend bool operator==(
2259783f28cSLouis Dionne       const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
2269783f28cSLouis Dionne       const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
227344cef66SArthur O'Dwyer 
2289783f28cSLouis Dionne   template <class _UInt,
2299783f28cSLouis Dionne             size_t _Wp,
2309783f28cSLouis Dionne             size_t _Np,
2319783f28cSLouis Dionne             size_t _Mp,
2329783f28cSLouis Dionne             size_t _Rp,
2339783f28cSLouis Dionne             _UInt _Ap,
2349783f28cSLouis Dionne             size_t _Up,
2359783f28cSLouis Dionne             _UInt _Dp,
2369783f28cSLouis Dionne             size_t _Sp,
2379783f28cSLouis Dionne             _UInt _Bp,
2389783f28cSLouis Dionne             size_t _Tp,
2399783f28cSLouis Dionne             _UInt _Cp,
2409783f28cSLouis Dionne             size_t _Lp,
2419783f28cSLouis Dionne             _UInt _Fp>
2429783f28cSLouis Dionne   friend bool operator!=(
2439783f28cSLouis Dionne       const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
2449783f28cSLouis Dionne       const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
245344cef66SArthur O'Dwyer 
2469783f28cSLouis Dionne   template <class _CharT,
2479783f28cSLouis Dionne             class _Traits,
2489783f28cSLouis Dionne             class _UInt,
2499783f28cSLouis Dionne             size_t _Wp,
2509783f28cSLouis Dionne             size_t _Np,
2519783f28cSLouis Dionne             size_t _Mp,
2529783f28cSLouis Dionne             size_t _Rp,
2539783f28cSLouis Dionne             _UInt _Ap,
2549783f28cSLouis Dionne             size_t _Up,
2559783f28cSLouis Dionne             _UInt _Dp,
2569783f28cSLouis Dionne             size_t _Sp,
2579783f28cSLouis Dionne             _UInt _Bp,
2589783f28cSLouis Dionne             size_t _Tp,
2599783f28cSLouis Dionne             _UInt _Cp,
2609783f28cSLouis Dionne             size_t _Lp,
2619783f28cSLouis Dionne             _UInt _Fp>
2629783f28cSLouis Dionne   friend basic_ostream<_CharT, _Traits>& operator<<(
2639783f28cSLouis Dionne       basic_ostream<_CharT, _Traits>& __os,
2649783f28cSLouis Dionne       const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
265344cef66SArthur O'Dwyer 
2669783f28cSLouis Dionne   template <class _CharT,
2679783f28cSLouis Dionne             class _Traits,
2689783f28cSLouis Dionne             class _UInt,
2699783f28cSLouis Dionne             size_t _Wp,
2709783f28cSLouis Dionne             size_t _Np,
2719783f28cSLouis Dionne             size_t _Mp,
2729783f28cSLouis Dionne             size_t _Rp,
2739783f28cSLouis Dionne             _UInt _Ap,
2749783f28cSLouis Dionne             size_t _Up,
2759783f28cSLouis Dionne             _UInt _Dp,
2769783f28cSLouis Dionne             size_t _Sp,
2779783f28cSLouis Dionne             _UInt _Bp,
2789783f28cSLouis Dionne             size_t _Tp,
2799783f28cSLouis Dionne             _UInt _Cp,
2809783f28cSLouis Dionne             size_t _Lp,
2819783f28cSLouis Dionne             _UInt _Fp>
2829783f28cSLouis Dionne   friend basic_istream<_CharT, _Traits>&
283344cef66SArthur O'Dwyer   operator>>(basic_istream<_CharT, _Traits>& __is,
2849783f28cSLouis Dionne              mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
285344cef66SArthur O'Dwyer 
2869783f28cSLouis Dionne private:
287344cef66SArthur O'Dwyer   template <class _Sseq>
28883ce1397SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
289344cef66SArthur O'Dwyer   template <class _Sseq>
29083ce1397SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
291344cef66SArthur O'Dwyer 
2929783f28cSLouis Dionne   template <size_t __count,
2939783f28cSLouis Dionne             __enable_if_t<__count< __w, int> = 0> _LIBCPP_HIDE_FROM_ABI static result_type __lshift(result_type __x) {
2949783f28cSLouis Dionne     return (__x << __count) & _Max;
2959783f28cSLouis Dionne   }
296344cef66SArthur O'Dwyer 
297475bd19eSNikolas Klauser   template <size_t __count, __enable_if_t<(__count >= __w), int> = 0>
2989783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI static result_type __lshift(result_type) {
2999783f28cSLouis Dionne     return result_type(0);
3009783f28cSLouis Dionne   }
301344cef66SArthur O'Dwyer 
3029783f28cSLouis Dionne   template <size_t __count,
3039783f28cSLouis Dionne             __enable_if_t<__count< _Dt, int> = 0> _LIBCPP_HIDE_FROM_ABI static result_type __rshift(result_type __x) {
3049783f28cSLouis Dionne     return __x >> __count;
3059783f28cSLouis Dionne   }
306344cef66SArthur O'Dwyer 
307475bd19eSNikolas Klauser   template <size_t __count, __enable_if_t<(__count >= _Dt), int> = 0>
3089783f28cSLouis Dionne   _LIBCPP_HIDE_FROM_ABI static result_type __rshift(result_type) {
3099783f28cSLouis Dionne     return result_type(0);
3109783f28cSLouis Dionne   }
311344cef66SArthur O'Dwyer };
312344cef66SArthur O'Dwyer 
3139783f28cSLouis Dionne template <class _UIntType,
3149783f28cSLouis Dionne           size_t __w,
3159783f28cSLouis Dionne           size_t __n,
3169783f28cSLouis Dionne           size_t __m,
3179783f28cSLouis Dionne           size_t __r,
3189783f28cSLouis Dionne           _UIntType __a,
3199783f28cSLouis Dionne           size_t __u,
3209783f28cSLouis Dionne           _UIntType __d,
3219783f28cSLouis Dionne           size_t __s,
3229783f28cSLouis Dionne           _UIntType __b,
3239783f28cSLouis Dionne           size_t __t,
3249783f28cSLouis Dionne           _UIntType __c,
3259783f28cSLouis Dionne           size_t __l,
3269783f28cSLouis Dionne           _UIntType __f>
3279783f28cSLouis Dionne void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::seed(
3289783f28cSLouis Dionne     result_type __sd) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { // __w >= 2
329344cef66SArthur O'Dwyer   __x_[0] = __sd & _Max;
330344cef66SArthur O'Dwyer   for (size_t __i = 1; __i < __n; ++__i)
331344cef66SArthur O'Dwyer     __x_[__i] = (__f * (__x_[__i - 1] ^ __rshift<__w - 2>(__x_[__i - 1])) + __i) & _Max;
332344cef66SArthur O'Dwyer   __i_ = 0;
333344cef66SArthur O'Dwyer }
334344cef66SArthur O'Dwyer 
3359783f28cSLouis Dionne template <class _UIntType,
3369783f28cSLouis Dionne           size_t __w,
3379783f28cSLouis Dionne           size_t __n,
3389783f28cSLouis Dionne           size_t __m,
3399783f28cSLouis Dionne           size_t __r,
3409783f28cSLouis Dionne           _UIntType __a,
3419783f28cSLouis Dionne           size_t __u,
3429783f28cSLouis Dionne           _UIntType __d,
3439783f28cSLouis Dionne           size_t __s,
3449783f28cSLouis Dionne           _UIntType __b,
3459783f28cSLouis Dionne           size_t __t,
3469783f28cSLouis Dionne           _UIntType __c,
3479783f28cSLouis Dionne           size_t __l,
3489783f28cSLouis Dionne           _UIntType __f>
349344cef66SArthur O'Dwyer template <class _Sseq>
3509783f28cSLouis Dionne void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::__seed(
3519783f28cSLouis Dionne     _Sseq& __q, integral_constant<unsigned, 1>) {
352344cef66SArthur O'Dwyer   const unsigned __k = 1;
353344cef66SArthur O'Dwyer   uint32_t __ar[__n * __k];
354344cef66SArthur O'Dwyer   __q.generate(__ar, __ar + __n * __k);
355344cef66SArthur O'Dwyer   for (size_t __i = 0; __i < __n; ++__i)
356344cef66SArthur O'Dwyer     __x_[__i] = static_cast<result_type>(__ar[__i] & _Max);
3579783f28cSLouis Dionne   const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
358344cef66SArthur O'Dwyer   __i_                     = 0;
3599783f28cSLouis Dionne   if ((__x_[0] & ~__mask) == 0) {
360344cef66SArthur O'Dwyer     for (size_t __i = 1; __i < __n; ++__i)
361344cef66SArthur O'Dwyer       if (__x_[__i] != 0)
362344cef66SArthur O'Dwyer         return;
363344cef66SArthur O'Dwyer     __x_[0] = result_type(1) << (__w - 1);
364344cef66SArthur O'Dwyer   }
365344cef66SArthur O'Dwyer }
366344cef66SArthur O'Dwyer 
3679783f28cSLouis Dionne template <class _UIntType,
3689783f28cSLouis Dionne           size_t __w,
3699783f28cSLouis Dionne           size_t __n,
3709783f28cSLouis Dionne           size_t __m,
3719783f28cSLouis Dionne           size_t __r,
3729783f28cSLouis Dionne           _UIntType __a,
3739783f28cSLouis Dionne           size_t __u,
3749783f28cSLouis Dionne           _UIntType __d,
3759783f28cSLouis Dionne           size_t __s,
3769783f28cSLouis Dionne           _UIntType __b,
3779783f28cSLouis Dionne           size_t __t,
3789783f28cSLouis Dionne           _UIntType __c,
3799783f28cSLouis Dionne           size_t __l,
3809783f28cSLouis Dionne           _UIntType __f>
381344cef66SArthur O'Dwyer template <class _Sseq>
3829783f28cSLouis Dionne void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::__seed(
3839783f28cSLouis Dionne     _Sseq& __q, integral_constant<unsigned, 2>) {
384344cef66SArthur O'Dwyer   const unsigned __k = 2;
385344cef66SArthur O'Dwyer   uint32_t __ar[__n * __k];
386344cef66SArthur O'Dwyer   __q.generate(__ar, __ar + __n * __k);
387344cef66SArthur O'Dwyer   for (size_t __i = 0; __i < __n; ++__i)
3889783f28cSLouis Dionne     __x_[__i] = static_cast<result_type>((__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max);
3899783f28cSLouis Dionne   const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
390344cef66SArthur O'Dwyer   __i_                     = 0;
3919783f28cSLouis Dionne   if ((__x_[0] & ~__mask) == 0) {
392344cef66SArthur O'Dwyer     for (size_t __i = 1; __i < __n; ++__i)
393344cef66SArthur O'Dwyer       if (__x_[__i] != 0)
394344cef66SArthur O'Dwyer         return;
395344cef66SArthur O'Dwyer     __x_[0] = result_type(1) << (__w - 1);
396344cef66SArthur O'Dwyer   }
397344cef66SArthur O'Dwyer }
398344cef66SArthur O'Dwyer 
3999783f28cSLouis Dionne template <class _UIntType,
4009783f28cSLouis Dionne           size_t __w,
4019783f28cSLouis Dionne           size_t __n,
4029783f28cSLouis Dionne           size_t __m,
4039783f28cSLouis Dionne           size_t __r,
4049783f28cSLouis Dionne           _UIntType __a,
4059783f28cSLouis Dionne           size_t __u,
4069783f28cSLouis Dionne           _UIntType __d,
4079783f28cSLouis Dionne           size_t __s,
4089783f28cSLouis Dionne           _UIntType __b,
4099783f28cSLouis Dionne           size_t __t,
4109783f28cSLouis Dionne           _UIntType __c,
4119783f28cSLouis Dionne           size_t __l,
4129783f28cSLouis Dionne           _UIntType __f>
413344cef66SArthur O'Dwyer _UIntType
4149783f28cSLouis Dionne mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::operator()() {
415344cef66SArthur O'Dwyer   const size_t __j         = (__i_ + 1) % __n;
4169783f28cSLouis Dionne   const result_type __mask = __r == _Dt ? result_type(~0) : (result_type(1) << __r) - result_type(1);
417d05f8895SNikolas Klauser   const result_type __yp   = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask);
418344cef66SArthur O'Dwyer   const size_t __k         = (__i_ + __m) % __n;
419d05f8895SNikolas Klauser   __x_[__i_]               = __x_[__k] ^ __rshift<1>(__yp) ^ (__a * (__yp & 1));
420344cef66SArthur O'Dwyer   result_type __z          = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d);
421344cef66SArthur O'Dwyer   __i_                     = __j;
422344cef66SArthur O'Dwyer   __z ^= __lshift<__s>(__z) & __b;
423344cef66SArthur O'Dwyer   __z ^= __lshift<__t>(__z) & __c;
424344cef66SArthur O'Dwyer   return __z ^ __rshift<__l>(__z);
425344cef66SArthur O'Dwyer }
426344cef66SArthur O'Dwyer 
4279783f28cSLouis Dionne template <class _UInt,
4289783f28cSLouis Dionne           size_t _Wp,
4299783f28cSLouis Dionne           size_t _Np,
4309783f28cSLouis Dionne           size_t _Mp,
4319783f28cSLouis Dionne           size_t _Rp,
4329783f28cSLouis Dionne           _UInt _Ap,
4339783f28cSLouis Dionne           size_t _Up,
4349783f28cSLouis Dionne           _UInt _Dp,
4359783f28cSLouis Dionne           size_t _Sp,
4369783f28cSLouis Dionne           _UInt _Bp,
4379783f28cSLouis Dionne           size_t _Tp,
4389783f28cSLouis Dionne           _UInt _Cp,
4399783f28cSLouis Dionne           size_t _Lp,
4409783f28cSLouis Dionne           _UInt _Fp>
44180c7e93aSNikolas Klauser _LIBCPP_HIDE_FROM_ABI bool
4429783f28cSLouis Dionne operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
4439783f28cSLouis Dionne            const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y) {
444344cef66SArthur O'Dwyer   if (__x.__i_ == __y.__i_)
44577a00c0dSLouis Dionne     return std::equal(__x.__x_, __x.__x_ + _Np, __y.__x_);
4469783f28cSLouis Dionne   if (__x.__i_ == 0 || __y.__i_ == 0) {
44777a00c0dSLouis Dionne     size_t __j = std::min(_Np - __x.__i_, _Np - __y.__i_);
4489783f28cSLouis Dionne     if (!std::equal(__x.__x_ + __x.__i_, __x.__x_ + __x.__i_ + __j, __y.__x_ + __y.__i_))
449344cef66SArthur O'Dwyer       return false;
450344cef66SArthur O'Dwyer     if (__x.__i_ == 0)
45177a00c0dSLouis Dionne       return std::equal(__x.__x_ + __j, __x.__x_ + _Np, __y.__x_);
45277a00c0dSLouis Dionne     return std::equal(__x.__x_, __x.__x_ + (_Np - __j), __y.__x_ + __j);
453344cef66SArthur O'Dwyer   }
4549783f28cSLouis Dionne   if (__x.__i_ < __y.__i_) {
455344cef66SArthur O'Dwyer     size_t __j = _Np - __y.__i_;
4569783f28cSLouis Dionne     if (!std::equal(__x.__x_ + __x.__i_, __x.__x_ + (__x.__i_ + __j), __y.__x_ + __y.__i_))
457344cef66SArthur O'Dwyer       return false;
4589783f28cSLouis Dionne     if (!std::equal(__x.__x_ + (__x.__i_ + __j), __x.__x_ + _Np, __y.__x_))
459344cef66SArthur O'Dwyer       return false;
4609783f28cSLouis Dionne     return std::equal(__x.__x_, __x.__x_ + __x.__i_, __y.__x_ + (_Np - (__x.__i_ + __j)));
461344cef66SArthur O'Dwyer   }
462344cef66SArthur O'Dwyer   size_t __j = _Np - __x.__i_;
4639783f28cSLouis Dionne   if (!std::equal(__y.__x_ + __y.__i_, __y.__x_ + (__y.__i_ + __j), __x.__x_ + __x.__i_))
464344cef66SArthur O'Dwyer     return false;
4659783f28cSLouis Dionne   if (!std::equal(__y.__x_ + (__y.__i_ + __j), __y.__x_ + _Np, __x.__x_))
466344cef66SArthur O'Dwyer     return false;
4679783f28cSLouis Dionne   return std::equal(__y.__x_, __y.__x_ + __y.__i_, __x.__x_ + (_Np - (__y.__i_ + __j)));
468344cef66SArthur O'Dwyer }
469344cef66SArthur O'Dwyer 
4709783f28cSLouis Dionne template <class _UInt,
4719783f28cSLouis Dionne           size_t _Wp,
4729783f28cSLouis Dionne           size_t _Np,
4739783f28cSLouis Dionne           size_t _Mp,
4749783f28cSLouis Dionne           size_t _Rp,
4759783f28cSLouis Dionne           _UInt _Ap,
4769783f28cSLouis Dionne           size_t _Up,
4779783f28cSLouis Dionne           _UInt _Dp,
4789783f28cSLouis Dionne           size_t _Sp,
4799783f28cSLouis Dionne           _UInt _Bp,
4809783f28cSLouis Dionne           size_t _Tp,
4819783f28cSLouis Dionne           _UInt _Cp,
4829783f28cSLouis Dionne           size_t _Lp,
4839783f28cSLouis Dionne           _UInt _Fp>
4849783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI bool
4859783f28cSLouis Dionne operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
4869783f28cSLouis Dionne            const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __y) {
487344cef66SArthur O'Dwyer   return !(__x == __y);
488344cef66SArthur O'Dwyer }
489344cef66SArthur O'Dwyer 
4909783f28cSLouis Dionne template <class _CharT,
4919783f28cSLouis Dionne           class _Traits,
4929783f28cSLouis Dionne           class _UInt,
4939783f28cSLouis Dionne           size_t _Wp,
4949783f28cSLouis Dionne           size_t _Np,
4959783f28cSLouis Dionne           size_t _Mp,
4969783f28cSLouis Dionne           size_t _Rp,
4979783f28cSLouis Dionne           _UInt _Ap,
4989783f28cSLouis Dionne           size_t _Up,
4999783f28cSLouis Dionne           _UInt _Dp,
5009783f28cSLouis Dionne           size_t _Sp,
5019783f28cSLouis Dionne           _UInt _Bp,
5029783f28cSLouis Dionne           size_t _Tp,
5039783f28cSLouis Dionne           _UInt _Cp,
5049783f28cSLouis Dionne           size_t _Lp,
5059783f28cSLouis Dionne           _UInt _Fp>
50680c7e93aSNikolas Klauser _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
507344cef66SArthur O'Dwyer operator<<(basic_ostream<_CharT, _Traits>& __os,
5089783f28cSLouis Dionne            const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x) {
509344cef66SArthur O'Dwyer   __save_flags<_CharT, _Traits> __lx(__os);
510344cef66SArthur O'Dwyer   typedef basic_ostream<_CharT, _Traits> _Ostream;
511344cef66SArthur O'Dwyer   __os.flags(_Ostream::dec | _Ostream::left);
512344cef66SArthur O'Dwyer   _CharT __sp = __os.widen(' ');
513344cef66SArthur O'Dwyer   __os.fill(__sp);
514344cef66SArthur O'Dwyer   __os << __x.__x_[__x.__i_];
515344cef66SArthur O'Dwyer   for (size_t __j = __x.__i_ + 1; __j < _Np; ++__j)
516344cef66SArthur O'Dwyer     __os << __sp << __x.__x_[__j];
517344cef66SArthur O'Dwyer   for (size_t __j = 0; __j < __x.__i_; ++__j)
518344cef66SArthur O'Dwyer     __os << __sp << __x.__x_[__j];
519344cef66SArthur O'Dwyer   return __os;
520344cef66SArthur O'Dwyer }
521344cef66SArthur O'Dwyer 
5229783f28cSLouis Dionne template <class _CharT,
5239783f28cSLouis Dionne           class _Traits,
5249783f28cSLouis Dionne           class _UInt,
5259783f28cSLouis Dionne           size_t _Wp,
5269783f28cSLouis Dionne           size_t _Np,
5279783f28cSLouis Dionne           size_t _Mp,
5289783f28cSLouis Dionne           size_t _Rp,
5299783f28cSLouis Dionne           _UInt _Ap,
5309783f28cSLouis Dionne           size_t _Up,
5319783f28cSLouis Dionne           _UInt _Dp,
5329783f28cSLouis Dionne           size_t _Sp,
5339783f28cSLouis Dionne           _UInt _Bp,
5349783f28cSLouis Dionne           size_t _Tp,
5359783f28cSLouis Dionne           _UInt _Cp,
5369783f28cSLouis Dionne           size_t _Lp,
5379783f28cSLouis Dionne           _UInt _Fp>
53880c7e93aSNikolas Klauser _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
539344cef66SArthur O'Dwyer operator>>(basic_istream<_CharT, _Traits>& __is,
5409783f28cSLouis Dionne            mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp, _Bp, _Tp, _Cp, _Lp, _Fp>& __x) {
541344cef66SArthur O'Dwyer   __save_flags<_CharT, _Traits> __lx(__is);
542344cef66SArthur O'Dwyer   typedef basic_istream<_CharT, _Traits> _Istream;
543344cef66SArthur O'Dwyer   __is.flags(_Istream::dec | _Istream::skipws);
544344cef66SArthur O'Dwyer   _UInt __t[_Np];
545344cef66SArthur O'Dwyer   for (size_t __i = 0; __i < _Np; ++__i)
546344cef66SArthur O'Dwyer     __is >> __t[__i];
5479783f28cSLouis Dionne   if (!__is.fail()) {
548344cef66SArthur O'Dwyer     for (size_t __i = 0; __i < _Np; ++__i)
549344cef66SArthur O'Dwyer       __x.__x_[__i] = __t[__i];
550344cef66SArthur O'Dwyer     __x.__i_ = 0;
551344cef66SArthur O'Dwyer   }
552344cef66SArthur O'Dwyer   return __is;
553344cef66SArthur O'Dwyer }
554344cef66SArthur O'Dwyer 
5559783f28cSLouis Dionne typedef mersenne_twister_engine<
5569783f28cSLouis Dionne     uint_fast32_t,
5579783f28cSLouis Dionne     32,
5589783f28cSLouis Dionne     624,
5599783f28cSLouis Dionne     397,
5609783f28cSLouis Dionne     31,
5619783f28cSLouis Dionne     0x9908b0df,
5629783f28cSLouis Dionne     11,
5639783f28cSLouis Dionne     0xffffffff,
5649783f28cSLouis Dionne     7,
5659783f28cSLouis Dionne     0x9d2c5680,
5669783f28cSLouis Dionne     15,
5679783f28cSLouis Dionne     0xefc60000,
5689783f28cSLouis Dionne     18,
5699783f28cSLouis Dionne     1812433253>
5709783f28cSLouis Dionne     mt19937;
5719783f28cSLouis Dionne typedef mersenne_twister_engine<
5729783f28cSLouis Dionne     uint_fast64_t,
5739783f28cSLouis Dionne     64,
5749783f28cSLouis Dionne     312,
5759783f28cSLouis Dionne     156,
5769783f28cSLouis Dionne     31,
5779783f28cSLouis Dionne     0xb5026f5aa96619e9ULL,
5789783f28cSLouis Dionne     29,
5799783f28cSLouis Dionne     0x5555555555555555ULL,
5809783f28cSLouis Dionne     17,
5819783f28cSLouis Dionne     0x71d67fffeda60000ULL,
5829783f28cSLouis Dionne     37,
5839783f28cSLouis Dionne     0xfff7eee000000000ULL,
5849783f28cSLouis Dionne     43,
5859783f28cSLouis Dionne     6364136223846793005ULL>
5869783f28cSLouis Dionne     mt19937_64;
587344cef66SArthur O'Dwyer 
588344cef66SArthur O'Dwyer _LIBCPP_END_NAMESPACE_STD
589344cef66SArthur O'Dwyer 
590344cef66SArthur O'Dwyer _LIBCPP_POP_MACROS
591344cef66SArthur O'Dwyer 
592344cef66SArthur O'Dwyer #endif // _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H
593