From fd4efbb298c624e70a2737147fa7d47de226def6 Mon Sep 17 00:00:00 2001 From: Steven Watanabe Date: Thu, 7 Jul 2011 04:57:37 +0000 Subject: [PATCH] Merge [72825] and [72826] from the trunk. Authorized by Beman. [SVN r72951] --- .../boost/random/detail/generator_bits.hpp | 36 +++++++++++++++++++ include/boost/random/detail/seed_impl.hpp | 3 +- .../boost/random/detail/uniform_int_float.hpp | 5 ++- include/boost/random/discard_block.hpp | 34 ++++++++++++------ include/boost/random/generate_canonical.hpp | 3 +- include/boost/random/lagged_fibonacci.hpp | 29 +++++++++------ include/boost/random/subtract_with_carry.hpp | 27 ++++++++------ test/concepts.hpp | 11 ------ 8 files changed, 103 insertions(+), 45 deletions(-) create mode 100644 include/boost/random/detail/generator_bits.hpp diff --git a/include/boost/random/detail/generator_bits.hpp b/include/boost/random/detail/generator_bits.hpp new file mode 100644 index 0000000..0527614 --- /dev/null +++ b/include/boost/random/detail/generator_bits.hpp @@ -0,0 +1,36 @@ +/* boost random/detail/generator_bits.hpp header file + * + * Copyright Steven Watanabe 2011 + * 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$ + * + */ + +#ifndef BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP +#define BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP + +#include + +namespace boost { +namespace random { +namespace detail { + +// This is a temporary measure that retains backwards +// compatibility. +template +struct generator_bits { + static std::size_t value() { + return std::numeric_limits::digits; + } +}; + +} // namespace detail +} // namespace random +} // namespace boost + +#endif // BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP diff --git a/include/boost/random/detail/seed_impl.hpp b/include/boost/random/detail/seed_impl.hpp index 31b216f..aa58d05 100644 --- a/include/boost/random/detail/seed_impl.hpp +++ b/include/boost/random/detail/seed_impl.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -87,7 +88,7 @@ void generate_from_real(Engine& eng, Iter begin, Iter end) { using std::fmod; typedef typename Engine::result_type RealType; - const int Bits = Engine::precision(); + const int Bits = detail::generator_bits::value(); int remaining_bits = 0; boost::uint_least32_t saved_bits = 0; RealType multiplier = pow2( Bits); diff --git a/include/boost/random/detail/uniform_int_float.hpp b/include/boost/random/detail/uniform_int_float.hpp index f65abd2..393c455 100644 --- a/include/boost/random/detail/uniform_int_float.hpp +++ b/include/boost/random/detail/uniform_int_float.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -48,7 +49,9 @@ public: static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { std::size_t digits = std::numeric_limits::digits; - if(URNG::precision() < digits) digits = URNG::precision(); + if(detail::generator_bits::value() < digits) { + digits = detail::generator_bits::value(); + } return (result_type(2) << (digits - 1)) - 1; } base_type& base() { return _rng; } diff --git a/include/boost/random/discard_block.hpp b/include/boost/random/discard_block.hpp index 0c136e0..f4934a9 100644 --- a/include/boost/random/discard_block.hpp +++ b/include/boost/random/discard_block.hpp @@ -108,7 +108,12 @@ public: { if(_n >= returned_block) { // discard values of random number generator - _rng.discard(total_block - _n); + // Don't use discard, since we still need to + // be somewhat compatible with TR1. + // _rng.discard(total_block - _n); + for(std::size_t i = 0; i < total_block - _n; ++i) { + _rng(); + } _n = 0; } ++_n; @@ -139,16 +144,6 @@ public: static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return (base_type::max)(); } - /** - * INTERNAL ONLY - * Returns the number of random bits. - * This is not part of the standard, and I'm not sure that - * it's the best solution, but something like this is needed - * to implement generate_canonical. For now, mark it as - * an implementation detail. - */ - static std::size_t precision() { return base_type::precision(); } - #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS /** Writes a \discard_block_engine to a @c std::ostream. */ template @@ -221,6 +216,23 @@ public: /// \endcond +namespace detail { + + template + struct generator_bits; + + template + struct generator_bits > { + static std::size_t value() { return generator_bits::value(); } + }; + + template + struct generator_bits > { + static std::size_t value() { return generator_bits::value(); } + }; + +} + } // namespace random } // namespace boost diff --git a/include/boost/random/generate_canonical.hpp b/include/boost/random/generate_canonical.hpp index 752fc8c..88c2907 100644 --- a/include/boost/random/generate_canonical.hpp +++ b/include/boost/random/generate_canonical.hpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace boost { namespace random { @@ -56,7 +57,7 @@ RealType generate_canonical_impl(URNG& g, boost::mpl::false_ /*is_integral*/) BOOST_ASSERT((g.max)() == 1); typedef typename URNG::result_type base_result; std::size_t digits = std::numeric_limits::digits; - std::size_t engine_bits = g.precision(); + std::size_t engine_bits = detail::generator_bits::value(); std::size_t b = (std::min)(bits, digits); RealType R = pow(RealType(2), RealType(engine_bits)); RealType mult = R; diff --git a/include/boost/random/lagged_fibonacci.hpp b/include/boost/random/lagged_fibonacci.hpp index 87e9076..2f65088 100644 --- a/include/boost/random/lagged_fibonacci.hpp +++ b/include/boost/random/lagged_fibonacci.hpp @@ -324,16 +324,6 @@ public: /** Returns the upper bound of the generators outputs. */ static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return result_type(1); } - /** - * INTERNAL ONLY - * Returns the number of random bits. - * This is not part of the standard, and I'm not sure that - * it's the best solution, but something like this is needed - * to implement generate_canonical. For now, mark it as - * an implementation detail. - */ - static std::size_t precision() { return w; } - /** Returns the next value of the generator. */ result_type operator()() { @@ -466,6 +456,25 @@ public: /// \endcond +namespace detail { + +template +struct generator_bits; + +template +struct generator_bits > +{ + static std::size_t value() { return w; } +}; + +template +struct generator_bits > +{ + static std::size_t value() { return w; } +}; + +} + #ifdef BOOST_RANDOM_DOXYGEN namespace detail { /** diff --git a/include/boost/random/subtract_with_carry.hpp b/include/boost/random/subtract_with_carry.hpp index eed4b0a..e1061dd 100644 --- a/include/boost/random/subtract_with_carry.hpp +++ b/include/boost/random/subtract_with_carry.hpp @@ -427,16 +427,6 @@ public: static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return result_type(1); } - /** - * INTERNAL ONLY - * Returns the number of random bits. - * This is not part of the standard, and I'm not sure that - * it's the best solution, but something like this is needed - * to implement generate_canonical. For now, mark it as - * an implementation detail. - */ - static std::size_t precision() { return w; } - /** Returns the next value of the generator. */ result_type operator()() { @@ -600,6 +590,23 @@ public: /// \endcond +namespace detail { + +template +struct generator_bits; + +template +struct generator_bits > { + static std::size_t value() { return w; } +}; + +template +struct generator_bits > { + static std::size_t value() { return w; } +}; + +} + } // namespace random } // namespace boost diff --git a/test/concepts.hpp b/test/concepts.hpp index 52852e4..76c2e0f 100644 --- a/test/concepts.hpp +++ b/test/concepts.hpp @@ -130,8 +130,6 @@ public: same_type((E::min)(), result_type()); same_type((E::max)(), result_type()); - check_extra(boost::is_integral()); - (void)E(); (void)E(s); (void)E(q); @@ -154,15 +152,6 @@ private: seed_seq_archetype<> q; typename detail::seed_type::type s; unsigned long long z; - - void check_extra(boost::mpl::true_ /*is_integral*/) {} - - void check_extra(boost::mpl::false_ /*is_integral*/) - { - // This is an undocumented extension, but we still need - // to check for it. - same_type(E::precision(), std::size_t(0)); - } input_iterator_archetype sb, se; };