- 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<class It> 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<class It> 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<typename base1_type::result_type>::is_integer);
- BOOST_STATIC_ASSERT(std::numeric_limits<typename base2_type::result_type>::is_integer);
- BOOST_STATIC_ASSERT(std::numeric_limits<typename base1_type::result_type>::digits >= std::numeric_limits<typename base2_type::result_type>::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<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const xor_combine& s)
- {
- os << s._rng1 << " " << s._rng2 << " ";
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& 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<class It> 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<class It> 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<class Iter>
+ 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)