Declare variables as inline
Declare empty_guid and guid_encoder as inline to fix multiple defined symbol errors when compiling with clang++.
This commit is contained in:
parent
9357e5280c
commit
5f739d3e26
299
include/uuid.h
299
include/uuid.h
@ -24,7 +24,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef UUID_TIME_GENERATOR
|
#ifdef UUID_TIME_GENERATOR
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#pragma comment(lib, "IPHLPAPI.lib")
|
#pragma comment(lib, "IPHLPAPI.lib")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -69,24 +69,24 @@ namespace uuids
|
|||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
constexpr inline bool is_hex(TChar const ch)
|
constexpr inline bool is_hex(TChar const ch)
|
||||||
{
|
{
|
||||||
return
|
return (ch >= static_cast<TChar>('0') && ch <= static_cast<TChar>('9')) ||
|
||||||
(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')) ||
|
(ch >= static_cast<TChar>('A') && ch <= static_cast<TChar>('F'));
|
||||||
(ch >= static_cast<TChar>('A') && ch <= static_cast<TChar>('F'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
constexpr std::basic_string_view<TChar> to_string_view(TChar const * str)
|
constexpr std::basic_string_view<TChar> to_string_view(TChar const *str)
|
||||||
{
|
{
|
||||||
if (str) return str;
|
if (str)
|
||||||
|
return str;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename StringType>
|
template <typename StringType>
|
||||||
constexpr std::basic_string_view<
|
constexpr std::basic_string_view<
|
||||||
typename StringType::value_type,
|
typename StringType::value_type,
|
||||||
typename StringType::traits_type>
|
typename StringType::traits_type>
|
||||||
to_string_view(StringType const & str)
|
to_string_view(StringType const &str)
|
||||||
{
|
{
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@ -99,14 +99,14 @@ namespace uuids
|
|||||||
|
|
||||||
static constexpr unsigned int block_bytes = 64;
|
static constexpr unsigned int block_bytes = 64;
|
||||||
|
|
||||||
inline static uint32_t left_rotate(uint32_t value, size_t const count)
|
inline static uint32_t left_rotate(uint32_t value, size_t const count)
|
||||||
{
|
{
|
||||||
return (value << count) ^ (value >> (32 - count));
|
return (value << count) ^ (value >> (32 - count));
|
||||||
}
|
}
|
||||||
|
|
||||||
sha1() { reset(); }
|
sha1() { reset(); }
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
m_digest[0] = 0x67452301;
|
m_digest[0] = 0x67452301;
|
||||||
m_digest[1] = 0xEFCDAB89;
|
m_digest[1] = 0xEFCDAB89;
|
||||||
@ -117,7 +117,7 @@ namespace uuids
|
|||||||
m_byteCount = 0;
|
m_byteCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_byte(uint8_t octet)
|
void process_byte(uint8_t octet)
|
||||||
{
|
{
|
||||||
this->m_block[this->m_blockByteIndex++] = octet;
|
this->m_block[this->m_blockByteIndex++] = octet;
|
||||||
++this->m_byteCount;
|
++this->m_byteCount;
|
||||||
@ -128,37 +128,42 @@ namespace uuids
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_block(void const * const start, void const * const end)
|
void process_block(void const *const start, void const *const end)
|
||||||
{
|
{
|
||||||
const uint8_t* begin = static_cast<const uint8_t*>(start);
|
const uint8_t *begin = static_cast<const uint8_t *>(start);
|
||||||
const uint8_t* finish = static_cast<const uint8_t*>(end);
|
const uint8_t *finish = static_cast<const uint8_t *>(end);
|
||||||
while (begin != finish)
|
while (begin != finish)
|
||||||
{
|
{
|
||||||
process_byte(*begin);
|
process_byte(*begin);
|
||||||
begin++;
|
begin++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_bytes(void const * const data, size_t const len)
|
void process_bytes(void const *const data, size_t const len)
|
||||||
{
|
{
|
||||||
const uint8_t* block = static_cast<const uint8_t*>(data);
|
const uint8_t *block = static_cast<const uint8_t *>(data);
|
||||||
process_block(block, block + len);
|
process_block(block, block + len);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t const * get_digest(digest32_t digest)
|
uint32_t const *get_digest(digest32_t digest)
|
||||||
{
|
{
|
||||||
size_t const bitCount = this->m_byteCount * 8;
|
size_t const bitCount = this->m_byteCount * 8;
|
||||||
process_byte(0x80);
|
process_byte(0x80);
|
||||||
if (this->m_blockByteIndex > 56) {
|
if (this->m_blockByteIndex > 56)
|
||||||
while (m_blockByteIndex != 0) {
|
{
|
||||||
|
while (m_blockByteIndex != 0)
|
||||||
|
{
|
||||||
process_byte(0);
|
process_byte(0);
|
||||||
}
|
}
|
||||||
while (m_blockByteIndex < 56) {
|
while (m_blockByteIndex < 56)
|
||||||
|
{
|
||||||
process_byte(0);
|
process_byte(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
while (m_blockByteIndex < 56) {
|
{
|
||||||
|
while (m_blockByteIndex < 56)
|
||||||
|
{
|
||||||
process_byte(0);
|
process_byte(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,13 +174,13 @@ namespace uuids
|
|||||||
process_byte(static_cast<unsigned char>((bitCount >> 24) & 0xFF));
|
process_byte(static_cast<unsigned char>((bitCount >> 24) & 0xFF));
|
||||||
process_byte(static_cast<unsigned char>((bitCount >> 16) & 0xFF));
|
process_byte(static_cast<unsigned char>((bitCount >> 16) & 0xFF));
|
||||||
process_byte(static_cast<unsigned char>((bitCount >> 8) & 0xFF));
|
process_byte(static_cast<unsigned char>((bitCount >> 8) & 0xFF));
|
||||||
process_byte(static_cast<unsigned char>((bitCount) & 0xFF));
|
process_byte(static_cast<unsigned char>((bitCount)&0xFF));
|
||||||
|
|
||||||
memcpy(digest, m_digest, 5 * sizeof(uint32_t));
|
memcpy(digest, m_digest, 5 * sizeof(uint32_t));
|
||||||
return digest;
|
return digest;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t const * get_digest_bytes(digest8_t digest)
|
uint8_t const *get_digest_bytes(digest8_t digest)
|
||||||
{
|
{
|
||||||
digest32_t d32;
|
digest32_t d32;
|
||||||
get_digest(d32);
|
get_digest(d32);
|
||||||
@ -209,16 +214,18 @@ namespace uuids
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void process_block()
|
void process_block()
|
||||||
{
|
{
|
||||||
uint32_t w[80];
|
uint32_t w[80];
|
||||||
for (size_t i = 0; i < 16; i++) {
|
for (size_t i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
w[i] = static_cast<uint32_t>(m_block[i * 4 + 0] << 24);
|
w[i] = static_cast<uint32_t>(m_block[i * 4 + 0] << 24);
|
||||||
w[i] |= static_cast<uint32_t>(m_block[i * 4 + 1] << 16);
|
w[i] |= static_cast<uint32_t>(m_block[i * 4 + 1] << 16);
|
||||||
w[i] |= static_cast<uint32_t>(m_block[i * 4 + 2] << 8);
|
w[i] |= static_cast<uint32_t>(m_block[i * 4 + 2] << 8);
|
||||||
w[i] |= static_cast<uint32_t>(m_block[i * 4 + 3]);
|
w[i] |= static_cast<uint32_t>(m_block[i * 4 + 3]);
|
||||||
}
|
}
|
||||||
for (size_t i = 16; i < 80; i++) {
|
for (size_t i = 16; i < 80; i++)
|
||||||
|
{
|
||||||
w[i] = left_rotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1);
|
w[i] = left_rotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,24 +235,28 @@ namespace uuids
|
|||||||
uint32_t d = m_digest[3];
|
uint32_t d = m_digest[3];
|
||||||
uint32_t e = m_digest[4];
|
uint32_t e = m_digest[4];
|
||||||
|
|
||||||
for (std::size_t i = 0; i < 80; ++i)
|
for (std::size_t i = 0; i < 80; ++i)
|
||||||
{
|
{
|
||||||
uint32_t f = 0;
|
uint32_t f = 0;
|
||||||
uint32_t k = 0;
|
uint32_t k = 0;
|
||||||
|
|
||||||
if (i < 20) {
|
if (i < 20)
|
||||||
|
{
|
||||||
f = (b & c) | (~b & d);
|
f = (b & c) | (~b & d);
|
||||||
k = 0x5A827999;
|
k = 0x5A827999;
|
||||||
}
|
}
|
||||||
else if (i < 40) {
|
else if (i < 40)
|
||||||
|
{
|
||||||
f = b ^ c ^ d;
|
f = b ^ c ^ d;
|
||||||
k = 0x6ED9EBA1;
|
k = 0x6ED9EBA1;
|
||||||
}
|
}
|
||||||
else if (i < 60) {
|
else if (i < 60)
|
||||||
|
{
|
||||||
f = (b & c) | (b & d) | (c & d);
|
f = (b & c) | (b & d) | (c & d);
|
||||||
k = 0x8F1BBCDC;
|
k = 0x8F1BBCDC;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
f = b ^ c ^ d;
|
f = b ^ c ^ d;
|
||||||
k = 0xCA62C1D6;
|
k = 0xCA62C1D6;
|
||||||
}
|
}
|
||||||
@ -272,16 +283,16 @@ namespace uuids
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename CharT>
|
template <typename CharT>
|
||||||
constexpr CharT empty_guid[37] = "00000000-0000-0000-0000-000000000000";
|
inline constexpr CharT empty_guid[37] = "00000000-0000-0000-0000-000000000000";
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
constexpr wchar_t empty_guid<wchar_t>[37] = L"00000000-0000-0000-0000-000000000000";
|
inline constexpr wchar_t empty_guid<wchar_t>[37] = L"00000000-0000-0000-0000-000000000000";
|
||||||
|
|
||||||
template <typename CharT>
|
template <typename CharT>
|
||||||
constexpr CharT guid_encoder[17] = "0123456789abcdef";
|
inline constexpr CharT guid_encoder[17] = "0123456789abcdef";
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
constexpr wchar_t guid_encoder<wchar_t>[17] = L"0123456789abcdef";
|
inline constexpr wchar_t guid_encoder<wchar_t>[17] = L"0123456789abcdef";
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -321,35 +332,35 @@ namespace uuids
|
|||||||
// N bit pattern: 0xxx
|
// N bit pattern: 0xxx
|
||||||
// > the first 6 octets of the UUID are a 48-bit timestamp (the number of 4 microsecond units of time since 1 Jan 1980 UTC);
|
// > the first 6 octets of the UUID are a 48-bit timestamp (the number of 4 microsecond units of time since 1 Jan 1980 UTC);
|
||||||
// > the next 2 octets are reserved;
|
// > the next 2 octets are reserved;
|
||||||
// > the next octet is the "address family";
|
// > the next octet is the "address family";
|
||||||
// > the final 7 octets are a 56-bit host ID in the form specified by the address family
|
// > the final 7 octets are a 56-bit host ID in the form specified by the address family
|
||||||
ncs,
|
ncs,
|
||||||
|
|
||||||
// RFC 4122/DCE 1.1
|
// RFC 4122/DCE 1.1
|
||||||
// N bit pattern: 10xx
|
// N bit pattern: 10xx
|
||||||
// > big-endian byte order
|
// > big-endian byte order
|
||||||
rfc,
|
rfc,
|
||||||
|
|
||||||
// Microsoft Corporation backward compatibility
|
// Microsoft Corporation backward compatibility
|
||||||
// N bit pattern: 110x
|
// N bit pattern: 110x
|
||||||
// > little endian byte order
|
// > little endian byte order
|
||||||
// > formely used in the Component Object Model (COM) library
|
// > formely used in the Component Object Model (COM) library
|
||||||
microsoft,
|
microsoft,
|
||||||
|
|
||||||
// reserved for possible future definition
|
// reserved for possible future definition
|
||||||
// N bit pattern: 111x
|
// N bit pattern: 111x
|
||||||
reserved
|
reserved
|
||||||
};
|
};
|
||||||
|
|
||||||
// indicated by a bit pattern in octet 6, marked with M in xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx
|
// indicated by a bit pattern in octet 6, marked with M in xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx
|
||||||
enum class uuid_version
|
enum class uuid_version
|
||||||
{
|
{
|
||||||
none = 0, // only possible for nil or invalid uuids
|
none = 0, // only possible for nil or invalid uuids
|
||||||
time_based = 1, // The time-based version specified in RFC 4122
|
time_based = 1, // The time-based version specified in RFC 4122
|
||||||
dce_security = 2, // DCE Security version, with embedded POSIX UIDs.
|
dce_security = 2, // DCE Security version, with embedded POSIX UIDs.
|
||||||
name_based_md5 = 3, // The name-based version specified in RFS 4122 with MD5 hashing
|
name_based_md5 = 3, // The name-based version specified in RFS 4122 with MD5 hashing
|
||||||
random_number_based = 4, // The randomly or pseudo-randomly generated version specified in RFS 4122
|
random_number_based = 4, // The randomly or pseudo-randomly generated version specified in RFS 4122
|
||||||
name_based_sha1 = 5 // The name-based version specified in RFS 4122 with SHA1 hashing
|
name_based_sha1 = 5 // The name-based version specified in RFS 4122 with SHA1 hashing
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -362,25 +373,25 @@ namespace uuids
|
|||||||
|
|
||||||
constexpr uuid() noexcept = default;
|
constexpr uuid() noexcept = default;
|
||||||
|
|
||||||
uuid(value_type(&arr)[16]) noexcept
|
uuid(value_type (&arr)[16]) noexcept
|
||||||
{
|
{
|
||||||
std::copy(std::cbegin(arr), std::cend(arr), std::begin(data));
|
std::copy(std::cbegin(arr), std::cend(arr), std::begin(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr uuid(std::array<value_type, 16> const & arr) noexcept : data{arr} {}
|
constexpr uuid(std::array<value_type, 16> const &arr) noexcept : data{arr} {}
|
||||||
|
|
||||||
explicit uuid(span<value_type, 16> bytes)
|
explicit uuid(span<value_type, 16> bytes)
|
||||||
{
|
{
|
||||||
std::copy(std::cbegin(bytes), std::cend(bytes), std::begin(data));
|
std::copy(std::cbegin(bytes), std::cend(bytes), std::begin(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ForwardIterator>
|
template <typename ForwardIterator>
|
||||||
explicit uuid(ForwardIterator first, ForwardIterator last)
|
explicit uuid(ForwardIterator first, ForwardIterator last)
|
||||||
{
|
{
|
||||||
if (std::distance(first, last) == 16)
|
if (std::distance(first, last) == 16)
|
||||||
std::copy(first, last, std::begin(data));
|
std::copy(first, last, std::begin(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr uuid_variant variant() const noexcept
|
constexpr uuid_variant variant() const noexcept
|
||||||
{
|
{
|
||||||
if ((data[8] & 0x80) == 0x00)
|
if ((data[8] & 0x80) == 0x00)
|
||||||
@ -411,22 +422,24 @@ namespace uuids
|
|||||||
|
|
||||||
constexpr bool is_nil() const noexcept
|
constexpr bool is_nil() const noexcept
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < data.size(); ++i) if (data[i] != 0) return false;
|
for (size_t i = 0; i < data.size(); ++i)
|
||||||
|
if (data[i] != 0)
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(uuid & other) noexcept
|
void swap(uuid &other) noexcept
|
||||||
{
|
{
|
||||||
data.swap(other.data);
|
data.swap(other.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline span<std::byte const, 16> as_bytes() const
|
inline span<std::byte const, 16> as_bytes() const
|
||||||
{
|
{
|
||||||
return span<std::byte const, 16>(reinterpret_cast<std::byte const*>(data.data()), 16);
|
return span<std::byte const, 16>(reinterpret_cast<std::byte const *>(data.data()), 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename StringType>
|
template <typename StringType>
|
||||||
constexpr static bool is_valid_uuid(StringType const & in_str) noexcept
|
constexpr static bool is_valid_uuid(StringType const &in_str) noexcept
|
||||||
{
|
{
|
||||||
auto str = detail::to_string_view(in_str);
|
auto str = detail::to_string_view(in_str);
|
||||||
bool firstDigit = true;
|
bool firstDigit = true;
|
||||||
@ -443,7 +456,8 @@ namespace uuids
|
|||||||
|
|
||||||
for (size_t i = hasBraces; i < str.size() - hasBraces; ++i)
|
for (size_t i = hasBraces; i < str.size() - hasBraces; ++i)
|
||||||
{
|
{
|
||||||
if (str[i] == '-') continue;
|
if (str[i] == '-')
|
||||||
|
continue;
|
||||||
|
|
||||||
if (index >= 16 || !detail::is_hex(str[i]))
|
if (index >= 16 || !detail::is_hex(str[i]))
|
||||||
{
|
{
|
||||||
@ -470,16 +484,17 @@ namespace uuids
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename StringType>
|
template <typename StringType>
|
||||||
constexpr static std::optional<uuid> from_string(StringType const & in_str) noexcept
|
constexpr static std::optional<uuid> from_string(StringType const &in_str) noexcept
|
||||||
{
|
{
|
||||||
auto str = detail::to_string_view(in_str);
|
auto str = detail::to_string_view(in_str);
|
||||||
bool firstDigit = true;
|
bool firstDigit = true;
|
||||||
size_t hasBraces = 0;
|
size_t hasBraces = 0;
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
|
|
||||||
std::array<uint8_t, 16> data{ { 0 } };
|
std::array<uint8_t, 16> data{{0}};
|
||||||
|
|
||||||
if (str.empty()) return {};
|
if (str.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
if (str.front() == '{')
|
if (str.front() == '{')
|
||||||
hasBraces = 1;
|
hasBraces = 1;
|
||||||
@ -488,7 +503,8 @@ namespace uuids
|
|||||||
|
|
||||||
for (size_t i = hasBraces; i < str.size() - hasBraces; ++i)
|
for (size_t i = hasBraces; i < str.size() - hasBraces; ++i)
|
||||||
{
|
{
|
||||||
if (str[i] == '-') continue;
|
if (str[i] == '-')
|
||||||
|
continue;
|
||||||
|
|
||||||
if (index >= 16 || !detail::is_hex(str[i]))
|
if (index >= 16 || !detail::is_hex(str[i]))
|
||||||
{
|
{
|
||||||
@ -503,7 +519,7 @@ namespace uuids
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
data[index] = static_cast<uint8_t>(data[index] | detail::hex2char(str[i]));
|
data[index] = static_cast<uint8_t>(data[index] | detail::hex2char(str[i]));
|
||||||
index++;
|
index++;
|
||||||
firstDigit = true;
|
firstDigit = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -513,20 +529,20 @@ namespace uuids
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return uuid{ data };
|
return uuid{data};
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<value_type, 16> data{ { 0 } };
|
std::array<value_type, 16> data{{0}};
|
||||||
|
|
||||||
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 <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<class CharT, class Traits, class Allocator>
|
template <class CharT, class Traits, class Allocator>
|
||||||
friend std::basic_string<CharT, Traits, Allocator> to_string(uuid const& id);
|
friend std::basic_string<CharT, Traits, Allocator> to_string(uuid const &id);
|
||||||
|
|
||||||
friend std::hash<uuid>;
|
friend std::hash<uuid>;
|
||||||
};
|
};
|
||||||
@ -535,25 +551,25 @@ namespace uuids
|
|||||||
// operators and non-member functions
|
// operators and non-member functions
|
||||||
// --------------------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
inline bool operator== (uuid const& lhs, uuid const& rhs) noexcept
|
inline bool operator==(uuid const &lhs, uuid const &rhs) noexcept
|
||||||
{
|
{
|
||||||
return lhs.data == rhs.data;
|
return lhs.data == rhs.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator!= (uuid const& lhs, uuid const& rhs) noexcept
|
inline bool operator!=(uuid const &lhs, uuid const &rhs) noexcept
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator< (uuid const& lhs, uuid const& rhs) noexcept
|
inline bool operator<(uuid const &lhs, uuid const &rhs) noexcept
|
||||||
{
|
{
|
||||||
return lhs.data < rhs.data;
|
return lhs.data < rhs.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class CharT = char,
|
template <class CharT = char,
|
||||||
class Traits = std::char_traits<CharT>,
|
class Traits = std::char_traits<CharT>,
|
||||||
class Allocator = std::allocator<CharT>>
|
class Allocator = std::allocator<CharT>>
|
||||||
inline std::basic_string<CharT, Traits, Allocator> to_string(uuid const & id)
|
inline std::basic_string<CharT, Traits, Allocator> to_string(uuid const &id)
|
||||||
{
|
{
|
||||||
std::basic_string<CharT, Traits, Allocator> uustr{detail::empty_guid<CharT>};
|
std::basic_string<CharT, Traits, Allocator> uustr{detail::empty_guid<CharT>};
|
||||||
|
|
||||||
@ -572,15 +588,15 @@ namespace uuids
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class Elem, class Traits>
|
template <class Elem, class Traits>
|
||||||
std::basic_ostream<Elem, Traits>& operator<<(std::basic_ostream<Elem, Traits>& s, uuid const& id)
|
std::basic_ostream<Elem, Traits> &operator<<(std::basic_ostream<Elem, Traits> &s, uuid const &id)
|
||||||
{
|
{
|
||||||
s << to_string(id);
|
s << to_string(id);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void swap(uuids::uuid & lhs, uuids::uuid & rhs) noexcept
|
inline void swap(uuids::uuid &lhs, uuids::uuid &rhs) noexcept
|
||||||
{
|
{
|
||||||
lhs.swap(rhs);
|
lhs.swap(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -588,16 +604,16 @@ namespace uuids
|
|||||||
// --------------------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Name string is a fully-qualified domain name
|
// Name string is a fully-qualified domain name
|
||||||
static uuid uuid_namespace_dns{ {0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} };
|
static uuid uuid_namespace_dns{{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}};
|
||||||
|
|
||||||
// Name string is a URL
|
// Name string is a URL
|
||||||
static uuid uuid_namespace_url{ {0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} };
|
static uuid uuid_namespace_url{{0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}};
|
||||||
|
|
||||||
// Name string is an ISO OID (See https://oidref.com/, https://en.wikipedia.org/wiki/Object_identifier)
|
// Name string is an ISO OID (See https://oidref.com/, https://en.wikipedia.org/wiki/Object_identifier)
|
||||||
static uuid uuid_namespace_oid{ {0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} };
|
static uuid uuid_namespace_oid{{0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}};
|
||||||
|
|
||||||
// Name string is an X.500 DN, in DER or a text output format (See https://en.wikipedia.org/wiki/X.500, https://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One)
|
// Name string is an X.500 DN, in DER or a text output format (See https://en.wikipedia.org/wiki/X.500, https://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One)
|
||||||
static uuid uuid_namespace_x500{ {0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} };
|
static uuid uuid_namespace_x500{{0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------------------
|
||||||
// uuid generators
|
// uuid generators
|
||||||
@ -622,8 +638,7 @@ namespace uuids
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::array<uint8_t, 16> bytes =
|
std::array<uint8_t, 16> bytes =
|
||||||
{ {
|
{{static_cast<unsigned char>((newId.Data1 >> 24) & 0xFF),
|
||||||
static_cast<unsigned char>((newId.Data1 >> 24) & 0xFF),
|
|
||||||
static_cast<unsigned char>((newId.Data1 >> 16) & 0xFF),
|
static_cast<unsigned char>((newId.Data1 >> 16) & 0xFF),
|
||||||
static_cast<unsigned char>((newId.Data1 >> 8) & 0xFF),
|
static_cast<unsigned char>((newId.Data1 >> 8) & 0xFF),
|
||||||
static_cast<unsigned char>((newId.Data1) & 0xFF),
|
static_cast<unsigned char>((newId.Data1) & 0xFF),
|
||||||
@ -641,10 +656,9 @@ namespace uuids
|
|||||||
newId.Data4[4],
|
newId.Data4[4],
|
||||||
newId.Data4[5],
|
newId.Data4[5],
|
||||||
newId.Data4[6],
|
newId.Data4[6],
|
||||||
newId.Data4[7]
|
newId.Data4[7]}};
|
||||||
} };
|
|
||||||
|
|
||||||
return uuid{ std::begin(bytes), std::end(bytes) };
|
return uuid{std::begin(bytes), std::end(bytes)};
|
||||||
|
|
||||||
#elif defined(__linux__) || defined(__unix__)
|
#elif defined(__linux__) || defined(__unix__)
|
||||||
|
|
||||||
@ -652,8 +666,7 @@ namespace uuids
|
|||||||
uuid_generate(id);
|
uuid_generate(id);
|
||||||
|
|
||||||
std::array<uint8_t, 16> bytes =
|
std::array<uint8_t, 16> bytes =
|
||||||
{ {
|
{{id[0],
|
||||||
id[0],
|
|
||||||
id[1],
|
id[1],
|
||||||
id[2],
|
id[2],
|
||||||
id[3],
|
id[3],
|
||||||
@ -668,10 +681,9 @@ namespace uuids
|
|||||||
id[12],
|
id[12],
|
||||||
id[13],
|
id[13],
|
||||||
id[14],
|
id[14],
|
||||||
id[15]
|
id[15]}};
|
||||||
} };
|
|
||||||
|
|
||||||
return uuid{ std::begin(bytes), std::end(bytes) };
|
return uuid{std::begin(bytes), std::end(bytes)};
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
auto newId = CFUUIDCreate(NULL);
|
auto newId = CFUUIDCreate(NULL);
|
||||||
@ -679,8 +691,7 @@ namespace uuids
|
|||||||
CFRelease(newId);
|
CFRelease(newId);
|
||||||
|
|
||||||
std::array<uint8_t, 16> arrbytes =
|
std::array<uint8_t, 16> arrbytes =
|
||||||
{ {
|
{{bytes.byte0,
|
||||||
bytes.byte0,
|
|
||||||
bytes.byte1,
|
bytes.byte1,
|
||||||
bytes.byte2,
|
bytes.byte2,
|
||||||
bytes.byte3,
|
bytes.byte3,
|
||||||
@ -695,9 +706,8 @@ namespace uuids
|
|||||||
bytes.byte12,
|
bytes.byte12,
|
||||||
bytes.byte13,
|
bytes.byte13,
|
||||||
bytes.byte14,
|
bytes.byte14,
|
||||||
bytes.byte15
|
bytes.byte15}};
|
||||||
} };
|
return uuid{std::begin(arrbytes), std::end(arrbytes)};
|
||||||
return uuid{ std::begin(arrbytes), std::end(arrbytes) };
|
|
||||||
#else
|
#else
|
||||||
return uuid{};
|
return uuid{};
|
||||||
#endif
|
#endif
|
||||||
@ -706,21 +716,19 @@ namespace uuids
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename UniformRandomNumberGenerator>
|
template <typename UniformRandomNumberGenerator>
|
||||||
class basic_uuid_random_generator
|
class basic_uuid_random_generator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using engine_type = UniformRandomNumberGenerator;
|
using engine_type = UniformRandomNumberGenerator;
|
||||||
|
|
||||||
explicit basic_uuid_random_generator(engine_type& gen) :
|
explicit basic_uuid_random_generator(engine_type &gen) : generator(&gen, [](auto) {}) {}
|
||||||
generator(&gen, [](auto) {}) {}
|
explicit basic_uuid_random_generator(engine_type *gen) : generator(gen, [](auto) {}) {}
|
||||||
explicit basic_uuid_random_generator(engine_type* gen) :
|
|
||||||
generator(gen, [](auto) {}) {}
|
|
||||||
|
|
||||||
uuid operator()()
|
uuid operator()()
|
||||||
{
|
{
|
||||||
uint8_t bytes[16];
|
uint8_t bytes[16];
|
||||||
for (int i = 0; i < 16; i += 4)
|
for (int i = 0; i < 16; i += 4)
|
||||||
*reinterpret_cast<uint32_t*>(bytes + i) = distribution(*generator);
|
*reinterpret_cast<uint32_t *>(bytes + i) = distribution(*generator);
|
||||||
|
|
||||||
// variant must be 10xxxxxx
|
// variant must be 10xxxxxx
|
||||||
bytes[8] &= 0xBF;
|
bytes[8] &= 0xBF;
|
||||||
@ -734,21 +742,22 @@ namespace uuids
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::uniform_int_distribution<uint32_t> distribution;
|
std::uniform_int_distribution<uint32_t> distribution;
|
||||||
std::shared_ptr<UniformRandomNumberGenerator> generator;
|
std::shared_ptr<UniformRandomNumberGenerator> generator;
|
||||||
};
|
};
|
||||||
|
|
||||||
using uuid_random_generator = basic_uuid_random_generator<std::mt19937>;
|
using uuid_random_generator = basic_uuid_random_generator<std::mt19937>;
|
||||||
|
|
||||||
class uuid_name_generator
|
class uuid_name_generator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit uuid_name_generator(uuid const& namespace_uuid) noexcept
|
explicit uuid_name_generator(uuid const &namespace_uuid) noexcept
|
||||||
: nsuuid(namespace_uuid)
|
: nsuuid(namespace_uuid)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template <typename StringType>
|
template <typename StringType>
|
||||||
uuid operator()(StringType const & name)
|
uuid operator()(StringType const &name)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
process_characters(detail::to_string_view(name));
|
process_characters(detail::to_string_view(name));
|
||||||
@ -756,7 +765,7 @@ namespace uuids
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
hasher.reset();
|
hasher.reset();
|
||||||
std::byte bytes[16];
|
std::byte bytes[16];
|
||||||
@ -793,7 +802,7 @@ namespace uuids
|
|||||||
digest[6] &= 0x5F;
|
digest[6] &= 0x5F;
|
||||||
digest[6] |= 0x50;
|
digest[6] |= 0x50;
|
||||||
|
|
||||||
return uuid{ digest, digest + 16 };
|
return uuid{digest, digest + 16};
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -811,20 +820,22 @@ namespace uuids
|
|||||||
std::optional<mac_address> device_address;
|
std::optional<mac_address> device_address;
|
||||||
|
|
||||||
bool get_mac_address()
|
bool get_mac_address()
|
||||||
{
|
{
|
||||||
if (device_address.has_value())
|
if (device_address.has_value())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD len = 0;
|
DWORD len = 0;
|
||||||
auto ret = GetAdaptersInfo(nullptr, &len);
|
auto ret = GetAdaptersInfo(nullptr, &len);
|
||||||
if (ret != ERROR_BUFFER_OVERFLOW) return false;
|
if (ret != ERROR_BUFFER_OVERFLOW)
|
||||||
|
return false;
|
||||||
std::vector<unsigned char> buf(len);
|
std::vector<unsigned char> buf(len);
|
||||||
auto pips = reinterpret_cast<PIP_ADAPTER_INFO>(&buf.front());
|
auto pips = reinterpret_cast<PIP_ADAPTER_INFO>(&buf.front());
|
||||||
ret = GetAdaptersInfo(pips, &len);
|
ret = GetAdaptersInfo(pips, &len);
|
||||||
if (ret != ERROR_SUCCESS) return false;
|
if (ret != ERROR_SUCCESS)
|
||||||
|
return false;
|
||||||
mac_address addr;
|
mac_address addr;
|
||||||
std::copy(pips->Address, pips->Address + 6, std::begin(addr));
|
std::copy(pips->Address, pips->Address + 6, std::begin(addr));
|
||||||
device_address = addr;
|
device_address = addr;
|
||||||
@ -860,7 +871,7 @@ namespace uuids
|
|||||||
|
|
||||||
auto clock_seq = get_clock_sequence();
|
auto clock_seq = get_clock_sequence();
|
||||||
|
|
||||||
auto ptm = reinterpret_cast<uuids::uuid::value_type*>(&tm);
|
auto ptm = reinterpret_cast<uuids::uuid::value_type *>(&tm);
|
||||||
|
|
||||||
memcpy(&data[0], ptm + 4, 4);
|
memcpy(&data[0], ptm + 4, 4);
|
||||||
memcpy(&data[4], ptm + 2, 2);
|
memcpy(&data[4], ptm + 2, 2);
|
||||||
@ -893,7 +904,7 @@ namespace std
|
|||||||
struct hash<uuids::uuid>
|
struct hash<uuids::uuid>
|
||||||
{
|
{
|
||||||
using argument_type = uuids::uuid;
|
using argument_type = uuids::uuid;
|
||||||
using result_type = std::size_t;
|
using result_type = std::size_t;
|
||||||
|
|
||||||
result_type operator()(argument_type const &uuid) const
|
result_type operator()(argument_type const &uuid) const
|
||||||
{
|
{
|
||||||
@ -901,24 +912,24 @@ namespace std
|
|||||||
std::hash<std::string> hasher;
|
std::hash<std::string> hasher;
|
||||||
return static_cast<result_type>(hasher(uuids::to_string(uuid)));
|
return static_cast<result_type>(hasher(uuids::to_string(uuid)));
|
||||||
#else
|
#else
|
||||||
uint64_t l =
|
uint64_t l =
|
||||||
static_cast<uint64_t>(uuid.data[0]) << 56 |
|
static_cast<uint64_t>(uuid.data[0]) << 56 |
|
||||||
static_cast<uint64_t>(uuid.data[1]) << 48 |
|
static_cast<uint64_t>(uuid.data[1]) << 48 |
|
||||||
static_cast<uint64_t>(uuid.data[2]) << 40 |
|
static_cast<uint64_t>(uuid.data[2]) << 40 |
|
||||||
static_cast<uint64_t>(uuid.data[3]) << 32 |
|
static_cast<uint64_t>(uuid.data[3]) << 32 |
|
||||||
static_cast<uint64_t>(uuid.data[4]) << 24 |
|
static_cast<uint64_t>(uuid.data[4]) << 24 |
|
||||||
static_cast<uint64_t>(uuid.data[5]) << 16 |
|
static_cast<uint64_t>(uuid.data[5]) << 16 |
|
||||||
static_cast<uint64_t>(uuid.data[6]) << 8 |
|
static_cast<uint64_t>(uuid.data[6]) << 8 |
|
||||||
static_cast<uint64_t>(uuid.data[7]);
|
static_cast<uint64_t>(uuid.data[7]);
|
||||||
uint64_t h =
|
uint64_t h =
|
||||||
static_cast<uint64_t>(uuid.data[8]) << 56 |
|
static_cast<uint64_t>(uuid.data[8]) << 56 |
|
||||||
static_cast<uint64_t>(uuid.data[9]) << 48 |
|
static_cast<uint64_t>(uuid.data[9]) << 48 |
|
||||||
static_cast<uint64_t>(uuid.data[10]) << 40 |
|
static_cast<uint64_t>(uuid.data[10]) << 40 |
|
||||||
static_cast<uint64_t>(uuid.data[11]) << 32 |
|
static_cast<uint64_t>(uuid.data[11]) << 32 |
|
||||||
static_cast<uint64_t>(uuid.data[12]) << 24 |
|
static_cast<uint64_t>(uuid.data[12]) << 24 |
|
||||||
static_cast<uint64_t>(uuid.data[13]) << 16 |
|
static_cast<uint64_t>(uuid.data[13]) << 16 |
|
||||||
static_cast<uint64_t>(uuid.data[14]) << 8 |
|
static_cast<uint64_t>(uuid.data[14]) << 8 |
|
||||||
static_cast<uint64_t>(uuid.data[15]);
|
static_cast<uint64_t>(uuid.data[15]);
|
||||||
|
|
||||||
if (sizeof(result_type) > 4)
|
if (sizeof(result_type) > 4)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user