mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-25 21:35:41 +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:
|
public:
|
||||||
SPROUT_CONSTEXPR bernoulli_distribution()
|
SPROUT_CONSTEXPR bernoulli_distribution() SPROUT_NOEXCEPT
|
||||||
: p_(RealType(0.5))
|
: p_(RealType(0.5))
|
||||||
{}
|
{}
|
||||||
explicit SPROUT_CONSTEXPR bernoulli_distribution(RealType p_arg)
|
explicit SPROUT_CONSTEXPR bernoulli_distribution(RealType p_arg)
|
||||||
: p_((SPROUT_ASSERT(p_arg >= RealType(0)), SPROUT_ASSERT(p_arg <= RealType(1)), 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())
|
: p_(parm.p())
|
||||||
{}
|
{}
|
||||||
SPROUT_CONSTEXPR RealType p() const SPROUT_NOEXCEPT {
|
SPROUT_CONSTEXPR RealType p() const SPROUT_NOEXCEPT {
|
||||||
|
@ -113,12 +113,28 @@ namespace sprout {
|
||||||
p_ = parm.p();
|
p_ = parm.p();
|
||||||
}
|
}
|
||||||
template<typename Engine>
|
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 {
|
SPROUT_CONSTEXPR sprout::random::random_result<Engine, bernoulli_distribution> const operator()(Engine const& eng) const {
|
||||||
return p_ == RealType(0)
|
return p_ == RealType(0)
|
||||||
? sprout::random::random_result<Engine, bernoulli_distribution>(false, eng, *this)
|
? sprout::random::random_result<Engine, bernoulli_distribution>(false, eng, *this)
|
||||||
: generate<Engine>(eng())
|
: 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>
|
template<typename Elem, typename Traits>
|
||||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||||
std::basic_istream<Elem, Traits>& lhs,
|
std::basic_istream<Elem, Traits>& lhs,
|
||||||
|
|
|
@ -210,6 +210,91 @@ namespace sprout {
|
||||||
return m_ < 11;
|
return m_ < 11;
|
||||||
}
|
}
|
||||||
template<typename Engine>
|
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>
|
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 {
|
invert_4(Engine const& eng, RealType u, RealType q, RealType s, RealType a, RealType r, IntType x = 0) const {
|
||||||
return u > r
|
return u > r
|
||||||
|
@ -351,7 +436,7 @@ namespace sprout {
|
||||||
? generate_7<D + 1>(eng, v, k)
|
? generate_7<D + 1>(eng, v, k)
|
||||||
: generate_8<D + 1>(
|
: generate_8<D + 1>(
|
||||||
eng, sprout::math::log(v), k,
|
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))
|
-km * km / (2 * btrd_.npq))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -649,6 +734,15 @@ namespace sprout {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
template<typename Engine>
|
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 {
|
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> const operator()(Engine const& eng) const {
|
||||||
return use_inversion() ? RealType(0.5) < p_
|
return use_inversion() ? RealType(0.5) < p_
|
||||||
? invert2(t_, 1 - p_, eng)
|
? invert2(t_, 1 - p_, eng)
|
||||||
|
@ -657,6 +751,14 @@ namespace sprout {
|
||||||
: generate(eng)
|
: 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>
|
template<typename Elem, typename Traits>
|
||||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||||
std::basic_istream<Elem, Traits>& lhs,
|
std::basic_istream<Elem, Traits>& lhs,
|
||||||
|
|
|
@ -32,6 +32,16 @@ namespace sprout {
|
||||||
>::fast result_type;
|
>::fast result_type;
|
||||||
private:
|
private:
|
||||||
base_type rng_;
|
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:
|
public:
|
||||||
SPROUT_CONSTEXPR uniform_int_float()
|
SPROUT_CONSTEXPR uniform_int_float()
|
||||||
: rng_()
|
: rng_()
|
||||||
|
@ -59,16 +69,10 @@ namespace sprout {
|
||||||
SPROUT_CONSTEXPR base_type const& base() const {
|
SPROUT_CONSTEXPR base_type const& base() const {
|
||||||
return rng_;
|
return rng_;
|
||||||
}
|
}
|
||||||
SPROUT_CONSTEXPR sprout::random::random_result<uniform_int_float> generate(
|
SPROUT_CXX14_CONSTEXPR result_type operator()() {
|
||||||
sprout::random::random_result<base_type> const& rnd
|
return static_cast<result_type>(static_cast<base_result>(rng_()) * static_cast<base_result>(max()) + 1);
|
||||||
) 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_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_());
|
return generate(rng_());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -129,9 +129,23 @@ namespace sprout {
|
||||||
log_1mp_ = init_log_1mp(p_);
|
log_1mp_ = init_log_1mp(p_);
|
||||||
}
|
}
|
||||||
template<typename Engine>
|
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 {
|
SPROUT_CONSTEXPR sprout::random::random_result<Engine, geometric_distribution> const operator()(Engine const& eng) const {
|
||||||
return generate(eng);
|
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>
|
template<typename Elem, typename Traits>
|
||||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||||
std::basic_istream<Elem, Traits>& lhs,
|
std::basic_istream<Elem, Traits>& lhs,
|
||||||
|
|
|
@ -206,9 +206,34 @@ namespace sprout {
|
||||||
valid_ = false;
|
valid_ = false;
|
||||||
}
|
}
|
||||||
template<typename Engine>
|
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 {
|
SPROUT_CONSTEXPR sprout::random::random_result<Engine, normal_distribution> const operator()(Engine const& eng) const {
|
||||||
return generate(eng);
|
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>
|
template<typename Elem, typename Traits>
|
||||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||||
std::basic_istream<Elem, Traits>& lhs,
|
std::basic_istream<Elem, Traits>& lhs,
|
||||||
|
|
|
@ -121,8 +121,8 @@ namespace sprout {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
explicit SPROUT_CONSTEXPR uniform_01() {}
|
uniform_01() = default;
|
||||||
explicit SPROUT_CONSTEXPR uniform_01(param_type const&) {}
|
explicit SPROUT_CONSTEXPR uniform_01(param_type const&) SPROUT_NOEXCEPT {}
|
||||||
SPROUT_CONSTEXPR result_type min() const SPROUT_NOEXCEPT {
|
SPROUT_CONSTEXPR result_type min() const SPROUT_NOEXCEPT {
|
||||||
return result_type(0);
|
return result_type(0);
|
||||||
}
|
}
|
||||||
|
@ -132,11 +132,35 @@ namespace sprout {
|
||||||
SPROUT_CONSTEXPR param_type param() const SPROUT_NOEXCEPT {
|
SPROUT_CONSTEXPR param_type param() const SPROUT_NOEXCEPT {
|
||||||
return param_type();
|
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>
|
template<typename Engine>
|
||||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> const operator()(Engine const& eng) const {
|
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> const operator()(Engine const& eng) const {
|
||||||
return generate(eng, eng());
|
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>
|
template<typename Elem, typename Traits>
|
||||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||||
std::basic_istream<Elem, Traits>& lhs,
|
std::basic_istream<Elem, Traits>& lhs,
|
||||||
|
|
|
@ -28,6 +28,105 @@ namespace sprout {
|
||||||
Engine engine;
|
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
|
#ifdef SPROUT_WORKAROUND_NOT_TERMINATE_RECURSIVE_CONSTEXPR_FUNCTION_TEMPLATE
|
||||||
template<int D = 16, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
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>
|
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result<T, Engine>
|
||||||
|
@ -760,7 +859,7 @@ namespace sprout {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
SPROUT_CONSTEXPR uniform_int_distribution()
|
SPROUT_CONSTEXPR uniform_int_distribution() SPROUT_NOEXCEPT
|
||||||
: min_(0)
|
: min_(0)
|
||||||
, max_(9)
|
, max_(9)
|
||||||
{}
|
{}
|
||||||
|
@ -768,7 +867,7 @@ namespace sprout {
|
||||||
: min_((SPROUT_ASSERT(min_arg <= max_arg), min_arg))
|
: min_((SPROUT_ASSERT(min_arg <= max_arg), min_arg))
|
||||||
, max_(max_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())
|
: min_(parm.a())
|
||||||
, max_(parm.b())
|
, max_(parm.b())
|
||||||
{}
|
{}
|
||||||
|
@ -792,9 +891,21 @@ namespace sprout {
|
||||||
max_ = parm.b();
|
max_ = parm.b();
|
||||||
}
|
}
|
||||||
template<typename Engine>
|
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 {
|
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_));
|
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>
|
template<typename Elem, typename Traits>
|
||||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||||
std::basic_istream<Elem, Traits>& lhs,
|
std::basic_istream<Elem, Traits>& lhs,
|
||||||
|
|
|
@ -26,21 +26,73 @@ namespace sprout {
|
||||||
Engine engine;
|
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
|
#ifdef SPROUT_WORKAROUND_NOT_TERMINATE_RECURSIVE_CONSTEXPR_FUNCTION_TEMPLATE
|
||||||
template<int D = 16, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
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(
|
generate_uniform_real_false_1(
|
||||||
EngineResult const& rnd,
|
EngineResult const& rnd,
|
||||||
T min_value, T max_value
|
T min_value, T max_value
|
||||||
);
|
);
|
||||||
template<int D = 16, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
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(
|
generate_uniform_real_false_1(
|
||||||
EngineResult const& rnd,
|
EngineResult const& rnd,
|
||||||
T min_value, T max_value
|
T min_value, T max_value
|
||||||
);
|
);
|
||||||
template<int D, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
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(
|
generate_uniform_real_false_3(
|
||||||
Engine const& eng,
|
Engine const& eng,
|
||||||
T min_value, T max_value,
|
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)>
|
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(
|
generate_uniform_real_false_3(
|
||||||
Engine const&,
|
Engine const&,
|
||||||
T, T,
|
T, T,
|
||||||
|
@ -63,7 +115,7 @@ namespace sprout {
|
||||||
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
||||||
}
|
}
|
||||||
template<int D, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
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(
|
generate_uniform_real_false_2(
|
||||||
Engine const& eng,
|
Engine const& eng,
|
||||||
T min_value, T max_value,
|
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)>
|
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(
|
generate_uniform_real_false_2(
|
||||||
Engine const&,
|
Engine const&,
|
||||||
T, T,
|
T, T,
|
||||||
|
@ -89,7 +141,7 @@ namespace sprout {
|
||||||
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
||||||
}
|
}
|
||||||
template<int D, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE_DECL(D)>
|
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(
|
generate_uniform_real_false_1(
|
||||||
EngineResult const& rnd,
|
EngineResult const& rnd,
|
||||||
T min_value, T max_value
|
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)>
|
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(
|
generate_uniform_real_false_1(
|
||||||
EngineResult const&,
|
EngineResult const&,
|
||||||
T, T
|
T, T
|
||||||
|
@ -111,19 +163,19 @@ namespace sprout {
|
||||||
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
||||||
}
|
}
|
||||||
template<int D = 16, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
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(
|
generate_uniform_real_true_1(
|
||||||
EngineResult const& rnd,
|
EngineResult const& rnd,
|
||||||
T min_value, T max_value
|
T min_value, T max_value
|
||||||
);
|
);
|
||||||
template<int D = 16, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
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(
|
generate_uniform_real_true_1(
|
||||||
EngineResult const& rnd,
|
EngineResult const& rnd,
|
||||||
T min_value, T max_value
|
T min_value, T max_value
|
||||||
);
|
);
|
||||||
template<int D, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
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(
|
generate_uniform_real_true_3(
|
||||||
Engine const& eng,
|
Engine const& eng,
|
||||||
T min_value, T max_value,
|
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)>
|
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(
|
generate_uniform_real_true_3(
|
||||||
Engine const&,
|
Engine const&,
|
||||||
T, T,
|
T, T,
|
||||||
|
@ -146,7 +198,7 @@ namespace sprout {
|
||||||
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
||||||
}
|
}
|
||||||
template<int D, typename Engine, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
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(
|
generate_uniform_real_true_2(
|
||||||
Engine const& eng,
|
Engine const& eng,
|
||||||
T min_value, T max_value,
|
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)>
|
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(
|
generate_uniform_real_true_2(
|
||||||
Engine const&,
|
Engine const&,
|
||||||
T, T,
|
T, T,
|
||||||
|
@ -172,7 +224,7 @@ namespace sprout {
|
||||||
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
||||||
}
|
}
|
||||||
template<int D, typename EngineResult, typename T, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE_DECL(D)>
|
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(
|
generate_uniform_real_true_1(
|
||||||
EngineResult const& rnd,
|
EngineResult const& rnd,
|
||||||
T min_value, T max_value
|
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)>
|
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(
|
generate_uniform_real_true_1(
|
||||||
EngineResult const&,
|
EngineResult const&,
|
||||||
T, T
|
T, T
|
||||||
|
@ -197,13 +249,13 @@ namespace sprout {
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
template<typename EngineResult, typename T>
|
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(
|
generate_uniform_real_false_1(
|
||||||
EngineResult const& rnd,
|
EngineResult const& rnd,
|
||||||
T min_value, T max_value
|
T min_value, T max_value
|
||||||
);
|
);
|
||||||
template<typename Engine, typename T>
|
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(
|
generate_uniform_real_false_3(
|
||||||
Engine const& eng,
|
Engine const& eng,
|
||||||
T min_value, T max_value,
|
T min_value, T max_value,
|
||||||
|
@ -216,7 +268,7 @@ namespace sprout {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
template<typename Engine, typename T>
|
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(
|
generate_uniform_real_false_2(
|
||||||
Engine const& eng,
|
Engine const& eng,
|
||||||
T min_value, T max_value,
|
T min_value, T max_value,
|
||||||
|
@ -232,7 +284,7 @@ namespace sprout {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
template<typename EngineResult, typename T>
|
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(
|
generate_uniform_real_false_1(
|
||||||
EngineResult const& rnd,
|
EngineResult const& rnd,
|
||||||
T min_value, T max_value
|
T min_value, T max_value
|
||||||
|
@ -245,13 +297,13 @@ namespace sprout {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
template<typename EngineResult, typename T>
|
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(
|
generate_uniform_real_true_1(
|
||||||
EngineResult const& rnd,
|
EngineResult const& rnd,
|
||||||
T min_value, T max_value
|
T min_value, T max_value
|
||||||
);
|
);
|
||||||
template<typename Engine, typename T>
|
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(
|
generate_uniform_real_true_3(
|
||||||
Engine const& eng,
|
Engine const& eng,
|
||||||
T min_value, T max_value,
|
T min_value, T max_value,
|
||||||
|
@ -264,7 +316,7 @@ namespace sprout {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
template<typename Engine, typename T>
|
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(
|
generate_uniform_real_true_2(
|
||||||
Engine const& eng,
|
Engine const& eng,
|
||||||
T min_value, T max_value,
|
T min_value, T max_value,
|
||||||
|
@ -280,7 +332,7 @@ namespace sprout {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
template<typename EngineResult, typename T>
|
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(
|
generate_uniform_real_true_1(
|
||||||
EngineResult const& rnd,
|
EngineResult const& rnd,
|
||||||
T min_value, T max_value
|
T min_value, T max_value
|
||||||
|
@ -296,7 +348,7 @@ namespace sprout {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
template<typename Engine, typename T>
|
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(
|
generate_uniform_real(
|
||||||
Engine const& eng,
|
Engine const& eng,
|
||||||
T min_value, T max_value,
|
T min_value, T max_value,
|
||||||
|
@ -309,7 +361,7 @@ namespace sprout {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
template<typename Engine, typename T>
|
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(
|
generate_uniform_real(
|
||||||
Engine const& eng,
|
Engine const& eng,
|
||||||
T min_value, T max_value,
|
T min_value, T max_value,
|
||||||
|
@ -322,7 +374,7 @@ namespace sprout {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
template<typename Engine, typename T>
|
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(
|
generate_uniform_real(
|
||||||
Engine const& eng,
|
Engine const& eng,
|
||||||
T min_value, T max_value
|
T min_value, T max_value
|
||||||
|
@ -331,7 +383,7 @@ namespace sprout {
|
||||||
return sprout::random::detail::generate_uniform_real(
|
return sprout::random::detail::generate_uniform_real(
|
||||||
eng,
|
eng,
|
||||||
min_value, max_value,
|
min_value, max_value,
|
||||||
std::is_integral<typename Engine::result_type>()
|
typename std::is_integral<typename Engine::result_type>::type()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
@ -414,7 +466,7 @@ namespace sprout {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
SPROUT_CONSTEXPR uniform_real_distribution()
|
SPROUT_CONSTEXPR uniform_real_distribution() SPROUT_NOEXCEPT
|
||||||
: min_(RealType(0.0))
|
: min_(RealType(0.0))
|
||||||
, max_(RealType(1.0))
|
, max_(RealType(1.0))
|
||||||
{}
|
{}
|
||||||
|
@ -422,7 +474,7 @@ namespace sprout {
|
||||||
: min_((SPROUT_ASSERT(min_arg <= max_arg), min_arg))
|
: min_((SPROUT_ASSERT(min_arg <= max_arg), min_arg))
|
||||||
, max_(max_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())
|
: min_(parm.a())
|
||||||
, max_(parm.b())
|
, max_(parm.b())
|
||||||
{}
|
{}
|
||||||
|
@ -446,9 +498,21 @@ namespace sprout {
|
||||||
max_ = parm.b();
|
max_ = parm.b();
|
||||||
}
|
}
|
||||||
template<typename Engine>
|
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 {
|
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_));
|
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>
|
template<typename Elem, typename Traits>
|
||||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||||
std::basic_istream<Elem, Traits>& lhs,
|
std::basic_istream<Elem, Traits>& lhs,
|
||||||
|
|
|
@ -89,6 +89,39 @@ namespace sprout {
|
||||||
IntType min_;
|
IntType min_;
|
||||||
IntType max_;
|
IntType max_;
|
||||||
private:
|
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>
|
template<typename Engine, typename EngineResult, typename RangeType, typename BaseUnsigned>
|
||||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_true_2(
|
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_true_2(
|
||||||
Engine const&,
|
Engine const&,
|
||||||
|
@ -176,8 +209,8 @@ namespace sprout {
|
||||||
return generate_false_2(
|
return generate_false_2(
|
||||||
eng,
|
eng,
|
||||||
rnd,
|
rnd,
|
||||||
RangeType(sprout::random::detail::subtract<result_type>()(max_, min_)),
|
static_cast<RangeType>(sprout::random::detail::subtract<result_type>()(max_, min_)),
|
||||||
RangeType(static_cast<RangeType>(rnd.result() * (static_cast<base_result>(range) + 1)))
|
static_cast<RangeType>(rnd.result() * (static_cast<base_result>(range) + 1))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
template<class Engine>
|
template<class Engine>
|
||||||
|
@ -191,11 +224,11 @@ namespace sprout {
|
||||||
return generate_false_1(
|
return generate_false_1(
|
||||||
eng,
|
eng,
|
||||||
sprout::random::uniform_01<base_result>()(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:
|
public:
|
||||||
SPROUT_CONSTEXPR uniform_smallint()
|
SPROUT_CONSTEXPR uniform_smallint() SPROUT_NOEXCEPT
|
||||||
: min_(0)
|
: min_(0)
|
||||||
, max_(9)
|
, max_(9)
|
||||||
{}
|
{}
|
||||||
|
@ -203,7 +236,7 @@ namespace sprout {
|
||||||
: min_((SPROUT_ASSERT(min_arg <= max_arg), min_arg))
|
: min_((SPROUT_ASSERT(min_arg <= max_arg), min_arg))
|
||||||
, max_(max_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())
|
: min_(parm.a())
|
||||||
, max_(parm.b())
|
, max_(parm.b())
|
||||||
{}
|
{}
|
||||||
|
@ -227,10 +260,25 @@ namespace sprout {
|
||||||
max_ = parm.b();
|
max_ = parm.b();
|
||||||
}
|
}
|
||||||
template<typename Engine>
|
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 {
|
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> const operator()(Engine const& eng) const {
|
||||||
typedef typename Engine::result_type base_result;
|
typedef typename Engine::result_type base_result;
|
||||||
return generate(eng, typename std::is_integral<base_result>::type());
|
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>
|
template<typename Elem, typename Traits>
|
||||||
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
friend SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>& operator>>(
|
||||||
std::basic_istream<Elem, Traits>& lhs,
|
std::basic_istream<Elem, Traits>& lhs,
|
||||||
|
|
Loading…
Reference in a new issue