constructors implementation
This commit is contained in:
parent
f6e2b21fc7
commit
9b1ef4f116
154
include/uuid.h
154
include/uuid.h
@ -21,6 +21,36 @@
|
|||||||
|
|
||||||
namespace uuids
|
namespace uuids
|
||||||
{
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template <typename TChar>
|
||||||
|
constexpr inline unsigned char hex2char(TChar const ch)
|
||||||
|
{
|
||||||
|
if (ch >= static_cast<TChar>('0') && ch <= static_cast<TChar>('9'))
|
||||||
|
return ch - static_cast<TChar>('0');
|
||||||
|
if (ch >= static_cast<TChar>('a') && ch <= static_cast<TChar>('f'))
|
||||||
|
return 10 + ch - static_cast<TChar>('a');
|
||||||
|
if (ch >= static_cast<TChar>('A') && ch <= static_cast<TChar>('F'))
|
||||||
|
return 10 + ch - static_cast<TChar>('A');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TChar>
|
||||||
|
constexpr inline bool is_hex(TChar const ch)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(ch >= static_cast<TChar>('0') && ch <= static_cast<TChar>('9')) ||
|
||||||
|
(ch >= static_cast<TChar>('a') && ch <= static_cast<TChar>('f')) ||
|
||||||
|
(ch >= static_cast<TChar>('A') && ch <= static_cast<TChar>('F'));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TChar>
|
||||||
|
constexpr inline unsigned char hexpair2char(TChar const a, TChar const b)
|
||||||
|
{
|
||||||
|
return (hex2char(a) << 4) | hex2char(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// UUID format https://tools.ietf.org/html/rfc4122
|
// UUID format https://tools.ietf.org/html/rfc4122
|
||||||
// Field NDR Data Type Octet # Note
|
// Field NDR Data Type Octet # Note
|
||||||
// --------------------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -397,8 +427,15 @@ namespace uuids
|
|||||||
std::copy(first, last, std::begin(data));
|
std::copy(first, last, std::begin(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit uuid(std::string_view str);
|
explicit uuid(std::string_view str)
|
||||||
explicit uuid(std::wstring_view str);
|
{
|
||||||
|
create(str.data(), str.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit uuid(std::wstring_view str)
|
||||||
|
{
|
||||||
|
create(str.data(), str.size());
|
||||||
|
}
|
||||||
|
|
||||||
constexpr uuid_variant variant() const noexcept
|
constexpr uuid_variant variant() const noexcept
|
||||||
{
|
{
|
||||||
@ -457,11 +494,43 @@ namespace uuids
|
|||||||
friend bool operator==(uuid const & lhs, uuid const & rhs) noexcept;
|
friend bool operator==(uuid const & lhs, uuid const & rhs) noexcept;
|
||||||
friend bool operator<(uuid const & lhs, uuid const & rhs) noexcept;
|
friend bool operator<(uuid const & lhs, uuid const & rhs) noexcept;
|
||||||
|
|
||||||
template <typename TChar>
|
|
||||||
void create(TChar const * const str, size_t const size);
|
|
||||||
|
|
||||||
template <class Elem, class Traits>
|
template <class Elem, class Traits>
|
||||||
friend std::basic_ostream<Elem, Traits> & operator<<(std::basic_ostream<Elem, Traits> &s, uuid const & id);
|
friend std::basic_ostream<Elem, Traits> & operator<<(std::basic_ostream<Elem, Traits> &s, uuid const & id);
|
||||||
|
|
||||||
|
template <typename TChar>
|
||||||
|
void create(TChar const * const str, size_t const size)
|
||||||
|
{
|
||||||
|
TChar digit = 0;
|
||||||
|
bool firstdigit = true;
|
||||||
|
size_t index = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
if (str[i] == static_cast<TChar>('-')) continue;
|
||||||
|
|
||||||
|
if (index >= 16 || !detail::is_hex(str[i]))
|
||||||
|
{
|
||||||
|
std::fill(std::begin(data), std::end(data), 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstdigit)
|
||||||
|
{
|
||||||
|
digit = str[i];
|
||||||
|
firstdigit = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data[index++] = detail::hexpair2char(digit, str[i]);
|
||||||
|
firstdigit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < 16)
|
||||||
|
{
|
||||||
|
std::fill(std::begin(data), std::end(data), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator== (uuid const& lhs, uuid const& rhs) noexcept
|
inline bool operator== (uuid const& lhs, uuid const& rhs) noexcept
|
||||||
@ -655,81 +724,6 @@ namespace uuids
|
|||||||
};
|
};
|
||||||
|
|
||||||
using uuid_random_generator = basic_uuid_random_generator<std::mt19937>;
|
using uuid_random_generator = basic_uuid_random_generator<std::mt19937>;
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template <typename TChar>
|
|
||||||
constexpr inline unsigned char hex2char(TChar const ch)
|
|
||||||
{
|
|
||||||
if (ch >= static_cast<TChar>('0') && ch <= static_cast<TChar>('9'))
|
|
||||||
return ch - static_cast<TChar>('0');
|
|
||||||
if (ch >= static_cast<TChar>('a') && ch <= static_cast<TChar>('f'))
|
|
||||||
return 10 + ch - static_cast<TChar>('a');
|
|
||||||
if (ch >= static_cast<TChar>('A') && ch <= static_cast<TChar>('F'))
|
|
||||||
return 10 + ch - static_cast<TChar>('A');
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TChar>
|
|
||||||
constexpr inline bool is_hex(TChar const ch)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
(ch >= static_cast<TChar>('0') && ch <= static_cast<TChar>('9')) ||
|
|
||||||
(ch >= static_cast<TChar>('a') && ch <= static_cast<TChar>('f')) ||
|
|
||||||
(ch >= static_cast<TChar>('A') && ch <= static_cast<TChar>('F'));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TChar>
|
|
||||||
constexpr inline unsigned char hexpair2char(TChar const a, TChar const b)
|
|
||||||
{
|
|
||||||
return (hex2char(a) << 4) | hex2char(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uuid::uuid(std::string_view str)
|
|
||||||
{
|
|
||||||
create(str.data(), str.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uuid::uuid(std::wstring_view str)
|
|
||||||
{
|
|
||||||
create(str.data(), str.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TChar>
|
|
||||||
void uuid::create(TChar const * const str, size_t const size)
|
|
||||||
{
|
|
||||||
TChar digit = 0;
|
|
||||||
bool firstdigit = true;
|
|
||||||
size_t index = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < size; ++i)
|
|
||||||
{
|
|
||||||
if (str[i] == static_cast<TChar>('-')) continue;
|
|
||||||
|
|
||||||
if (index >= 16 || !detail::is_hex(str[i]))
|
|
||||||
{
|
|
||||||
std::fill(std::begin(data), std::end(data), 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstdigit)
|
|
||||||
{
|
|
||||||
digit = str[i];
|
|
||||||
firstdigit = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
data[index++] = detail::hexpair2char(digit, str[i]);
|
|
||||||
firstdigit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index < 16)
|
|
||||||
{
|
|
||||||
std::fill(std::begin(data), std::end(data), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
|
|||||||
@ -52,7 +52,7 @@ int main()
|
|||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::array<uint8_t, 16> arr{ {
|
std::array<uuids::uuid::value_type, 16> arr{ {
|
||||||
0x47, 0x18, 0x38, 0x23,
|
0x47, 0x18, 0x38, 0x23,
|
||||||
0x25, 0x74,
|
0x25, 0x74,
|
||||||
0x4b, 0xfd,
|
0x4b, 0xfd,
|
||||||
@ -64,7 +64,7 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
uint8_t arr[16] = {
|
uuids::uuid::value_type arr[16] = {
|
||||||
0x47, 0x18, 0x38, 0x23,
|
0x47, 0x18, 0x38, 0x23,
|
||||||
0x25, 0x74,
|
0x25, 0x74,
|
||||||
0x4b, 0xfd,
|
0x4b, 0xfd,
|
||||||
@ -91,16 +91,17 @@ int main()
|
|||||||
std::cout << "Test comparison" << std::endl;
|
std::cout << "Test comparison" << std::endl;
|
||||||
|
|
||||||
auto empty = uuid{};
|
auto empty = uuid{};
|
||||||
auto id = uuids::uuid_default_generator{}();
|
uuids::uuid_default_generator gen;
|
||||||
|
auto id = gen();
|
||||||
|
|
||||||
assert(empty < id);
|
assert(empty < id);
|
||||||
|
|
||||||
std::set<uuids::uuid> ids{
|
std::set<uuids::uuid> ids{
|
||||||
uuid{},
|
uuid{},
|
||||||
uuids::uuid_default_generator{}(),
|
gen(),
|
||||||
uuids::uuid_default_generator{}(),
|
gen(),
|
||||||
uuids::uuid_default_generator{}(),
|
gen(),
|
||||||
uuids::uuid_default_generator{}()
|
gen()
|
||||||
};
|
};
|
||||||
|
|
||||||
assert(ids.size() == 5);
|
assert(ids.size() == 5);
|
||||||
@ -118,12 +119,14 @@ int main()
|
|||||||
auto h2 = std::hash<uuid>{};
|
auto h2 = std::hash<uuid>{};
|
||||||
assert(h1(str) == h2(guid));
|
assert(h1(str) == h2(guid));
|
||||||
|
|
||||||
|
uuids::uuid_default_generator gen;
|
||||||
|
|
||||||
std::unordered_set<uuids::uuid> ids{
|
std::unordered_set<uuids::uuid> ids{
|
||||||
uuid{},
|
uuid{},
|
||||||
uuids::uuid_default_generator{}(),
|
gen(),
|
||||||
uuids::uuid_default_generator{}(),
|
gen(),
|
||||||
uuids::uuid_default_generator{}(),
|
gen(),
|
||||||
uuids::uuid_default_generator{}()
|
gen()
|
||||||
};
|
};
|
||||||
|
|
||||||
assert(ids.size() == 5);
|
assert(ids.size() == 5);
|
||||||
@ -161,7 +164,7 @@ int main()
|
|||||||
{
|
{
|
||||||
std::cout << "Test iterators" << std::endl;
|
std::cout << "Test iterators" << std::endl;
|
||||||
|
|
||||||
std::array<uint8_t, 16> arr{{
|
std::array<uuids::uuid::value_type, 16> arr{{
|
||||||
0x47, 0x18, 0x38, 0x23,
|
0x47, 0x18, 0x38, 0x23,
|
||||||
0x25, 0x74,
|
0x25, 0x74,
|
||||||
0x4b, 0xfd,
|
0x4b, 0xfd,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user