32 #ifndef VSMC_RNG_SEED_HPP
33 #define VSMC_RNG_SEED_HPP
37 #define VSMC_STATIC_ASSERT_RNG_SEED_GENERATOR_RESULT_TYPE(T) \
38 VSMC_STATIC_ASSERT((::vsmc::cxx11::is_unsigned<T>::value), \
39 USE_SeedGenerator_WITH_A_RESULT_TYPE_NOT_AN_UNSIGNED_INTEGER)
41 #define VSMC_RUNTIME_ASSERT_RNG_SEED_GENERATOR_MODULO(div, rem) \
42 VSMC_RUNTIME_ASSERT((div > rem), \
43 ("**SeedGenerator::modulo** " \
44 "REMAINDER IS NOT SMALLER THAN THE DIVISOR"))
46 #define VSMC_RUNTIME_WARNING_RNG_SEED_GENERATOR_MODULO(div, rem) \
47 VSMC_RUNTIME_WARNING((div == 1 && rem == 0), \
48 ("**SeedGenerator::modulo** " \
49 "COUNTER TYPE SEED DOES NOT SUPPORT MODULO"))
51 #define VSMC_RUNTIME_ASSERT_RNG_SEED_MAX(seed_max) \
52 VSMC_RUNTIME_ASSERT((seed_max > 1), \
53 ("**SeedGenerator::modulo** " \
54 "THE MAXIMUM OF THE INTERNAL SEED IS NO LARGER THAN 1"))
58 #ifndef VSMC_SEED_RESULT_TYPE
59 #define VSMC_SEED_RESULT_TYPE unsigned
86 template <
typename ID,
typename ResultType = VSMC_SEED_RESULT_TYPE>
102 result_type
get () {
skip();
return seed_ * divisor_ + remainder_;}
110 void set (result_type
seed) {seed_ = seed % seed_max_;}
113 result_type
seed ()
const {
return seed_;}
125 void modulo (skip_type div, skip_type rem)
131 seed_max_ =
static_cast<skip_type
>(~static_cast<skip_type>(0));
132 seed_max_ -= seed_max_ % divisor_;
133 seed_max_ /= divisor_;
143 result_type incr = steps % seed_max_;
144 result_type diff = seed_max_ - seed_;
145 seed_ = incr <= diff ? (seed_ + incr) : (incr - diff);
149 void skip () {seed_ = seed_ == seed_max_ ? 1 : (seed_ + 1);}
151 template <
typename CharT,
typename Traits>
152 friend inline std::basic_ostream<CharT, Traits> &
operator<< (
153 std::basic_ostream<CharT, Traits> &os,
159 os << sg.seed_ <<
' ';
160 os << sg.divisor_ <<
' ';
166 template <
typename CharT,
typename Traits>
167 friend inline std::basic_istream<CharT, Traits> &
operator>> (
168 std::basic_istream<CharT, Traits> &is,
178 is >> std::ws >> div;
179 is >> std::ws >> rem;
192 result_type seed_max_;
194 skip_type remainder_;
196 SeedGenerator () : seed_(0), seed_max_(0), divisor_(1), remainder_(0)
200 modulo(divisor_, remainder_);
203 SeedGenerator (
const SeedGenerator<ID, ResultType> &);
205 SeedGenerator<ID, ResultType> &operator= (
206 const SeedGenerator<ID, ResultType> &);
229 template <
typename ID,
typename T, std::
size_t K>
244 result_type
get () {
skip();
return seed_;}
248 result_type
seed ()
const {
return seed_;}
256 void modulo (skip_type div, skip_type rem)
262 seed_max_.fill(static_cast<skip_type>(~static_cast<skip_type>(0)));
272 template <
typename CharT,
typename Traits>
273 friend inline std::basic_ostream<CharT, Traits> &
operator<< (
274 std::basic_ostream<CharT, Traits> &os,
280 os << sg.seed_ <<
' ';
281 os << sg.divisor_ <<
' ';
282 os << sg.remainder_ <<
' ';
287 template <
typename CharT,
typename Traits>
288 friend inline std::basic_istream<CharT, Traits> &
operator>> (
289 std::basic_istream<CharT, Traits> &is,
299 is >> std::ws >> div;
300 is >> std::ws >> rem;
313 result_type seed_max_;
315 skip_type remainder_;
323 modulo(divisor_, remainder_);
326 SeedGenerator<ID, Array<T, K> > (
const SeedGenerator<ID, Array<T, K> > &);
328 SeedGenerator<ID, Array<T, K> > &operator= (
329 const SeedGenerator<ID, Array<T, K> > &);
338 #endif // VSMC_RNG_SEED_HPP
static SeedGenerator< ID, ResultType > & instance()
void modulo(skip_type div, skip_type rem)
result_type seed_max() const
void skip(skip_type steps)
Skip the internal seed by a given steps.
void set(result_type seed)
#define VSMC_STATIC_ASSERT_RNG_SEED_GENERATOR_RESULT_TYPE(T)
#define VSMC_RUNTIME_ASSERT_RNG_SEED_GENERATOR_MODULO(div, rem)
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, SeedGenerator< ID, ResultType > &sg)
void set(result_type seed)
Set the internal seed.
#define VSMC_RUNTIME_WARNING_RNG_SEED_GENERATOR_MODULO(div, rem)
result_type seed_max() const
The maximum of the internal seed integer.
skip_type remainder() const
SeedGenerator< NullType, unsigned > Seed
The default Seed type.
skip_type divisor() const
The divisor of the output seed.
skip_type remainder() const
The remainder of the output seed.
#define VSMC_RUNTIME_ASSERT_RNG_SEED_MAX(seed_max)
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const SeedGenerator< ID, ResultType > &sg)
result_type seed() const
The current internal seed.
Array< T, K > result_type
void modulo(skip_type div, skip_type rem)
Set the divisor and the remainder.
skip_type divisor() const
void skip()
Skip the internal seed by 1 step.
void skip(skip_type steps)
static SeedGenerator< ID, Array< T, K > > & instance()