33#include <memory_resource>
37namespace DiscordCoreAPI {
39 namespace DiscordCoreInternal {
40 struct EventDelegateToken;
45 template<
typename ValueType>
46 concept EtfSerializerT = std::same_as<ValueType, EtfSerializer>;
48 template<
typename ValueType>
49 concept BoolT = std::same_as<std::decay_t<ValueType>,
bool> && !EtfSerializerT<ValueType> && !std::integral<ValueType>;
51 template<
typename ValueType>
52 concept EnumT = std::is_enum<std::decay_t<ValueType>>::value;
54 template<
typename ValueType>
55 concept IntegerT = std::integral<std::decay_t<ValueType>> && !BoolT<std::decay_t<ValueType>>;
57 class GuildMemberCacheData;
58 struct VoiceStateDataLight;
59 struct VoiceStateData;
60 class GuildMemberData;
62 template<
typename ValueType>
63 concept VoiceStateT = std::same_as<ValueType, VoiceStateDataLight>;
65 template<
typename ValueType>
66 concept GuildMemberT = std::same_as<ValueType, GuildMemberCacheData> || std::same_as<ValueType, GuildMemberData>;
68 template<
typename ValueType>
69 concept HasId =
requires(ValueType value) { value.id; };
71 template<
typename ValueType>
72 concept HasTwoId = VoiceStateT<ValueType> || GuildMemberT<ValueType>;
74 template<
typename ValueType>
75 concept EventDelegateTokenT = std::same_as<ValueType, DiscordCoreInternal::EventDelegateToken>;
77 struct ObjectCompare {
78 template<
typename ValueType01,
typename ValueType02>
inline bool operator()(
const ValueType01& lhs,
const ValueType02& rhs)
const {
82 template<
typename ValueType01,
typename ValueType02>
inline bool operator()(ValueType01& lhs, ValueType02& rhs) {
87 inline uint64_t internalHashFunction(
const void* value, uint64_t count) {
88 static constexpr uint64_t fnvOffsetBasis{ 0xcbf29ce484222325 };
89 static constexpr uint64_t fnvPrime{ 0x00000100000001B3 };
90 uint64_t hash{ fnvOffsetBasis };
91 for (uint64_t x = 0; x < count; ++x) {
92 hash ^=
static_cast<const uint8_t*
>(value)[x];
100 template<GuildMemberT ValueType> TwoIdKey(
const ValueType& other);
101 template<VoiceStateT ValueType> TwoIdKey(
const ValueType& other);
107 template<
typename ValueType>
struct KeyHasher;
109 template<HasId ValueType>
struct KeyHasher<ValueType> {
110 inline uint64_t operator()(
const ValueType& other)
const {
111 return internalHashFunction(&other.id.operator
const uint64_t&(),
sizeof(uint64_t));
115 template<u
int64_t size>
struct KeyHasher<char[size]> {
116 inline uint64_t operator()(
const char (&other)[size])
const {
117 return internalHashFunction(other, std::char_traits<char>::length(other));
121 template<IntegerT ValueType>
struct KeyHasher<ValueType> {
122 inline uint64_t operator()(
const ValueType& other)
const {
123 return internalHashFunction(&other,
sizeof(other));
127 template<>
struct KeyHasher<TwoIdKey> {
128 inline uint64_t operator()(
const TwoIdKey& other)
const {
129 uint64_t values[2]{};
130 values[0] = other.idOne.operator
const uint64_t&();
131 values[1] = other.idTwo.operator
const uint64_t&();
132 return internalHashFunction(values,
sizeof(uint64_t) * std::size(values));
136 template<EnumT ValueType>
struct KeyHasher<ValueType> {
137 inline uint64_t operator()(
const ValueType& other)
const {
138 return internalHashFunction(&other,
sizeof(other));
142 template<jsonifier_
internal::
string_t ValueType>
struct KeyHasher<ValueType> {
143 inline uint64_t operator()(
const ValueType& other)
const {
144 return internalHashFunction(other.data(), other.size());
148 template<>
struct KeyHasher<Snowflake> {
149 inline uint64_t operator()(
const Snowflake& data)
const {
150 return internalHashFunction(&data.operator
const uint64_t&(),
sizeof(uint64_t));
154 template<>
struct KeyHasher<jsonifier::vector<std::string>> {
155 inline uint64_t operator()(
const jsonifier::vector<std::string>& data)
const {
156 std::string newString{};
157 for (
auto& value: data) {
158 newString.append(value);
160 return internalHashFunction(newString.data(), newString.size());
164 template<HasTwoId ValueType>
struct KeyHasher<ValueType> {
165 inline uint64_t operator()(
const ValueType& other)
const {
166 return KeyHasher<TwoIdKey>{}.operator()(TwoIdKey{ other });
170 template<jsonifier_
internal::unique_ptr_t ValueType>
struct KeyHasher<ValueType> {
171 inline uint64_t operator()(
const ValueType& other)
const {
172 return KeyHasher<typename ValueType::element_type>{}.operator()(*other);
177 template<GuildMemberT ValueType> uint64_t operator()(
const ValueType& other)
const {
178 return KeyHasher<ValueType>{}.operator()(other);
181 template<VoiceStateT ValueType> uint64_t operator()(
const ValueType& other)
const {
182 return KeyHasher<ValueType>{}.operator()(other);
185 uint64_t operator()(
const Snowflake& other)
const {
186 return KeyHasher<Snowflake>{}.operator()(other);
189 uint64_t operator()(
const TwoIdKey& other)
const {
190 return KeyHasher<TwoIdKey>{}.operator()(other);
193 template<u
int64_t size>
inline uint64_t operator()(
const char (&other)[size])
const {
194 return KeyHasher<char[size]>{}.operator()(other);
197 template<jsonifier_
internal::
string_t ValueType> uint64_t operator()(
const ValueType& other)
const {
198 return KeyHasher<ValueType>{}.operator()(other);
201 template<HasId ValueType> uint64_t operator()(
const ValueType& other)
const {
202 return KeyHasher<ValueType>{}.operator()(other);
205 template<jsonifier_
internal::unique_ptr_t ValueType> uint64_t operator()(
const ValueType& other)
const {
206 return KeyHasher<ValueType>{}.operator()(other);
209 uint64_t operator()(
const jsonifier::vector<std::string>& other)
const {
210 return KeyHasher<jsonifier::vector<std::string>>{}.operator()(other);
214 inline constexpr int8_t minLookups{ 0 };
216 template<
typename ValueType>
struct HashPolicy {
217 template<
typename KeyType>
inline uint64_t indexForHash(KeyType&& key)
const {
218 return KeyHasher<std::remove_cvref_t<KeyType>>{}.operator()(key) & (
static_cast<const ValueType*
>(
this)->capacityVal - 1);
221 static inline int8_t log2(uint64_t value) {
222 static constexpr int8_t table[64] = { 63, 0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61, 51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62, 57,
223 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, 56, 45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5 };
228 value |= value >> 16;
229 value |= value >> 32;
230 return table[((value - (value >> 1)) * 0x07EDD5E59A4E28C2) >> 58];
233 static inline uint64_t nextPowerOfTwo(uint64_t size) {
245 static int8_t computeMaxLookAheadDistance(uint64_t num_buckets) {
246 int8_t desired = log2(num_buckets);
247 return std::max(minLookups, desired);
251 template<
typename FirstType,
typename SecondType>
class Pair {
253 using first_type = FirstType;
254 using second_type = SecondType;
259 template<
typename FirstTypeNew,
typename SecondTypeNew>
inline Pair(FirstTypeNew&& firstNew, SecondTypeNew&& secondNew)
260 : first{ std::forward<FirstTypeNew>(firstNew) }, second{ std::forward<SecondTypeNew>(secondNew) } {
263 template<
typename FirstTypeNew>
inline Pair(FirstTypeNew&& firstNew) : first{ std::forward<FirstTypeNew>(firstNew) } {
266 template<
typename... Args>
inline Pair(Args&&... args) : Pair{ std::forward<Args>(args)... } {
269 inline bool operator==(
const Pair& other)
const {
270 return first == other.first && second == other.second;
274 template<
typename ValueTypeInternal>
class HashIterator {
276 using iterator_category = std::forward_iterator_tag;
277 using value_type_internal = ValueTypeInternal;
278 using value_type = ValueTypeInternal::value_type;
279 using reference = value_type&;
280 using pointer = value_type*;
281 using pointer_internal = value_type_internal*;
282 using size_type = uint64_t;
284 inline HashIterator() noexcept = default;
286 inline HashIterator(pointer_internal valueNew, size_type currentIndexNew) : value{ valueNew }, currentIndex{ currentIndexNew } {};
288 inline HashIterator& operator++() {
293 inline pointer getRawPtr() {
294 return &value->data[currentIndex];
297 inline bool operator==(
const HashIterator&)
const {
298 return !value || value->sentinelVector[currentIndex] == -1;
301 inline pointer operator->() {
302 return &value->data[currentIndex];
305 inline reference operator*() {
306 return value->data[currentIndex];
310 pointer_internal value{};
311 size_type currentIndex{};
313 void skipEmptySlots() {
315 while (value && value->sentinelVector[currentIndex] == 0) {