[*] 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:
Reece Wilson 2022-02-27 07:49:13 +00:00
parent 47d09d4dc7
commit 60944ec71e

View File

@ -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()()
{