#pragma once #include #include namespace xoroshiro { namespace detail { template class XorOshiro { private: static constexpr unsigned STATE_BITS = 8 * sizeof(STATE); static constexpr unsigned RESULT_BITS = 8 * sizeof(RESULT); static_assert( STATE_BITS >= RESULT_BITS, "STATE must have at least as many bits as RESULT"); STATE x; STATE y; static inline STATE rotl(STATE x, STATE k) { return (x << k) | (x >> (STATE_BITS - k)); } public: XorOshiro(STATE x_ = 5489, STATE y_ = 0) : x(x_), y(y_) { // If both zero, then this does not work if (x_ == 0 && y_ == 0) abort(); next(); } void set_state(STATE x_, STATE y_ = 0) { // If both zero, then this does not work if (x_ == 0 && y_ == 0) abort(); x = x_; y = y_; next(); } RESULT next() { STATE r = x + y; y ^= x; x = rotl(x, A) ^ y ^ (y << B); y = rotl(y, C); // If both zero, then this does not work if (x == 0 && y == 0) abort(); return r >> (STATE_BITS - RESULT_BITS); } }; } using p128r64 = detail::XorOshiro; using p128r32 = detail::XorOshiro; using p64r32 = detail::XorOshiro; using p64r16 = detail::XorOshiro; using p32r16 = detail::XorOshiro; using p32r8 = detail::XorOshiro; using p16r8 = detail::XorOshiro; }