From 05880da6911c366d6f9546fec448ae1b3e6e8b7b Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Thu, 3 Dec 2020 14:37:56 +1000 Subject: [PATCH] rand/distribution: allow rvalues for uniform distributions --- rand/distribution/uniform.hpp | 36 ++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/rand/distribution/uniform.hpp b/rand/distribution/uniform.hpp index a96c55fc..3ebdbfee 100644 --- a/rand/distribution/uniform.hpp +++ b/rand/distribution/uniform.hpp @@ -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 - result_type operator() (GeneratorT &gen) + result_type operator() (GeneratorT &&gen) { - return this->template operator() (gen, m_param); + return this->template operator() (std::forward (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 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; + using num_t = std::common_type_t< + result_type, + typename std::remove_cvref_t::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 struct uniform_real_distribution { static_assert (std::is_floating_point_v); @@ -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 - result_type operator() (GeneratorT &gen) + result_type operator() (GeneratorT &&gen) { - return this->template operator() (gen, m_param); + return this->template operator() (std::forward (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 result_type - operator() (GeneratorT &gen, param_type const &p) + operator() (GeneratorT &&gen, param_type const &p) { return ::cruft::rand::distribution::generate_canonical< result_type,