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 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
|
||||
// Field NDR Data Type Octet # Note
|
||||
// --------------------------------------------------------------------------------------------------------------------------
|
||||
@ -397,8 +427,15 @@ namespace uuids
|
||||
std::copy(first, last, std::begin(data));
|
||||
}
|
||||
|
||||
explicit uuid(std::string_view str);
|
||||
explicit uuid(std::wstring_view str);
|
||||
explicit uuid(std::string_view str)
|
||||
{
|
||||
create(str.data(), str.size());
|
||||
}
|
||||
|
||||
explicit uuid(std::wstring_view str)
|
||||
{
|
||||
create(str.data(), str.size());
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
template <typename TChar>
|
||||
void create(TChar const * const str, size_t const size);
|
||||
|
||||
template <class Elem, class Traits>
|
||||
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
|
||||
@ -655,81 +724,6 @@ namespace uuids
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
@ -52,7 +52,7 @@ int main()
|
||||
using namespace std::string_literals;
|
||||
|
||||
{
|
||||
std::array<uint8_t, 16> arr{ {
|
||||
std::array<uuids::uuid::value_type, 16> arr{ {
|
||||
0x47, 0x18, 0x38, 0x23,
|
||||
0x25, 0x74,
|
||||
0x4b, 0xfd,
|
||||
@ -64,7 +64,7 @@ int main()
|
||||
}
|
||||
|
||||
{
|
||||
uint8_t arr[16] = {
|
||||
uuids::uuid::value_type arr[16] = {
|
||||
0x47, 0x18, 0x38, 0x23,
|
||||
0x25, 0x74,
|
||||
0x4b, 0xfd,
|
||||
@ -91,16 +91,17 @@ int main()
|
||||
std::cout << "Test comparison" << std::endl;
|
||||
|
||||
auto empty = uuid{};
|
||||
auto id = uuids::uuid_default_generator{}();
|
||||
uuids::uuid_default_generator gen;
|
||||
auto id = gen();
|
||||
|
||||
assert(empty < id);
|
||||
|
||||
std::set<uuids::uuid> ids{
|
||||
uuid{},
|
||||
uuids::uuid_default_generator{}(),
|
||||
uuids::uuid_default_generator{}(),
|
||||
uuids::uuid_default_generator{}(),
|
||||
uuids::uuid_default_generator{}()
|
||||
gen(),
|
||||
gen(),
|
||||
gen(),
|
||||
gen()
|
||||
};
|
||||
|
||||
assert(ids.size() == 5);
|
||||
@ -118,12 +119,14 @@ int main()
|
||||
auto h2 = std::hash<uuid>{};
|
||||
assert(h1(str) == h2(guid));
|
||||
|
||||
uuids::uuid_default_generator gen;
|
||||
|
||||
std::unordered_set<uuids::uuid> ids{
|
||||
uuid{},
|
||||
uuids::uuid_default_generator{}(),
|
||||
uuids::uuid_default_generator{}(),
|
||||
uuids::uuid_default_generator{}(),
|
||||
uuids::uuid_default_generator{}()
|
||||
gen(),
|
||||
gen(),
|
||||
gen(),
|
||||
gen()
|
||||
};
|
||||
|
||||
assert(ids.size() == 5);
|
||||
@ -161,7 +164,7 @@ int main()
|
||||
{
|
||||
std::cout << "Test iterators" << std::endl;
|
||||
|
||||
std::array<uint8_t, 16> arr{{
|
||||
std::array<uuids::uuid::value_type, 16> arr{{
|
||||
0x47, 0x18, 0x38, 0x23,
|
||||
0x25, 0x74,
|
||||
0x4b, 0xfd,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user