File indexing completed on 2025-01-18 09:51:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef BOOST_RANDOM_DISCARD_BLOCK_HPP
0018 #define BOOST_RANDOM_DISCARD_BLOCK_HPP
0019
0020 #include <iostream>
0021 #include <boost/config.hpp>
0022 #include <boost/cstdint.hpp>
0023 #include <boost/limits.hpp>
0024 #include <boost/static_assert.hpp>
0025 #include <boost/random/detail/config.hpp>
0026 #include <boost/random/detail/seed.hpp>
0027 #include <boost/random/detail/seed_impl.hpp>
0028
0029
0030 namespace boost {
0031 namespace random {
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 template<class UniformRandomNumberGenerator, std::size_t p, std::size_t r>
0043 class discard_block_engine
0044 {
0045 typedef typename detail::seed_type<
0046 typename UniformRandomNumberGenerator::result_type>::type seed_type;
0047 public:
0048 typedef UniformRandomNumberGenerator base_type;
0049 typedef typename base_type::result_type result_type;
0050
0051 BOOST_STATIC_CONSTANT(std::size_t, block_size = p);
0052 BOOST_STATIC_CONSTANT(std::size_t, used_block = r);
0053
0054 BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
0055 BOOST_STATIC_CONSTANT(std::size_t, total_block = p);
0056 BOOST_STATIC_CONSTANT(std::size_t, returned_block = r);
0057
0058 BOOST_STATIC_ASSERT(total_block >= returned_block);
0059
0060
0061 discard_block_engine() : _rng(), _n(0) { }
0062
0063 explicit discard_block_engine(const base_type & rng) : _rng(rng), _n(0) { }
0064
0065 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0066
0067 explicit discard_block_engine(base_type && rng) : _rng(rng), _n(0) { }
0068 #endif
0069
0070
0071
0072
0073
0074 BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(discard_block_engine,
0075 seed_type, value)
0076 { _rng.seed(value); _n = 0; }
0077
0078
0079
0080
0081
0082 BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(discard_block_engine, SeedSeq, seq)
0083 { _rng.seed(seq); _n = 0; }
0084
0085
0086
0087
0088
0089 template<class It> discard_block_engine(It& first, It last)
0090 : _rng(first, last), _n(0) { }
0091
0092
0093 void seed() { _rng.seed(); _n = 0; }
0094
0095 BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(discard_block_engine, seed_type, s)
0096 { _rng.seed(s); _n = 0; }
0097
0098 BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(discard_block_engine, SeedSeq, seq)
0099 { _rng.seed(seq); _n = 0; }
0100
0101 template<class It> void seed(It& first, It last)
0102 { _rng.seed(first, last); _n = 0; }
0103
0104
0105 const base_type& base() const { return _rng; }
0106
0107
0108 result_type operator()()
0109 {
0110 if(_n >= returned_block) {
0111
0112
0113
0114
0115 for(std::size_t i = 0; i < total_block - _n; ++i) {
0116 _rng();
0117 }
0118 _n = 0;
0119 }
0120 ++_n;
0121 return _rng();
0122 }
0123
0124 void discard(boost::uintmax_t z)
0125 {
0126 for(boost::uintmax_t j = 0; j < z; ++j) {
0127 (*this)();
0128 }
0129 }
0130
0131 template<class It>
0132 void generate(It first, It last)
0133 { detail::generate(*this, first, last); }
0134
0135
0136
0137
0138
0139 static BOOST_CONSTEXPR result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
0140 { return (base_type::min)(); }
0141
0142
0143
0144
0145 static BOOST_CONSTEXPR result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
0146 { return (base_type::max)(); }
0147
0148 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
0149
0150 template<class CharT, class Traits>
0151 friend std::basic_ostream<CharT,Traits>&
0152 operator<<(std::basic_ostream<CharT,Traits>& os,
0153 const discard_block_engine& s)
0154 {
0155 os << s._rng << ' ' << s._n;
0156 return os;
0157 }
0158
0159
0160 template<class CharT, class Traits>
0161 friend std::basic_istream<CharT,Traits>&
0162 operator>>(std::basic_istream<CharT,Traits>& is, discard_block_engine& s)
0163 {
0164 is >> s._rng >> std::ws >> s._n;
0165 return is;
0166 }
0167 #endif
0168
0169
0170 friend bool operator==(const discard_block_engine& x,
0171 const discard_block_engine& y)
0172 { return x._rng == y._rng && x._n == y._n; }
0173
0174 friend bool operator!=(const discard_block_engine& x,
0175 const discard_block_engine& y)
0176 { return !(x == y); }
0177
0178 private:
0179 base_type _rng;
0180 std::size_t _n;
0181 };
0182
0183 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
0184
0185 template<class URNG, std::size_t p, std::size_t r>
0186 const bool discard_block_engine<URNG, p, r>::has_fixed_range;
0187 template<class URNG, std::size_t p, std::size_t r>
0188 const std::size_t discard_block_engine<URNG, p, r>::total_block;
0189 template<class URNG, std::size_t p, std::size_t r>
0190 const std::size_t discard_block_engine<URNG, p, r>::returned_block;
0191 template<class URNG, std::size_t p, std::size_t r>
0192 const std::size_t discard_block_engine<URNG, p, r>::block_size;
0193 template<class URNG, std::size_t p, std::size_t r>
0194 const std::size_t discard_block_engine<URNG, p, r>::used_block;
0195 #endif
0196
0197
0198
0199 template<class URNG, int p, int r>
0200 class discard_block : public discard_block_engine<URNG, p, r>
0201 {
0202 typedef discard_block_engine<URNG, p, r> base_t;
0203 public:
0204 typedef typename base_t::result_type result_type;
0205 discard_block() {}
0206 template<class T>
0207 discard_block(T& arg) : base_t(arg) {}
0208 template<class T>
0209 discard_block(const T& arg) : base_t(arg) {}
0210 template<class It>
0211 discard_block(It& first, It last) : base_t(first, last) {}
0212 result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
0213 { return (this->base().min)(); }
0214 result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
0215 { return (this->base().max)(); }
0216 };
0217
0218
0219
0220 namespace detail {
0221
0222 template<class Engine>
0223 struct generator_bits;
0224
0225 template<class URNG, std::size_t p, std::size_t r>
0226 struct generator_bits<discard_block_engine<URNG, p, r> > {
0227 static std::size_t value() { return generator_bits<URNG>::value(); }
0228 };
0229
0230 template<class URNG, int p, int r>
0231 struct generator_bits<discard_block<URNG, p, r> > {
0232 static std::size_t value() { return generator_bits<URNG>::value(); }
0233 };
0234
0235 }
0236
0237 }
0238
0239 }
0240
0241 #endif