random: use UniformRandomBit concept

This commit is contained in:
Danny Robson 2022-05-10 12:48:29 +10:00
parent b7f8d73d95
commit 234adca06f

View File

@ -22,9 +22,23 @@
namespace cruft::random {
template <typename T>
concept UniformRandomBitGenerator =
std::is_unsigned_v<typename T::result_type> and
std::is_integral_v<typename T::result_type> and
requires (T t)
{
typename T::result_type;
{ T::min () } -> std::same_as<typename T::result_type>;
{ T::max () } -> std::same_as<typename T::result_type>;
{ t () } -> std::same_as<typename T::result_type>;
};
///////////////////////////////////////////////////////////////////////////
/// Initialise and return a generator using random_device.
template <typename GeneratorT>
template <UniformRandomBitGenerator GeneratorT>
GeneratorT
initialise (void)
{
@ -81,6 +95,7 @@ namespace cruft::random {
/// type. As such, the interval is the same as the std library; ie, closed
/// for integers, half-open for reals.
template <typename ValueT, typename GeneratorT>
requires (UniformRandomBitGenerator<std::remove_cvref_t<GeneratorT>>)
decltype(auto)
uniform (ValueT lo, ValueT hi, GeneratorT &&gen)
{
@ -122,6 +137,7 @@ namespace cruft::random {
/// Interval bounds are treated as per the standard Generator
/// implementations; ie, inclusive for integers, exclusive upper for reals.
template <typename T, typename GeneratorT>
requires (UniformRandomBitGenerator<std::remove_cvref_t<GeneratorT>>)
decltype(auto)
uniform (T hi, GeneratorT &&gen)
{
@ -133,9 +149,12 @@ namespace cruft::random {
/// Return a uniformly random value chosen on the interval [0,1)
template <
typename ValueT,
typename GeneratorT,
typename = std::enable_if_t<std::is_floating_point_v<ValueT>>
typename GeneratorT
>
requires (
std::is_floating_point_v<ValueT> and
UniformRandomBitGenerator<std::remove_cvref_t<GeneratorT>>
)
decltype(auto)
uniform (GeneratorT &&gen)
{
@ -146,9 +165,9 @@ namespace cruft::random {
///------------------------------------------------------------------------
/// Return a uniformly random chosen value on the interval [0.f, 1.f)
template <
typename ValueT,
typename = std::enable_if_t<std::is_floating_point_v<ValueT>>
typename ValueT
>
requires (std::is_floating_point_v<ValueT>)
decltype(auto)
uniform (void)
{
@ -157,9 +176,10 @@ namespace cruft::random {
///------------------------------------------------------------------------
/// Return a uniformly random chosen value on the interval [0, 1]
/// Return a uniformly random chosen value over integral values in the type
template <typename T>
std::enable_if_t<std::is_integral_v<T>,T>
requires (std::is_integral_v<T>)
T
uniform (void)
{
return uniform<T> (
@ -211,6 +231,7 @@ namespace cruft::random {
//
/// \return An iterator to the chosen value.
template <typename ContainerT, typename GeneratorT>
requires (UniformRandomBitGenerator<std::remove_cvref_t<GeneratorT>>)
decltype(auto)
choose (ContainerT &data, GeneratorT &&gen)
{