
Andy wrote: ...
template <typename Engine>
We can supply a default here: template<class Engine = mt19937> It's still slightly less convenient to use uuid_generator<> g; and I'm not quite sure why one would want to replace the default engine, but it's good enough, I guess.
class uuid_generator { unsigned rd_[5]; Engine en_;
uuid_generator() { init rd_; seed en_ with rd_[4]; }
uuid operator() { generate a 128-bit number using en_; xor it with rd_[0..3]; return a uuid based on it; } };
But, how does the xor part help? It is just for the case where we are only producing one uuid?
The xor part just varies the sequence produced by the RNG by rd_[0..3]. The RNG seeded by the 32-bit value rd_[4] can produce 2^32 distinct UUID sequences. With the xor part - and assuming that the contents of rd_[] are random for simplicity - it will produce 2^32 * 2^128 distinct UUID sequences. The statistical properties of the UUID sequence will still correspond to the original 2^32 source, but this doesn't matter for our purposes since UUID's or their bits are not cross-checked for correlations with one another, only collisions matter. In short, the above is a relatively easy way to approximate a RNG seeded with the entire contents of rd_ instead of throwing 4/5 of it away. You said earlier that you had a problem with the iterator range seed, and if Engine is a template parameter, we probably need to support engines that only take a 32 bit seed anyway. It also has the advantage of being "obviously" at least as random as just using the Engine, so this should help alleviate people's concerns. :-)