epoc32/include/stdapis/boost/random/uniform_smallint.hpp
branchSymbian2
changeset 2 2fe1408b6811
     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