1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/random/uniform_smallint.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,236 @@
1.4 +/* boost random/uniform_smallint.hpp header file
1.5 + *
1.6 + * Copyright Jens Maurer 2000-2001
1.7 + * Distributed under the Boost Software License, Version 1.0. (See
1.8 + * accompanying file LICENSE_1_0.txt or copy at
1.9 + * http://www.boost.org/LICENSE_1_0.txt)
1.10 + *
1.11 + * See http://www.boost.org for most recent version including documentation.
1.12 + *
1.13 + * $Id: uniform_smallint.hpp,v 1.29 2004/07/27 03:43:32 dgregor Exp $
1.14 + *
1.15 + * Revision history
1.16 + * 2001-04-08 added min<max assertion (N. Becker)
1.17 + * 2001-02-18 moved to individual header files
1.18 + */
1.19 +
1.20 +#ifndef BOOST_RANDOM_UNIFORM_SMALLINT_HPP
1.21 +#define BOOST_RANDOM_UNIFORM_SMALLINT_HPP
1.22 +
1.23 +#include <cassert>
1.24 +#include <iostream>
1.25 +#include <boost/config.hpp>
1.26 +#include <boost/limits.hpp>
1.27 +#include <boost/static_assert.hpp>
1.28 +#include <boost/random/uniform_01.hpp>
1.29 +#include <boost/detail/workaround.hpp>
1.30 +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
1.31 +#include <boost/type_traits/is_float.hpp>
1.32 +#endif
1.33 +
1.34 +
1.35 +namespace boost {
1.36 +
1.37 +// uniform integer distribution on a small range [min, max]
1.38 +
1.39 +namespace detail {
1.40 +
1.41 +template <class InputStream, class UniformInt, class Impl>
1.42 +InputStream& extract_uniform_int(InputStream& is, UniformInt& ud, Impl& impl)
1.43 +{
1.44 + typename UniformInt::result_type min, max;
1.45 + is >> std::ws >> min >> std::ws >> max;
1.46 + impl.set(min, max);
1.47 + return is;
1.48 +}
1.49 +
1.50 +template<class UniformRandomNumberGenerator, class IntType>
1.51 +struct uniform_smallint_integer
1.52 +{
1.53 +public:
1.54 + typedef UniformRandomNumberGenerator base_type;
1.55 + typedef IntType result_type;
1.56 +
1.57 + uniform_smallint_integer(base_type & rng, IntType min, IntType max)
1.58 + : _rng(&rng)
1.59 + { set(min, max); }
1.60 +
1.61 + void set(result_type min, result_type max);
1.62 +
1.63 + result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
1.64 + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
1.65 + base_type& base() const { return *_rng; }
1.66 +
1.67 + result_type operator()()
1.68 + {
1.69 + // we must not use the low bits here, because LCGs get very bad then
1.70 + return (((*_rng)() - (_rng->min)()) / _factor) % _range + _min;
1.71 + }
1.72 +
1.73 +private:
1.74 + typedef typename base_type::result_type base_result;
1.75 + base_type * _rng;
1.76 + IntType _min, _max;
1.77 + base_result _range;
1.78 + int _factor;
1.79 +};
1.80 +
1.81 +template<class UniformRandomNumberGenerator, class IntType>
1.82 +void uniform_smallint_integer<UniformRandomNumberGenerator, IntType>::
1.83 +set(result_type min, result_type max)
1.84 +{
1.85 + _min = min;
1.86 + _max = max;
1.87 + assert(min < max);
1.88 +
1.89 + _range = static_cast<base_result>(_max-_min)+1;
1.90 + base_result _factor = 1;
1.91 +
1.92 + // LCGs get bad when only taking the low bits.
1.93 + // (probably put this logic into a partial template specialization)
1.94 + // Check how many low bits we can ignore before we get too much
1.95 + // quantization error.
1.96 + base_result r_base = (_rng->max)() - (_rng->min)();
1.97 + if(r_base == (std::numeric_limits<base_result>::max)()) {
1.98 + _factor = 2;
1.99 + r_base /= 2;
1.100 + }
1.101 + r_base += 1;
1.102 + if(r_base % _range == 0) {
1.103 + // No quantization effects, good
1.104 + _factor = r_base / _range;
1.105 + } else {
1.106 + // carefully avoid overflow; pessimizing heree
1.107 + for( ; r_base/_range/32 >= _range; _factor *= 2)
1.108 + r_base /= 2;
1.109 + }
1.110 +}
1.111 +
1.112 +template<class UniformRandomNumberGenerator, class IntType>
1.113 +class uniform_smallint_float
1.114 +{
1.115 +public:
1.116 + typedef UniformRandomNumberGenerator base_type;
1.117 + typedef IntType result_type;
1.118 +
1.119 + uniform_smallint_float(base_type & rng, IntType min, IntType max)
1.120 + : _rng(rng)
1.121 + {
1.122 + // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
1.123 +#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300)
1.124 + BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
1.125 + BOOST_STATIC_ASSERT(!std::numeric_limits<typename base_type::result_type>::is_integer);
1.126 +#endif
1.127 +
1.128 + assert(min < max);
1.129 + set(min, max);
1.130 + }
1.131 +
1.132 + void set(result_type min, result_type max)
1.133 + {
1.134 + _min = min;
1.135 + _max = max;
1.136 + _range = static_cast<base_result>(_max-_min)+1;
1.137 + }
1.138 +
1.139 + result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
1.140 + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
1.141 + base_type& base() const { return _rng.base(); }
1.142 +
1.143 + result_type operator()()
1.144 + {
1.145 + return static_cast<IntType>(_rng() * _range) + _min;
1.146 + }
1.147 +
1.148 +private:
1.149 + typedef typename base_type::result_type base_result;
1.150 + uniform_01<base_type> _rng;
1.151 + IntType _min, _max;
1.152 + base_result _range;
1.153 +};
1.154 +
1.155 +
1.156 +} // namespace detail
1.157 +
1.158 +
1.159 +
1.160 +
1.161 +template<class IntType = int>
1.162 +class uniform_smallint
1.163 +{
1.164 +public:
1.165 + typedef IntType input_type;
1.166 + typedef IntType result_type;
1.167 +
1.168 + explicit uniform_smallint(IntType min = 0, IntType max = 9)
1.169 + : _min(min), _max(max)
1.170 + {
1.171 +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
1.172 + // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
1.173 + BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
1.174 +#endif
1.175 + }
1.176 +
1.177 + result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
1.178 + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
1.179 + void reset() { }
1.180 +
1.181 + template<class Engine>
1.182 + result_type operator()(Engine& eng)
1.183 + {
1.184 + typedef typename Engine::result_type base_result;
1.185 + base_result _range = static_cast<base_result>(_max-_min)+1;
1.186 + base_result _factor = 1;
1.187 +
1.188 + // LCGs get bad when only taking the low bits.
1.189 + // (probably put this logic into a partial template specialization)
1.190 + // Check how many low bits we can ignore before we get too much
1.191 + // quantization error.
1.192 + base_result r_base = (eng.max)() - (eng.min)();
1.193 + if(r_base == (std::numeric_limits<base_result>::max)()) {
1.194 + _factor = 2;
1.195 + r_base /= 2;
1.196 + }
1.197 + r_base += 1;
1.198 + if(r_base % _range == 0) {
1.199 + // No quantization effects, good
1.200 + _factor = r_base / _range;
1.201 + } else {
1.202 + // carefully avoid overflow; pessimizing heree
1.203 + for( ; r_base/_range/32 >= _range; _factor *= 2)
1.204 + r_base /= 2;
1.205 + }
1.206 +
1.207 + return ((eng() - (eng.min)()) / _factor) % _range + _min;
1.208 + }
1.209 +
1.210 +#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
1.211 + template<class CharT, class Traits>
1.212 + friend std::basic_ostream<CharT,Traits>&
1.213 + operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_smallint& ud)
1.214 + {
1.215 + os << ud._min << " " << ud._max;
1.216 + return os;
1.217 + }
1.218 +
1.219 + template<class CharT, class Traits>
1.220 + friend std::basic_istream<CharT,Traits>&
1.221 + operator>>(std::basic_istream<CharT,Traits>& is, uniform_smallint& ud)
1.222 + {
1.223 +# if BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
1.224 + return detail::extract_uniform_int(is, ud, ud._impl);
1.225 +# else
1.226 + is >> std::ws >> ud._min >> std::ws >> ud._max;
1.227 + return is;
1.228 +# endif
1.229 + }
1.230 +#endif
1.231 +
1.232 +private:
1.233 + result_type _min;
1.234 + result_type _max;
1.235 +};
1.236 +
1.237 +} // namespace boost
1.238 +
1.239 +#endif // BOOST_RANDOM_UNIFORM_SMALLINT_HPP