From 1f7c5191b7b82528e071a284911ddcb6544d3234 Mon Sep 17 00:00:00 2001 From: Laurent Georget Date: Fri, 10 Jul 2020 08:08:22 +0200 Subject: [PATCH] Add == and < operators on CassUuid-s to make them usable in std::set, std::map, etc. containers --- include/cassandra.h | 5 +++ include/uuid_operators.hpp | 48 +++++++++++++++++++++++++++++ src/uuids.cpp | 12 ++++++++ tests/src/unit/tests/test_uuids.cpp | 32 +++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 include/uuid_operators.hpp diff --git a/include/cassandra.h b/include/cassandra.h index d08f64b69..29d00f2a3 100644 --- a/include/cassandra.h +++ b/include/cassandra.h @@ -144,6 +144,11 @@ typedef struct CassUuid_ { cass_uint64_t clock_seq_and_node; } CassUuid; +#ifdef __cplusplus +// If the current project is a C++ one, expose C++ operators on CassUuid. +#include "uuid_operators.hpp" +#endif + /** * A cluster object describes the configuration of the Cassandra cluster and is used * to construct a session instance. Unlike other DataStax drivers the cluster object diff --git a/include/uuid_operators.hpp b/include/uuid_operators.hpp new file mode 100644 index 000000000..6d32dc016 --- /dev/null +++ b/include/uuid_operators.hpp @@ -0,0 +1,48 @@ +/* + Copyright (c) DataStax, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __UUID_OPERATORS_HPP_INCLUDED__ +#define __UUID_OPERATORS_HPP_INCLUDED__ + +#ifdef __cplusplus +#include "cassandra.h" + +/** + * Compare two UUIDs for ordering + * + * This operator is useful to use CassUuid variables as std::map keys, for + * instance. + * + * @param uuid1 A UUID + * @param uuid2 Another UUID + * @return true if, and only if, uuid1 is numerically less or equal than uuid2 + */ +bool operator<(const CassUuid& uuid1, const CassUuid& uuid2); + +/** + * Compare two UUIDs for equality + * + * This operator is useful to use CassUuid variables as std::map keys, for + * instance. + * + * @param uuid1 A UUID + * @param uuid2 Another UUID + * @return true if, and only if, uuid1 is numerically less or equal than uuid2 + */ +bool operator==(const CassUuid& uuid1, const CassUuid& uuid2); +#endif + +#endif /* __UUID_OPERATORS_HPP_INCLUDED__ */ diff --git a/src/uuids.cpp b/src/uuids.cpp index 1bd0d3bd3..32b90d48c 100644 --- a/src/uuids.cpp +++ b/src/uuids.cpp @@ -44,6 +44,18 @@ static uint64_t set_version(uint64_t timestamp, uint8_t version) { return (timestamp & 0x0FFFFFFFFFFFFFFFLL) | (static_cast(version) << 60); } +bool operator<(const CassUuid& uuid1, const CassUuid& uuid2) { + if (uuid1.time_and_version == uuid2.time_and_version) + return uuid1.clock_seq_and_node < uuid2.clock_seq_and_node; + else + return uuid1.time_and_version < uuid2.time_and_version; +} + +bool operator==(const CassUuid& uuid1, const CassUuid& uuid2) { + return uuid1.time_and_version == uuid2.time_and_version + && uuid1.clock_seq_and_node == uuid2.clock_seq_and_node; +} + extern "C" { CassUuidGen* cass_uuid_gen_new() { return CassUuidGen::to(new UuidGen()); } diff --git a/tests/src/unit/tests/test_uuids.cpp b/tests/src/unit/tests/test_uuids.cpp index af08bb477..aa8e76e9d 100644 --- a/tests/src/unit/tests/test_uuids.cpp +++ b/tests/src/unit/tests/test_uuids.cpp @@ -167,3 +167,35 @@ TEST(UuidUnitTest, FromStringInvalid) { EXPECT_EQ(cass_uuid_from_string_n("00-00-00-00-11-11-11-11-22-22-22-22-deadbeaf", 36, &uuid), CASS_ERROR_LIB_BAD_PARAMS); } + +TEST(UuidUnitTest, Operators) { + CassUuid uuid1 = { 0x0000112233445566LL, 0x0000112233445566LL }; + CassUuid uuid2 = { 0x0000112233445566LL, 0x0000112233445566LL }; + CassUuid uuid3 = { 0x9988776655443322LL, 0x0000112233445566LL }; + CassUuid uuid4 = { 0x9988776655443322LL, 0x9988776655443322LL }; + + // uuid1 == uuid2 + EXPECT_TRUE(uuid1 == uuid2); + // uuid1 != uuid3 + EXPECT_FALSE(uuid1 == uuid3); + // uuid1 != uuid4 + EXPECT_FALSE(uuid1 == uuid4); + // uuid2 != uuid3 + EXPECT_FALSE(uuid2 == uuid3); + // uuid2 != uuid3 + EXPECT_FALSE(uuid2 == uuid4); + // uuid3 != uuid4 + EXPECT_FALSE(uuid3 == uuid4); + // uuid1 >= uuid2 + EXPECT_FALSE(uuid1 < uuid2); + // uuid1 < uuid3 + EXPECT_TRUE(uuid1 < uuid3); + // uuid1 < uuid4 + EXPECT_TRUE(uuid1 < uuid4); + // uuid2 < uuid3 + EXPECT_TRUE(uuid2 < uuid3); + // uuid2 < uuid3 + EXPECT_TRUE(uuid2 < uuid4); + // uuid3 < uuid4 + EXPECT_TRUE(uuid3 < uuid4); +}