@@ -30,28 +30,45 @@ template <unsigned long long __a,
30
30
unsigned long long __c,
31
31
unsigned long long __m,
32
32
unsigned long long _Mp,
33
- bool _MightOverflow = (__a != 0 && __m != 0 && __m - 1 > (_Mp - __c) / __a),
34
- bool _OverflowOK = ((__m & (__m - 1 )) == 0ull ), // m = 2^n
35
- bool _SchrageOK = (__a != 0 && __m != 0 && __m % __a <= __m / __a)> // r <= q
33
+ bool _HasOverflow = (__a != 0ull && (__m & (__m - 1ull )) != 0ull ), // a != 0, m != 0, m != 2^n
34
+ bool _Full = (!_HasOverflow || __m - 1ull <= (_Mp - __c) / __a), // (a * x + c) % m works
35
+ bool _Part = (!_HasOverflow || __m - 1ull <= _Mp / __a), // (a * x) % m works
36
+ bool _Schrage = (_HasOverflow && __m % __a <= __m / __a)> // r <= q
36
37
struct __lce_alg_picker {
37
- static_assert (!_MightOverflow || _OverflowOK || _SchrageOK,
38
- " The current values of a, c, and m cannot generate a number "
39
- " within bounds of linear_congruential_engine." );
38
+ static _LIBCPP_CONSTEXPR const int __mode = _Full ? 0 : _Part ? 1 : _Schrage ? 2 : 3 ;
40
39
41
- static _LIBCPP_CONSTEXPR const bool __use_schrage = _MightOverflow && !_OverflowOK && _SchrageOK;
40
+ #ifndef __SIZEOF_INT128__
41
+ static_assert (_Mp != (unsigned long long )(~0 ) || _Full || _Part || _Schrage,
42
+ "The current values for a, c, and m are not currently supported on platforms without __int128");
43
+ #endif
42
44
};
43
45
44
46
template <unsigned long long __a,
45
47
unsigned long long __c,
46
48
unsigned long long __m,
47
49
unsigned long long _Mp,
48
- bool _UseSchrage = __lce_alg_picker<__a, __c, __m, _Mp>::__use_schrage >
50
+ int _Mode = __lce_alg_picker<__a, __c, __m, _Mp>::__mode >
49
51
struct __lce_ta ;
50
52
51
53
// 64
52
54
55
+ #ifdef __SIZEOF_INT128__
56
+ template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>
57
+ struct __lce_ta <_Ap, _Cp, _Mp, (unsigned long long )(~0 ), 3 > {
58
+ typedef unsigned long long result_type;
59
+ _LIBCPP_HIDE_FROM_ABI static result_type next (result_type _Xp) {
60
+ __extension__ typedef unsigned __int128 calc_type;
61
+ const calc_type __a = static_cast <calc_type>(_Ap);
62
+ const calc_type __c = static_cast <calc_type>(_Cp);
63
+ const calc_type __m = static_cast <calc_type>(_Mp);
64
+ const calc_type __x = static_cast <calc_type>(_Xp);
65
+ return static_cast <result_type>((__a * __x + __c) % __m);
66
+ }
67
+ };
68
+ #endif
69
+
53
70
template <unsigned long long __a, unsigned long long __c, unsigned long long __m>
54
- struct __lce_ta <__a, __c, __m, (unsigned long long )(~0 ), true > {
71
+ struct __lce_ta <__a, __c, __m, (unsigned long long )(~0 ), 2 > {
55
72
typedef unsigned long long result_type;
56
73
_LIBCPP_HIDE_FROM_ABI static result_type next (result_type __x) {
57
74
// Schrage's algorithm
@@ -66,7 +83,7 @@ struct __lce_ta<__a, __c, __m, (unsigned long long)(~0), true> {
66
83
};
67
84
68
85
template <unsigned long long __a, unsigned long long __m>
69
- struct __lce_ta <__a, 0 , __m, (unsigned long long )(~0 ), true > {
86
+ struct __lce_ta <__a, 0ull , __m, (unsigned long long )(~0 ), 2 > {
70
87
typedef unsigned long long result_type;
71
88
_LIBCPP_HIDE_FROM_ABI static result_type next (result_type __x) {
72
89
// Schrage's algorithm
@@ -80,21 +97,40 @@ struct __lce_ta<__a, 0, __m, (unsigned long long)(~0), true> {
80
97
};
81
98
82
99
template <unsigned long long __a, unsigned long long __c, unsigned long long __m>
83
- struct __lce_ta <__a, __c, __m, (unsigned long long )(~0 ), false > {
100
+ struct __lce_ta <__a, __c, __m, (unsigned long long )(~0 ), 1 > {
101
+ typedef unsigned long long result_type;
102
+ _LIBCPP_HIDE_FROM_ABI static result_type next (result_type __x) {
103
+ // Use (((a*x) % m) + c) % m
104
+ __x = (__a * __x) % __m;
105
+ __x += __c - (__x >= __m - __c) * __m;
106
+ return __x;
107
+ }
108
+ };
109
+
110
+ template <unsigned long long __a, unsigned long long __c, unsigned long long __m>
111
+ struct __lce_ta <__a, __c, __m, (unsigned long long )(~0 ), 0 > {
84
112
typedef unsigned long long result_type;
85
113
_LIBCPP_HIDE_FROM_ABI static result_type next (result_type __x) { return (__a * __x + __c) % __m; }
86
114
};
87
115
88
116
template <unsigned long long __a, unsigned long long __c>
89
- struct __lce_ta <__a, __c, 0 , (unsigned long long )(~0 ), false > {
117
+ struct __lce_ta <__a, __c, 0ull , (unsigned long long )(~0 ), 0 > {
90
118
typedef unsigned long long result_type;
91
119
_LIBCPP_HIDE_FROM_ABI static result_type next (result_type __x) { return __a * __x + __c; }
92
120
};
93
121
94
122
// 32
95
123
124
+ template <unsigned long long __a, unsigned long long __c, unsigned long long __m>
125
+ struct __lce_ta <__a, __c, __m, unsigned (~0 ), 3 > {
126
+ typedef unsigned result_type;
127
+ _LIBCPP_HIDE_FROM_ABI static result_type next (result_type __x) {
128
+ return static_cast <result_type>(__lce_ta<__a, __c, __m, (unsigned long long )(~0 )>::next (__x));
129
+ }
130
+ };
131
+
96
132
template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>
97
- struct __lce_ta <_Ap, _Cp, _Mp, unsigned (~0 ), true > {
133
+ struct __lce_ta <_Ap, _Cp, _Mp, unsigned (~0 ), 2 > {
98
134
typedef unsigned result_type;
99
135
_LIBCPP_HIDE_FROM_ABI static result_type next (result_type __x) {
100
136
const result_type __a = static_cast <result_type>(_Ap);
@@ -112,7 +148,7 @@ struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), true> {
112
148
};
113
149
114
150
template <unsigned long long _Ap, unsigned long long _Mp>
115
- struct __lce_ta <_Ap, 0 , _Mp, unsigned (~0 ), true > {
151
+ struct __lce_ta <_Ap, 0ull , _Mp, unsigned (~0 ), 2 > {
116
152
typedef unsigned result_type;
117
153
_LIBCPP_HIDE_FROM_ABI static result_type next (result_type __x) {
118
154
const result_type __a = static_cast <result_type>(_Ap);
@@ -128,7 +164,21 @@ struct __lce_ta<_Ap, 0, _Mp, unsigned(~0), true> {
128
164
};
129
165
130
166
template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>
131
- struct __lce_ta <_Ap, _Cp, _Mp, unsigned (~0 ), false > {
167
+ struct __lce_ta <_Ap, _Cp, _Mp, unsigned (~0 ), 1 > {
168
+ typedef unsigned result_type;
169
+ _LIBCPP_HIDE_FROM_ABI static result_type next (result_type __x) {
170
+ const result_type __a = static_cast <result_type>(_Ap);
171
+ const result_type __c = static_cast <result_type>(_Cp);
172
+ const result_type __m = static_cast <result_type>(_Mp);
173
+ // Use (((a*x) % m) + c) % m
174
+ __x = (__a * __x) % __m;
175
+ __x += __c - (__x >= __m - __c) * __m;
176
+ return __x;
177
+ }
178
+ };
179
+
180
+ template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>
181
+ struct __lce_ta <_Ap, _Cp, _Mp, unsigned (~0 ), 0 > {
132
182
typedef unsigned result_type;
133
183
_LIBCPP_HIDE_FROM_ABI static result_type next (result_type __x) {
134
184
const result_type __a = static_cast <result_type>(_Ap);
@@ -139,7 +189,7 @@ struct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), false> {
139
189
};
140
190
141
191
template <unsigned long long _Ap, unsigned long long _Cp>
142
- struct __lce_ta <_Ap, _Cp, 0 , unsigned (~0 ), false > {
192
+ struct __lce_ta <_Ap, _Cp, 0ull , unsigned (~0 ), 0 > {
143
193
typedef unsigned result_type;
144
194
_LIBCPP_HIDE_FROM_ABI static result_type next (result_type __x) {
145
195
const result_type __a = static_cast <result_type>(_Ap);
@@ -150,8 +200,8 @@ struct __lce_ta<_Ap, _Cp, 0, unsigned(~0), false> {
150
200
151
201
// 16
152
202
153
- template <unsigned long long __a, unsigned long long __c, unsigned long long __m, bool __b >
154
- struct __lce_ta <__a, __c, __m, (unsigned short )(~0 ), __b > {
203
+ template <unsigned long long __a, unsigned long long __c, unsigned long long __m, int __mode >
204
+ struct __lce_ta <__a, __c, __m, (unsigned short )(~0 ), __mode > {
155
205
typedef unsigned short result_type;
156
206
_LIBCPP_HIDE_FROM_ABI static result_type next (result_type __x) {
157
207
return static_cast <result_type>(__lce_ta<__a, __c, __m, unsigned (~0 )>::next (__x));
0 commit comments