what is the best way to use the C type uuid_t as a key in a std::map?
Solution 1
I guess the best way of using third-party C-structures is to use them through their friendly functions. So if you wanna use uuid_t in STL, I'd suggest you to create some kind of C++ interface/wrapper to that structure like
struct Uuid {
uuid_t uuid;
Uuid(const Uuid &other) { uuid_copy(uuid, other.uuid); }
Uuid(const uuid_t other_uuid) { uuid_copy(uuid, other_uuid); }
void generateInplace() { uuid_generate(uuid); }
static Uuid generate() { Uuid wrapped; uuid_generate(wrapped.uuid); return wrapped; }
bool operator<(const Uuid &other) { return uuid_compare(uuid, other.uuid) < 0; }
bool operator==(const Uuid &other) { return uuid_compare(uuid, other.uuid) == 0; }
// ...
};
That should hide from you the fact that uuid_t
isn't structure but pointer to array (i.e. typedef unsigned char uuid_t[16]
).
Note: there is boost version of uuid library
Solution 2
The STL containers always contain copies of the object, and that applies to map keys, also.
The simplest way to support this is using a custom comparator for the map.
struct UUIDComparator
{
bool operator()(const uuid_t &a, const uuid_t &b)
{
//compare and return a < b
}
};
std::map<uuid_t, int, UUIDComparator> map;
Another slightly controversial solution would be to convert the uuid_t
into a std::pair<uint64_t, uint64_t>
as both types are 128 bits wide, and, AFAICT, layout compatible. And the std::pair
are directly usable as map keys.
std::map<std::pair<uint64_t, uint64_t>, int, UUIDComparator> map;
Solution 3
Simpler: uuid_unparse(...) converts it into a char* (37 chars long), which you can then wrap a string around...
Dave
By Day: Owner/Operator of Lumiera, a creative technology studio By Night: Build light sculptures and make music
Updated on June 04, 2022Comments
-
Dave almost 2 years
Is this an appropriate way to provide unique keys in a map? In other words, is the key being made from the unique value contained in the uuid, or is it being made from the pointer to the
uuid_t
struct? A side question, is there a more efficient container, when I don't care about the ordering by keys inside the container?#include <uuid/uuid.h> int main(int argc, char **argv) { std::map<uuid_t,int> myMap; uuid_t id1; uuid_t id2; uuid_generate( (unsigned char *)&id1 ); uuid_generate( (unsigned char *)&id2 ); myMap[id1] = 5; myMap[id2] = 4; }