Sprout/sprout/random/detail/uniform_int_float.hpp
2012-08-10 12:39:03 +09:00

72 lines
2.2 KiB
C++

#ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
#define SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
#include <cstddef>
#include <cstdint>
#include <limits>
#include <sprout/config.hpp>
#include <sprout/random/random_result.hpp>
#include <sprout/random/detail/generator_bits.hpp>
#include <sprout/detail/integer.hpp>
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace random {
namespace detail {
template<class URNG>
class uniform_int_float {
public:
typedef URNG base_type;
typedef typename base_type::result_type base_result;
typedef typename sprout::detail::uint_t<
(std::numeric_limits<std::uintmax_t>::digits < std::numeric_limits<base_result>::digits)
? std::numeric_limits<std::uintmax_t>::digits
: std::numeric_limits<base_result>::digits
>::fast result_type;
private:
base_type rng_;
public:
SPROUT_CONSTEXPR uniform_int_float()
: rng_()
{}
explicit SPROUT_CONSTEXPR uniform_int_float(base_type const& rng)
: rng_(rng)
{}
SPROUT_CONSTEXPR result_type min() const {
return 0;
}
SPROUT_CONSTEXPR result_type max() const {
return (
result_type(2) << (
NS_SSCRISK_CEL_OR_SPROUT::min(
std::numeric_limits<result_type>::digits,
sprout::random::detail::generator_bits<base_type>::value()
) - 1
)
) - 1
;
}
base_type& base() {
return rng_;
}
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_CONSTEXPR sprout::random::random_result<uniform_int_float> operator()() const {
return generate(rng_());
}
};
} // namespace detail
} // namespace random
} // namespace sprout
#endif // #ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP