[*] Reformat because 3 space indents were doing my head in
[*] Obliterate string streams because why the hell would we EVER want the overhead of streams and arbitrary allocs when merely stringifying a uuid
This commit is contained in:
parent
47d09d4dc7
commit
60944ec71e
294
include/uuid.h
294
include/uuid.h
@ -2,54 +2,36 @@
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <array>
|
||||
#include <iterator>
|
||||
#include <random>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <optional>
|
||||
#include <chrono>
|
||||
#include <numeric>
|
||||
#include <atomic>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifdef UUID_SYSTEM_GENERATOR
|
||||
#include <objbase.h>
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
#include <iphlpapi.h>
|
||||
#pragma comment(lib, "IPHLPAPI.lib")
|
||||
|
||||
#elif defined(__linux__) || defined(__unix__)
|
||||
|
||||
#ifdef UUID_SYSTEM_GENERATOR
|
||||
#include <uuid/uuid.h>
|
||||
#endif
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
#ifdef UUID_SYSTEM_GENERATOR
|
||||
#include <CoreFoundation/CFUUID.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace uuids
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
constexpr inline char NibbleToChar(unsigned char nib)
|
||||
{
|
||||
if (nib < 10)
|
||||
return '0' + nib;
|
||||
else
|
||||
return 'A' + (nib - 10);
|
||||
}
|
||||
|
||||
template <typename TChar>
|
||||
constexpr inline void ByteToHex(unsigned char val, TChar *hex)
|
||||
{
|
||||
unsigned char lowNibble = val & 0xF;
|
||||
unsigned char hiNibble = (val >> 4) & 0xF;
|
||||
|
||||
hex[0] = NibbleToChar(hiNibble);
|
||||
hex[1] = NibbleToChar(lowNibble);
|
||||
}
|
||||
|
||||
|
||||
template <typename TChar>
|
||||
constexpr inline unsigned char hex2char(TChar const ch)
|
||||
{
|
||||
@ -90,7 +72,10 @@ namespace uuids
|
||||
return (value << count) ^ (value >> (32 - count));
|
||||
}
|
||||
|
||||
sha1() { reset(); }
|
||||
sha1()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
@ -135,16 +120,21 @@ namespace uuids
|
||||
{
|
||||
size_t const bitCount = this->m_byteCount * 8;
|
||||
process_byte(0x80);
|
||||
if (this->m_blockByteIndex > 56) {
|
||||
while (m_blockByteIndex != 0) {
|
||||
if (this->m_blockByteIndex > 56)
|
||||
{
|
||||
while (m_blockByteIndex != 0)
|
||||
{
|
||||
process_byte(0);
|
||||
}
|
||||
while (m_blockByteIndex < 56) {
|
||||
while (m_blockByteIndex < 56)
|
||||
{
|
||||
process_byte(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (m_blockByteIndex < 56) {
|
||||
else
|
||||
{
|
||||
while (m_blockByteIndex < 56)
|
||||
{
|
||||
process_byte(0);
|
||||
}
|
||||
}
|
||||
@ -198,13 +188,15 @@ namespace uuids
|
||||
void process_block()
|
||||
{
|
||||
uint32_t w[80];
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
for (size_t i = 0; i < 16; i++)
|
||||
{
|
||||
w[i] = (m_block[i * 4 + 0] << 24);
|
||||
w[i] |= (m_block[i * 4 + 1] << 16);
|
||||
w[i] |= (m_block[i * 4 + 2] << 8);
|
||||
w[i] |= (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);
|
||||
}
|
||||
|
||||
@ -219,19 +211,23 @@ namespace uuids
|
||||
uint32_t f = 0;
|
||||
uint32_t k = 0;
|
||||
|
||||
if (i < 20) {
|
||||
if (i < 20)
|
||||
{
|
||||
f = (b & c) | (~b & d);
|
||||
k = 0x5A827999;
|
||||
}
|
||||
else if (i < 40) {
|
||||
else if (i < 40)
|
||||
{
|
||||
f = b ^ c ^ d;
|
||||
k = 0x6ED9EBA1;
|
||||
}
|
||||
else if (i < 60) {
|
||||
else if (i < 60)
|
||||
{
|
||||
f = (b & c) | (b & d) | (c & d);
|
||||
k = 0x8F1BBCDC;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
f = b ^ c ^ d;
|
||||
k = 0xCA62C1D6;
|
||||
}
|
||||
@ -257,9 +253,6 @@ namespace uuids
|
||||
size_t m_byteCount;
|
||||
};
|
||||
|
||||
static std::mt19937 clock_gen(std::random_device{}());
|
||||
static std::uniform_int_distribution<short> clock_dis{ -32768, 32767 };
|
||||
static std::atomic_short clock_sequence = clock_dis(clock_gen);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------------
|
||||
@ -338,7 +331,8 @@ namespace uuids
|
||||
public:
|
||||
using value_type = uint8_t;
|
||||
|
||||
constexpr uuid() noexcept : data({}) {};
|
||||
constexpr uuid() noexcept : data({})
|
||||
{};
|
||||
|
||||
//uuid(value_type(&arr)[16]) noexcept
|
||||
//{
|
||||
@ -460,10 +454,8 @@ namespace uuids
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class CharT = char,
|
||||
class Traits = std::char_traits<CharT>,
|
||||
class Allocator = std::allocator<CharT>>
|
||||
static bool is_valid_uuid(std::basic_string<CharT, Traits, Allocator> const & str) noexcept
|
||||
template<class String_t>
|
||||
static bool is_valid_uuid(const String_t &str) noexcept
|
||||
{
|
||||
return is_valid_uuid(str.c_str());
|
||||
}
|
||||
@ -519,12 +511,49 @@ namespace uuids
|
||||
return uuid {std::cbegin(data), std::cend(data)};
|
||||
}
|
||||
|
||||
template<class String_t>
|
||||
static std::optional<uuid> from_string(const String_t &str) noexcept
|
||||
{
|
||||
return from_string(str.c_str());
|
||||
}
|
||||
|
||||
template<class CharT = char>
|
||||
inline void to_string(CharT(&out)[36]) const
|
||||
{
|
||||
detail::ByteToHex(data[0], out + (2 * 0));
|
||||
detail::ByteToHex(data[1], out + (2 * 1));
|
||||
detail::ByteToHex(data[2], out + (2 * 2));
|
||||
detail::ByteToHex(data[3], out + (2 * 3));
|
||||
out[(2 * 4)] = '-';
|
||||
|
||||
detail::ByteToHex(data[4], out + (2 * 4) + 1);
|
||||
detail::ByteToHex(data[5], out + (2 * 5) + 1);
|
||||
out[(2 * 6) + 1] = '-';
|
||||
|
||||
detail::ByteToHex(data[6], out + (2 * 6) + 2);
|
||||
detail::ByteToHex(data[7], out + (2 * 7) + 2);
|
||||
out[(2 * 8) + 2] = '-';
|
||||
|
||||
detail::ByteToHex(data[8], out + (2 * 8) + 3);
|
||||
detail::ByteToHex(data[9], out + (2 * 9) + 3);
|
||||
out[(2 * 10) + 3] = '-';
|
||||
|
||||
detail::ByteToHex(data[10], out + (2 * 10) + 4);
|
||||
detail::ByteToHex(data[11], out + (2 * 11) + 4);
|
||||
detail::ByteToHex(data[12], out + (2 * 12) + 4);
|
||||
detail::ByteToHex(data[13], out + (2 * 13) + 4);
|
||||
detail::ByteToHex(data[14], out + (2 * 14) + 4);
|
||||
detail::ByteToHex(data[15], out + (2 * 15) + 4);
|
||||
}
|
||||
|
||||
template<class CharT = char,
|
||||
class Traits = std::char_traits<CharT>,
|
||||
class Allocator = std::allocator<CharT>>
|
||||
static std::optional<uuid> from_string(std::basic_string<CharT, Traits, Allocator> const & str) noexcept
|
||||
inline std::basic_string<CharT, Traits, Allocator> to_string() const
|
||||
{
|
||||
return from_string(str.c_str());
|
||||
CharT stackStr[36];
|
||||
to_string(stackStr);
|
||||
return std::basic_string<CharT, Traits, Allocator>(stackStr, stackStr + 36);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -532,9 +561,6 @@ namespace uuids
|
||||
|
||||
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>
|
||||
friend std::basic_ostream<Elem, Traits> & operator<<(std::basic_ostream<Elem, Traits> &s, uuid const & id);
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------------
|
||||
@ -556,49 +582,13 @@ namespace uuids
|
||||
return lhs.data < rhs.data;
|
||||
}
|
||||
|
||||
template <class Elem, class Traits>
|
||||
std::basic_ostream<Elem, Traits> & operator<<(std::basic_ostream<Elem, Traits> &s, uuid const & id)
|
||||
{
|
||||
// save current flags
|
||||
std::ios_base::fmtflags f(s.flags());
|
||||
|
||||
// manipulate stream as needed
|
||||
s << std::hex << std::setfill(static_cast<Elem>('0'))
|
||||
<< std::setw(2) << (int)id.data[0]
|
||||
<< std::setw(2) << (int)id.data[1]
|
||||
<< std::setw(2) << (int)id.data[2]
|
||||
<< std::setw(2) << (int)id.data[3]
|
||||
<< '-'
|
||||
<< std::setw(2) << (int)id.data[4]
|
||||
<< std::setw(2) << (int)id.data[5]
|
||||
<< '-'
|
||||
<< std::setw(2) << (int)id.data[6]
|
||||
<< std::setw(2) << (int)id.data[7]
|
||||
<< '-'
|
||||
<< std::setw(2) << (int)id.data[8]
|
||||
<< std::setw(2) << (int)id.data[9]
|
||||
<< '-'
|
||||
<< std::setw(2) << (int)id.data[10]
|
||||
<< std::setw(2) << (int)id.data[11]
|
||||
<< std::setw(2) << (int)id.data[12]
|
||||
<< std::setw(2) << (int)id.data[13]
|
||||
<< std::setw(2) << (int)id.data[14]
|
||||
<< std::setw(2) << (int)id.data[15];
|
||||
|
||||
// restore original flags
|
||||
s.flags(f);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
template<class CharT = char,
|
||||
class Traits = std::char_traits<CharT>,
|
||||
class Allocator = std::allocator<CharT>>
|
||||
inline std::basic_string<CharT, Traits, Allocator> to_string(uuid const &id)
|
||||
{
|
||||
std::basic_stringstream<CharT, Traits, Allocator> sstr;
|
||||
sstr << id;
|
||||
return sstr.str();
|
||||
return id.to_string<CharT, Traits, Allocator>();
|
||||
}
|
||||
|
||||
inline void swap(uuids::uuid &lhs, uuids::uuid &rhs) noexcept
|
||||
@ -626,103 +616,6 @@ namespace uuids
|
||||
// uuid generators
|
||||
// --------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef UUID_SYSTEM_GENERATOR
|
||||
class uuid_system_generator
|
||||
{
|
||||
public:
|
||||
using result_type = uuid;
|
||||
|
||||
uuid operator()()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
GUID newId;
|
||||
::CoCreateGuid(&newId);
|
||||
|
||||
std::array<uint8_t, 16> bytes =
|
||||
{ {
|
||||
(unsigned char)((newId.Data1 >> 24) & 0xFF),
|
||||
(unsigned char)((newId.Data1 >> 16) & 0xFF),
|
||||
(unsigned char)((newId.Data1 >> 8) & 0xFF),
|
||||
(unsigned char)((newId.Data1) & 0xFF),
|
||||
|
||||
(unsigned char)((newId.Data2 >> 8) & 0xFF),
|
||||
(unsigned char)((newId.Data2) & 0xFF),
|
||||
|
||||
(unsigned char)((newId.Data3 >> 8) & 0xFF),
|
||||
(unsigned char)((newId.Data3) & 0xFF),
|
||||
|
||||
newId.Data4[0],
|
||||
newId.Data4[1],
|
||||
newId.Data4[2],
|
||||
newId.Data4[3],
|
||||
newId.Data4[4],
|
||||
newId.Data4[5],
|
||||
newId.Data4[6],
|
||||
newId.Data4[7]
|
||||
} };
|
||||
|
||||
return uuid{ std::begin(bytes), std::end(bytes) };
|
||||
|
||||
#elif defined(__linux__) || defined(__unix__)
|
||||
|
||||
uuid_t id;
|
||||
uuid_generate(id);
|
||||
|
||||
std::array<uint8_t, 16> bytes =
|
||||
{ {
|
||||
id[0],
|
||||
id[1],
|
||||
id[2],
|
||||
id[3],
|
||||
id[4],
|
||||
id[5],
|
||||
id[6],
|
||||
id[7],
|
||||
id[8],
|
||||
id[9],
|
||||
id[10],
|
||||
id[11],
|
||||
id[12],
|
||||
id[13],
|
||||
id[14],
|
||||
id[15]
|
||||
} };
|
||||
|
||||
return uuid{ std::begin(bytes), std::end(bytes) };
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
auto newId = CFUUIDCreate(NULL);
|
||||
auto bytes = CFUUIDGetUUIDBytes(newId);
|
||||
CFRelease(newId);
|
||||
|
||||
std::array<uint8_t, 16> arrbytes =
|
||||
{ {
|
||||
bytes.byte0,
|
||||
bytes.byte1,
|
||||
bytes.byte2,
|
||||
bytes.byte3,
|
||||
bytes.byte4,
|
||||
bytes.byte5,
|
||||
bytes.byte6,
|
||||
bytes.byte7,
|
||||
bytes.byte8,
|
||||
bytes.byte9,
|
||||
bytes.byte10,
|
||||
bytes.byte11,
|
||||
bytes.byte12,
|
||||
bytes.byte13,
|
||||
bytes.byte14,
|
||||
bytes.byte15
|
||||
} };
|
||||
return uuid{ std::begin(arrbytes), std::end(arrbytes) };
|
||||
#else
|
||||
return uuid{};
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
class basic_uuid_random_generator
|
||||
{
|
||||
@ -730,9 +623,14 @@ namespace uuids
|
||||
using engine_type = UniformRandomNumberGenerator;
|
||||
|
||||
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) {}) {}
|
||||
generator(gen, [](auto)
|
||||
{})
|
||||
{}
|
||||
|
||||
uuid operator()()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user