// // Created by loki on 8-2-19. // #ifndef T_MAN_UUID_H #define T_MAN_UUID_H #include namespace util { union uuid_t { std::uint8_t b8[16]; std::uint16_t b16[8]; std::uint32_t b32[4]; std::uint64_t b64[2]; static uuid_t generate(std::default_random_engine &engine) { std::uniform_int_distribution dist(0, std::numeric_limits::max()); uuid_t buf; for(auto &el : buf.b8) { el = dist(engine); } buf.b8[7] &= (std::uint8_t)0b00101111; buf.b8[9] &= (std::uint8_t)0b10011111; return buf; } static uuid_t generate() { std::random_device r; std::default_random_engine engine { r() }; return generate(engine); } [[nodiscard]] std::string string() const { std::string result; result.reserve(sizeof(uuid_t) * 2 + 4); auto hex = util::hex(*this, true); auto hex_view = hex.to_string_view(); std::string_view slices[] = { hex_view.substr(0, 8), hex_view.substr(8, 4), hex_view.substr(12, 4), hex_view.substr(16, 4) }; auto last_slice = hex_view.substr(20, 12); for(auto &slice : slices) { std::copy(std::begin(slice), std::end(slice), std::back_inserter(result)); result.push_back('-'); } std::copy(std::begin(last_slice), std::end(last_slice), std::back_inserter(result)); return result; } constexpr bool operator==(const uuid_t &other) const { return b64[0] == other.b64[0] && b64[1] == other.b64[1]; } constexpr bool operator<(const uuid_t &other) const { return (b64[0] < other.b64[0] || (b64[0] == other.b64[0] && b64[1] < other.b64[1])); } constexpr bool operator>(const uuid_t &other) const { return (b64[0] > other.b64[0] || (b64[0] == other.b64[0] && b64[1] > other.b64[1])); } }; } // namespace util #endif //T_MAN_UUID_H