diff options
author | Remko Tronçon <git@el-tramo.be> | 2012-12-23 13:16:26 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2012-12-23 14:43:26 (GMT) |
commit | 491ddd570a752cf9bda85933bed0c6942e39b1f9 (patch) | |
tree | 10c25c1be8cc08d0497df1dccd56a10fbb30beee /3rdParty/Boost/src/boost/random/detail | |
parent | da7d7a0ca71b80281aa9ff2526290b61ccb0cc60 (diff) | |
download | swift-491ddd570a752cf9bda85933bed0c6942e39b1f9.zip swift-491ddd570a752cf9bda85933bed0c6942e39b1f9.tar.bz2 |
Update Boost to 1.52.0.
Change-Id: I1e56bea2600bf2ed9c5b3aba8c4f9d2a0f350e77
Diffstat (limited to '3rdParty/Boost/src/boost/random/detail')
11 files changed, 936 insertions, 404 deletions
diff --git a/3rdParty/Boost/src/boost/random/detail/const_mod.hpp b/3rdParty/Boost/src/boost/random/detail/const_mod.hpp index e0a8839..9778f55 100644 --- a/3rdParty/Boost/src/boost/random/detail/const_mod.hpp +++ b/3rdParty/Boost/src/boost/random/detail/const_mod.hpp @@ -7,7 +7,7 @@ * * See http://www.boost.org for most recent version including documentation. * - * $Id: const_mod.hpp 58649 2010-01-02 21:23:17Z steven_watanabe $ + * $Id: const_mod.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $ * * Revision history * 2001-02-18 moved to individual header files @@ -16,113 +16,101 @@ #ifndef BOOST_RANDOM_CONST_MOD_HPP #define BOOST_RANDOM_CONST_MOD_HPP -#include <cassert> +#include <boost/assert.hpp> #include <boost/static_assert.hpp> -#include <boost/cstdint.hpp> #include <boost/integer_traits.hpp> -#include <boost/detail/workaround.hpp> +#include <boost/type_traits/make_unsigned.hpp> +#include <boost/random/detail/large_arithmetic.hpp> #include <boost/random/detail/disable_warnings.hpp> namespace boost { namespace random { -/* - * Some random number generators require modular arithmetic. Put - * everything we need here. - * IntType must be an integral type. - */ - -namespace detail { - - template<bool is_signed> - struct do_add - { }; - - template<> - struct do_add<true> - { - template<class IntType> - static IntType add(IntType m, IntType x, IntType c) - { - if (x < m - c) - return x + c; - else - return x - (m-c); - } - }; - - template<> - struct do_add<false> - { - template<class IntType> - static IntType add(IntType, IntType, IntType) - { - // difficult - assert(!"const_mod::add with c too large"); - return 0; - } - }; -} // namespace detail - -#if !(defined(__BORLANDC__) && (__BORLANDC__ == 0x560)) - template<class IntType, IntType m> class const_mod { public: + static IntType apply(IntType x) + { + if(((unsigned_m() - 1) & unsigned_m()) == 0) + return (unsigned_type(x)) & (unsigned_m() - 1); + else { + IntType supress_warnings = (m == 0); + BOOST_ASSERT(supress_warnings == 0); + return x % (m + supress_warnings); + } + } + static IntType add(IntType x, IntType c) { - if(c == 0) + if(((unsigned_m() - 1) & unsigned_m()) == 0) + return (unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1); + else if(c == 0) return x; - else if(c <= traits::const_max - m) // i.e. m+c < max - return add_small(x, c); + else if(x < m - c) + return x + c; else - return detail::do_add<traits::is_signed>::add(m, x, c); + return x - (m - c); } static IntType mult(IntType a, IntType x) { - if(a == 1) + if(((unsigned_m() - 1) & unsigned_m()) == 0) + return unsigned_type(a) * unsigned_type(x) & (unsigned_m() - 1); + else if(a == 0) + return 0; + else if(a == 1) return x; else if(m <= traits::const_max/a) // i.e. a*m <= max return mult_small(a, x); else if(traits::is_signed && (m%a < m/a)) return mult_schrage(a, x); - else { - // difficult - assert(!"const_mod::mult with a too large"); - return 0; - } + else + return mult_general(a, x); } static IntType mult_add(IntType a, IntType x, IntType c) { - if(m <= (traits::const_max-c)/a) // i.e. a*m+c <= max - return (a*x+c) % m; - else + if(((unsigned_m() - 1) & unsigned_m()) == 0) + return (unsigned_type(a) * unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1); + else if(a == 0) + return c; + else if(m <= (traits::const_max-c)/a) { // i.e. a*m+c <= max + IntType supress_warnings = (m == 0); + BOOST_ASSERT(supress_warnings == 0); + return (a*x+c) % (m + supress_warnings); + } else return add(mult(a, x), c); } + static IntType pow(IntType a, boost::uintmax_t exponent) + { + IntType result = 1; + while(exponent != 0) { + if(exponent % 2 == 1) { + result = mult(result, a); + } + a = mult(a, a); + exponent /= 2; + } + return result; + } + static IntType invert(IntType x) - { return x == 0 ? 0 : invert_euclidian(x); } + { return x == 0 ? 0 : (m == 0? invert_euclidian0(x) : invert_euclidian(x)); } private: typedef integer_traits<IntType> traits; + typedef typename make_unsigned<IntType>::type unsigned_type; const_mod(); // don't instantiate - static IntType add_small(IntType x, IntType c) - { - x += c; - if(x >= m) - x -= m; - return x; - } - static IntType mult_small(IntType a, IntType x) { - return a*x % m; + IntType supress_warnings = (m == 0); + BOOST_ASSERT(supress_warnings == 0); + return a*x % (m + supress_warnings); } static IntType mult_schrage(IntType a, IntType value) @@ -130,231 +118,96 @@ private: const IntType q = m / a; const IntType r = m % a; - assert(r < q); // check that overflow cannot happen + BOOST_ASSERT(r < q); // check that overflow cannot happen - value = a*(value%q) - r*(value/q); - // An optimizer bug in the SGI MIPSpro 7.3.1.x compiler requires this - // convoluted formulation of the loop (Synge Todo) - for(;;) { - if (value > 0) - break; - value += m; + return sub(a*(value%q), r*(value/q)); + } + + static IntType mult_general(IntType a, IntType b) + { + IntType suppress_warnings = (m == 0); + BOOST_ASSERT(suppress_warnings == 0); + IntType modulus = m + suppress_warnings; + BOOST_ASSERT(modulus == m); + if(::boost::uintmax_t(modulus) <= + (::std::numeric_limits< ::boost::uintmax_t>::max)() / modulus) + { + return static_cast<IntType>(boost::uintmax_t(a) * b % modulus); + } else { + return static_cast<IntType>(detail::mulmod(a, b, modulus)); } - return value; + } + + static IntType sub(IntType a, IntType b) + { + if(a < b) + return m - (b - a); + else + return a - b; + } + + static unsigned_type unsigned_m() + { + if(m == 0) { + return unsigned_type((std::numeric_limits<IntType>::max)()) + 1; + } else { + return unsigned_type(m); + } } // invert c in the finite field (mod m) (m must be prime) static IntType invert_euclidian(IntType c) { // we are interested in the gcd factor for c, because this is our inverse - BOOST_STATIC_ASSERT(m > 0); -#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) - assert(boost::integer_traits<IntType>::is_signed); -#elif !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) - BOOST_STATIC_ASSERT(boost::integer_traits<IntType>::is_signed); -#endif - assert(c > 0); + BOOST_ASSERT(c > 0); IntType l1 = 0; IntType l2 = 1; IntType n = c; IntType p = m; for(;;) { IntType q = p / n; - l1 -= q * l2; // this requires a signed IntType! + l1 += q * l2; p -= q * n; if(p == 0) - return (l2 < 1 ? l2 + m : l2); + return l2; IntType q2 = n / p; - l2 -= q2 * l1; + l2 += q2 * l1; n -= q2 * p; if(n == 0) - return (l1 < 1 ? l1 + m : l1); + return m - l1; } } -}; - -// The modulus is exactly the word size: rely on machine overflow handling. -// Due to a GCC bug, we cannot partially specialize in the presence of -// template value parameters. -template<> -class const_mod<unsigned int, 0> -{ - typedef unsigned int IntType; -public: - static IntType add(IntType x, IntType c) { return x+c; } - static IntType mult(IntType a, IntType x) { return a*x; } - static IntType mult_add(IntType a, IntType x, IntType c) { return a*x+c; } - - // m is not prime, thus invert is not useful -private: // don't instantiate - const_mod(); -}; - -template<> -class const_mod<unsigned long, 0> -{ - typedef unsigned long IntType; -public: - static IntType add(IntType x, IntType c) { return x+c; } - static IntType mult(IntType a, IntType x) { return a*x; } - static IntType mult_add(IntType a, IntType x, IntType c) { return a*x+c; } - - // m is not prime, thus invert is not useful -private: // don't instantiate - const_mod(); -}; - -// the modulus is some power of 2: rely partly on machine overflow handling -// we only specialize for rand48 at the moment -#ifndef BOOST_NO_INT64_T -template<> -class const_mod<uint64_t, uint64_t(1) << 48> -{ - typedef uint64_t IntType; -public: - static IntType add(IntType x, IntType c) { return c == 0 ? x : mod(x+c); } - static IntType mult(IntType a, IntType x) { return mod(a*x); } - static IntType mult_add(IntType a, IntType x, IntType c) - { return mod(a*x+c); } - static IntType mod(IntType x) { return x &= ((uint64_t(1) << 48)-1); } - - // m is not prime, thus invert is not useful -private: // don't instantiate - const_mod(); -}; -#endif /* !BOOST_NO_INT64_T */ - -#else - -// -// for some reason Borland C++ Builder 6 has problems with -// the full specialisations of const_mod, define a generic version -// instead, the compiler will optimise away the const-if statements: -// -template<class IntType, IntType m> -class const_mod -{ -public: - static IntType add(IntType x, IntType c) - { - if(0 == m) - { - return x+c; - } - else - { - if(c == 0) - return x; - else if(c <= traits::const_max - m) // i.e. m+c < max - return add_small(x, c); - else - return detail::do_add<traits::is_signed>::add(m, x, c); - } - } - - static IntType mult(IntType a, IntType x) - { - if(x == 0) - { - return a*x; - } - else - { - if(a == 1) - return x; - else if(m <= traits::const_max/a) // i.e. a*m <= max - return mult_small(a, x); - else if(traits::is_signed && (m%a < m/a)) - return mult_schrage(a, x); - else { - // difficult - assert(!"const_mod::mult with a too large"); - return 0; - } - } - } - - static IntType mult_add(IntType a, IntType x, IntType c) - { - if(m == 0) - { - return a*x+c; - } - else - { - if(m <= (traits::const_max-c)/a) // i.e. a*m+c <= max - return (a*x+c) % m; - else - return add(mult(a, x), c); - } - } - - static IntType invert(IntType x) - { return x == 0 ? 0 : invert_euclidian(x); } - -private: - typedef integer_traits<IntType> traits; - - const_mod(); // don't instantiate - - static IntType add_small(IntType x, IntType c) - { - x += c; - if(x >= m) - x -= m; - return x; - } - - static IntType mult_small(IntType a, IntType x) - { - return a*x % m; - } - - static IntType mult_schrage(IntType a, IntType value) - { - const IntType q = m / a; - const IntType r = m % a; - - assert(r < q); // check that overflow cannot happen - - value = a*(value%q) - r*(value/q); - while(value <= 0) - value += m; - return value; - } - - // invert c in the finite field (mod m) (m must be prime) - static IntType invert_euclidian(IntType c) + // invert c in the finite field (mod m) (c must be relatively prime to m) + static IntType invert_euclidian0(IntType c) { // we are interested in the gcd factor for c, because this is our inverse - BOOST_STATIC_ASSERT(m > 0); -#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS - BOOST_STATIC_ASSERT(boost::integer_traits<IntType>::is_signed); -#endif - assert(c > 0); + BOOST_ASSERT(c > 0); + if(c == 1) return 1; IntType l1 = 0; IntType l2 = 1; IntType n = c; IntType p = m; + IntType max = (std::numeric_limits<IntType>::max)(); + IntType q = max / n; + BOOST_ASSERT(max % n != n - 1 && "c must be relatively prime to m."); + l1 += q * l2; + p = max - q * n + 1; for(;;) { - IntType q = p / n; - l1 -= q * l2; // this requires a signed IntType! - p -= q * n; if(p == 0) - return (l2 < 1 ? l2 + m : l2); + return l2; IntType q2 = n / p; - l2 -= q2 * l1; + l2 += q2 * l1; n -= q2 * p; if(n == 0) - return (l1 < 1 ? l1 + m : l1); + return m - l1; + q = p / n; + l1 += q * l2; + p -= q * n; } } }; - -#endif - } // namespace random } // namespace boost diff --git a/3rdParty/Boost/src/boost/random/detail/generator_bits.hpp b/3rdParty/Boost/src/boost/random/detail/generator_bits.hpp new file mode 100644 index 0000000..44b4248 --- /dev/null +++ b/3rdParty/Boost/src/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: generator_bits.hpp 72951 2011-07-07 04:57:37Z steven_watanabe $ + * + */ + +#ifndef BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP +#define BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP + +#include <boost/limits.hpp> + +namespace boost { +namespace random { +namespace detail { + +// This is a temporary measure that retains backwards +// compatibility. +template<class URNG> +struct generator_bits { + static std::size_t value() { + return std::numeric_limits<typename URNG::result_type>::digits; + } +}; + +} // namespace detail +} // namespace random +} // namespace boost + +#endif // BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP diff --git a/3rdParty/Boost/src/boost/random/detail/generator_seed_seq.hpp b/3rdParty/Boost/src/boost/random/detail/generator_seed_seq.hpp new file mode 100644 index 0000000..6aaf98f --- /dev/null +++ b/3rdParty/Boost/src/boost/random/detail/generator_seed_seq.hpp @@ -0,0 +1,40 @@ +/* boost random/mersenne_twister.hpp header file + * + * Copyright Jens Maurer 2000-2001 + * Copyright Steven Watanabe 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: generator_seed_seq.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $ + * + */ + +#ifndef BOOST_RANDOM_DETAIL_GENERATOR_SEED_SEQ_HPP_INCLUDED +#define BOOST_RANDOM_DETAIL_GENERATOR_SEED_SEQ_HPP_INCLUDED + +namespace boost { +namespace random { +namespace detail { + +template<class Generator> +class generator_seed_seq { +public: + generator_seed_seq(Generator& g) : gen(&g) {} + template<class It> + void generate(It first, It last) { + for(; first != last; ++first) { + *first = (*gen)(); + } + } +private: + Generator* gen; +}; + +} +} +} + +#endif diff --git a/3rdParty/Boost/src/boost/random/detail/integer_log2.hpp b/3rdParty/Boost/src/boost/random/detail/integer_log2.hpp new file mode 100644 index 0000000..baee426 --- /dev/null +++ b/3rdParty/Boost/src/boost/random/detail/integer_log2.hpp @@ -0,0 +1,84 @@ +/* boost random/detail/integer_log2.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: integer_log2.hpp 76145 2011-12-24 19:05:17Z danieljames $ + * + */ + +#ifndef BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP +#define BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP + +#include <boost/config.hpp> +#include <boost/limits.hpp> +#include <boost/pending/integer_log2.hpp> + +namespace boost { +namespace random { +namespace detail { + +#if !defined(BOOST_NO_CONSTEXPR) +#define BOOST_RANDOM_DETAIL_CONSTEXPR constexpr +#elif defined(BOOST_MSVC) +#define BOOST_RANDOM_DETAIL_CONSTEXPR __forceinline +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define BOOST_RANDOM_DETAIL_CONSTEXPR __attribute__((const)) __attribute__((always_inline)) +#else +#define BOOST_RANDOM_DETAIL_CONSTEXPR inline +#endif + +template<int Shift> +struct integer_log2_impl +{ +#if defined(BOOST_NO_CONSTEXPR) + template<class T> + BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum) + { + int update = ((t >> Shift) != 0) * Shift; + return integer_log2_impl<Shift / 2>::apply(t >> update, accum + update); + } +#else + template<class T> + BOOST_RANDOM_DETAIL_CONSTEXPR static int apply2(T t, int accum, int update) + { + return integer_log2_impl<Shift / 2>::apply(t >> update, accum + update); + } + + template<class T> + BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum) + { + return apply2(t, accum, ((t >> Shift) != 0) * Shift); + } +#endif +}; + +template<> +struct integer_log2_impl<1> +{ + template<class T> + BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum) + { + return int(t >> 1) + accum; + } +}; + +template<class T> +BOOST_RANDOM_DETAIL_CONSTEXPR int integer_log2(T t) +{ + return integer_log2_impl< + ::boost::detail::max_pow2_less< + ::std::numeric_limits<T>::digits, 4 + >::value + >::apply(t, 0); +} + +} // namespace detail +} // namespace random +} // namespace boost + +#endif // BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP diff --git a/3rdParty/Boost/src/boost/random/detail/large_arithmetic.hpp b/3rdParty/Boost/src/boost/random/detail/large_arithmetic.hpp new file mode 100644 index 0000000..24177dc --- /dev/null +++ b/3rdParty/Boost/src/boost/random/detail/large_arithmetic.hpp @@ -0,0 +1,122 @@ +/* boost random/detail/large_arithmetic.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: large_arithmetic.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $ + */ + +#ifndef BOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP +#define BOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP + +#include <boost/cstdint.hpp> +#include <boost/integer.hpp> +#include <boost/limits.hpp> +#include <boost/random/detail/integer_log2.hpp> + +#include <boost/random/detail/disable_warnings.hpp> + +namespace boost { +namespace random { +namespace detail { + +struct div_t { + boost::uintmax_t quotient; + boost::uintmax_t remainder; +}; + +inline div_t muldivmod(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m) +{ + static const int bits = + ::std::numeric_limits< ::boost::uintmax_t>::digits / 2; + static const ::boost::uintmax_t mask = (::boost::uintmax_t(1) << bits) - 1; + typedef ::boost::uint_t<bits>::fast digit_t; + + int shift = std::numeric_limits< ::boost::uintmax_t>::digits - 1 + - detail::integer_log2(m); + + a <<= shift; + m <<= shift; + + digit_t product[4] = { 0, 0, 0, 0 }; + digit_t a_[2] = { digit_t(a & mask), digit_t((a >> bits) & mask) }; + digit_t b_[2] = { digit_t(b & mask), digit_t((b >> bits) & mask) }; + digit_t m_[2] = { digit_t(m & mask), digit_t((m >> bits) & mask) }; + + // multiply a * b + for(int i = 0; i < 2; ++i) { + digit_t carry = 0; + for(int j = 0; j < 2; ++j) { + ::boost::uint64_t temp = ::boost::uintmax_t(a_[i]) * b_[j] + + carry + product[i + j]; + product[i + j] = digit_t(temp & mask); + carry = digit_t(temp >> bits); + } + if(carry != 0) { + product[i + 2] += carry; + } + } + + digit_t quotient[2]; + + if(m == 0) { + div_t result = { + ((::boost::uintmax_t(product[3]) << bits) | product[2]), + ((::boost::uintmax_t(product[1]) << bits) | product[0]) >> shift, + }; + return result; + } + + // divide product / m + for(int i = 3; i >= 2; --i) { + ::boost::uintmax_t temp = + ::boost::uintmax_t(product[i]) << bits | product[i - 1]; + + digit_t q = digit_t((product[i] == m_[1]) ? mask : temp / m_[1]); + + ::boost::uintmax_t rem = + ((temp - ::boost::uintmax_t(q) * m_[1]) << bits) + product[i - 2]; + + ::boost::uintmax_t diff = m_[0] * ::boost::uintmax_t(q); + + int error = 0; + if(diff > rem) { + if(diff - rem > m) { + error = 2; + } else { + error = 1; + } + } + q -= error; + rem = rem + error * m - diff; + + quotient[i - 2] = q; + product[i] = 0; + product[i-1] = (rem >> bits) & mask; + product[i-2] = rem & mask; + } + + div_t result = { + ((::boost::uintmax_t(quotient[1]) << bits) | quotient[0]), + ((::boost::uintmax_t(product[1]) << bits) | product[0]) >> shift, + }; + return result; +} + +inline boost::uintmax_t muldiv(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m) +{ return detail::muldivmod(a, b, m).quotient; } + +inline boost::uintmax_t mulmod(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m) +{ return detail::muldivmod(a, b, m).remainder; } + +} // namespace detail +} // namespace random +} // namespace boost + +#include <boost/random/detail/enable_warnings.hpp> + +#endif // BOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP diff --git a/3rdParty/Boost/src/boost/random/detail/operators.hpp b/3rdParty/Boost/src/boost/random/detail/operators.hpp new file mode 100644 index 0000000..f27839a --- /dev/null +++ b/3rdParty/Boost/src/boost/random/detail/operators.hpp @@ -0,0 +1,84 @@ +/* boost random/detail/operators.hpp header file + * + * Copyright Steven Watanabe 2010-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: operators.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $ + */ + +#ifndef BOOST_RANDOM_DETAIL_OPERATORS_HPP +#define BOOST_RANDOM_DETAIL_OPERATORS_HPP + +#include <boost/random/detail/config.hpp> +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) \ + || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) + +#define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \ + template<class CharT, class Traits> \ + friend std::basic_ostream<CharT,Traits>& \ + operator<<(std::basic_ostream<CharT,Traits>& os, const T& t) { \ + t.print(os, t); \ + return os; \ + } \ + template<class CharT, class Traits> \ + static std::basic_ostream<CharT,Traits>& \ + print(std::basic_ostream<CharT,Traits>& os, const T& t) + +#define BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t) \ + template<class CharT, class Traits> \ + friend std::basic_istream<CharT,Traits>& \ + operator>>(std::basic_istream<CharT,Traits>& is, T& t) { \ + t.read(is, t); \ + return is; \ + } \ + template<class CharT, class Traits> \ + static std::basic_istream<CharT,Traits>& \ + read(std::basic_istream<CharT,Traits>& is, T& t) + +#endif + +#if defined(__BORLANDC__) + +#define BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs) \ + bool operator==(const T& rhs) const \ + { return T::is_equal(*this, rhs); } \ + static bool is_equal(const T& lhs, const T& rhs) + +#define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \ + bool operator!=(const T& rhs) const \ + { return !T::is_equal(*this, rhs); } + +#endif + +#ifndef BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR +#define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \ + template<class CharT, class Traits> \ + friend std::basic_ostream<CharT,Traits>& \ + operator<<(std::basic_ostream<CharT,Traits>& os, const T& t) +#endif + +#ifndef BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR +#define BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t) \ + template<class CharT, class Traits> \ + friend std::basic_istream<CharT,Traits>& \ + operator>>(std::basic_istream<CharT,Traits>& is, T& t) +#endif + +#ifndef BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR +#define BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs) \ + friend bool operator==(const T& lhs, const T& rhs) +#endif + +#ifndef BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR +#define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \ + friend bool operator!=(const T& lhs, const T& rhs) \ + { return !(lhs == rhs); } +#endif + +#endif diff --git a/3rdParty/Boost/src/boost/random/detail/pass_through_engine.hpp b/3rdParty/Boost/src/boost/random/detail/pass_through_engine.hpp deleted file mode 100644 index 468427c..0000000 --- a/3rdParty/Boost/src/boost/random/detail/pass_through_engine.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/* boost random/detail/uniform_int_float.hpp header file - * - * Copyright Jens Maurer 2000-2001 - * 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: pass_through_engine.hpp 58649 2010-01-02 21:23:17Z steven_watanabe $ - * - */ - -#ifndef BOOST_RANDOM_DETAIL_PASS_THROUGH_ENGINE_HPP -#define BOOST_RANDOM_DETAIL_PASS_THROUGH_ENGINE_HPP - -#include <boost/config.hpp> -#include <boost/random/detail/ptr_helper.hpp> -#include <boost/random/detail/disable_warnings.hpp> - -namespace boost { -namespace random { -namespace detail { - -template<class UniformRandomNumberGenerator> -class pass_through_engine -{ -private: - typedef ptr_helper<UniformRandomNumberGenerator> helper_type; - -public: - typedef typename helper_type::value_type base_type; - typedef typename base_type::result_type result_type; - - explicit pass_through_engine(UniformRandomNumberGenerator rng) - // make argument an rvalue to avoid matching Generator& constructor - : _rng(static_cast<typename helper_type::rvalue_type>(rng)) - { } - - result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (base().min)(); } - result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (base().max)(); } - base_type& base() { return helper_type::ref(_rng); } - const base_type& base() const { return helper_type::ref(_rng); } - - result_type operator()() { return base()(); } - -private: - UniformRandomNumberGenerator _rng; -}; - -#ifndef BOOST_NO_STD_LOCALE - -template<class UniformRandomNumberGenerator, class CharT, class Traits> -std::basic_ostream<CharT,Traits>& -operator<<( - std::basic_ostream<CharT,Traits>& os - , const pass_through_engine<UniformRandomNumberGenerator>& ud - ) -{ - return os << ud.base(); -} - -template<class UniformRandomNumberGenerator, class CharT, class Traits> -std::basic_istream<CharT,Traits>& -operator>>( - std::basic_istream<CharT,Traits>& is - , const pass_through_engine<UniformRandomNumberGenerator>& ud - ) -{ - return is >> ud.base(); -} - -#else // no new streams - -template<class UniformRandomNumberGenerator> -inline std::ostream& -operator<<(std::ostream& os, - const pass_through_engine<UniformRandomNumberGenerator>& ud) -{ - return os << ud.base(); -} - -template<class UniformRandomNumberGenerator> -inline std::istream& -operator>>(std::istream& is, - const pass_through_engine<UniformRandomNumberGenerator>& ud) -{ - return is >> ud.base(); -} - -#endif - -} // namespace detail -} // namespace random -} // namespace boost - -#include <boost/random/detail/enable_warnings.hpp> - -#endif // BOOST_RANDOM_DETAIL_PASS_THROUGH_ENGINE_HPP - diff --git a/3rdParty/Boost/src/boost/random/detail/seed.hpp b/3rdParty/Boost/src/boost/random/detail/seed.hpp index 48cc17e..979db29 100644 --- a/3rdParty/Boost/src/boost/random/detail/seed.hpp +++ b/3rdParty/Boost/src/boost/random/detail/seed.hpp @@ -7,7 +7,7 @@ * * See http://www.boost.org for most recent version including documentation. * - * $Id: seed.hpp 60755 2010-03-22 00:45:06Z steven_watanabe $ + * $Id: seed.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $ */ #ifndef BOOST_RANDOM_DETAIL_SEED_HPP @@ -43,12 +43,19 @@ struct disable_constructor<Engine, Engine> {}; template<class Generator> \ void seed(Generator& gen, typename ::boost::random::detail::disable_seed<Generator>::type* = 0) +#define BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self, SeedSeq, seq) \ + template<class SeedSeq> \ + explicit Self(SeedSeq& seq, typename ::boost::random::detail::disable_constructor<Self, SeedSeq>::type* = 0) + +#define BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self, SeedSeq, seq) \ + template<class SeedSeq> \ + void seed(SeedSeq& seq, typename ::boost::random::detail::disable_seed<SeedSeq>::type* = 0) + #define BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self, T, x) \ explicit Self(const T& x) #define BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(Self, T, x) \ void seed(const T& x) - } } } @@ -76,6 +83,24 @@ struct disable_constructor<Engine, Engine> {}; template<class Generator>\ void boost_random_seed_impl(Generator& gen, ::boost::mpl::false_) +#define BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self, SeedSeq, seq) \ + Self(Self& other) { *this = other; } \ + Self(const Self& other) { *this = other; } \ + template<class SeedSeq> \ + explicit Self(SeedSeq& seq) { \ + boost_random_constructor_impl(seq, ::boost::is_arithmetic<SeedSeq>());\ + } \ + template<class SeedSeq> \ + void boost_random_constructor_impl(SeedSeq& seq, ::boost::mpl::false_) + +#define BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self, SeedSeq, seq) \ + template<class SeedSeq> \ + void seed(SeedSeq& seq) { \ + boost_random_seed_impl(seq, ::boost::is_arithmetic<SeedSeq>()); \ + } \ + template<class SeedSeq> \ + void boost_random_seed_impl(SeedSeq& seq, ::boost::mpl::false_) + #define BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self, T, x) \ explicit Self(const T& x) { boost_random_constructor_impl(x, ::boost::mpl::true_()); }\ void boost_random_constructor_impl(const T& x, ::boost::mpl::true_) diff --git a/3rdParty/Boost/src/boost/random/detail/seed_impl.hpp b/3rdParty/Boost/src/boost/random/detail/seed_impl.hpp new file mode 100644 index 0000000..e044d45 --- /dev/null +++ b/3rdParty/Boost/src/boost/random/detail/seed_impl.hpp @@ -0,0 +1,397 @@ +/* boost random/detail/seed.hpp header file + * + * Copyright Steven Watanabe 2009 + * 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: seed_impl.hpp 72951 2011-07-07 04:57:37Z steven_watanabe $ + */ + +#ifndef BOOST_RANDOM_DETAIL_SEED_IMPL_HPP +#define BOOST_RANDOM_DETAIL_SEED_IMPL_HPP + +#include <stdexcept> +#include <boost/cstdint.hpp> +#include <boost/config/no_tr1/cmath.hpp> +#include <boost/integer/integer_mask.hpp> +#include <boost/integer/static_log2.hpp> +#include <boost/type_traits/is_signed.hpp> +#include <boost/type_traits/is_integral.hpp> +#include <boost/type_traits/make_unsigned.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/int.hpp> +#include <boost/random/detail/const_mod.hpp> +#include <boost/random/detail/integer_log2.hpp> +#include <boost/random/detail/signed_unsigned_tools.hpp> +#include <boost/random/detail/generator_bits.hpp> + +#include <boost/random/detail/disable_warnings.hpp> + +namespace boost { +namespace random { +namespace detail { + +// finds the seed type of an engine, given its +// result_type. If the result_type is integral +// the seed type is the same. If the result_type +// is floating point, the seed type is uint32_t +template<class T> +struct seed_type +{ + typedef typename boost::mpl::if_<boost::is_integral<T>, + T, + boost::uint32_t + >::type type; +}; + +template<int N> +struct const_pow_impl +{ + template<class T> + static T call(T arg, int n, T result) + { + return const_pow_impl<N / 2>::call(arg * arg, n / 2, + n%2 == 0? result : result * arg); + } +}; + +template<> +struct const_pow_impl<0> +{ + template<class T> + static T call(T, int, T result) + { + return result; + } +}; + +// requires N is an upper bound on n +template<int N, class T> +inline T const_pow(T arg, int n) { return const_pow_impl<N>::call(arg, n, T(1)); } + +template<class T> +inline T pow2(int n) +{ + typedef unsigned int_type; + const int max_bits = std::numeric_limits<int_type>::digits; + T multiplier = T(int_type(1) << (max_bits - 1)) * 2; + return (int_type(1) << (n % max_bits)) * + const_pow<std::numeric_limits<T>::digits / max_bits>(multiplier, n / max_bits); +} + +template<class Engine, class Iter> +void generate_from_real(Engine& eng, Iter begin, Iter end) +{ + using std::fmod; + typedef typename Engine::result_type RealType; + const int Bits = detail::generator_bits<Engine>::value(); + int remaining_bits = 0; + boost::uint_least32_t saved_bits = 0; + RealType multiplier = pow2<RealType>( Bits); + RealType mult32 = RealType(4294967296.0); // 2^32 + while(true) { + RealType val = eng() * multiplier; + int available_bits = Bits; + // Make sure the compiler can optimize this out + // if it isn't possible. + if(Bits < 32 && available_bits < 32 - remaining_bits) { + saved_bits |= boost::uint_least32_t(val) << remaining_bits; + remaining_bits += Bits; + } else { + // If Bits < 32, then remaining_bits != 0, since + // if remaining_bits == 0, available_bits < 32 - 0, + // and we won't get here to begin with. + if(Bits < 32 || remaining_bits != 0) { + boost::uint_least32_t divisor = + (boost::uint_least32_t(1) << (32 - remaining_bits)); + boost::uint_least32_t extra_bits = boost::uint_least32_t(fmod(val, mult32)) & (divisor - 1); + val = val / divisor; + *begin++ = saved_bits | (extra_bits << remaining_bits); + if(begin == end) return; + available_bits -= 32 - remaining_bits; + remaining_bits = 0; + } + // If Bits < 32 we should never enter this loop + if(Bits >= 32) { + for(; available_bits >= 32; available_bits -= 32) { + boost::uint_least32_t word = boost::uint_least32_t(fmod(val, mult32)); + val /= mult32; + *begin++ = word; + if(begin == end) return; + } + } + remaining_bits = available_bits; + saved_bits = static_cast<boost::uint_least32_t>(val); + } + } +} + +template<class Engine, class Iter> +void generate_from_int(Engine& eng, Iter begin, Iter end) +{ + typedef typename Engine::result_type IntType; + typedef typename boost::make_unsigned<IntType>::type unsigned_type; + int remaining_bits = 0; + boost::uint_least32_t saved_bits = 0; + unsigned_type range = boost::random::detail::subtract<IntType>()((eng.max)(), (eng.min)()); + + int bits = + (range == (std::numeric_limits<unsigned_type>::max)()) ? + std::numeric_limits<unsigned_type>::digits : + detail::integer_log2(range + 1); + + { + int discarded_bits = detail::integer_log2(bits); + unsigned_type excess = (range + 1) >> (bits - discarded_bits); + if(excess != 0) { + int extra_bits = detail::integer_log2((excess - 1) ^ excess); + bits = bits - discarded_bits + extra_bits; + } + } + + unsigned_type mask = (static_cast<unsigned_type>(2) << (bits - 1)) - 1; + unsigned_type limit = ((range + 1) & ~mask) - 1; + + while(true) { + unsigned_type val; + do { + val = boost::random::detail::subtract<IntType>()(eng(), (eng.min)()); + } while(limit != range && val > limit); + val &= mask; + int available_bits = bits; + if(available_bits == 32) { + *begin++ = static_cast<boost::uint_least32_t>(val) & 0xFFFFFFFFu; + if(begin == end) return; + } else if(available_bits % 32 == 0) { + for(int i = 0; i < available_bits / 32; ++i) { + boost::uint_least32_t word = boost::uint_least32_t(val) & 0xFFFFFFFFu; + int supress_warning = (bits >= 32); + BOOST_ASSERT(supress_warning == 1); + val >>= (32 * supress_warning); + *begin++ = word; + if(begin == end) return; + } + } else if(bits < 32 && available_bits < 32 - remaining_bits) { + saved_bits |= boost::uint_least32_t(val) << remaining_bits; + remaining_bits += bits; + } else { + if(bits < 32 || remaining_bits != 0) { + boost::uint_least32_t extra_bits = boost::uint_least32_t(val) & ((boost::uint_least32_t(1) << (32 - remaining_bits)) - 1); + val >>= 32 - remaining_bits; + *begin++ = saved_bits | (extra_bits << remaining_bits); + if(begin == end) return; + available_bits -= 32 - remaining_bits; + remaining_bits = 0; + } + if(bits >= 32) { + for(; available_bits >= 32; available_bits -= 32) { + boost::uint_least32_t word = boost::uint_least32_t(val) & 0xFFFFFFFFu; + int supress_warning = (bits >= 32); + BOOST_ASSERT(supress_warning == 1); + val >>= (32 * supress_warning); + *begin++ = word; + if(begin == end) return; + } + } + remaining_bits = available_bits; + saved_bits = static_cast<boost::uint_least32_t>(val); + } + } +} + +template<class Engine, class Iter> +void generate_impl(Engine& eng, Iter first, Iter last, boost::mpl::true_) +{ + return detail::generate_from_int(eng, first, last); +} + +template<class Engine, class Iter> +void generate_impl(Engine& eng, Iter first, Iter last, boost::mpl::false_) +{ + return detail::generate_from_real(eng, first, last); +} + +template<class Engine, class Iter> +void generate(Engine& eng, Iter first, Iter last) +{ + return detail::generate_impl(eng, first, last, boost::is_integral<typename Engine::result_type>()); +} + + + +template<class IntType, IntType m, class SeedSeq> +IntType seed_one_int(SeedSeq& seq) +{ + static const int log = ::boost::mpl::if_c<(m == 0), + ::boost::mpl::int_<(::std::numeric_limits<IntType>::digits)>, + ::boost::static_log2<m> >::type::value; + static const int k = + (log + ((~(static_cast<IntType>(2) << (log - 1)) & m)? 32 : 31)) / 32; + ::boost::uint_least32_t array[log / 32 + 4]; + seq.generate(&array[0], &array[0] + k + 3); + IntType s = 0; + for(int j = 0; j < k; ++j) { + IntType digit = const_mod<IntType, m>::apply(IntType(array[j+3])); + IntType mult = IntType(1) << 32*j; + s = const_mod<IntType, m>::mult_add(mult, digit, s); + } + return s; +} + +template<class IntType, IntType m, class Iter> +IntType get_one_int(Iter& first, Iter last) +{ + static const int log = ::boost::mpl::if_c<(m == 0), + ::boost::mpl::int_<(::std::numeric_limits<IntType>::digits)>, + ::boost::static_log2<m> >::type::value; + static const int k = + (log + ((~(static_cast<IntType>(2) << (log - 1)) & m)? 32 : 31)) / 32; + IntType s = 0; + for(int j = 0; j < k; ++j) { + if(first == last) { + throw ::std::invalid_argument("Not enough elements in call to seed."); + } + IntType digit = const_mod<IntType, m>::apply(IntType(*first++)); + IntType mult = IntType(1) << 32*j; + s = const_mod<IntType, m>::mult_add(mult, digit, s); + } + return s; +} + +// TODO: work in-place whenever possible +template<int w, std::size_t n, class SeedSeq, class UIntType> +void seed_array_int_impl(SeedSeq& seq, UIntType (&x)[n]) +{ + boost::uint_least32_t storage[((w+31)/32) * n]; + seq.generate(&storage[0], &storage[0] + ((w+31)/32) * n); + for(std::size_t j = 0; j < n; j++) { + UIntType val = 0; + for(std::size_t k = 0; k < (w+31)/32; ++k) { + val += static_cast<UIntType>(storage[(w+31)/32*j + k]) << 32*k; + } + x[j] = val & ::boost::low_bits_mask_t<w>::sig_bits; + } +} + +template<int w, std::size_t n, class SeedSeq, class IntType> +inline void seed_array_int_impl(SeedSeq& seq, IntType (&x)[n], boost::mpl::true_) +{ + typedef typename boost::make_unsigned<IntType>::type unsigned_array[n]; + seed_array_int_impl<w>(seq, reinterpret_cast<unsigned_array&>(x)); +} + +template<int w, std::size_t n, class SeedSeq, class IntType> +inline void seed_array_int_impl(SeedSeq& seq, IntType (&x)[n], boost::mpl::false_) +{ + seed_array_int_impl<w>(seq, x); +} + +template<int w, std::size_t n, class SeedSeq, class IntType> +inline void seed_array_int(SeedSeq& seq, IntType (&x)[n]) +{ + seed_array_int_impl<w>(seq, x, boost::is_signed<IntType>()); +} + +template<int w, std::size_t n, class Iter, class UIntType> +void fill_array_int_impl(Iter& first, Iter last, UIntType (&x)[n]) +{ + for(std::size_t j = 0; j < n; j++) { + UIntType val = 0; + for(std::size_t k = 0; k < (w+31)/32; ++k) { + if(first == last) { + throw std::invalid_argument("Not enough elements in call to seed."); + } + val += static_cast<UIntType>(*first++) << 32*k; + } + x[j] = val & ::boost::low_bits_mask_t<w>::sig_bits; + } +} + +template<int w, std::size_t n, class Iter, class IntType> +inline void fill_array_int_impl(Iter& first, Iter last, IntType (&x)[n], boost::mpl::true_) +{ + typedef typename boost::make_unsigned<IntType>::type unsigned_array[n]; + fill_array_int_impl<w>(first, last, reinterpret_cast<unsigned_array&>(x)); +} + +template<int w, std::size_t n, class Iter, class IntType> +inline void fill_array_int_impl(Iter& first, Iter last, IntType (&x)[n], boost::mpl::false_) +{ + fill_array_int_impl<w>(first, last, x); +} + +template<int w, std::size_t n, class Iter, class IntType> +inline void fill_array_int(Iter& first, Iter last, IntType (&x)[n]) +{ + fill_array_int_impl<w>(first, last, x, boost::is_signed<IntType>()); +} + +template<int w, std::size_t n, class RealType> +void seed_array_real_impl(const boost::uint_least32_t* storage, RealType (&x)[n]) +{ + boost::uint_least32_t mask = ~((~boost::uint_least32_t(0)) << (w%32)); + RealType two32 = 4294967296.0; + const RealType divisor = RealType(1)/detail::pow2<RealType>(w); + unsigned int j; + for(j = 0; j < n; ++j) { + RealType val = RealType(0); + RealType mult = divisor; + for(int k = 0; k < w/32; ++k) { + val += *storage++ * mult; + mult *= two32; + } + if(mask != 0) { + val += (*storage++ & mask) * mult; + } + BOOST_ASSERT(val >= 0); + BOOST_ASSERT(val < 1); + x[j] = val; + } +} + +template<int w, std::size_t n, class SeedSeq, class RealType> +void seed_array_real(SeedSeq& seq, RealType (&x)[n]) +{ + using std::pow; + boost::uint_least32_t storage[((w+31)/32) * n]; + seq.generate(&storage[0], &storage[0] + ((w+31)/32) * n); + seed_array_real_impl<w>(storage, x); +} + +template<int w, std::size_t n, class Iter, class RealType> +void fill_array_real(Iter& first, Iter last, RealType (&x)[n]) +{ + boost::uint_least32_t mask = ~((~boost::uint_least32_t(0)) << (w%32)); + RealType two32 = 4294967296.0; + const RealType divisor = RealType(1)/detail::pow2<RealType>(w); + unsigned int j; + for(j = 0; j < n; ++j) { + RealType val = RealType(0); + RealType mult = divisor; + for(int k = 0; k < w/32; ++k, ++first) { + if(first == last) throw std::invalid_argument("Not enough elements in call to seed."); + val += *first * mult; + mult *= two32; + } + if(mask != 0) { + if(first == last) throw std::invalid_argument("Not enough elements in call to seed."); + val += (*first & mask) * mult; + ++first; + } + BOOST_ASSERT(val >= 0); + BOOST_ASSERT(val < 1); + x[j] = val; + } +} + +} +} +} + +#include <boost/random/detail/enable_warnings.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/random/detail/signed_unsigned_tools.hpp b/3rdParty/Boost/src/boost/random/detail/signed_unsigned_tools.hpp index 3c81cf4..988cfb8 100644 --- a/3rdParty/Boost/src/boost/random/detail/signed_unsigned_tools.hpp +++ b/3rdParty/Boost/src/boost/random/detail/signed_unsigned_tools.hpp @@ -73,7 +73,7 @@ struct add<T1, T2, /* signed */ true> if (y >= 0) return T2(x) + y; // y < 0 - if (x >= T1(-(y+1))) // result >= 0 after subtraction + if (x > T1(-(y+1))) // result >= 0 after subtraction // avoid the nasty two's complement edge case for y == min() return T2(x - T1(-(y+1)) - 1); // abs(x) < abs(y), thus T2 able to represent x diff --git a/3rdParty/Boost/src/boost/random/detail/uniform_int_float.hpp b/3rdParty/Boost/src/boost/random/detail/uniform_int_float.hpp index 4607021..ef20915 100644 --- a/3rdParty/Boost/src/boost/random/detail/uniform_int_float.hpp +++ b/3rdParty/Boost/src/boost/random/detail/uniform_int_float.hpp @@ -1,85 +1,76 @@ /* boost random/detail/uniform_int_float.hpp header file * * Copyright Jens Maurer 2000-2001 + * 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: uniform_int_float.hpp 52492 2009-04-19 14:55:57Z steven_watanabe $ + * $Id: uniform_int_float.hpp 72951 2011-07-07 04:57:37Z steven_watanabe $ * */ #ifndef BOOST_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP #define BOOST_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP +#include <boost/limits.hpp> #include <boost/config.hpp> +#include <boost/integer.hpp> #include <boost/random/detail/config.hpp> -#include <boost/random/uniform_01.hpp> +#include <boost/random/detail/generator_bits.hpp> +#include <boost/random/detail/disable_warnings.hpp> namespace boost { namespace random { namespace detail { -template<class UniformRandomNumberGenerator, class IntType = unsigned long> +template<class URNG> class uniform_int_float { public: - typedef UniformRandomNumberGenerator base_type; - typedef IntType result_type; + typedef URNG base_type; + typedef typename base_type::result_type base_result; - uniform_int_float(base_type rng, IntType min_arg = 0, IntType max_arg = 0xffffffff) - : _rng(rng), _min(min_arg), _max(max_arg) - { - init(); - } + typedef typename boost::uint_t< + (std::numeric_limits<boost::uintmax_t>::digits < + std::numeric_limits<base_result>::digits)? + std::numeric_limits<boost::uintmax_t>::digits : + std::numeric_limits<base_result>::digits + >::fast result_type; - result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; } - result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; } - base_type& base() { return _rng.base(); } - const base_type& base() const { return _rng.base(); } + uniform_int_float(base_type& rng) + : _rng(rng) {} - result_type operator()() - { - return static_cast<IntType>(_rng() * _range) + _min; - } + static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () + { return 0; } + static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + std::size_t digits = std::numeric_limits<result_type>::digits; + if(detail::generator_bits<URNG>::value() < digits) { + digits = detail::generator_bits<URNG>::value(); + } + return (result_type(2) << (digits - 1)) - 1; + } + base_type& base() { return _rng; } + const base_type& base() const { return _rng; } -#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 uniform_int_float& ud) - { - os << ud._min << " " << ud._max; - return os; - } - - template<class CharT, class Traits> - friend std::basic_istream<CharT,Traits>& - operator>>(std::basic_istream<CharT,Traits>& is, uniform_int_float& ud) - { - is >> std::ws >> ud._min >> std::ws >> ud._max; - ud.init(); - return is; - } -#endif + result_type operator()() + { + base_result range = static_cast<base_result>((max)())+1; + return static_cast<result_type>(_rng() * range); + } private: - void init() - { - _range = static_cast<base_result>(_max-_min)+1; - } - - typedef typename base_type::result_type base_result; - uniform_01<base_type> _rng; - result_type _min, _max; - base_result _range; + base_type& _rng; }; - } // namespace detail } // namespace random } // namespace boost +#include <boost/random/detail/enable_warnings.hpp> + #endif // BOOST_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP |