Skip to content

Commit 9ed46e2

Browse files
authored
Define guid constructor to parse string_view (#833)
1 parent f0284a6 commit 9ed46e2

File tree

3 files changed

+92
-110
lines changed

3 files changed

+92
-110
lines changed

strings/base_types.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,44 @@ namespace winrt::impl
1818
uint32_t reserved2;
1919
void* data;
2020
};
21+
22+
template <typename T>
23+
constexpr uint8_t hex_to_uint(T const c) noexcept
24+
{
25+
if (c >= '0' && c <= '9')
26+
{
27+
return static_cast<uint8_t>(c - '0');
28+
}
29+
else if (c >= 'A' && c <= 'F')
30+
{
31+
return static_cast<uint8_t>(10 + c - 'A');
32+
}
33+
else if (c >= 'a' && c <= 'f')
34+
{
35+
return static_cast<uint8_t>(10 + c - 'a');
36+
}
37+
else
38+
{
39+
std::terminate();
40+
}
41+
}
42+
43+
template <typename T>
44+
constexpr uint8_t hex_to_uint8(T const a, T const b) noexcept
45+
{
46+
return (hex_to_uint(a) << 4) | hex_to_uint(b);
47+
}
48+
49+
constexpr uint16_t uint8_to_uint16(uint8_t a, uint8_t b) noexcept
50+
{
51+
return (static_cast<uint16_t>(a) << 8) | static_cast<uint16_t>(b);
52+
}
53+
54+
constexpr uint32_t uint8_to_uint32(uint8_t a, uint8_t b, uint8_t c, uint8_t d) noexcept
55+
{
56+
return (static_cast<uint32_t>(uint8_to_uint16(a, b)) << 16) |
57+
static_cast<uint32_t>(uint8_to_uint16(c, d));
58+
}
2159
}
2260

2361
WINRT_EXPORT namespace winrt
@@ -76,6 +114,58 @@ WINRT_EXPORT namespace winrt
76114
}
77115

78116
#endif
117+
118+
constexpr explicit guid(std::string_view const value) noexcept :
119+
guid(parse(value))
120+
{
121+
}
122+
123+
constexpr explicit guid(std::wstring_view const value) noexcept :
124+
guid(parse(value))
125+
{
126+
}
127+
128+
private:
129+
130+
template <typename TStringView>
131+
static constexpr guid parse(TStringView const value) noexcept
132+
{
133+
if (value.size() != 36 || value[8] != '-' || value[13] != '-' || value[18] != '-' || value[23] != '-')
134+
{
135+
std::terminate();
136+
}
137+
138+
return
139+
{
140+
impl::uint8_to_uint32
141+
(
142+
impl::hex_to_uint8(value[0], value[1]),
143+
impl::hex_to_uint8(value[2], value[3]),
144+
impl::hex_to_uint8(value[4], value[5]),
145+
impl::hex_to_uint8(value[6], value[7])
146+
),
147+
impl::uint8_to_uint16
148+
(
149+
impl::hex_to_uint8(value[9], value[10]),
150+
impl::hex_to_uint8(value[11], value[12])
151+
),
152+
impl::uint8_to_uint16
153+
(
154+
impl::hex_to_uint8(value[14], value[15]),
155+
impl::hex_to_uint8(value[16], value[17])
156+
),
157+
{
158+
impl::hex_to_uint8(value[19], value[20]),
159+
impl::hex_to_uint8(value[21], value[22]),
160+
impl::hex_to_uint8(value[24], value[25]),
161+
impl::hex_to_uint8(value[26], value[27]),
162+
impl::hex_to_uint8(value[28], value[29]),
163+
impl::hex_to_uint8(value[30], value[31]),
164+
impl::hex_to_uint8(value[32], value[33]),
165+
impl::hex_to_uint8(value[34], value[35]),
166+
}
167+
};
168+
}
79169
};
80170

81171
inline bool operator==(guid const& left, guid const& right) noexcept

test/test/generic_types.h

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,65 +6,11 @@ using namespace Windows::Foundation::Collections;
66
using namespace Windows::Foundation::Numerics;
77
using namespace std::literals;
88

9-
#define REQUIRE_EQUAL_GUID(left, ...) STATIC_REQUIRE(equal(make_guid(left), guid_of<__VA_ARGS__>()));
9+
#define REQUIRE_EQUAL_GUID(left, ...) STATIC_REQUIRE(equal(guid(left), guid_of<__VA_ARGS__>()));
1010
#define REQUIRE_EQUAL_NAME(left, ...) STATIC_REQUIRE(left == name_of<__VA_ARGS__>());
1111

