Skip to content

Instantly share code, notes, and snippets.

@AlexBAV
Last active August 10, 2024 06:24
Show Gist options
  • Select an option

  • Save AlexBAV/b58e92d7632bae5d6f5947be455f796f to your computer and use it in GitHub Desktop.

Select an option

Save AlexBAV/b58e92d7632bae5d6f5947be455f796f to your computer and use it in GitHub Desktop.

Revisions

  1. AlexBAV revised this gist Aug 3, 2018. 1 changed file with 9 additions and 2 deletions.
    11 changes: 9 additions & 2 deletions guid.h
    Original 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 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)
  2. AlexBAV revised this gist Nov 27, 2017. 1 changed file with 16 additions and 10 deletions.
    26 changes: 16 additions & 10 deletions guid.h
    Original 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 == 39 || N == 37, "GUIDs of the form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} or XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX are allowed");
    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 (N == 39 && (str[0]!='{' || str[37]!='}'))
    throw std::domain_error{ "Missing opening and closing brace"s };
    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 == 39 ? 1 : 0));
    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 == 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 };
    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 details::make_guid_helper(str + (N == 38 ? 1 : 0));
    return make_guid_helper(str + (N == long_guid_form_length ? 1 : 0));
    }
    }
    }
  3. AlexBAV revised this gist Nov 24, 2017. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion guid.h
    Original 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");
    constexpr auto base = N == 39 ? 1 : 0;

    if (N == 39 && (str[0]!='{' || str[37]!='}'))
    throw std::domain_error{ "Missing opening and closing brace"s };
  4. AlexBAV revised this gist Nov 24, 2017. 1 changed file with 30 additions and 10 deletions.
    40 changes: 30 additions & 10 deletions guid.h
    Original file line number Diff line number Diff line change
    @@ -42,18 +42,9 @@ namespace guid_parse
    return result;
    }

    template<size_t N>
    constexpr GUID make_guid(const char(&str)[N])
    constexpr GUID make_guid_helper(const char *begin)
    {
    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);
    @@ -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));
    }
    }
    }
  5. AlexBAV created this gist Nov 24, 2017.
    73 changes: 73 additions & 0 deletions guid.h
    Original 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;
    }