File uuid.h¶
File List > endstone > util > uuid.h
Go to the documentation of this file
// Copyright (c) 2024, The Endstone Project. (https://endstone.dev) All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <string>
namespace endstone {
class UUID {
public:
std::uint8_t *begin() noexcept
{
return data;
}
[[nodiscard]] const uint8_t *begin() const noexcept
{
return data;
}
std::uint8_t *end() noexcept
{
return data + size();
}
[[nodiscard]] const uint8_t *end() const noexcept
{
return data + size();
}
[[nodiscard]] static constexpr std::size_t size() noexcept
{
return 16;
}
[[nodiscard]] bool isNil() const noexcept
{
return std::all_of(std::begin(data), std::end(data), [](const auto &val) { return val == 0U; });
}
[[nodiscard]] int version() const noexcept
{
// version is stored in octet 9 which is index 6, since indexes count backwards
uint8_t octet9 = data[6];
if ((octet9 & 0xF0) == 0x10) {
return 1;
}
if ((octet9 & 0xF0) == 0x20) {
return 2;
}
if ((octet9 & 0xF0) == 0x30) {
return 3;
}
if ((octet9 & 0xF0) == 0x40) {
return 4;
}
if ((octet9 & 0xF0) == 0x50) {
return 5;
}
return -1;
}
void swap(UUID &rhs) noexcept
{
UUID tmp = *this;
*this = rhs;
rhs = tmp;
}
[[nodiscard]] std::string str() const
{
std::string result;
result.reserve(36);
static const char *chars = "0123456789abcdef";
for (size_t i = 0; i < 16; ++i) {
result.push_back(chars[(data[i] >> 4) & 0x0F]);
result.push_back(chars[data[i] & 0x0F]);
if (i == 3 || i == 5 || i == 7 || i == 9) {
result.push_back('-');
}
}
return result;
}
std::uint8_t data[16];
};
static_assert(sizeof(endstone::UUID) == endstone::UUID::size());
inline bool operator==(UUID const &lhs, UUID const &rhs) noexcept
{
return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) == 0;
}
inline bool operator<(UUID const &lhs, UUID const &rhs) noexcept
{
return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) < 0;
}
inline bool operator!=(UUID const &lhs, UUID const &rhs) noexcept
{
return !(lhs == rhs);
}
inline bool operator>(UUID const &lhs, UUID const &rhs) noexcept
{
return rhs < lhs;
}
inline bool operator<=(UUID const &lhs, UUID const &rhs) noexcept
{
return !(rhs < lhs);
}
inline bool operator>=(UUID const &lhs, UUID const &rhs) noexcept
{
return !(lhs < rhs);
}
inline void swap(UUID &lhs, UUID &rhs) noexcept
{
lhs.swap(rhs);
}
inline std::size_t hash_value(UUID const &u) noexcept
{
std::size_t seed = 0;
for (unsigned char i : u) {
seed ^= static_cast<std::size_t>(i) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
return seed;
}
} // namespace endstone
namespace std {
template <>
struct hash<endstone::UUID> {
std::size_t operator()(const endstone::UUID &value) const noexcept
{
return endstone::hash_value(value);
}
};
} // namespace std