/* boost random/discard_block.hpp header file | |
* | |
* Copyright Jens Maurer 2002 | |
* Distributed under the Boost Software License, Version 1.0. (See | |
* accompanying file LICENSE_1_0.txt or copy at | |
* http://www.boost.org/LICENSE_1_0.txt) | |
* | |
* See http://www.boost.org for most recent version including documentation. | |
* | |
* $Id: discard_block.hpp 60755 2010-03-22 00:45:06Z steven_watanabe $ | |
* | |
* Revision history | |
* 2001-03-02 created | |
*/ | |
#ifndef BOOST_RANDOM_DISCARD_BLOCK_HPP | |
#define BOOST_RANDOM_DISCARD_BLOCK_HPP | |
#include <iostream> | |
#include <boost/config.hpp> | |
#include <boost/limits.hpp> | |
#include <boost/static_assert.hpp> | |
#include <boost/random/detail/config.hpp> | |
namespace boost { | |
namespace random { | |
/** | |
* The class template \discard_block is a model of | |
* \pseudo_random_number_generator. It modifies | |
* another generator by discarding parts of its output. | |
* Out of every block of @c r results, the first @c p | |
* will be returned and the rest discarded. | |
* | |
* Requires: 0 < p <= r | |
*/ | |
template<class UniformRandomNumberGenerator, unsigned int p, unsigned int r> | |
class discard_block | |
{ | |
public: | |
typedef UniformRandomNumberGenerator base_type; | |
typedef typename base_type::result_type result_type; | |
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); | |
BOOST_STATIC_CONSTANT(unsigned int, total_block = p); | |
BOOST_STATIC_CONSTANT(unsigned int, returned_block = r); | |
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS | |
BOOST_STATIC_ASSERT(total_block >= returned_block); | |
#endif | |
discard_block() : _rng(), _n(0) { } | |
explicit discard_block(const base_type & rng) : _rng(rng), _n(0) { } | |
template<class T> explicit discard_block(T s) : _rng(s), _n(0) {} | |
template<class It> discard_block(It& first, It last) | |
: _rng(first, last), _n(0) { } | |
void seed() { _rng.seed(); _n = 0; } | |
template<class T> void seed(T s) { _rng.seed(s); _n = 0; } | |
template<class It> void seed(It& first, It last) | |
{ _n = 0; _rng.seed(first, last); } | |
const base_type& base() const { return _rng; } | |
result_type operator()() | |
{ | |
if(_n >= returned_block) { | |
// discard values of random number generator | |
for( ; _n < total_block; ++_n) | |
_rng(); | |
_n = 0; | |
} | |
++_n; | |
return _rng(); | |
} | |
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_rng.min)(); } | |
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_rng.max)(); } | |
static bool validation(result_type x) { return true; } // dummy | |
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE | |
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS | |
template<class CharT, class Traits> | |
friend std::basic_ostream<CharT,Traits>& | |
operator<<(std::basic_ostream<CharT,Traits>& os, const discard_block& s) | |
{ | |
os << s._rng << " " << s._n << " "; | |
return os; | |
} | |
template<class CharT, class Traits> | |
friend std::basic_istream<CharT,Traits>& | |
operator>>(std::basic_istream<CharT,Traits>& is, discard_block& s) | |
{ | |
is >> s._rng >> std::ws >> s._n >> std::ws; | |
return is; | |
} | |
#endif | |
friend bool operator==(const discard_block& x, const discard_block& y) | |
{ return x._rng == y._rng && x._n == y._n; } | |
friend bool operator!=(const discard_block& x, const discard_block& y) | |
{ return !(x == y); } | |
#else | |
// Use a member function; Streamable concept not supported. | |
bool operator==(const discard_block& rhs) const | |
{ return _rng == rhs._rng && _n == rhs._n; } | |
bool operator!=(const discard_block& rhs) const | |
{ return !(*this == rhs); } | |
#endif | |
private: | |
base_type _rng; | |
unsigned int _n; | |
}; | |
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION | |
// A definition is required even for integral static constants | |
template<class UniformRandomNumberGenerator, unsigned int p, unsigned int r> | |
const bool discard_block<UniformRandomNumberGenerator, p, r>::has_fixed_range; | |
template<class UniformRandomNumberGenerator, unsigned int p, unsigned int r> | |
const unsigned int discard_block<UniformRandomNumberGenerator, p, r>::total_block; | |
template<class UniformRandomNumberGenerator, unsigned int p, unsigned int r> | |
const unsigned int discard_block<UniformRandomNumberGenerator, p, r>::returned_block; | |
#endif | |
} // namespace random | |
} // namespace boost | |
#endif // BOOST_RANDOM_DISCARD_BLOCK_HPP |