From 95855404d2e672d123e2f6e8577ac6f75493d531 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 28 Jun 2025 19:39:43 +0300 Subject: [PATCH] Use the RNG output directly in basic_random_generator when its results are uniform uint32_t or uint64_t. Fixes #174. --- include/boost/uuid/basic_random_generator.hpp | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/include/boost/uuid/basic_random_generator.hpp b/include/boost/uuid/basic_random_generator.hpp index 16a0d29..d5bd7f8 100644 --- a/include/boost/uuid/basic_random_generator.hpp +++ b/include/boost/uuid/basic_random_generator.hpp @@ -56,14 +56,9 @@ public: { UniformRandomNumberGenerator& gen = p_? *p_: g_; - std::uniform_int_distribution dist; - result_type u; - detail::store_native_u32( u.data + 0, dist( gen ) ); - detail::store_native_u32( u.data + 4, dist( gen ) ); - detail::store_native_u32( u.data + 8, dist( gen ) ); - detail::store_native_u32( u.data + 12, dist( gen ) ); + fill_data( gen, u ); // set variant // must be 0b10xxxxxx @@ -80,6 +75,38 @@ public: private: + template static void fill_data_impl( URNG& gen, uuid& u, std::false_type, std::false_type ) + { + std::uniform_int_distribution dist; + + detail::store_little_u32( u.data + 0, dist( gen ) ); + detail::store_little_u32( u.data + 4, dist( gen ) ); + detail::store_little_u32( u.data + 8, dist( gen ) ); + detail::store_little_u32( u.data + 12, dist( gen ) ); + } + + template static void fill_data_impl( URNG& gen, uuid& u, std::true_type, std::false_type ) + { + detail::store_little_u32( u.data + 0, static_cast( gen() ) ); + detail::store_little_u32( u.data + 4, static_cast( gen() ) ); + detail::store_little_u32( u.data + 8, static_cast( gen() ) ); + detail::store_little_u32( u.data + 12, static_cast( gen() ) ); + } + + template static void fill_data_impl( URNG& gen, uuid& u, std::false_type, std::true_type ) + { + detail::store_little_u64( u.data + 0, static_cast( gen() ) ); + detail::store_little_u64( u.data + 8, static_cast( gen() ) ); + } + + template static void fill_data( URNG& gen, uuid& u ) + { + fill_data_impl( gen, u, + std::integral_constant( -1 )>(), + std::integral_constant( -1 )>() + ); + } + // Detect whether UniformRandomNumberGenerator has a seed() method which indicates that // it is a PseudoRandomNumberGenerator and needs a seed to initialize it. This allows // basic_random_generator to take any type of UniformRandomNumberGenerator and still