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); 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> 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> template <typename GeneratorT>
result_type result_type
operator() (GeneratorT &gen, param_type const &p) operator() (GeneratorT &&gen, param_type const &p)
{ {
// We use the same approach as libstdc++. // We use the same approach as libstdc++.
// //
// Specialising for downscaling gen, upscaling gen, and identify // Specialising for downscaling gen, upscaling gen, and identify
// gen transforms. // 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 gen_range = gen.max () - gen.min ();
num_t const our_range = p.b - p.a; num_t const our_range = p.b - p.a;
@ -168,6 +180,7 @@ namespace cruft::rand::distribution {
return accum / base; return accum / base;
} }
template <typename ResultT> template <typename ResultT>
struct uniform_real_distribution { struct uniform_real_distribution {
static_assert (std::is_floating_point_v<ResultT>); static_assert (std::is_floating_point_v<ResultT>);
@ -197,15 +210,24 @@ namespace cruft::rand::distribution {
void reset (void); 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> 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> template <typename GeneratorT>
result_type result_type
operator() (GeneratorT &gen, param_type const &p) operator() (GeneratorT &&gen, param_type const &p)
{ {
return ::cruft::rand::distribution::generate_canonical< return ::cruft::rand::distribution::generate_canonical<
result_type, result_type,