32 #ifndef VSMC_RNG_THREEFRY_HPP
33 #define VSMC_RNG_THREEFRY_HPP
37 #define VSMC_STATIC_ASSERT_RNG_THREEFRY_RESULT_TYPE(ResultType) \
39 (cxx11::is_same<ResultType, uint32_t>::value || \
40 cxx11::is_same<ResultType, uint64_t>::value), \
41 USE_ThreefryEngine_WITH_INTEGER_TYPE_OTHER_THAN_uint32_t_OR_uint64_t)
43 #define VSMC_STATIC_ASSERT_RNG_THREEFRY_SIZE(K) \
44 VSMC_STATIC_ASSERT((K == 2 || K == 4), \
45 USE_ThreefryEngine_WITH_SIZE_OTHER_THAN_2_OR_4)
47 #define VSMC_STATIC_ASSERT_RNG_THREEFRY \
48 VSMC_STATIC_ASSERT_RNG_THREEFRY_RESULT_TYPE(ResultType); \
49 VSMC_STATIC_ASSERT_RNG_THREEFRY_SIZE(K);
51 #define VSMC_DEFINE_RNG_THREEFRY_ROTATE_CONSTANT(T, K, N, I, val) \
52 template <> struct ThreefryRotateConstantValue < T, K, N, I > : \
53 public cxx11::integral_constant< unsigned, val > {};
57 #ifndef VSMC_RNG_THREEFRY_ROUNDS
58 #define VSMC_RNG_THREEFRY_ROUNDS 20
69 UINT32_C(0x1BD11BDA)> {};
73 UINT64_C(0x1BD11BDAA9FC1A22)> {};
75 template <
typename, std::
size_t, std::
size_t, std::
size_t>
134 template <
unsigned N>
135 struct ThreefryRotateImpl<uint32_t, N>
136 {
static uint32_t
eval (uint32_t x) {
return x << N | x >> (32 - N);}};
138 template <
unsigned N>
140 {
static uint64_t
eval (uint64_t x) {
return x << N | x >> (64 - N);}};
142 template <
typename ResultType, std::
size_t K, std::
size_t N,
bool = (N > 0)>
145 template <
typename ResultType, std::
size_t N>
162 template <
typename ResultType, std::
size_t N>
187 template <
typename ResultType, std::size_t K, std::size_t N,
195 template <
typename ResultType, std::
size_t N>
213 template <
typename ResultType, std::
size_t N>
263 template <
typename ResultType, std::size_t K,
286 template <
typename SeedSeq>
304 counter::reset(ctr_);
312 template <
typename SeedSeq>
318 counter::reset(ctr_);
327 counter::reset(ctr_);
332 ctr_type
ctr ()
const {
return ctr_;}
337 for (std::size_t i = 0; i != K; ++i)
343 void ctr (
const ctr_type &c)
345 counter::set(ctr_, c);
349 void key (
const key_type &k)
358 counter::increment(ctr_);
359 generate_buffer(ctr_, buffer_);
363 return buffer_[index_++];
371 generate_buffer(c, buf);
379 {generate_buffer(c, buf);}
383 std::size_t n =
static_cast<std::size_t
>(nskip);
384 if (index_ + n <= K) {
397 counter::increment(ctr_, static_cast<result_type>(n / K));
405 ~(
static_cast<result_type
>(0)));
415 eng1.index_ == eng2.index_ &&
416 eng1.ctr_ == eng2.ctr_ &&
417 eng1.par_ == eng2.par_;
423 {
return !(eng1 == eng2);}
425 template <
typename CharT,
typename Traits>
426 friend inline std::basic_ostream<CharT, Traits> &
operator<< (
427 std::basic_ostream<CharT, Traits> &os,
433 os << eng.ctr_ <<
' ';
434 os << eng.par_ <<
' ';
435 os << eng.buffer_ <<
' ';
441 template <
typename CharT,
typename Traits>
442 friend inline std::basic_istream<CharT, Traits> &
operator>> (
443 std::basic_istream<CharT, Traits> &is,
450 is >> std::ws >> eng_tmp.ctr_;
451 is >> std::ws >> eng_tmp.par_;
452 is >> std::ws >> eng_tmp.buffer_;
453 is >> std::ws >> eng_tmp.index_;
456 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
473 void generate_buffer (
const ctr_type &c, buffer_type &buf)
const
479 template <std::
size_t>
482 template <std::
size_t N>
487 generate_buffer<N + 1>(buf,
488 cxx11::integral_constant<bool, N < Rounds>());
493 par_.
back() = internal::ThreefryKSConstantValue<ResultType>::value;
494 par_xor<0>(
key, cxx11::integral_constant<bool, 0 < K>());
497 template <std::
size_t>
500 template <std::
size_t N>
503 par_[Position<N>()] = key[Position<N>()];
504 par_.
back() ^= key[Position<N>()];
505 par_xor<N + 1>(
key, cxx11::integral_constant<bool, N + 1 < K>());
535 #endif // VSMC_RNG_THREEFRY_HPP
void key(const key_type &k)
Array< ResultType, K > buffer_type
#define VSMC_RNG_THREEFRY_ROUNDS
ThreefryEngine default rounds.
void ctr(const ctr_type &c)
#define VSMC_CONSTEXPR
constexpr
Threefry RNG engine reimplemented.
#define VSMC_DEFINE_RNG_THREEFRY_ROTATE_CONSTANT(T, K, N, I, val)
friend bool operator==(const ThreefryEngine< ResultType, K, Rounds > &eng1, const ThreefryEngine< ResultType, K, Rounds > &eng2)
ThreefryEngine(result_type s=0)
static constexpr const result_type _Min
void discard(result_type nskip)
Threefry4x64 Threefry_64
The default 64-bits Threefry engine.
ThreefryEngine< uint32_t, 4 > Threefry4x32
Threefry4x32 RNG engine reimplemented.
friend bool operator!=(const ThreefryEngine< ResultType, K, Rounds > &eng1, const ThreefryEngine< ResultType, K, Rounds > &eng2)
static void eval(Array< ResultType, K > &)
Array< ResultType, K > key_type
static void eval(Array< ResultType, 4 > &state, const Array< ResultType, 5 > &par)
ThreefryEngine(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, result_type, key_type, ThreefryEngine< ResultType, K, Rounds > >::value >::type *=nullptr)
ThreefryEngine< uint64_t, 4 > Threefry4x64
Threefry4x64 RNG engine reimplemented.
ThreefryEngine< uint64_t, 2 > Threefry2x64
Threefry2x64 RNG engine reimplemented.
integral_constant< bool, false > false_type
Function template argument used for position.
Threefry4x32 Threefry
The default 32-bits Threefry engine.
static uint32_t eval(uint32_t x)
#define VSMC_MNE
Avoid MSVC stupid behavior: MNE = Macro No Expansion.
static constexpr const result_type _Max
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const ThreefryEngine< ResultType, K, Rounds > &eng)
#define VSMC_STATIC_ASSERT_RNG_THREEFRY
ThreefryEngine< uint32_t, 2 > Threefry2x32
Threefry2x32 RNG engine reimplemented.
static constexpr result_type min()
remove_reference< T >::type && move(T &&t) noexcept
static void eval(Array< ResultType, K > &, const Array< ResultType, K+1 > &)
static void eval(Array< ResultType, 2 > &state)
static void eval(Array< ResultType, 4 > &state)
#define VSMC_NULLPTR
nullptr
integral_constant< bool, true > true_type
ThreefryEngine(const key_type &k)
static uint64_t eval(uint64_t x)
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, ThreefryEngine< ResultType, K, Rounds > &eng)
void fill(const T &value)
static void eval(Array< ResultType, 2 > &state, const Array< ResultType, 3 > &par)
void seed(const key_type &k)
Array< ResultType, K > ctr_type
void seed(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, result_type, key_type, ThreefryEngine< ResultType, K, Rounds > >::value >::type *=nullptr)
static constexpr result_type max()