Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-26 08:55:46

0001 #ifndef BOOST_UUID_BASIC_RANDOM_GENERATOR_HPP_INCLUDED
0002 #define BOOST_UUID_BASIC_RANDOM_GENERATOR_HPP_INCLUDED
0003 
0004 // Copyright 2010 Andy Tompkins
0005 // Copyright 2017 James E. King III
0006 // Copyright 2024 Peter Dimov
0007 // Distributed under the Boost Software License, Version 1.0.
0008 // https://www.boost.org/LICENSE_1_0.txt
0009 
0010 #include <boost/uuid/uuid.hpp>
0011 #include <boost/uuid/detail/random_provider.hpp>
0012 #include <boost/uuid/detail/endian.hpp>
0013 #include <boost/assert.hpp>
0014 #include <type_traits>
0015 #include <random>
0016 #include <cstdint>
0017 
0018 namespace boost {
0019 namespace uuids {
0020 
0021 template<class UniformRandomNumberGenerator>
0022 class basic_random_generator
0023 {
0024 private:
0025 
0026     UniformRandomNumberGenerator* p_;
0027     UniformRandomNumberGenerator g_;
0028 
0029 public:
0030 
0031     using result_type = uuid;
0032 
0033     // default constructor creates the random number generator and
0034     // if the UniformRandomNumberGenerator is a PseudoRandomNumberGenerator
0035     // then it gets seeded by a random_provider.
0036     basic_random_generator(): p_( 0 ), g_()
0037     {
0038         // seed the random number generator if it is capable
0039         seed( g_, 0 );
0040     }
0041 
0042     // keep a reference to a random number generator
0043     // don't seed a given random number generator
0044     explicit basic_random_generator( UniformRandomNumberGenerator& gen ): p_( &gen )
0045     {
0046     }
0047 
0048     // keep a pointer to a random number generator
0049     // don't seed a given random number generator
0050     explicit basic_random_generator( UniformRandomNumberGenerator* gen ): p_( gen )
0051     {
0052         BOOST_ASSERT( gen != 0 );
0053     }
0054 
0055     result_type operator()()
0056     {
0057         UniformRandomNumberGenerator& gen = p_? *p_: g_;
0058 
0059         std::uniform_int_distribution<std::uint32_t> dist;
0060 
0061         result_type u;
0062 
0063         detail::store_native_u32( u.data +  0, dist( gen ) );
0064         detail::store_native_u32( u.data +  4, dist( gen ) );
0065         detail::store_native_u32( u.data +  8, dist( gen ) );
0066         detail::store_native_u32( u.data + 12, dist( gen ) );
0067 
0068         // set variant
0069         // must be 0b10xxxxxx
0070         *(u.begin() + 8) &= 0x3F;
0071         *(u.begin() + 8) |= 0x80;
0072 
0073         // set version
0074         // must be 0b0100xxxx
0075         *(u.begin() + 6) &= 0x0F; //0b00001111
0076         *(u.begin() + 6) |= 0x40; //0b01000000
0077 
0078         return u;
0079     }
0080 
0081 private:
0082 
0083     // Detect whether UniformRandomNumberGenerator has a seed() method which indicates that
0084     // it is a PseudoRandomNumberGenerator and needs a seed to initialize it.  This allows
0085     // basic_random_generator to take any type of UniformRandomNumberGenerator and still
0086     // meet the post-conditions for the default constructor.
0087 
0088     template<class MaybePseudoRandomNumberGenerator, class En = decltype( std::declval<MaybePseudoRandomNumberGenerator&>().seed() )>
0089     void seed( MaybePseudoRandomNumberGenerator& rng, int )
0090     {
0091         detail::random_provider seeder;
0092         rng.seed(seeder);
0093     }
0094 
0095     template<class MaybePseudoRandomNumberGenerator>
0096     void seed( MaybePseudoRandomNumberGenerator&, long )
0097     {
0098     }
0099 };
0100 
0101 }} // namespace boost::uuids
0102 
0103 #endif // BOOST_UUID_BASIC_RANDOM_GENERATOR_HPP_INCLUDED