diff -r b32e66a8708a -r 730a40ce2e78 boost/random.hpp --- a/boost/random.hpp Wed Jun 23 15:43:42 2010 -0700 +++ b/boost/random.hpp Sun Aug 29 04:34:19 2010 -0700 @@ -66,6 +66,7 @@ // distributions #include +#include #include #include #include diff -r b32e66a8708a -r 730a40ce2e78 boost/random/mersenne_twister.hpp --- a/boost/random/mersenne_twister.hpp Wed Jun 23 15:43:42 2010 -0700 +++ b/boost/random/mersenne_twister.hpp Sun Aug 29 04:34:19 2010 -0700 @@ -33,6 +33,28 @@ namespace boost { namespace random { +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +namespace detail { + +template +class mersenne_upper { + public: + typedef mersenne_upper type; + typedef vtype value_type; + static const vtype value = (1u << (w - 1)) | mersenne_upper::value; +}; + +template +class mersenne_upper { + public: + typedef mersenne_upper type; + typedef vtype value_type; + static const vtype value = 0; +}; + +} +#endif + /** * Instantiations of class template mersenne_twister model a * \pseudo_random_number_generator. It uses the algorithm described in @@ -79,7 +101,13 @@ BOOST_STATIC_CONSTANT(UIntType, output_c = c); BOOST_STATIC_CONSTANT(int, output_l = l); +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION + static const bool has_fixed_range = true; + static const result_type min_value = 0; + static const result_type max_value = detail::mersenne_upper::value; +#else BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); +#endif /** * Constructs a @c mersenne_twister and calls @c seed(). @@ -159,11 +187,15 @@ result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; } result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION + return max_value; +#else // avoid "left shift count >= with of type" warning result_type res = 0; for(int j = 0; j < w; ++j) res |= (1u << j); return res; +#endif } result_type operator()(); diff -r b32e66a8708a -r 730a40ce2e78 boost/random/uniform_staticint.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/boost/random/uniform_staticint.hpp Sun Aug 29 04:34:19 2010 -0700 @@ -0,0 +1,225 @@ +/* boost random/uniform_staticint.hpp header file + * + * Copyright Eric Hopper 2010 + * 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$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_RANDOM_UNIFORM_STATICINT_HPP +#define BOOST_RANDOM_UNIFORM_STATICINT_HPP + +namespace boost { + +namespace detail { + +namespace staticint { + +template +class int_log_recur { + public: + typedef int_log_recur type; + typedef unsigned long long value_type; + + private: + static const value_type remainder = val / base; + + public: + static const value_type value = 1 + int_log_recur< (base > remainder), remainder, base>::value; +}; + +template +class int_log_recur { + public: + typedef int_log_recur type; + typedef unsigned long long value_type; + static const value_type value = 0; +}; + +template +class int_log { + public: + typedef int_log type; + typedef unsigned long long value_type; + static const value_type value = int_log_recur< (base > val), val, base >::value; +}; + +template +class int_pow { + public: + typedef int_pow type; + typedef unsigned long long value_type; + static const value_type value = ((exp % 2) == 0) ? + int_pow::value : + (base * int_pow::value); +}; + +template +class int_pow { + public: + typedef int_pow type; + typedef unsigned long long value_type; + static const value_type value = base; +}; + +template +class int_pow { + public: + typedef int_pow type; + typedef unsigned long long value_type; + static const value_type value = 1; +}; + +//----------------generator parameters-------------- + +template +class generator_parameters_priv { + public: + static const unsigned int next_power = cur_power - 1; + static const unsigned long long cur_used_output = int_pow::value; + static const unsigned long long cur_discard_divide = possible_outputs / cur_used_output; + static const bool too_much_wastage = ((possible_outputs - cur_discard_divide * cur_used_output)) * max_wastage_ratio > possible_outputs; + + typedef generator_parameters_priv nextstep_t; + + static const unsigned int results_per_output = nextstep_t::results_per_output; + static const unsigned long long useful_ouputs = nextstep_t::useful_ouputs; + static const unsigned int discard_divide = nextstep_t::discard_divide; +}; + +//--- + +template +class generator_parameters_priv +{ + public: + static const unsigned long long cur_used_output = int_pow::value; + + static const unsigned int results_per_output = cur_power; + static const unsigned int discard_divide = possible_outputs / cur_used_output; + static const unsigned long long useful_ouputs = discard_divide * cur_used_output; +}; + +//--- + +template +class generator_parameters { + public: + static const unsigned int max_power = int_log::value; + static const unsigned long long used_output = int_pow::value; + static const unsigned long long min_divide = possible_outputs / used_output; + static const bool too_much_wastage = ((possible_outputs - min_divide * used_output)) * max_wastage_ratio > possible_outputs; + + typedef generator_parameters_priv< + max_power, modfield_size, possible_outputs, max_wastage_ratio, + (max_power < 2) || !too_much_wastage + > results_t; + + static const unsigned int results_per_output = results_t::results_per_output; + static const unsigned int discard_divide = results_t::discard_divide; + static const unsigned long long useful_ouputs = results_t::useful_ouputs; +}; + +} // namespace boost::detail::staticint + +} // namespace boost::detail + +template +class uniform_staticint { + private: + static const unsigned int max_wastage_ratio = 5; + BOOST_STATIC_ASSERT(Generator::has_fixed_range && + ((ULLONG_MAX / max_wastage_ratio) > + (Generator::max_value - Generator::min_value))); + BOOST_STATIC_ASSERT(((maxval - minval) + 1U) > (maxval - minval)); + BOOST_STATIC_ASSERT(((Generator::max_value - Generator::min_value) + 1ULL) > + (Generator::max_value - Generator::min_value)); + static const unsigned int value_field_size = (maxval - minval) + 1U; + typedef detail::staticint::generator_parameters< value_field_size, + ((Generator::max_value - + Generator::min_value) + + 1ULL), + max_wastage_ratio > + gen_params_t; + + public: + typedef unsigned int result_type; + typedef typename Generator::result_type input_type; + + uniform_staticint() : remaining_vals_(0) {} + + void reset() { remaining_vals_ = 0; } + + template + result_type operator ()(LocalGen &e) { + if (remaining_vals_ <= 0) { + BOOST_STATIC_ASSERT(LocalGen::has_fixed_range && ((LocalGen::max_value - LocalGen::min_value) == (Generator::max_value - Generator::min_value))); + typename LocalGen::result_type val = e() - LocalGen::min_value; + while (val >= gen_params_t::useful_ouputs) { + val = e() - LocalGen::min_value; + } + val /= gen_params_t::discard_divide; + for (unsigned int i = 0; i < gen_params_t::results_per_output; ++i) { + vals_[i] = (val % value_field_size) + minval; + val /= value_field_size; + } + remaining_vals_ = gen_params_t::results_per_output; + } + return vals_[gen_params_t::results_per_output - (remaining_vals_--)] + minval; + } + +#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_staticint& ud) + { + os << ud.remaining_vals_; + for (unsigned int i = 0; i < gen_params_t::results_per_output; ++i) { + os << ' ' << ud.vals_[i]; + } + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, uniform_staticint& ud) + { + is >> std::ws >> ud.remaining_vals_; + for (unsigned int i = 0; i < gen_params_t::results_per_output; ++i) { + is >> std::ws >> ud.vals_[i]; + } + return is; + } +#endif + + private: + unsigned int vals_[gen_params_t::results_per_output]; + unsigned int remaining_vals_; +}; + +} // namespace boost + +#endif