X-Git-Url: https://git.donarmstrong.com/?p=rsem.git;a=blobdiff_plain;f=boost%2Frandom%2Fxor_combine.hpp;h=d997a1c1a02eacaa0c24cee4cbf08fe6bf099432;hp=fb39490fba1e720912e00f351dc70fb838c54923;hb=2d71eb92104693ca9baa5a2e1c23eeca776d8fd3;hpb=a95154919f950f86de9104b2b9dcf1f0c7e83387 diff --git a/boost/random/xor_combine.hpp b/boost/random/xor_combine.hpp index fb39490..d997a1c 100644 --- a/boost/random/xor_combine.hpp +++ b/boost/random/xor_combine.hpp @@ -7,176 +7,199 @@ * * See http://www.boost.org for most recent version including documentation. * - * $Id: xor_combine.hpp 60755 2010-03-22 00:45:06Z steven_watanabe $ + * $Id: xor_combine.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $ * */ #ifndef BOOST_RANDOM_XOR_COMBINE_HPP #define BOOST_RANDOM_XOR_COMBINE_HPP -#include +#include +#include #include #include // for std::min and std::max #include #include -#include #include // uint32_t #include - +#include +#include namespace boost { namespace random { -/// \cond hide_private_members -#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS - #define BOOST_RANDOM_VAL_TYPE typename URNG1::result_type -#else - #define BOOST_RANDOM_VAL_TYPE uint32_t -#endif -/// \endcond - /** - * Instantiations of @c xor_combine model a \pseudo_random_number_generator. - * To produce its output it invokes each of the base generators, shifts - * their results and xors them together. + * Instantiations of @c xor_combine_engine model a + * \pseudo_random_number_generator. To produce its output it + * invokes each of the base generators, shifts their results + * and xors them together. */ -template -class xor_combine +template +class xor_combine_engine { public: - typedef URNG1 base1_type; - typedef URNG2 base2_type; - typedef typename base1_type::result_type result_type; - - BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); - BOOST_STATIC_CONSTANT(int, shift1 = s1); - BOOST_STATIC_CONSTANT(int, shift2 = s2); - - /** - * Constructors a @c xor_combine by default constructing - * both base generators. - */ - xor_combine() : _rng1(), _rng2() - { } - /** - * Constructs a @c xor_combine by copying two base generators. - */ - xor_combine(const base1_type & rng1, const base2_type & rng2) - : _rng1(rng1), _rng2(rng2) { } - /** - * Constructs a @c xor_combine, seeding both base generators - * with @c v. - */ - xor_combine(const result_type & v) - : _rng1(v), _rng2(v) { } - /** - * Constructs a @c xor_combine, seeding both base generators - * with values from the iterator range [first, last) and changes - * first to point to the element after the last one used. If there - * are not enough elements in the range to seed both generators, - * throws @c std::invalid_argument. - */ - template xor_combine(It& first, It last) - : _rng1(first, last), _rng2( /* advanced by other call */ first, last) { } - /** - * Calls @c seed() for both base generators. - */ - void seed() { _rng1.seed(); _rng2.seed(); } - /** - * @c seeds both base generators with @c v. - */ - void seed(const result_type & v) { _rng1.seed(v); _rng2.seed(v); } - /** - * seeds both base generators with values from the iterator - * range [first, last) and changes first to point to the element - * after the last one used. If there are not enough elements in - * the range to seed both generators, throws @c std::invalid_argument. - */ - template void seed(It& first, It last) - { - _rng1.seed(first, last); - _rng2.seed(first, last); - } - - /** Returns the first base generator. */ - const base1_type& base1() { return _rng1; } - /** Returns the second base generator. */ - const base2_type& base2() { return _rng2; } - - /** Returns the next value of the generator. */ - result_type operator()() - { - // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope -#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300) - BOOST_STATIC_ASSERT(std::numeric_limits::is_integer); - BOOST_STATIC_ASSERT(std::numeric_limits::is_integer); - BOOST_STATIC_ASSERT(std::numeric_limits::digits >= std::numeric_limits::digits); -#endif - return (_rng1() << s1) ^ (_rng2() << s2); - } - - /** - * Returns the smallest value that the generator can produce. - */ - result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::min BOOST_PREVENT_MACRO_SUBSTITUTION((_rng1.min)(), (_rng2.min)()); } - /** - * Returns the largest value that the generator can produce. - */ - result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::max BOOST_PREVENT_MACRO_SUBSTITUTION((_rng1.min)(), (_rng2.max)()); } - static bool validation(result_type x) { return val == x; } - -#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE - -#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS - template - friend std::basic_ostream& - operator<<(std::basic_ostream& os, const xor_combine& s) - { - os << s._rng1 << " " << s._rng2 << " "; - return os; - } - - template - friend std::basic_istream& - operator>>(std::basic_istream& is, xor_combine& s) - { - is >> s._rng1 >> std::ws >> s._rng2 >> std::ws; - return is; - } -#endif - - friend bool operator==(const xor_combine& x, const xor_combine& y) - { return x._rng1 == y._rng1 && x._rng2 == y._rng2; } - friend bool operator!=(const xor_combine& x, const xor_combine& y) - { return !(x == y); } -#else - // Use a member function; Streamable concept not supported. - bool operator==(const xor_combine& rhs) const - { return _rng1 == rhs._rng1 && _rng2 == rhs._rng2; } - bool operator!=(const xor_combine& rhs) const - { return !(*this == rhs); } -#endif + typedef URNG1 base1_type; + typedef URNG2 base2_type; + typedef typename base1_type::result_type result_type; + + BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); + BOOST_STATIC_CONSTANT(int, shift1 = s1); + BOOST_STATIC_CONSTANT(int, shift2 = s2); + + /** + * Constructors a @c xor_combine_engine by default constructing + * both base generators. + */ + xor_combine_engine() : _rng1(), _rng2() { } + + /** Constructs a @c xor_combine by copying two base generators. */ + xor_combine_engine(const base1_type & rng1, const base2_type & rng2) + : _rng1(rng1), _rng2(rng2) { } + + /** + * Constructs a @c xor_combine_engine, seeding both base generators + * with @c v. + * + * @xmlwarning + * The exact algorithm used by this function may change in the future. + * @endxmlwarning + */ + BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(xor_combine_engine, + result_type, v) + { seed(v); } + + /** + * Constructs a @c xor_combine_engine, seeding both base generators + * with values produced by @c seq. + */ + BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(xor_combine_engine, + SeedSeq, seq) + { seed(seq); } + + /** + * Constructs a @c xor_combine_engine, seeding both base generators + * with values from the iterator range [first, last) and changes + * first to point to the element after the last one used. If there + * are not enough elements in the range to seed both generators, + * throws @c std::invalid_argument. + */ + template xor_combine_engine(It& first, It last) + : _rng1(first, last), _rng2( /* advanced by other call */ first, last) { } + + /** Calls @c seed() for both base generators. */ + void seed() { _rng1.seed(); _rng2.seed(); } + + /** @c seeds both base generators with @c v. */ + BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(xor_combine_engine, result_type, v) + { _rng1.seed(v); _rng2.seed(v); } + + /** @c seeds both base generators with values produced by @c seq. */ + BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(xor_combine_engine, SeedSeq, seq) + { _rng1.seed(seq); _rng2.seed(seq); } + + /** + * seeds both base generators with values from the iterator + * range [first, last) and changes first to point to the element + * after the last one used. If there are not enough elements in + * the range to seed both generators, throws @c std::invalid_argument. + */ + template void seed(It& first, It last) + { + _rng1.seed(first, last); + _rng2.seed(first, last); + } + + /** Returns the first base generator. */ + const base1_type& base1() const { return _rng1; } + + /** Returns the second base generator. */ + const base2_type& base2() const { return _rng2; } + + /** Returns the next value of the generator. */ + result_type operator()() + { + return (_rng1() << s1) ^ (_rng2() << s2); + } + + /** Fills a range with random values */ + template + void generate(Iter first, Iter last) + { detail::generate_from_int(*this, first, last); } + + /** Advances the state of the generator by @c z. */ + void discard(boost::uintmax_t z) + { + _rng1.discard(z); + _rng2.discard(z); + } + + /** Returns the smallest value that the generator can produce. */ + static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return (std::min)((URNG1::min)(), (URNG2::min)()); } + /** Returns the largest value that the generator can produce. */ + static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return (std::max)((URNG1::min)(), (URNG2::max)()); } + + /** + * Writes the textual representation of the generator to a @c std::ostream. + */ + BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, xor_combine_engine, s) + { + os << s._rng1 << ' ' << s._rng2; + return os; + } + + /** + * Reads the textual representation of the generator from a @c std::istream. + */ + BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, xor_combine_engine, s) + { + is >> s._rng1 >> std::ws >> s._rng2; + return is; + } + + /** Returns true if the two generators will produce identical sequences. */ + BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(xor_combine_engine, x, y) + { return x._rng1 == y._rng1 && x._rng2 == y._rng2; } + + /** Returns true if the two generators will produce different sequences. */ + BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(xor_combine_engine) private: - base1_type _rng1; - base2_type _rng2; + base1_type _rng1; + base2_type _rng2; }; #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION // A definition is required even for integral static constants -template -const bool xor_combine::has_fixed_range; -template -const int xor_combine::shift1; -template -const int xor_combine::shift2; +template +const bool xor_combine_engine::has_fixed_range; +template +const int xor_combine_engine::shift1; +template +const int xor_combine_engine::shift2; #endif -#undef BOOST_RANDOM_VAL_TYPE +/// \cond show_private + +/** Provided for backwards compatibility. */ +template +class xor_combine : public xor_combine_engine +{ + typedef xor_combine_engine base_type; +public: + typedef typename base_type::result_type result_type; + xor_combine() {} + xor_combine(result_type val) : base_type(val) {} + template + xor_combine(It& first, It last) : base_type(first, last) {} + xor_combine(const URNG1 & rng1, const URNG2 & rng2) + : base_type(rng1, rng2) { } + + result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::min)((this->base1().min)(), (this->base2().min)()); } + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::max)((this->base1().min)(), (this->base2().max)()); } +}; + +/// \endcond } // namespace random } // namespace boost