mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
support C++14 constexpr: random distributions
This commit is contained in:
parent
230630b45b
commit
3c4a465d35
9 changed files with 468 additions and 60 deletions
|
@ -88,13 +88,13 @@ namespace sprout {
|
|||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR bernoulli_distribution()
|
||||
SPROUT_CONSTEXPR bernoulli_distribution() SPROUT_NOEXCEPT
|
||||
: p_(RealType(0.5))
|
||||
{}
|
||||
explicit SPROUT_CONSTEXPR bernoulli_distribution(RealType p_arg)
|
||||
: p_((SPROUT_ASSERT(p_arg >= RealType(0)), SPROUT_ASSERT(p_arg <= RealType(1)), p_arg))
|
||||
{}
|
||||
explicit SPROUT_CONSTEXPR bernoulli_distribution(param_type const& parm)
|
||||
explicit SPROUT_CONSTEXPR bernoulli_distribution(param_type const& parm) SPROUT_NOEXCEPT
|
||||
: p_(parm.p())
|
||||
{}
|
||||
SPROUT_CONSTEXPR RealType p() const SPROUT_NOEXCEPT {
|
||||
|
@ -113,12 +113,28 @@ namespace sprout {
|
|||
p_ = parm.p();
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng) const {
|
||||
typedef typename Engine::result_type base_result;
|
||||
return p_ == RealType(0)
|
||||
? false
|
||||
: RealType(static_cast<base_result>(eng()) - eng.min()) <= p_ * RealType(eng.max() - eng.min())
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, bernoulli_distribution> const operator()(Engine const& eng) const {
|
||||
return p_ == RealType(0)
|
||||
? sprout::random::random_result<Engine, bernoulli_distribution>(false, eng, *this)
|
||||
: generate<Engine>(eng())
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng, param_type const& parm) const {
|
||||
return bernoulli_distribution(parm)(eng);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, bernoulli_distribution> const operator()(Engine const& eng, param_type const& parm) const {
|
||||
return bernoulli_distribution(parm)(eng);
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
|
|
|
@ -210,6 +210,91 @@ namespace sprout {
|
|||
return m_ < 11;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type
|
||||
invert(IntType t, RealType p, Engine& eng) const {
|
||||
RealType q = 1 - p;
|
||||
RealType s = p / q;
|
||||
RealType a = (t + 1) * s;
|
||||
RealType r = q_n_;
|
||||
RealType u = static_cast<RealType>(sprout::random::uniform_01<RealType>()(eng));
|
||||
IntType x = 0;
|
||||
while (u > r) {
|
||||
u = u - r;
|
||||
++x;
|
||||
r = ((a / x) - s) * r;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type
|
||||
generate(Engine& eng) const {
|
||||
for (; ; ) {
|
||||
RealType u = RealType();
|
||||
RealType v = static_cast<RealType>(sprout::random::uniform_01<RealType>()(eng));
|
||||
if (v <= btrd_.u_rv_r) {
|
||||
RealType u = v / btrd_.v_r - RealType(0.43);
|
||||
return static_cast<result_type>(sprout::math::floor((2 * btrd_.a / (RealType(0.5) - sprout::math::abs(u)) + btrd_.b) * u + btrd_.c));
|
||||
}
|
||||
|
||||
if (v >= btrd_.v_r) {
|
||||
u = static_cast<RealType>(sprout::random::uniform_01<RealType>()(eng)) - RealType(0.5);
|
||||
} else {
|
||||
u = v / btrd_.v_r - RealType(0.93);
|
||||
u = ((u < 0) ? -RealType(0.5) : RealType(0.5)) - u;
|
||||
v = static_cast<RealType>(sprout::random::uniform_01<RealType>()(eng)) * btrd_.v_r;
|
||||
}
|
||||
RealType us = RealType(0.5) - sprout::math::abs(u);
|
||||
IntType k = static_cast<IntType>(sprout::math::floor((2 * btrd_.a / us + btrd_.b) * u + btrd_.c));
|
||||
if (k < 0 || k > t_) {
|
||||
continue;
|
||||
}
|
||||
v = v * btrd_.alpha / (btrd_.a / (us * us) + btrd_.b);
|
||||
RealType km = sprout::math::abs(k - m_);
|
||||
if (km <= 15) {
|
||||
RealType f = RealType(1);
|
||||
if (m_ < k) {
|
||||
IntType i = m_;
|
||||
do {
|
||||
++i;
|
||||
f = f * (btrd_.nr / i - btrd_.r);
|
||||
} while (i != k);
|
||||
} else if (m_ > k) {
|
||||
IntType i = k;
|
||||
do {
|
||||
++i;
|
||||
v = v * (btrd_.nr / i - btrd_.r);
|
||||
} while (i != m_);
|
||||
}
|
||||
if (v <= f) {
|
||||
return k;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
v = sprout::math::log(v);
|
||||
RealType rho = (km / btrd_.npq) * (((km / RealType(3) + RealType(0.625)) * km + RealType(1) / 6) / btrd_.npq + RealType(0.5));
|
||||
RealType t = -km * km / (2 * btrd_.npq);
|
||||
if (v < t - rho) {
|
||||
return k;
|
||||
}
|
||||
if (v > t + rho) {
|
||||
continue;
|
||||
}
|
||||
IntType nm = t_ - m_ + 1;
|
||||
RealType h = (m_ + RealType(0.5)) * sprout::math::log((m_ + 1) / (btrd_.r * nm)) + fc(m_) + fc(t_ - m_);
|
||||
IntType nk = t_ - k + 1;
|
||||
if (v <= h + (t_ + 1) * sprout::math::log(static_cast<RealType>(nm) / nk)
|
||||
+ (k + RealType(0.5)) * sprout::math::log(nk * btrd_.r / (k + 1)) - fc(k) - fc(t_ - k)
|
||||
)
|
||||
{
|
||||
return k;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution>
|
||||
invert_4(Engine const& eng, RealType u, RealType q, RealType s, RealType a, RealType r, IntType x = 0) const {
|
||||
return u > r
|
||||
|
@ -351,7 +436,7 @@ namespace sprout {
|
|||
? generate_7<D + 1>(eng, v, k)
|
||||
: generate_8<D + 1>(
|
||||
eng, sprout::math::log(v), k,
|
||||
(km / btrd_.npq) * (((km / RealType(3.0) + RealType(0.625)) * km + RealType(1.0) / 6) / btrd_.npq + RealType(0.5)),
|
||||
(km / btrd_.npq) * (((km / RealType(3) + RealType(0.625)) * km + RealType(1) / 6) / btrd_.npq + RealType(0.5)),
|
||||
-km * km / (2 * btrd_.npq))
|
||||
;
|
||||
}
|
||||
|
@ -649,6 +734,15 @@ namespace sprout {
|
|||
init();
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng) const {
|
||||
return use_inversion() ? RealType(0.5) < p_
|
||||
? t_ - invert(t_, 1 - p_, eng)
|
||||
: invert(t_, p_, eng)
|
||||
: RealType(0.5) < p_ ? t_ - generate(eng)
|
||||
: generate(eng)
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> const operator()(Engine const& eng) const {
|
||||
return use_inversion() ? RealType(0.5) < p_
|
||||
? invert2(t_, 1 - p_, eng)
|
||||
|
@ -657,6 +751,14 @@ namespace sprout {
|
|||
: generate(eng)
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng, param_type const& parm) const {
|
||||
return binomial_distribution(parm)(eng);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> const operator()(Engine const& eng, param_type const& parm) const {
|
||||
return binomial_distribution(parm)(eng);
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
|
|
|
@ -32,6 +32,16 @@ namespace sprout {
|
|||
>::fast result_type;
|
||||
private:
|
||||
base_type rng_;
|
||||
private:
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<uniform_int_float> generate(
|
||||
sprout::random::random_result<base_type> const& rnd
|
||||
) const
|
||||
{
|
||||
return sprout::random::random_result<uniform_int_float>(
|
||||
static_cast<result_type>(rnd.result() * (static_cast<base_result>(max()) + 1)),
|
||||
uniform_int_float(rnd.engine())
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR uniform_int_float()
|
||||
: rng_()
|
||||
|
@ -59,16 +69,10 @@ namespace sprout {
|
|||
SPROUT_CONSTEXPR base_type const& base() const {
|
||||
return rng_;
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<uniform_int_float> generate(
|
||||
sprout::random::random_result<base_type> const& rnd
|
||||
) const
|
||||
{
|
||||
return sprout::random::random_result<uniform_int_float>(
|
||||
static_cast<result_type>(rnd.result() * (static_cast<base_result>(max()) + 1)),
|
||||
uniform_int_float(rnd.engine())
|
||||
);
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()() {
|
||||
return static_cast<result_type>(static_cast<base_result>(rng_()) * static_cast<base_result>(max()) + 1);
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<uniform_int_float> operator()() const {
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<uniform_int_float> const operator()() const {
|
||||
return generate(rng_());
|
||||
}
|
||||
};
|
||||
|
|
|
@ -129,9 +129,23 @@ namespace sprout {
|
|||
log_1mp_ = init_log_1mp(p_);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng) const {
|
||||
return static_cast<result_type>(
|
||||
sprout::math::floor(sprout::math::log(RealType(1) - static_cast<RealType>(sprout::random::uniform_01<RealType>()(eng))) / log_1mp_)
|
||||
);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, geometric_distribution> const operator()(Engine const& eng) const {
|
||||
return generate(eng);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng, param_type const& parm) const {
|
||||
return geometric_distribution(parm)(eng);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, geometric_distribution> const operator()(Engine const& eng, param_type const& parm) const {
|
||||
return geometric_distribution(parm)(eng);
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
|
|
|
@ -206,9 +206,34 @@ namespace sprout {
|
|||
valid_ = false;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng) {
|
||||
if (!valid_) {
|
||||
r1_ = static_cast<RealType>(sprout::random::uniform_01<RealType>()(eng));
|
||||
r2_ = static_cast<RealType>(sprout::random::uniform_01<RealType>()(eng));
|
||||
cached_rho_ = sprout::math::sqrt(-result_type(2) * sprout::math::log(result_type(1) - r2_));
|
||||
valid_ = true;
|
||||
} else {
|
||||
valid_ = false;
|
||||
}
|
||||
return cached_rho_
|
||||
* (valid_
|
||||
? sprout::math::cos(sprout::math::two_pi<result_type>() * r1_)
|
||||
: sprout::math::sin(sprout::math::two_pi<result_type>() * r1_))
|
||||
* sigma_ + mean_
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, normal_distribution> const operator()(Engine const& eng) const {
|
||||
return generate(eng);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng, param_type const& parm) const {
|
||||
return normal_distribution(parm)(eng);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, normal_distribution> const operator()(Engine const& eng, param_type const& parm) const {
|
||||
return normal_distribution(parm)(eng);
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*=============================================================================
|
||||
Copyright (c) 2011-2013 Bolero MURAKAMI
|
||||
https://github.com/bolero-MURAKAMI/Sprout
|
||||
Copyright (c) 2011-2013 Bolero MURAKAMI
|
||||
https://github.com/bolero-MURAKAMI/Sprout
|
||||
|
||||
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)
|
||||
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)
|
||||
=============================================================================*/
|
||||
#ifndef SPROUT_RANDOM_UNIFORM_01_HPP
|
||||
#define SPROUT_RANDOM_UNIFORM_01_HPP
|
||||
|
@ -121,8 +121,8 @@ namespace sprout {
|
|||
}
|
||||
#endif
|
||||
public:
|
||||
explicit SPROUT_CONSTEXPR uniform_01() {}
|
||||
explicit SPROUT_CONSTEXPR uniform_01(param_type const&) {}
|
||||
uniform_01() = default;
|
||||
explicit SPROUT_CONSTEXPR uniform_01(param_type const&) SPROUT_NOEXCEPT {}
|
||||
SPROUT_CONSTEXPR result_type min() const SPROUT_NOEXCEPT {
|
||||
return result_type(0);
|
||||
}
|
||||
|
@ -132,11 +132,35 @@ namespace sprout {
|
|||
SPROUT_CONSTEXPR param_type param() const SPROUT_NOEXCEPT {
|
||||
return param_type();
|
||||
}
|
||||
SPROUT_CXX14_CONSTEXPR void param(param_type const&) {}
|
||||
SPROUT_CXX14_CONSTEXPR void param(param_type const&) SPROUT_NOEXCEPT {}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng) const {
|
||||
for (; ; ) {
|
||||
typedef typename Engine::result_type base_result;
|
||||
result_type result = result_type(static_cast<base_result>(eng()) - eng.min()) * (
|
||||
result_type(1) / (
|
||||
result_type(eng.max() - eng.min()) + result_type(
|
||||
std::numeric_limits<base_result>::is_integer ? 1 : 0
|
||||
)
|
||||
)
|
||||
);
|
||||
if (result < result_type(1)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> const operator()(Engine const& eng) const {
|
||||
return generate(eng, eng());
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng, param_type const&) const {
|
||||
return operator()(eng);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> const operator()(Engine const& eng, param_type const&) const {
|
||||
return operator()(eng);
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
|
|
|
@ -28,6 +28,105 @@ namespace sprout {
|
|||
Engine engine;
|
||||
};
|
||||
|
||||
template<typename Engine, typename T>
|
||||
inline SPROUT_CXX14_CONSTEXPR T
|
||||
generate_uniform_int(
|
||||
Engine& eng, T min_value, T max_value, std::true_type
|
||||
)
|
||||
{
|
||||
typedef T result_type;
|
||||
typedef typename std::make_unsigned<T>::type range_type;
|
||||
typedef typename Engine::result_type base_result;
|
||||
typedef typename std::make_unsigned<base_result>::type base_unsigned;
|
||||
range_type const range = sprout::random::detail::subtract<result_type>()(max_value, min_value);
|
||||
base_result const bmin = eng.min();
|
||||
base_unsigned const brange = sprout::random::detail::subtract<base_result>()(eng.max(), eng.min());
|
||||
if (range == 0) {
|
||||
return min_value;
|
||||
} else if (brange == range) {
|
||||
base_unsigned v = sprout::random::detail::subtract<base_result>()(static_cast<base_result>(eng()), bmin);
|
||||
return sprout::random::detail::add<base_unsigned, result_type>()(
|
||||
static_cast<base_unsigned>(sprout::random::detail::subtract<base_result>()(static_cast<base_result>(eng()), bmin)),
|
||||
min_value
|
||||
);
|
||||
} else if (brange < range) {
|
||||
for(; ; ) {
|
||||
range_type limit = range_type();
|
||||
if (range == std::numeric_limits<range_type>::max()) {
|
||||
limit = range / (range_type(brange) + 1);
|
||||
if (range % (range_type(brange) + 1) == range_type(brange)) {
|
||||
++limit;
|
||||
}
|
||||
} else {
|
||||
limit = (range + 1) / (range_type(brange) + 1);
|
||||
}
|
||||
range_type result = range_type(0);
|
||||
range_type mult = range_type(1);
|
||||
while (mult <= limit) {
|
||||
result += static_cast<range_type>(sprout::random::detail::subtract<base_result>()(static_cast<base_result>(eng()), bmin) * mult);
|
||||
if (mult * range_type(brange) == range - mult + 1) {
|
||||
return result;
|
||||
}
|
||||
mult *= range_type(brange) + range_type(1);
|
||||
}
|
||||
range_type result_increment = sprout::random::detail::generate_uniform_int(
|
||||
eng,
|
||||
static_cast<range_type>(0),
|
||||
static_cast<range_type>(range / mult),
|
||||
std::true_type()
|
||||
);
|
||||
if (std::numeric_limits<range_type>::max() / mult < result_increment) {
|
||||
continue;
|
||||
}
|
||||
result_increment *= mult;
|
||||
result += result_increment;
|
||||
if (result < result_increment) {
|
||||
continue;
|
||||
}
|
||||
if (result > range) {
|
||||
continue;
|
||||
}
|
||||
return sprout::random::detail::add<range_type, result_type>()(result, min_value);
|
||||
}
|
||||
} else {
|
||||
base_unsigned bucket_size = base_unsigned();
|
||||
if (brange == std::numeric_limits<base_unsigned>::max()) {
|
||||
bucket_size = brange / (static_cast<base_unsigned>(range) + 1);
|
||||
if (brange % (static_cast<base_unsigned>(range) + 1) == static_cast<base_unsigned>(range)) {
|
||||
++bucket_size;
|
||||
}
|
||||
} else {
|
||||
bucket_size = (brange + 1) / (static_cast<base_unsigned>(range) + 1);
|
||||
}
|
||||
for(; ; ) {
|
||||
base_unsigned result = sprout::random::detail::subtract<base_result>()(static_cast<base_result>(eng()), bmin) / bucket_size;
|
||||
if (result <= static_cast<base_unsigned>(range)) {
|
||||
return sprout::random::detail::add<base_unsigned, result_type>()(result, min_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
inline SPROUT_CXX14_CONSTEXPR T
|
||||
generate_uniform_int(
|
||||
Engine& eng, T min_value, T max_value, std::false_type
|
||||
)
|
||||
{
|
||||
sprout::random::detail::uniform_int_float<Engine> wrapper(eng);
|
||||
return sprout::random::detail::generate_uniform_int(wrapper, min_value, max_value, std::true_type());
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
inline SPROUT_CXX14_CONSTEXPR T
|
||||
generate_uniform_int(
|
||||
Engine& eng, T min_value, T max_value
|
||||
)
|
||||
{
|
||||
return sprout::random::detail::generate_uniform_int(
|
||||
eng, min_value, max_value,
|
||||
std::is_integral<typename Engine::result_type>()
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef SPROUT_WORKAROUND_NOT_TERMINATE_RECURSIVE_CONSTEXPR_FUNCTION_TEMPLATE
|
||||
template<int D = 16, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result<T, Engine>
|
||||
|
@ -760,7 +859,7 @@ namespace sprout {
|
|||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR uniform_int_distribution()
|
||||
SPROUT_CONSTEXPR uniform_int_distribution() SPROUT_NOEXCEPT
|
||||
: min_(0)
|
||||
, max_(9)
|
||||
{}
|
||||
|
@ -768,7 +867,7 @@ namespace sprout {
|
|||
: min_((SPROUT_ASSERT(min_arg <= max_arg), min_arg))
|
||||
, max_(max_arg)
|
||||
{}
|
||||
explicit SPROUT_CONSTEXPR uniform_int_distribution(param_type const& parm)
|
||||
explicit SPROUT_CONSTEXPR uniform_int_distribution(param_type const& parm) SPROUT_NOEXCEPT
|
||||
: min_(parm.a())
|
||||
, max_(parm.b())
|
||||
{}
|
||||
|
@ -792,9 +891,21 @@ namespace sprout {
|
|||
max_ = parm.b();
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng) const {
|
||||
return sprout::random::detail::generate_uniform_int(eng, min_, max_);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_int_distribution> const operator()(Engine const& eng) const {
|
||||
return generate<Engine>(sprout::random::detail::generate_uniform_int(eng, min_, max_));
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng, param_type const& parm) const {
|
||||
return sprout::random::detail::generate_uniform_int(eng, parm.a(), parm.b());
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_int_distribution> const operator()(Engine const& eng, param_type const& parm) const {
|
||||
return generate<Engine>(sprout::random::detail::generate_uniform_int(eng, parm.a(), parm.b()));
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*=============================================================================
|
||||
Copyright (c) 2011-2013 Bolero MURAKAMI
|
||||
https://github.com/bolero-MURAKAMI/Sprout
|
||||
Copyright (c) 2011-2013 Bolero MURAKAMI
|
||||
https://github.com/bolero-MURAKAMI/Sprout
|
||||
|
||||
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)
|
||||
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)
|
||||
=============================================================================*/
|
||||
#ifndef SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
|
||||
#define SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
|
||||
|
@ -26,21 +26,73 @@ namespace sprout {
|
|||
Engine engine;
|
||||
};
|
||||
|
||||
template<typename Engine, typename T>
|
||||
inline SPROUT_CXX14_CONSTEXPR T
|
||||
generate_uniform_real(
|
||||
Engine& eng, T min_value, T max_value,
|
||||
std::false_type
|
||||
)
|
||||
{
|
||||
for(;;) {
|
||||
typedef T result_type;
|
||||
typedef typename Engine::result_type base_result;
|
||||
result_type numerator = static_cast<T>(static_cast<base_result>(eng()) - eng.min());
|
||||
result_type divisor = static_cast<T>(eng.max() - eng.min());
|
||||
SPROUT_ASSERT(divisor > 0);
|
||||
SPROUT_ASSERT(numerator >= 0 && numerator <= divisor);
|
||||
result_type result = numerator / divisor * (max_value - min_value) + min_value;
|
||||
if (result < max_value) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
inline SPROUT_CXX14_CONSTEXPR T
|
||||
generate_uniform_real(
|
||||
Engine& eng, T min_value, T max_value,
|
||||
std::true_type
|
||||
)
|
||||
{
|
||||
for(;;) {
|
||||
typedef T result_type;
|
||||
typedef typename Engine::result_type base_result;
|
||||
result_type numerator = static_cast<T>(sprout::random::detail::subtract<base_result>()(static_cast<base_result>(eng()), eng.min()));
|
||||
result_type divisor = static_cast<T>(sprout::random::detail::subtract<base_result>()(eng.max(), eng.min())) + 1;
|
||||
SPROUT_ASSERT(divisor > 0);
|
||||
SPROUT_ASSERT(numerator >= 0 && numerator <= divisor);
|
||||
result_type result = numerator / divisor * (max_value - min_value) + min_value;
|
||||
if (result < max_value) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
inline SPROUT_CXX14_CONSTEXPR T
|
||||
generate_uniform_real(
|
||||
Engine& eng, T min_value, T max_value
|
||||
)
|
||||
{
|
||||
return sprout::random::detail::generate_uniform_real(
|
||||
eng, min_value, max_value,
|
||||
typename std::is_integral<typename Engine::result_type>::type()
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef SPROUT_WORKAROUND_NOT_TERMINATE_RECURSIVE_CONSTEXPR_FUNCTION_TEMPLATE
|
||||
template<int D = 16, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
generate_uniform_real_false_1(
|
||||
EngineResult const& rnd,
|
||||
T min_value, T max_value
|
||||
);
|
||||
template<int D = 16, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
generate_uniform_real_false_1(
|
||||
EngineResult const& rnd,
|
||||
T min_value, T max_value
|
||||
);
|
||||
template<int D, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real_false_3(
|
||||
Engine const& eng,
|
||||
T min_value, T max_value,
|
||||
|
@ -53,7 +105,7 @@ namespace sprout {
|
|||
;
|
||||
}
|
||||
template<int D, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real_false_3(
|
||||
Engine const&,
|
||||
T, T,
|
||||
|
@ -63,7 +115,7 @@ namespace sprout {
|
|||
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
||||
}
|
||||
template<int D, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real_false_2(
|
||||
Engine const& eng,
|
||||
T min_value, T max_value,
|
||||
|
@ -79,7 +131,7 @@ namespace sprout {
|
|||
;
|
||||
}
|
||||
template<int D, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real_false_2(
|
||||
Engine const&,
|
||||
T, T,
|
||||
|
@ -89,7 +141,7 @@ namespace sprout {
|
|||
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
||||
}
|
||||
template<int D, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE_DECL(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
generate_uniform_real_false_1(
|
||||
EngineResult const& rnd,
|
||||
T min_value, T max_value
|
||||
|
@ -102,7 +154,7 @@ namespace sprout {
|
|||
);
|
||||
}
|
||||
template<int D, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK_DECL(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
generate_uniform_real_false_1(
|
||||
EngineResult const&,
|
||||
T, T
|
||||
|
@ -111,19 +163,19 @@ namespace sprout {
|
|||
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
||||
}
|
||||
template<int D = 16, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
generate_uniform_real_true_1(
|
||||
EngineResult const& rnd,
|
||||
T min_value, T max_value
|
||||
);
|
||||
template<int D = 16, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
generate_uniform_real_true_1(
|
||||
EngineResult const& rnd,
|
||||
T min_value, T max_value
|
||||
);
|
||||
template<int D, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real_true_3(
|
||||
Engine const& eng,
|
||||
T min_value, T max_value,
|
||||
|
@ -136,7 +188,7 @@ namespace sprout {
|
|||
;
|
||||
}
|
||||
template<int D, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real_true_3(
|
||||
Engine const&,
|
||||
T, T,
|
||||
|
@ -146,7 +198,7 @@ namespace sprout {
|
|||
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
||||
}
|
||||
template<int D, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real_true_2(
|
||||
Engine const& eng,
|
||||
T min_value, T max_value,
|
||||
|
@ -162,7 +214,7 @@ namespace sprout {
|
|||
;
|
||||
}
|
||||
template<int D, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real_true_2(
|
||||
Engine const&,
|
||||
T, T,
|
||||
|
@ -172,7 +224,7 @@ namespace sprout {
|
|||
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
||||
}
|
||||
template<int D, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE_DECL(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
generate_uniform_real_true_1(
|
||||
EngineResult const& rnd,
|
||||
T min_value, T max_value
|
||||
|
@ -187,7 +239,7 @@ namespace sprout {
|
|||
);
|
||||
}
|
||||
template<int D, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK_DECL(D)>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
generate_uniform_real_true_1(
|
||||
EngineResult const&,
|
||||
T, T
|
||||
|
@ -197,13 +249,13 @@ namespace sprout {
|
|||
}
|
||||
#else
|
||||
template<typename EngineResult, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
generate_uniform_real_false_1(
|
||||
EngineResult const& rnd,
|
||||
T min_value, T max_value
|
||||
);
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real_false_3(
|
||||
Engine const& eng,
|
||||
T min_value, T max_value,
|
||||
|
@ -216,7 +268,7 @@ namespace sprout {
|
|||
;
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real_false_2(
|
||||
Engine const& eng,
|
||||
T min_value, T max_value,
|
||||
|
@ -232,7 +284,7 @@ namespace sprout {
|
|||
;
|
||||
}
|
||||
template<typename EngineResult, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
generate_uniform_real_false_1(
|
||||
EngineResult const& rnd,
|
||||
T min_value, T max_value
|
||||
|
@ -245,13 +297,13 @@ namespace sprout {
|
|||
);
|
||||
}
|
||||
template<typename EngineResult, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
generate_uniform_real_true_1(
|
||||
EngineResult const& rnd,
|
||||
T min_value, T max_value
|
||||
);
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real_true_3(
|
||||
Engine const& eng,
|
||||
T min_value, T max_value,
|
||||
|
@ -264,7 +316,7 @@ namespace sprout {
|
|||
;
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real_true_2(
|
||||
Engine const& eng,
|
||||
T min_value, T max_value,
|
||||
|
@ -280,7 +332,7 @@ namespace sprout {
|
|||
;
|
||||
}
|
||||
template<typename EngineResult, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, typename EngineResult::engine_type>
|
||||
generate_uniform_real_true_1(
|
||||
EngineResult const& rnd,
|
||||
T min_value, T max_value
|
||||
|
@ -296,7 +348,7 @@ namespace sprout {
|
|||
}
|
||||
#endif
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real(
|
||||
Engine const& eng,
|
||||
T min_value, T max_value,
|
||||
|
@ -309,7 +361,7 @@ namespace sprout {
|
|||
);
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real(
|
||||
Engine const& eng,
|
||||
T min_value, T max_value,
|
||||
|
@ -322,7 +374,7 @@ namespace sprout {
|
|||
);
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine>
|
||||
generate_uniform_real(
|
||||
Engine const& eng,
|
||||
T min_value, T max_value
|
||||
|
@ -331,7 +383,7 @@ namespace sprout {
|
|||
return sprout::random::detail::generate_uniform_real(
|
||||
eng,
|
||||
min_value, max_value,
|
||||
std::is_integral<typename Engine::result_type>()
|
||||
typename std::is_integral<typename Engine::result_type>::type()
|
||||
);
|
||||
}
|
||||
} // namespace detail
|
||||
|
@ -414,7 +466,7 @@ namespace sprout {
|
|||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR uniform_real_distribution()
|
||||
SPROUT_CONSTEXPR uniform_real_distribution() SPROUT_NOEXCEPT
|
||||
: min_(RealType(0.0))
|
||||
, max_(RealType(1.0))
|
||||
{}
|
||||
|
@ -422,7 +474,7 @@ namespace sprout {
|
|||
: min_((SPROUT_ASSERT(min_arg <= max_arg), min_arg))
|
||||
, max_(max_arg)
|
||||
{}
|
||||
explicit SPROUT_CONSTEXPR uniform_real_distribution(param_type const& parm)
|
||||
explicit SPROUT_CONSTEXPR uniform_real_distribution(param_type const& parm) SPROUT_NOEXCEPT
|
||||
: min_(parm.a())
|
||||
, max_(parm.b())
|
||||
{}
|
||||
|
@ -446,9 +498,21 @@ namespace sprout {
|
|||
max_ = parm.b();
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng) const {
|
||||
return sprout::random::detail::generate_uniform_real(eng, min_, max_);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_real_distribution> const operator()(Engine const& eng) const {
|
||||
return generate<Engine>(sprout::random::detail::generate_uniform_real(eng, min_, max_));
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng, param_type const& parm) const {
|
||||
return sprout::random::detail::generate_uniform_real(eng, parm.a(), parm.b());
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_real_distribution> const operator()(Engine const& eng, param_type const& parm) const {
|
||||
return generate<Engine>(sprout::random::detail::generate_uniform_real(eng, parm.a(), parm.b()));
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
|
|
|
@ -89,6 +89,39 @@ namespace sprout {
|
|||
IntType min_;
|
||||
IntType max_;
|
||||
private:
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type generate(
|
||||
Engine& eng,
|
||||
std::true_type
|
||||
) const
|
||||
{
|
||||
typedef typename Engine::result_type base_result;
|
||||
typedef typename std::make_unsigned<base_result>::type base_unsigned;
|
||||
typedef typename std::make_unsigned<result_type>::type range_type;
|
||||
range_type range = sprout::random::detail::subtract<result_type>()(max_, min_);
|
||||
base_unsigned base_range = sprout::random::detail::subtract<result_type>()(eng.max(), eng.min());
|
||||
base_unsigned val = sprout::random::detail::subtract<base_result>()(static_cast<base_result>(eng()), eng.min());
|
||||
return range >= base_range
|
||||
? sprout::random::detail::add<range_type, result_type>()(static_cast<range_type>(val), min_)
|
||||
: sprout::random::detail::add<range_type, result_type>()(static_cast<range_type>(val % (static_cast<base_result>(range) + 1)), min_)
|
||||
;
|
||||
}
|
||||
template<class Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type generate(
|
||||
Engine& eng,
|
||||
std::false_type
|
||||
) const
|
||||
{
|
||||
typedef typename Engine::result_type base_result;
|
||||
typedef typename std::make_unsigned<result_type>::type range_type;
|
||||
range_type range = sprout::random::detail::subtract<result_type>()(max_, min_);
|
||||
base_result val = sprout::random::uniform_01<base_result>()(eng);
|
||||
range_type offset = static_cast<range_type>(val * (static_cast<base_result>(range) + 1));
|
||||
return offset > range
|
||||
? max_
|
||||
: sprout::random::detail::add<range_type, result_type>()(offset, min_)
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename EngineResult, typename RangeType, typename BaseUnsigned>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_true_2(
|
||||
Engine const&,
|
||||
|
@ -176,8 +209,8 @@ namespace sprout {
|
|||
return generate_false_2(
|
||||
eng,
|
||||
rnd,
|
||||
RangeType(sprout::random::detail::subtract<result_type>()(max_, min_)),
|
||||
RangeType(static_cast<RangeType>(rnd.result() * (static_cast<base_result>(range) + 1)))
|
||||
static_cast<RangeType>(sprout::random::detail::subtract<result_type>()(max_, min_)),
|
||||
static_cast<RangeType>(rnd.result() * (static_cast<base_result>(range) + 1))
|
||||
);
|
||||
}
|
||||
template<class Engine>
|
||||
|
@ -191,11 +224,11 @@ namespace sprout {
|
|||
return generate_false_1(
|
||||
eng,
|
||||
sprout::random::uniform_01<base_result>()(eng),
|
||||
range_type(sprout::random::detail::subtract<result_type>()(max_, min_))
|
||||
static_cast<range_type>(sprout::random::detail::subtract<result_type>()(max_, min_))
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR uniform_smallint()
|
||||
SPROUT_CONSTEXPR uniform_smallint() SPROUT_NOEXCEPT
|
||||
: min_(0)
|
||||
, max_(9)
|
||||
{}
|
||||
|
@ -203,7 +236,7 @@ namespace sprout {
|
|||
: min_((SPROUT_ASSERT(min_arg <= max_arg), min_arg))
|
||||
, max_(max_arg)
|
||||
{}
|
||||
explicit SPROUT_CONSTEXPR uniform_smallint(param_type const& parm)
|
||||
explicit SPROUT_CONSTEXPR uniform_smallint(param_type const& parm) SPROUT_NOEXCEPT
|
||||
: min_(parm.a())
|
||||
, max_(parm.b())
|
||||
{}
|
||||
|
@ -227,10 +260,25 @@ namespace sprout {
|
|||
max_ = parm.b();
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng) const {
|
||||
typedef typename Engine::result_type base_result;
|
||||
return generate(eng, typename std::is_integral<base_result>::type());
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> const operator()(Engine const& eng) const {
|
||||
typedef typename Engine::result_type base_result;
|
||||
return generate(eng, typename std::is_integral<base_result>::type());
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CXX14_CONSTEXPR result_type operator()(Engine& eng, param_type const& parm) const {
|
||||
typedef typename Engine::result_type base_result;
|
||||
return uniform_smallint(parm)(eng);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> const operator()(Engine const& eng, param_type const& parm) const {
|
||||
typedef typename Engine::result_type base_result;
|
||||
return uniform_smallint(parm)(eng);
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
|
|
Loading…
Reference in a new issue