51 #ifndef TINYMT_TINYMT_H 52 #define TINYMT_TINYMT_H 60 #include <type_traits> 67 #define TINYMT_CPP_ENABLE_WHEN(...) \ 68 typename TINYMT_CPP_ENABLE_WHEN_T_ = std::nullptr_t, \ 69 typename std::enable_if < std::is_same<TINYMT_CPP_ENABLE_WHEN_T_, \ 70 std::nullptr_t>::value && \ 72 std::nullptr_t > ::type = nullptr 120 : std::conditional<(typename std::make_signed<T>::type(-1) &
121 typename std::make_signed<T>::type(1)) &&
122 (typename std::make_signed<T>::type(-1) &
123 typename std::make_signed<T>::type(2)),
124 #ifndef TINYMT_CPP_TWOS_COMPLEMENT
125 std::true_type, std::false_type>::type {
126 #elif TINYMT_CPP_TWOS_COMPLEMENT 127 std::true_type, std::true_type>::type {
129 std::false_type, std::false_type>::type {
132 static_assert(std::is_integral<T>::value,
"T must be an integral type");
138 template <
class UIntType>
148 template <
class UIntType, std::size_t WordSize, std::uintmax_t Mat1,
149 std::uintmax_t Mat2, std::uintmax_t TMat>
152 template <
class UIntType, std::uintmax_t Mat1, std::uintmax_t Mat2,
160 struct is_dynamic : std::false_type {};
163 template <
class UIntType>
168 struct is_dynamic : std::true_type {};
171 template <
class UIntType1,
class UIntType2, std::size_t WordSize,
172 std::uintmax_t Mat11, std::uintmax_t Mat12, std::uintmax_t Mat21,
173 std::uintmax_t Mat22, std::uintmax_t TMat1, std::uintmax_t TMat2>
177 return a.mat1 == b.mat1 && a.mat2 == b.mat2 && a.tmat == b.tmat &&
178 a.status == b.status;
181 template <
class UIntType1,
class UIntType2, std::size_t WordSize,
182 std::uintmax_t Mat11, std::uintmax_t Mat12, std::uintmax_t Mat21,
183 std::uintmax_t Mat22, std::uintmax_t TMat1, std::uintmax_t TMat2>
190 template <
class CharT,
class Traits,
class UIntType, std::size_t WordSize,
191 std::uintmax_t Mat1, std::uintmax_t Mat2, std::uintmax_t TMat>
193 std::basic_ostream<CharT, Traits>& os,
199 for (
const auto& x : s.status) {
208 if (status_type::is_dynamic::value) {
218 class CharT,
class Traits,
class UIntType, std::size_t WordSize,
219 std::uintmax_t Mat1, std::uintmax_t Mat2, std::uintmax_t TMat,
221 TMat>::is_dynamic::value)>
223 std::basic_istream<CharT, Traits>& is,
225 for (
auto& x : s.status) {
232 class CharT,
class Traits,
class UIntType, std::size_t WordSize,
233 std::uintmax_t Mat1, std::uintmax_t Mat2, std::uintmax_t TMat,
235 TMat>::is_dynamic::value)>
236 inline std::basic_istream<CharT, Traits>&
operator>>(
237 std::basic_istream<CharT, Traits>& is,
239 for (
auto& x : s.status) {
242 is >> s.mat1 >> std::ws;
243 is >> s.mat2 >> std::ws;
244 is >> s.tmat >> std::ws;
251 template <
class UIntType, std::size_t WordSize, std::uintmax_t Mat1,
252 std::uintmax_t Mat2, std::uintmax_t TMat,
bool DoPeriodCertification>
255 template <
class UIntType, std::uintmax_t Mat1, std::uintmax_t Mat2,
256 std::uintmax_t TMat,
bool DoPeriodCertification>
258 DoPeriodCertification> {
264 static constexpr std::size_t state_size = 4;
265 static constexpr std::uintmax_t max = 0xffffffffU;
267 static constexpr std::size_t sh0 = 1;
268 static constexpr std::size_t sh1 = 10;
269 static constexpr std::size_t sh8 = 8;
291 const unsigned int MIN_LOOP = 8;
292 const unsigned int PRE_LOOP = 8;
296 s.
status[0] = seed & mask32;
303 for (
unsigned int i = 1; i < MIN_LOOP; i++) {
304 s.
status[i & 3] ^= i + 1812433253 * (s.
status[(i - 1) & 3] ^
305 (s.
status[(i - 1) & 3] >> 30));
306 s.
status[i & 3] &= mask32;
309 if (DoPeriodCertification) {
310 period_certification(s);
313 for (
unsigned int i = 0; i < PRE_LOOP; i++) {
318 template <TINYMT_CPP_ENABLE_WHEN(!is_twos_complement<result_type>::value)>
322 x ^= (x << sh0) & mask32;
326 s.
status[2] = (x ^ (y << sh1)) & mask32;
334 template <TINYMT_CPP_ENABLE_WHEN(is_twos_complement<result_type>::value)>
338 x ^= (x << sh0) & mask32;
342 s.
status[2] = (x ^ (y << sh1)) & mask32;
352 template <TINYMT_CPP_ENABLE_WHEN(!is_twos_complement<result_type>::value)>
363 template <TINYMT_CPP_ENABLE_WHEN(is_twos_complement<result_type>::value)>
372 t0 ^= t1mask & s.
tmat;
394 template <
class UIntType, std::size_t WordSize, UIntType Mat1, UIntType Mat2,
395 UIntType TMat,
bool DoPeriodCertification =
true>
397 static_assert(std::is_integral<UIntType>::value &&
398 std::is_unsigned<UIntType>::value,
399 "result_type must be an unsigned integral type");
400 static_assert(WordSize == 32,
"word_size must be 32");
403 DoPeriodCertification>;
407 static_assert(std::numeric_limits<UIntType>::max() >= impl::max,
408 "size of result_type must be lager than word_size");
409 static_assert(Mat1 <= impl::max,
"Mat1 must be < 2^word_size");
410 static_assert(Mat2 <= impl::max,
"Mat2 must be < 2^word_size");
411 static_assert(TMat <= impl::max,
"TMat must be < 2^word_size");
429 static constexpr std::size_t word_size = WordSize;
434 static constexpr std::size_t state_size = impl::state_size;
446 template <TINYMT_CPP_ENABLE_WHEN(!status_type::is_dynamic::value)>
448 impl::init(s_, seed);
457 template <TINYMT_CPP_ENABLE_WHEN(status_type::is_dynamic::value)>
460 s_.mat1 = param.mat1 & impl::word_mask;
461 s_.mat2 = param.mat2 & impl::word_mask;
462 s_.tmat = param.tmat & impl::word_mask;
463 impl::init(s_, seed);
481 for (
unsigned long long i = 0; i < z; i++) {
482 impl::next_state(s_);
506 impl::next_state(s_);
507 return impl::temper(s_);
541 template <
class CharT,
class Traits>
543 std::basic_ostream<CharT, Traits>& os,
const tinymt_engine& e) {
554 template <
class CharT,
class Traits>
576 #endif // TINYMT_TINYMT_H typename impl::param_type param_type
Type of the generator parameter set.
Definition: tinymt.h:424
typename std::make_signed< result_type >::type signed_result_type
Definition: tinymt.h:260
tinymt_engine(result_type seed=default_seed)
Constructs the engine (non-DC mode).
Definition: tinymt.h:447
static constexpr result_type tmat
Definition: tinymt.h:159
Generator's parameter set.
Definition: tinymt.h:139
std::array< result_type, 4 > status
Definition: tinymt.h:167
Generator's state and parameter set.
Definition: tinymt.h:150
bool operator!=(const tinymt_engine_status< UIntType1, WordSize, Mat11, Mat21, TMat1 > &a, const tinymt_engine_status< UIntType2, WordSize, Mat12, Mat22, TMat2 > &b)
Definition: tinymt.h:184
static void period_certification(status_type &s)
Definition: tinymt.h:275
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, tinymt_engine &e)
Deserializes the state of the given engine from a stream.
Definition: tinymt.h:555
constexpr uint_least32_t tinymt32_default_param_mat2
Default parameter mat2 of TinyMT32 specified in RFC 8682.
Definition: tinymt.h:93
result_type operator()()
Returns the next pseudo-random number.
Definition: tinymt.h:505
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const tinymt_engine &e)
Serializes the state of the given engine into a stream.
Definition: tinymt.h:542
Core implementation of the TinyMT algorithms.
Definition: tinymt.h:253
UIntType mat2
Definition: tinymt.h:141
tinymt_engine(const param_type ¶m, result_type seed=default_seed)
Constructs the engine (DC mode).
Definition: tinymt.h:458
bool operator==(const tinymt_engine_status< UIntType1, WordSize, Mat11, Mat21, TMat1 > &a, const tinymt_engine_status< UIntType2, WordSize, Mat12, Mat22, TMat2 > &b)
Definition: tinymt.h:174
friend bool operator!=(const tinymt_engine &a, const tinymt_engine &b)
Compares two engines.
Definition: tinymt.h:530
void seed(result_type value=default_seed)
Reinitializes the engine.
Definition: tinymt.h:471
std::array< result_type, 4 > status
Definition: tinymt.h:156
std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, tinymt_engine_status< UIntType, WordSize, Mat1, Mat2, TMat > &s)
Definition: tinymt.h:222
UIntType mat1
Definition: tinymt.h:140
static constexpr result_type min()
Returns the smallest possible value in the output range.
Definition: tinymt.h:491
static constexpr result_type mat1
Definition: tinymt.h:157
friend bool operator==(const tinymt_engine &a, const tinymt_engine &b)
Compares two engines.
Definition: tinymt.h:518
constexpr uint_least32_t tinymt32_default_param_mat1
Default parameter mat1 of TinyMT32 specified in RFC 8682.
Definition: tinymt.h:88
UIntType result_type
Definition: tinymt.h:155
static constexpr result_type mat2
Definition: tinymt.h:158
void discard(unsigned long long z)
Advances the state of the engine by the given amount.
Definition: tinymt.h:480
static result_type temper(const status_type &s)
Definition: tinymt.h:353
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const tinymt_engine_status< UIntType, WordSize, Mat1, Mat2, TMat > &s)
Definition: tinymt.h:192
Checks whether the given integral type T (or its signed type) uses 2's complement for the signed inte...
Definition: tinymt.h:119
#define TINYMT_CPP_ENABLE_WHEN(...)
Macro to enable/disable function via SFINAE.
Definition: tinymt.h:67
constexpr uint_least32_t tinymt32_default_param_tmat
Default parameter tmat of TinyMT32 specified in RFC 8682.
Definition: tinymt.h:98
static void next_state(status_type &s)
Definition: tinymt.h:319
static void init(status_type &s, result_type seed)
Definition: tinymt.h:290
static constexpr result_type max()
Returns the largest possible value in the output range.
Definition: tinymt.h:498
Pseudo-random number generator engine based on the TinyMT algorithms.
Definition: tinymt.h:396
UIntType result_type
Definition: tinymt.h:166
UIntType tmat
Definition: tinymt.h:142
Namespace for classes that implement the TinyMT algorithms.
Definition: tinymt.h:77
UIntType result_type
Definition: tinymt.h:259
UIntType result_type
Integral type generated by the engine.
Definition: tinymt.h:419