From ab9644382d14eb1254ce33e38227c874fd80a08f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 24 Sep 2021 12:55:26 +0200 Subject: 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. --- source/blender/blenlib/BLI_uuid.h | 5 +++++ source/blender/blenlib/intern/uuid.cc | 19 +++++++++++++++++++ source/blender/blenlib/tests/BLI_uuid_test.cc | 23 +++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/source/blender/blenlib/BLI_uuid.h b/source/blender/blenlib/BLI_uuid.h index 98a600a5de8..ed0d31b625f 100644 --- a/source/blender/blenlib/BLI_uuid.h +++ b/source/blender/blenlib/BLI_uuid.h @@ -98,6 +98,11 @@ class bUUID : public ::bUUID { 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 #endif diff --git a/source/blender/blenlib/intern/uuid.cc b/source/blender/blenlib/intern/uuid.cc index fe237b8aae6..3c86238036c 100644 --- a/source/blender/blenlib/intern/uuid.cc +++ b/source/blender/blenlib/intern/uuid.cc @@ -27,6 +27,7 @@ #include #include #include +#include /* 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"); @@ -189,4 +190,22 @@ bool operator!=(const bUUID uuid1, const bUUID 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 diff --git a/source/blender/blenlib/tests/BLI_uuid_test.cc b/source/blender/blenlib/tests/BLI_uuid_test.cc index f2160f614ba..b406a0521a1 100644 --- a/source/blender/blenlib/tests/BLI_uuid_test.cc +++ b/source/blender/blenlib/tests/BLI_uuid_test.cc @@ -75,6 +75,29 @@ TEST(BLI_uuid, equality) 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) { bUUID uuid; -- cgit v1.2.3