I think you've already solved this problem for most practical purposes by finding Boost::Uuid, with the exception of your requirement to recycle identifiers already generated.
From the documentation you linked to in the question:
When UUIDs are generated by one of the
defined mechanisms, they are either
guaranteed to be unique, different
from all other generated UUIDs (that
is, it has never been generated before
and it will never be generated again),
or it is extremely likely to be unique
(depending on the mechanism).
If you're hell-bent on recycling and re-using existing identifiers, I suppose you could maintain build up a pool of UUIDs over time, generating new ones only when you need one and find that the pool is empty. But I can't imagine a scenario where that would be preferable to generating a new UUID.
EDIT: You've commented that you need a guarantee as to uniqueness. Realistically, you're never going to get one when programatically generating a unique identifier. In practice, you're going to store the generated ID in a data type which has finite size, and so the possible set of IDs you can generate is finite too. IMHO, the best you can achieve then is to simulate uniqueness within a tolerance threshold.
You could do this by
Using a technique that makes the chances of getting a duplicate UUID very remote (this is what Boost::UUID will do);
Wrapping the generation of the highly-probably-to-be-unique UUID in some other logic that looks up the newly-generated UUID in a list of already-generated UUIDs to eliminate that tiny chance that the new one is a duplicate. Obviously, the practicality of doing this becomes decreases as you approach very large quantities of UUIDs in your list. How many do you anticipate generating?
If you want truly huge quantities of unique IDs, bigger than would fit in a native type, you could implement a type that manages the memory and does the necessary maths, and just produce sequential Ids, or you could perhaps use something like the GNU Bignum Library to do it for you.
sprintf("id%d", ++id)
with a static id counter and it'd be good for a couple billion values, or return astd::string
after+= 'x'
;-). If in practice the values aren't exhausted, recycling could be a no-op, or you could create a deque<> and use it preferentially. What other constraints / expectations do you really have... on length, format, performance, cross-host uniqueness, cross-process-run uniqueness etc.? Or are we supposed to infer requirements akin to Boost::Uuid's purpose? – Hindgutint
, or even chain 2 with a simpleif (!++low_order) ++high_order;
...? That ought to be ok until the sun burns out.... – Hindgutboost::random_device
as the source forboost::uuids::random_generator
. – Tupper