rand/distribution: allow rvalues for uniform distributions

This commit is contained in:
Danny Robson 2020-12-03 14:37:56 +10:00
parent 12716e8cb2
commit 05880da691

View File

@ -48,22 +48,34 @@ namespace cruft::rand::distribution {
void reset (void);
// As a difference to libstd++ and libcxx we accept universal
// references as arguments; purely because it fits some of our
// existing code better, not because it's an efficient or desirable
// pattern.
template <typename GeneratorT>
result_type operator() (GeneratorT &gen)
result_type operator() (GeneratorT &&gen)
{
return this->template operator() (gen, m_param);
return this->template operator() (std::forward<GeneratorT> (gen), m_param);
}
// As a difference to libstd++ and libcxx we accept universal
// references as arguments; purely because it fits some of our
// existing code better, not because it's an efficient or desirable
// pattern.
template <typename GeneratorT>
result_type
operator() (GeneratorT &gen, param_type const &p)
operator() (GeneratorT &&gen, param_type const &p)
{
// We use the same approach as libstdc++.
//
// Specialising for downscaling gen, upscaling gen, and identify
// gen transforms.
using num_t = std::common_type_t<result_type, typename GeneratorT::result_type>;
using num_t = std::common_type_t<
result_type,
typename std::remove_cvref_t<GeneratorT>::result_type
>;
num_t const gen_range = gen.max () - gen.min ();
num_t const our_range = p.b - p.a;
@ -168,6 +180,7 @@ namespace cruft::rand::distribution {
return accum / base;
}
template <typename ResultT>
struct uniform_real_distribution {
static_assert (std::is_floating_point_v<ResultT>);
@ -197,15 +210,24 @@ namespace cruft::rand::distribution {
void reset (void);
// As a difference to libstd++ and libcxx we accept universal
// references as arguments; purely because it fits some of our
// existing code better, not because it's an efficient or desirable
// pattern.
template <typename GeneratorT>
result_type operator() (GeneratorT &gen)
result_type operator() (GeneratorT &&gen)
{
return this->template operator() (gen, m_param);
return this->template operator() (std::forward<GeneratorT> (gen), m_param);
}
// As a difference to libstd++ and libcxx we accept universal
// references as arguments; purely because it fits some of our
// existing code better, not because it's an efficient or desirable
// pattern.
template <typename GeneratorT>
result_type
operator() (GeneratorT &gen, param_type const &p)
operator() (GeneratorT &&gen, param_type const &p)
{
return ::cruft::rand::distribution::generate_canonical<
result_type,