1212
namespace
1313
{
14-
constexpr uint32_t to_uint(char const value) noexcept
15-
{
16-
if (value >= '0' && value <= '9')
17-
{
18-
return value - '0';
19-
}
20-
21-
if (value >= 'A' && value <= 'F')
22-
{
23-
return 10 + value - 'A';
24-
}
25-
26-
if (value >= 'a' && value <= 'f')
27-
{
28-
return 10 + value - 'a';
29-
}
30-
31-
std::terminate();
32-
}
33-
34-
constexpr guid make_guid(std::string_view const& value) noexcept
35-
{
36-
if (value.size() != 36 || value[8] != '-' || value[13] != '-' || value[18] != '-' || value[23] != '-')
37-
{
38-
std::terminate();
39-
}
40-
41-
return
42-
{
43-
((to_uint(value[0]) * 16 + to_uint(value[1])) << 24) +
44-
((to_uint(value[2]) * 16 + to_uint(value[3])) << 16) +
45-
((to_uint(value[4]) * 16 + to_uint(value[5])) << 8) +
46-
(to_uint(value[6]) * 16 + to_uint(value[7])),
47-
48-
static_cast<uint16_t>(((to_uint(value[9]) * 16 + to_uint(value[10])) << 8) +
49-
(to_uint(value[11]) * 16 + to_uint(value[12]))),
50-
51-
static_cast<uint16_t>(((to_uint(value[14]) * 16 + to_uint(value[15])) << 8) +
52-
(to_uint(value[16]) * 16 + to_uint(value[17]))),
53-
54-
{
55-
static_cast<uint8_t>(to_uint(value[19]) * 16 + to_uint(value[20])),
56-
static_cast<uint8_t>(to_uint(value[21]) * 16 + to_uint(value[22])),
57-
58-
static_cast<uint8_t>(to_uint(value[24]) * 16 + to_uint(value[25])),
59-
static_cast<uint8_t>(to_uint(value[26]) * 16 + to_uint(value[27])),
60-
static_cast<uint8_t>(to_uint(value[28]) * 16 + to_uint(value[29])),
61-
static_cast<uint8_t>(to_uint(value[30]) * 16 + to_uint(value[31])),
62-
static_cast<uint8_t>(to_uint(value[32]) * 16 + to_uint(value[33])),
63-
static_cast<uint8_t>(to_uint(value[34]) * 16 + to_uint(value[35])),
64-
}
65-
};
66-
}
67-
6814
constexpr bool equal(guid const& left, guid const& right) noexcept
6915
{
7016
return left.Data1 == right.Data1 &&

test/test_win7/generic_types.h

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,65 +6,11 @@ using namespace Windows::Foundation::Collections;
66
using namespace Windows::Foundation::Numerics;
77
using namespace std::literals;
88

9-
#define REQUIRE_EQUAL_GUID(left, ...) STATIC_REQUIRE(equal(make_guid(left), guid_of<__VA_ARGS__>()));
9+
#define REQUIRE_EQUAL_GUID(left, ...) STATIC_REQUIRE(equal(guid(left), guid_of<__VA_ARGS__>()));
1010
#define REQUIRE_EQUAL_NAME(left, ...) STATIC_REQUIRE(left == name_of<__VA_ARGS__>());
1111

1212
namespace
1313
{
14-
constexpr uint32_t to_uint(char const value) noexcept
15-
{
16-
if (value >= '0' && value <= '9')
17-
{
18-
return value - '0';
19-
}
20-
21-
if (value >= 'A' && value <= 'F')
22-
{
23-
return 10 + value - 'A';
24-
}
25-
26-
if (value >= 'a' && value <= 'f')
27-
{
28-
return 10 + value - 'a';
29-
}
30-
31-
std::terminate();
32-
}
33-
34-
constexpr guid make_guid(std::string_view const& value) noexcept
35-
{
36-
if (value.size() != 36 || value[8] != '-' || value[13] != '-' || value[18] != '-' || value[23] != '-')
37-
{
38-
std::terminate();
39-
}
40-
41-
return
42-
{
43-
((to_uint(value[0]) * 16 + to_uint(value[1])) << 24) +
44-
((to_uint(value[2]) * 16 + to_uint(value[3])) << 16) +
45-
((to_uint(value[4]) * 16 + to_uint(value[5])) << 8) +
46-
(to_uint(value[6]) * 16 + to_uint(value[7])),
47-
48-
static_cast<uint16_t>(((to_uint(value[9]) * 16 + to_uint(value[10])) << 8) +
49-
(to_uint(value[11]) * 16 + to_uint(value[12]))),
50-
51-
static_cast<uint16_t>(((to_uint(value[14]) * 16 + to_uint(value[15])) << 8) +
52-
(to_uint(value[16]) * 16 + to_uint(value[17]))),
53-
54-
{
55-
static_cast<uint8_t>(to_uint(value[19]) * 16 + to_uint(value[20])),
56-
static_cast<uint8_t>(to_uint(value[21]) * 16 + to_uint(value[22])),
57-
58-
static_cast<uint8_t>(to_uint(value[24]) * 16 + to_uint(value[25])),
59-
static_cast<uint8_t>(to_uint(value[26]) * 16 + to_uint(value[27])),
60-
static_cast<uint8_t>(to_uint(value[28]) * 16 + to_uint(value[29])),
61-
static_cast<uint8_t>(to_uint(value[30]) * 16 + to_uint(value[31])),
62-
static_cast<uint8_t>(to_uint(value[32]) * 16 + to_uint(value[33])),
63-
static_cast<uint8_t>(to_uint(value[34]) * 16 + to_uint(value[35])),
64-
}
65-
};
66-
}
67-
6814
constexpr bool equal(guid const& left, guid const& right) noexcept
6915
{
7016
return left.Data1 == right.Data1 &&

0 commit comments

Comments
 (0)