Chris@16: // Boost random_generator.hpp header file ----------------------------------------------// Chris@16: Chris@16: // Copyright 2010 Andy Tompkins. Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_UUID_RANDOM_GENERATOR_HPP Chris@16: #define BOOST_UUID_RANDOM_GENERATOR_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace uuids { Chris@16: Chris@16: // generate a random-based uuid Chris@16: template Chris@16: class basic_random_generator { Chris@16: private: Chris@16: typedef uniform_int distribution_type; Chris@16: typedef variate_generator generator_type; Chris@16: Chris@16: struct null_deleter Chris@16: { Chris@16: void operator()(void const *) const {} Chris@16: }; Chris@16: Chris@16: public: Chris@16: typedef uuid result_type; Chris@16: Chris@16: // default constructor creates the random number generator Chris@16: basic_random_generator() Chris@16: : pURNG(new UniformRandomNumberGenerator) Chris@16: , generator Chris@16: ( pURNG.get() Chris@16: , distribution_type Chris@16: ( (std::numeric_limits::min)() Chris@16: , (std::numeric_limits::max)() Chris@16: ) Chris@16: ) Chris@16: { Chris@16: // seed the random number generator Chris@16: detail::seed(*pURNG); Chris@16: } Chris@16: Chris@16: // keep a reference to a random number generator Chris@16: // don't seed a given random number generator Chris@16: explicit basic_random_generator(UniformRandomNumberGenerator& gen) Chris@16: : pURNG(&gen, null_deleter()) Chris@16: , generator Chris@16: ( pURNG.get() Chris@16: , distribution_type Chris@16: ( (std::numeric_limits::min)() Chris@16: , (std::numeric_limits::max)() Chris@16: ) Chris@16: ) Chris@16: {} Chris@16: Chris@16: // keep a pointer to a random number generator Chris@16: // don't seed a given random number generator Chris@16: explicit basic_random_generator(UniformRandomNumberGenerator* pGen) Chris@16: : pURNG(pGen, null_deleter()) Chris@16: , generator Chris@16: ( pURNG.get() Chris@16: , distribution_type Chris@16: ( (std::numeric_limits::min)() Chris@16: , (std::numeric_limits::max)() Chris@16: ) Chris@16: ) Chris@16: { Chris@16: BOOST_ASSERT(pURNG); Chris@16: } Chris@16: Chris@16: uuid operator()() Chris@16: { Chris@16: uuid u; Chris@16: Chris@16: int i=0; Chris@16: unsigned long random_value = generator(); Chris@16: for (uuid::iterator it=u.begin(); it!=u.end(); ++it, ++i) { Chris@16: if (i==sizeof(unsigned long)) { Chris@16: random_value = generator(); Chris@16: i = 0; Chris@16: } Chris@16: Chris@16: // static_cast gets rid of warnings of converting unsigned long to boost::uint8_t Chris@16: *it = static_cast((random_value >> (i*8)) & 0xFF); Chris@16: } Chris@16: Chris@16: // set variant Chris@16: // must be 0b10xxxxxx Chris@16: *(u.begin()+8) &= 0xBF; Chris@16: *(u.begin()+8) |= 0x80; Chris@16: Chris@16: // set version Chris@16: // must be 0b0100xxxx Chris@16: *(u.begin()+6) &= 0x4F; //0b01001111 Chris@16: *(u.begin()+6) |= 0x40; //0b01000000 Chris@16: Chris@16: return u; Chris@16: } Chris@16: Chris@16: private: Chris@16: shared_ptr pURNG; Chris@16: generator_type generator; Chris@16: }; Chris@16: Chris@16: typedef basic_random_generator random_generator; Chris@16: Chris@16: }} // namespace boost::uuids Chris@16: Chris@16: #endif //BOOST_UUID_RANDOM_GENERATOR_HPP