diff --git a/include/uuid.h b/include/uuid.h index 42b0cb2..7d10405 100644 --- a/include/uuid.h +++ b/include/uuid.h @@ -31,7 +31,7 @@ namespace uuids // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // indicated by a bit pattern in octet 8, marked with N in xxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxx - enum class variant_type + enum class uuid_variant { // NCS backward compatibility (with the obsolete Apollo Network Computing System 1.5 UUID format) // N bit pattern: 0xxx @@ -58,7 +58,7 @@ namespace uuids }; // indicated by a bit pattern in octet 6, marked with M in xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx - enum class version_type + enum class uuid_version { none = 0, // only possible for nil or invalid uuids time_based = 1, // The time-based version specified in RFC 4122 @@ -68,19 +68,6 @@ namespace uuids name_based_sha1 = 5 // The name-based version specified in RFS 4122 with SHA1 hashing }; - struct guid_exception : public std::runtime_error - { - explicit guid_exception(std::string const & message) - : std::runtime_error(message.c_str()) - { - } - - explicit guid_exception(char const * const message) - : std::runtime_error(message) - { - } - }; - struct uuid { public: @@ -103,32 +90,32 @@ namespace uuids explicit uuid(std::string const & str); explicit uuid(std::wstring const & str); - constexpr variant_type variant() const noexcept + constexpr uuid_variant variant() const noexcept { if ((data[8] & 0x80) == 0x00) - return variant_type::ncs; + return uuid_variant::ncs; else if ((data[8] & 0xC0) == 0x80) - return variant_type::rfc; + return uuid_variant::rfc; else if ((data[8] & 0xE0) == 0xC0) - return variant_type::microsoft; + return uuid_variant::microsoft; else - return variant_type::future; + return uuid_variant::future; } - constexpr version_type version() const + constexpr uuid_version version() const { if ((data[6] & 0xF0) == 0x10) - return version_type::time_based; + return uuid_version::time_based; else if ((data[6] & 0xF0) == 0x20) - return version_type::dce_security; + return uuid_version::dce_security; else if ((data[6] & 0xF0) == 0x30) - return version_type::name_based_md5; + return uuid_version::name_based_md5; else if ((data[6] & 0xF0) == 0x40) - return version_type::random_number_based; + return uuid_version::random_number_based; else if ((data[6] & 0xF0) == 0x50) - return version_type::name_based_sha1; + return uuid_version::name_based_sha1; else - return version_type::none; + return uuid_version::none; } constexpr std::size_t size() const noexcept { return 16; } @@ -182,6 +169,7 @@ namespace uuids std::array data{ 0 }; friend bool operator==(uuid const & lhs, uuid const & rhs) noexcept; + friend bool operator<(uuid const & lhs, uuid const & rhs) noexcept; template void create(TChar const * const str, size_t const size); @@ -200,6 +188,11 @@ namespace uuids return !(lhs == rhs); } + inline bool operator< (uuid const& lhs, uuid const& rhs) noexcept + { + return lhs.data < rhs.data; + } + template std::basic_ostream & operator<<(std::basic_ostream &s, uuid const & id) { diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..bb35e58 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1 @@ +CMakeFiles \ No newline at end of file diff --git a/test/test.cpp b/test/test.cpp index 51683dd..61a7edd 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,31 +1,53 @@ #include "..\include\uuid.h" #include #include +#include +#include int main() { using namespace uuids; { - std::cout << "Test nill" << std::endl; + std::cout << "Test default constructor" << std::endl; uuid empty; assert(empty.is_nil()); assert(empty.size() == 16); } + { + std::cout << "Test string constructor" << std::endl; + + using namespace std::string_literals; + + auto str = "47183823-2574-4bfd-b411-99ed177d3e43"s; + uuid guid(str); + assert(guid.string() == str); + } + + { + std::cout << "Test wstring constructor" << std::endl; + + using namespace std::string_literals; + + auto str = L"47183823-2574-4bfd-b411-99ed177d3e43"s; + uuid guid(str); + assert(guid.wstring() == str); + } + { std::cout << "Test make" << std::endl; uuid const guid = uuids::make_uuid(); assert(!guid.is_nil()); assert(guid.size() == 16); - assert(guid.version() == uuids::version_type::random_number_based); - assert(guid.variant() == uuids::variant_type::rfc); + assert(guid.version() == uuids::uuid_version::random_number_based); + assert(guid.variant() == uuids::uuid_variant::rfc); } { - std::cout << "Test comparison" << std::endl; + std::cout << "Test equality" << std::endl; uuid empty; uuid guid = uuids::make_uuid(); @@ -35,6 +57,49 @@ int main() assert(empty != guid); } + { + std::cout << "Test comparison" << std::endl; + + auto empty = uuid{}; + auto id = make_uuid(); + + assert(empty < id); + + std::set ids{ + uuid{}, + uuids::make_uuid(), + uuids::make_uuid(), + uuids::make_uuid(), + uuids::make_uuid() + }; + + assert(ids.size() == 5); + assert(ids.find(uuid{}) != ids.end()); + } + + { + std::cout << "Test hashing" << std::endl; + + using namespace std::string_literals; + auto str = "47183823-2574-4bfd-b411-99ed177d3e43"s; + auto guid = uuid{ str }; + + auto h1 = std::hash{}; + auto h2 = std::hash{}; + assert(h1(str) == h2(guid)); + + std::unordered_set ids{ + uuid{}, + uuids::make_uuid(), + uuids::make_uuid(), + uuids::make_uuid(), + uuids::make_uuid() + }; + + assert(ids.size() == 5); + assert(ids.find(uuid{}) != ids.end()); + } + { std::cout << "Test swap" << std::endl; @@ -61,27 +126,7 @@ int main() uuid empty; assert(empty.string() == "00000000-0000-0000-0000-000000000000"); assert(empty.wstring() == L"00000000-0000-0000-0000-000000000000"); - } - - { - std::cout << "Test string constructor" << std::endl; - - using namespace std::string_literals; - - auto str = "47183823-2574-4bfd-b411-99ed177d3e43"s; - uuid guid(str); - assert(guid.string() == str); - } - - { - std::cout << "Test wstring constructor" << std::endl; - - using namespace std::string_literals; - - auto str = L"47183823-2574-4bfd-b411-99ed177d3e43"s; - uuid guid(str); - assert(guid.wstring() == str); - } + } { std::cout << "Test constexpr" << std::endl; @@ -89,8 +134,8 @@ int main() constexpr uuid empty; constexpr bool isnil = empty.is_nil(); constexpr size_t size = empty.size(); - constexpr uuids::variant_type variant = empty.variant(); - constexpr uuids::version_type version = empty.version(); + constexpr uuid_variant variant = empty.variant(); + constexpr uuid_version version = empty.version(); } std::cout << "ALL PASSED" << std::endl;