diff --git a/include/uuid.h b/include/uuid.h index 95b15f9..f2e2c50 100644 --- a/include/uuid.h +++ b/include/uuid.h @@ -501,10 +501,67 @@ namespace uuids constexpr uuid_const_iterator begin() const noexcept { return uuid_const_iterator(&data[0], 0); } constexpr uuid_const_iterator end() const noexcept { return uuid_const_iterator(&data[0], 16); } - inline gsl::span as_bytes() const + constexpr inline gsl::span as_bytes() const { return gsl::span(reinterpret_cast(data.data()), 16); } + + template + static uuid from_string(TChar const * const str, size_t const size) + { + TChar digit = 0; + bool firstDigit = true; + int hasBraces = 0; + size_t index = 0; + std::array data{ { 0 } }; + + if (str == nullptr || size == 0) + throw uuid_error{ "Wrong uuid format" }; + + if (str[0] == static_cast('{')) + hasBraces = 1; + if (hasBraces && str[size - 1] != static_cast('}')) + throw uuid_error{ "Wrong uuid format" }; + + for (size_t i = hasBraces; i < size - hasBraces; ++i) + { + if (str[i] == static_cast('-')) continue; + + if (index >= 16 || !detail::is_hex(str[i])) + { + throw uuid_error{ "Wrong uuid format" }; + } + + if (firstDigit) + { + digit = str[i]; + firstDigit = false; + } + else + { + data[index++] = detail::hexpair2char(digit, str[i]); + firstDigit = true; + } + } + + if (index < 16) + { + throw uuid_error{ "Wrong uuid format" }; + } + + return uuid{ std::cbegin(data), std::cend(data) }; + } + + static uuid from_string(std::string_view str) + { + return from_string(str.data(), str.size()); + } + + static uuid from_string(std::wstring_view str) + { + return from_string(str.data(), str.size()); + } + private: std::array data{ { 0 } }; @@ -569,62 +626,6 @@ namespace uuids << std::setw(2) << (int)id.data[15]; } - template - inline uuid from_string(TChar const * const str, size_t const size) - { - TChar digit = 0; - bool firstDigit = true; - int hasBraces = 0; - size_t index = 0; - std::array data{ { 0 } }; - - if(str == nullptr || size == 0) - throw uuid_error{ "Wrong uuid format" }; - - if (str[0] == static_cast('{')) - hasBraces = 1; - if(hasBraces && str[size-1] != static_cast('}')) - throw uuid_error{ "Wrong uuid format" }; - - for (size_t i = hasBraces; i < size - hasBraces; ++i) - { - if (str[i] == static_cast('-')) continue; - - if (index >= 16 || !detail::is_hex(str[i])) - { - throw uuid_error{"Wrong uuid format"}; - } - - if (firstDigit) - { - digit = str[i]; - firstDigit = false; - } - else - { - data[index++] = detail::hexpair2char(digit, str[i]); - firstDigit = true; - } - } - - if (index < 16) - { - throw uuid_error{"Wrong uuid format"}; - } - - return uuid{std::cbegin(data), std::cend(data)}; - } - - inline uuid from_string(std::string_view str) - { - return from_string(str.data(), str.size()); - } - - inline uuid from_string(std::wstring_view str) - { - return from_string(str.data(), str.size()); - } - inline std::string to_string(uuid const & id) { std::stringstream sstr; diff --git a/test/test_generators.cpp b/test/test_generators.cpp index 180c483..394c2b9 100644 --- a/test/test_generators.cpp +++ b/test/test_generators.cpp @@ -190,7 +190,7 @@ TEST_CASE("Test basic random generator (conversion ctor w/ ref) w/ ranlux48_base TEST_CASE("Test name generator", "[gen][name]") { - uuids::uuid_name_generator dgen(uuids::from_string("47183823-2574-4bfd-b411-99ed177d3e43")); + uuids::uuid_name_generator dgen(uuids::uuid::from_string("47183823-2574-4bfd-b411-99ed177d3e43")); auto id1 = dgen("john"); REQUIRE(!id1.is_nil()); REQUIRE(id1.size() == 16); diff --git a/test/test_uuid.cpp b/test/test_uuid.cpp index e0293d1..8e418b1 100644 --- a/test/test_uuid.cpp +++ b/test/test_uuid.cpp @@ -21,25 +21,25 @@ TEST_CASE("Test from_string(string_view)", "[parse]") { auto str = "47183823-2574-4bfd-b411-99ed177d3e43"s; - auto guid = uuids::from_string(str); + auto guid = uuids::uuid::from_string(str); REQUIRE(uuids::to_string(guid) == str); } { auto str = "{47183823-2574-4bfd-b411-99ed177d3e43}"s; - auto guid = uuids::from_string(str); + auto guid = uuids::uuid::from_string(str); REQUIRE(uuids::to_string(guid) == "47183823-2574-4bfd-b411-99ed177d3e43"); } { - auto guid = uuids::from_string("47183823-2574-4bfd-b411-99ed177d3e43"); + auto guid = uuids::uuid::from_string("47183823-2574-4bfd-b411-99ed177d3e43"); REQUIRE(uuids::to_string(guid) == "47183823-2574-4bfd-b411-99ed177d3e43"); REQUIRE(uuids::to_wstring(guid) == L"47183823-2574-4bfd-b411-99ed177d3e43"); } { auto str = "4718382325744bfdb41199ed177d3e43"s; - REQUIRE_NOTHROW(uuids::from_string(str)); + REQUIRE_NOTHROW(uuids::uuid::from_string(str)); } } @@ -48,7 +48,7 @@ TEST_CASE("Test from_string(wstring_view)", "[parse]") using namespace std::string_literals; auto str = L"47183823-2574-4bfd-b411-99ed177d3e43"s; - auto guid = uuids::from_string(str); + auto guid = uuids::uuid::from_string(str); REQUIRE(uuids::to_wstring(guid) == str); } @@ -58,32 +58,32 @@ TEST_CASE("Test from_string invalid format", "[parse]") { auto str = ""s; - REQUIRE_THROWS_AS(uuids::from_string(str), uuids::uuid_error); + REQUIRE_THROWS_AS(uuids::uuid::from_string(str), uuids::uuid_error); } { auto str = "{}"s; - REQUIRE_THROWS_AS(uuids::from_string(str), uuids::uuid_error); + REQUIRE_THROWS_AS(uuids::uuid::from_string(str), uuids::uuid_error); } { auto str = "47183823-2574-4bfd-b411-99ed177d3e4"s; - REQUIRE_THROWS_AS(uuids::from_string(str), uuids::uuid_error); + REQUIRE_THROWS_AS(uuids::uuid::from_string(str), uuids::uuid_error); } { auto str = "47183823-2574-4bfd-b411-99ed177d3e430"s; - REQUIRE_THROWS_AS(uuids::from_string(str), uuids::uuid_error); + REQUIRE_THROWS_AS(uuids::uuid::from_string(str), uuids::uuid_error); } { auto str = "{47183823-2574-4bfd-b411-99ed177d3e43"s; - REQUIRE_THROWS_AS(uuids::from_string(str), uuids::uuid_error); + REQUIRE_THROWS_AS(uuids::uuid::from_string(str), uuids::uuid_error); } { auto str = "47183823-2574-4bfd-b411-99ed177d3e43}"s; - REQUIRE_THROWS_AS(uuids::from_string(str), uuids::uuid_error); + REQUIRE_THROWS_AS(uuids::uuid::from_string(str), uuids::uuid_error); } } @@ -150,7 +150,7 @@ TEST_CASE("Test hashing", "[ops]") { using namespace std::string_literals; auto str = "47183823-2574-4bfd-b411-99ed177d3e43"s; - auto guid = uuids::from_string(str); + auto guid = uuids::uuid::from_string(str); auto h1 = std::hash{}; auto h2 = std::hash{}; @@ -218,7 +218,7 @@ TEST_CASE("Test iterators", "[iter]") } { - const uuid guid = uuids::from_string("47183823-2574-4bfd-b411-99ed177d3e43"); + const uuid guid = uuids::uuid::from_string("47183823-2574-4bfd-b411-99ed177d3e43"); REQUIRE(!guid.is_nil()); REQUIRE(uuids::to_string(guid) == "47183823-2574-4bfd-b411-99ed177d3e43"); @@ -246,11 +246,11 @@ TEST_CASE("Test size", "[operators]") TEST_CASE("Test assignment", "[ops]") { - auto id1 = uuids::from_string("47183823-2574-4bfd-b411-99ed177d3e43"); + auto id1 = uuids::uuid::from_string("47183823-2574-4bfd-b411-99ed177d3e43"); auto id2 = id1; REQUIRE(id1 == id2); - id1 = uuids::from_string("{fea43102-064f-4444-adc2-02cec42623f8}"); + id1 = uuids::uuid::from_string("{fea43102-064f-4444-adc2-02cec42623f8}"); REQUIRE(id1 != id2); auto id3 = std::move(id2);