Last active
August 10, 2024 06:24
-
-
Save AlexBAV/b58e92d7632bae5d6f5947be455f796f to your computer and use it in GitHub Desktop.
Revisions
-
AlexBAV revised this gist
Aug 3, 2018 . 1 changed file with 9 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,10 @@ //------------------------------------------------------------------------------------------------------- // constexpr GUID parsing // Written by Alexander Bessonov // // Licensed under the MIT license. //------------------------------------------------------------------------------------------------------- #pragma once #include <stdexcept> #include <string> @@ -18,8 +25,8 @@ namespace guid_parse { namespace details { constexpr const size_t short_guid_form_length = 36; // XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX constexpr const size_t long_guid_form_length = 38; // {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} // constexpr int parse_hex_digit(const char c) -
AlexBAV revised this gist
Nov 27, 2017 . 1 changed file with 16 additions and 10 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -18,6 +18,9 @@ namespace guid_parse { namespace details { constexpr const size_t short_guid_form_length = 36; // {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} constexpr const size_t long_guid_form_length = 38; // XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX // constexpr int parse_hex_digit(const char c) { @@ -64,14 +67,16 @@ namespace guid_parse constexpr GUID make_guid(const char(&str)[N]) { using namespace std::string_literals; static_assert(N == (long_guid_form_length + 1) || N == (short_guid_form_length + 1), "String GUID of the form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} or XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX is expected"); if constexpr(N == (long_guid_form_length + 1)) { if (str[0] != '{' || str[long_guid_form_length - 1] != '}') throw std::domain_error{ "Missing opening or closing brace"s }; } return make_guid_helper(str + (N == (long_guid_form_length + 1) ? 1 : 0)); } } using details::make_guid; @@ -80,13 +85,14 @@ namespace guid_parse constexpr GUID operator "" _guid(const char *str, size_t N) { using namespace std::string_literals; using namespace details; if (!(N == long_guid_form_length || N == short_guid_form_length)) throw std::domain_error{ "String GUID of the form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} or XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX is expected"s }; if (N == long_guid_form_length && (str[0] != '{' || str[long_guid_form_length - 1] != '}')) throw std::domain_error{ "Missing opening or closing brace"s }; return make_guid_helper(str + (N == long_guid_form_length ? 1 : 0)); } } } -
AlexBAV revised this gist
Nov 24, 2017 . 1 changed file with 0 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -65,7 +65,6 @@ namespace guid_parse { using namespace std::string_literals; static_assert(N == 39 || N == 37, "GUIDs of the form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} or XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX are allowed"); if (N == 39 && (str[0]!='{' || str[37]!='}')) throw std::domain_error{ "Missing opening and closing brace"s }; -
AlexBAV revised this gist
Nov 24, 2017 . 1 changed file with 30 additions and 10 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -42,18 +42,9 @@ namespace guid_parse return result; } constexpr GUID make_guid_helper(const char *begin) { GUID result{}; result.Data1 = parse_hex<uint32_t>(begin); begin += 8 + 1; result.Data2 = parse_hex<uint16_t>(begin); @@ -68,6 +59,35 @@ namespace guid_parse result.Data4[i + 2] = parse_hex<uint8_t>(begin + i * 2); return result; } template<size_t N> constexpr GUID make_guid(const char(&str)[N]) { using namespace std::string_literals; static_assert(N == 39 || N == 37, "GUIDs of the form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} or XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX are allowed"); constexpr auto base = N == 39 ? 1 : 0; if (N == 39 && (str[0]!='{' || str[37]!='}')) throw std::domain_error{ "Missing opening and closing brace"s }; return make_guid_helper(str + (N == 39 ? 1 : 0)); } } using details::make_guid; namespace literals { constexpr GUID operator "" _guid(const char *str, size_t N) { using namespace std::string_literals; if (!(N == 38 || N == 36)) throw std::domain_error{ "GUIDs of the form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} or XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX are allowed"s }; if (N == 38 && (str[0] != '{' || str[37] != '}')) throw std::domain_error{ "Missing opening and closing brace"s }; return details::make_guid_helper(str + (N == 38 ? 1 : 0)); } } } -
AlexBAV created this gist
Nov 24, 2017 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,73 @@ #pragma once #include <stdexcept> #include <string> #include <cassert> #include <cstdint> #if !defined(GUID_DEFINED) #define GUID_DEFINED struct GUID { uint32_t Data1; uint16_t Data2; uint16_t Data3; uint8_t Data4[8]; }; #endif namespace guid_parse { namespace details { // constexpr int parse_hex_digit(const char c) { using namespace std::string_literals; if ('0' <= c && c <= '9') return c - '0'; else if ('a' <= c && c <= 'f') return 10 + c - 'a'; else if ('A' <= c && c <= 'F') return 10 + c - 'A'; else throw std::domain_error{ "invalid character in GUID"s }; } template<class T> constexpr T parse_hex(const char *ptr) { constexpr size_t digits = sizeof(T) * 2; T result{}; for (size_t i = 0; i < digits; ++i) result |= parse_hex_digit(ptr[i]) << (4 * (digits - i - 1)); return result; } template<size_t N> constexpr GUID make_guid(const char(&str)[N]) { using namespace std::string_literals; static_assert(N == 39 || N == 37, "GUIDs of the form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} or XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX are allowed"); constexpr auto base = N == 39 ? 1 : 0; if (N == 39 && (str[0]!='{' || str[37]!='}')) throw std::domain_error{ "Missing opening and closing brace"s }; GUID result{}; auto begin = str + base; result.Data1 = parse_hex<uint32_t>(begin); begin += 8 + 1; result.Data2 = parse_hex<uint16_t>(begin); begin += 4 + 1; result.Data3 = parse_hex<uint16_t>(begin); begin += 4 + 1; result.Data4[0] = parse_hex<uint8_t>(begin); begin += 2; result.Data4[1] = parse_hex<uint8_t>(begin); begin += 2 + 1; for (size_t i = 0; i < 6; ++i) result.Data4[i + 2] = parse_hex<uint8_t>(begin + i * 2); return result; } } using details::make_guid; }