UUID: add less-than operator

Add `operator<` to C++ class to allow lexicographic ordering of UUIDs.

This will be necessary when writing asset catalogs to disk in a predictable
(i.e. ordered) manner.
This commit is contained in:
2021-09-24 12:55:26 +02:00
parent 2b9ca0f112
commit ab9644382d
3 changed files with 47 additions and 0 deletions

View File

@@ -98,6 +98,11 @@ class bUUID : public ::bUUID {
bool operator==(bUUID uuid1, bUUID uuid2); bool operator==(bUUID uuid1, bUUID uuid2);
bool operator!=(bUUID uuid1, bUUID uuid2); bool operator!=(bUUID uuid1, bUUID uuid2);
/**
* Lexicographic comparison of the UUIDs.
* Equivalent to string comparison on the formatted UUIDs. */
bool operator<(bUUID uuid1, bUUID uuid2);
} // namespace blender } // namespace blender
#endif #endif

View File

@@ -27,6 +27,7 @@
#include <random> #include <random>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <tuple>
/* Ensure the UUID struct doesn't have any padding, to be compatible with memcmp(). */ /* Ensure the UUID struct doesn't have any padding, to be compatible with memcmp(). */
static_assert(sizeof(bUUID) == 16, "expect UUIDs to be 128 bit exactly"); static_assert(sizeof(bUUID) == 16, "expect UUIDs to be 128 bit exactly");
@@ -189,4 +190,22 @@ bool operator!=(const bUUID uuid1, const bUUID uuid2)
return !(uuid1 == uuid2); return !(uuid1 == uuid2);
} }
bool operator<(const bUUID uuid1, const bUUID uuid2)
{
auto simple_fields1 = std::tie(uuid1.time_low,
uuid1.time_mid,
uuid1.time_hi_and_version,
uuid1.clock_seq_hi_and_reserved,
uuid1.clock_seq_low);
auto simple_fields2 = std::tie(uuid2.time_low,
uuid2.time_mid,
uuid2.time_hi_and_version,
uuid2.clock_seq_hi_and_reserved,
uuid2.clock_seq_low);
if (simple_fields1 == simple_fields2) {
return std::memcmp(uuid1.node, uuid2.node, sizeof(uuid1.node)) < 0;
}
return simple_fields1 < simple_fields2;
}
} // namespace blender } // namespace blender

View File

@@ -75,6 +75,29 @@ TEST(BLI_uuid, equality)
EXPECT_NE(uuid1, uuid2); EXPECT_NE(uuid1, uuid2);
} }
TEST(BLI_uuid, comparison_trivial)
{
const bUUID uuid0{};
const bUUID uuid1("11111111-1111-1111-1111-111111111111");
const bUUID uuid2("22222222-2222-2222-2222-222222222222");
EXPECT_LT(uuid0, uuid1);
EXPECT_LT(uuid0, uuid2);
EXPECT_LT(uuid1, uuid2);
}
TEST(BLI_uuid, comparison_byte_order_check)
{
const bUUID uuid0{};
/* Chosen to test byte ordering is taken into account correctly when comparing. */
const bUUID uuid12("12222222-2222-2222-2222-222222222222");
const bUUID uuid21("21111111-1111-1111-1111-111111111111");
EXPECT_LT(uuid0, uuid12);
EXPECT_LT(uuid0, uuid21);
EXPECT_LT(uuid12, uuid21);
}
TEST(BLI_uuid, string_formatting) TEST(BLI_uuid, string_formatting)
{ {
bUUID uuid; bUUID uuid;