1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/random/uniform_int.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,152 @@
1.4 +/* boost random/uniform_int.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_int.hpp,v 1.27 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_INT_HPP
1.21 +#define BOOST_RANDOM_UNIFORM_INT_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/detail/workaround.hpp>
1.29 +#include <boost/random/uniform_smallint.hpp>
1.30 +#include <boost/random/detail/signed_unsigned_compare.hpp>
1.31 +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
1.32 +#include <boost/type_traits/is_float.hpp>
1.33 +#endif
1.34 +
1.35 +namespace boost {
1.36 +
1.37 +// uniform integer distribution on [min, max]
1.38 +template<class IntType = int>
1.39 +class uniform_int
1.40 +{
1.41 +public:
1.42 + typedef IntType input_type;
1.43 + typedef IntType result_type;
1.44 +
1.45 + explicit uniform_int(IntType min = 0, IntType max = 9)
1.46 + : _min(min), _max(max)
1.47 + {
1.48 +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
1.49 + // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
1.50 + BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
1.51 +#endif
1.52 + assert(min <= max);
1.53 + init();
1.54 + }
1.55 +
1.56 + result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
1.57 + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
1.58 + void reset() { }
1.59 +
1.60 + // can't have member function templates out-of-line due to MSVC bugs
1.61 + template<class Engine>
1.62 + result_type operator()(Engine& eng)
1.63 + {
1.64 + typedef typename Engine::result_type base_result;
1.65 + base_result bmin = (eng.min)();
1.66 + base_result brange = (eng.max)() - (eng.min)();
1.67 +
1.68 + if(_range == 0) {
1.69 + return _min;
1.70 + } else if(random::equal_signed_unsigned(brange, _range)) {
1.71 + // this will probably never happen in real life
1.72 + // basically nothing to do; just take care we don't overflow / underflow
1.73 + return static_cast<result_type>(eng() - bmin) + _min;
1.74 + } else if(random::lessthan_signed_unsigned(brange, _range)) {
1.75 + // use rejection method to handle things like 0..3 --> 0..4
1.76 + for(;;) {
1.77 + // concatenate several invocations of the base RNG
1.78 + // take extra care to avoid overflows
1.79 + result_type limit;
1.80 + if(_range == (std::numeric_limits<result_type>::max)()) {
1.81 + limit = _range/(result_type(brange)+1);
1.82 + if(_range % result_type(brange)+1 == result_type(brange))
1.83 + ++limit;
1.84 + } else {
1.85 + limit = (_range+1)/(result_type(brange)+1);
1.86 + }
1.87 + // We consider "result" as expressed to base (brange+1):
1.88 + // For every power of (brange+1), we determine a random factor
1.89 + result_type result = result_type(0);
1.90 + result_type mult = result_type(1);
1.91 + while(mult <= limit) {
1.92 + result += (eng() - bmin) * mult;
1.93 + mult *= result_type(brange)+result_type(1);
1.94 + }
1.95 + if(mult == limit)
1.96 + // _range+1 is an integer power of brange+1: no rejections required
1.97 + return result;
1.98 + // _range/mult < brange+1 -> no endless loop
1.99 + result += uniform_int<result_type>(0, _range/mult)(eng) * mult;
1.100 + if(result <= _range)
1.101 + return result + _min;
1.102 + }
1.103 + } else { // brange > range
1.104 + if(brange / _range > 4 /* quantization_cutoff */ ) {
1.105 + // the new range is vastly smaller than the source range,
1.106 + // so quantization effects are not relevant
1.107 + return boost::uniform_smallint<result_type>(_min, _max)(eng);
1.108 + } else {
1.109 + // use rejection method to handle cases like 0..5 -> 0..4
1.110 + for(;;) {
1.111 + base_result result = eng() - bmin;
1.112 + // result and range are non-negative, and result is possibly larger
1.113 + // than range, so the cast is safe
1.114 + if(result <= static_cast<base_result>(_range))
1.115 + return result + _min;
1.116 + }
1.117 + }
1.118 + }
1.119 + }
1.120 +
1.121 +#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
1.122 + template<class CharT, class Traits>
1.123 + friend std::basic_ostream<CharT,Traits>&
1.124 + operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_int& ud)
1.125 + {
1.126 + os << ud._min << " " << ud._max;
1.127 + return os;
1.128 + }
1.129 +
1.130 + template<class CharT, class Traits>
1.131 + friend std::basic_istream<CharT,Traits>&
1.132 + operator>>(std::basic_istream<CharT,Traits>& is, uniform_int& ud)
1.133 + {
1.134 +# if BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
1.135 + return detail::extract_uniform_int(is, ud, ud.impl);
1.136 +# else
1.137 + is >> std::ws >> ud._min >> std::ws >> ud._max;
1.138 + ud.init();
1.139 + return is;
1.140 +# endif
1.141 + }
1.142 +#endif
1.143 +
1.144 +private:
1.145 + void init()
1.146 + {
1.147 + _range = _max - _min;
1.148 + }
1.149 +
1.150 + result_type _min, _max, _range;
1.151 +};
1.152 +
1.153 +} // namespace boost
1.154 +
1.155 +#endif // BOOST_RANDOM_UNIFORM_INT_HPP