32#include <memory_resource>
39 namespace discord_core_internal {
48 template<
typename value_type>
49 concept voice_state_t = std::same_as<value_type, voice_state_data_light>;
51 template<
typename value_type>
52 concept guild_member_t = std::same_as<value_type, guild_member_cache_data> || std::same_as<value_type, guild_member_data>;
54 template<
typename value_type>
55 concept has_id =
requires(value_type value) { value.id; };
57 template<
typename value_type>
58 concept has_two_id = voice_state_t<value_type> || guild_member_t<value_type>;
60 template<
typename value_type>
61 concept event_delegate_token_t = std::same_as<value_type, discord_core_internal::event_delegate_token>;
63 struct object_compare {
64 template<
typename value_type01,
typename value_type02> DCA_INLINE
bool operator()(
const value_type01& lhs,
const value_type02& rhs) {
65 return lhs ==
static_cast<value_type01
>(rhs);
68 template<
typename value_type01> DCA_INLINE
bool operator()(
const value_type01& lhs,
const value_type01& rhs) {
73 DCA_INLINE uint64_t internalHashFunction(
const void* value, uint64_t count) {
74 static constexpr uint64_t fnvOffsetBasis{ 0xcbf29ce484222325 };
75 static constexpr uint64_t fnvPrime{ 0x00000100000001B3 };
76 uint64_t hash{ fnvOffsetBasis };
77 for (uint64_t x = 0; x < count; ++x) {
78 hash ^=
static_cast<const uint8_t*
>(value)[x];
86 template<guild_member_t value_type> two_id_key(
const value_type& other);
87 template<voice_state_t value_type> two_id_key(
const value_type& other);
93 template<
typename value_type>
struct key_hasher;
95 template<has_
id value_type>
struct key_hasher<value_type> {
96 DCA_INLINE
static uint64_t getHashKey(
const value_type& other) {
97 return internalHashFunction(&other.id.operator
const uint64_t&(),
sizeof(uint64_t));
101 template<>
struct key_hasher<const char*> {
102 DCA_INLINE
static uint64_t getHashKey(
const char* other) {
103 return internalHashFunction(other, std::char_traits<char>::length(other));
107 template<u
int64_t size>
struct key_hasher<char[size]> {
108 DCA_INLINE
static uint64_t getHashKey(
const char (&other)[size]) {
109 return internalHashFunction(other, std::char_traits<char>::length(other));
113 template<jsonifier::concepts::
integer_t value_type>
struct key_hasher<value_type> {
114 DCA_INLINE
static uint64_t getHashKey(
const value_type& other) {
115 return internalHashFunction(&other,
sizeof(other));
119 template<>
struct key_hasher<two_id_key> {
120 DCA_INLINE
static uint64_t getHashKey(
const two_id_key& other) {
121 uint64_t values[2]{};
122 values[0] = other.idOne.operator
const uint64_t&();
123 values[1] = other.idTwo.operator
const uint64_t&();
124 return internalHashFunction(values,
sizeof(uint64_t) * std::size(values));
128 template<jsonifier::concepts::enum_t value_type>
struct key_hasher<value_type> {
129 DCA_INLINE
static uint64_t getHashKey(
const value_type& other) {
130 return internalHashFunction(&other,
sizeof(other));
134 template<jsonifier::concepts::
string_t value_type>
struct key_hasher<value_type> {
135 DCA_INLINE
static uint64_t getHashKey(
const value_type& other) {
136 return internalHashFunction(other.data(), other.size());
140 template<>
struct key_hasher<
snowflake> {
141 DCA_INLINE
static uint64_t getHashKey(
const snowflake& data) {
142 return internalHashFunction(&data.operator
const uint64_t&(),
sizeof(uint64_t));
146 template<>
struct key_hasher<jsonifier::vector<jsonifier::string>> {
147 DCA_INLINE
static uint64_t getHashKey(
const jsonifier::vector<jsonifier::string>& data) {
148 jsonifier::string newString{};
149 for (
auto& value: data) {
150 newString.append(value);
152 return internalHashFunction(newString.data(), newString.size());
156 template<has_two_
id value_type>
struct key_hasher<value_type> {
157 DCA_INLINE
static uint64_t getHashKey(
const value_type& other) {
158 return key_hasher<two_id_key>::getHashKey(two_id_key{ other });
162 template<jsonifier::concepts::unique_ptr_t value_type>
struct key_hasher<value_type> {
163 DCA_INLINE
static uint64_t getHashKey(
const value_type& other) {
164 return key_hasher<typename value_type::element_type>::getHashKey(*other);
168 template<
typename value_Type>
struct key_accessor;
170 template<voice_state_t value_type>
struct key_accessor<value_type> {
171 DCA_INLINE
static uint64_t getHashKey(
const value_type& other) {
172 return key_hasher<value_type>::getHashKey(other);
176 template<>
struct key_accessor<
snowflake> {
177 DCA_INLINE
static uint64_t getHashKey(
const snowflake& other) {
178 return key_hasher<snowflake>::getHashKey(other);
182 template<>
struct key_accessor<two_id_key> {
183 DCA_INLINE
static uint64_t getHashKey(
const two_id_key& other) {
184 return key_hasher<two_id_key>::getHashKey(other);
188 template<>
struct key_accessor<const char*> {
189 DCA_INLINE
static uint64_t getHashKey(
const char* other) {
190 return key_hasher<const char*>::getHashKey(other);
194 template<u
int64_t size>
struct key_accessor<char[size]> {
195 DCA_INLINE
static uint64_t getHashKey(
const char (&other)[size]) {
196 return key_hasher<char[size]>::getHashKey(other);
200 template<jsonifier::concepts::
string_t value_type>
struct key_accessor<value_type> {
201 DCA_INLINE
static uint64_t getHashKey(
const value_type& other) {
202 return key_hasher<value_type>::getHashKey(other);
206 template<has_
id value_type>
struct key_accessor<value_type> {
207 DCA_INLINE
static uint64_t getHashKey(
const value_type& other) {
208 return key_hasher<value_type>::getHashKey(other);
212 template<jsonifier::concepts::unique_ptr_t value_type>
struct key_accessor<value_type> {
213 DCA_INLINE
static uint64_t getHashKey(
const value_type& other) {
214 return key_hasher<value_type>::getHashKey(other);
218 template<>
struct key_accessor<jsonifier::vector<jsonifier::string>> {
219 DCA_INLINE
static uint64_t getHashKey(
const jsonifier::vector<jsonifier::string>& other) {
220 return key_hasher<jsonifier::vector<jsonifier::string>>::getHashKey(other);
224 template<
typename value_type>
struct hash_policy {
225 template<
typename key_type> DCA_INLINE uint64_t indexForHash(key_type&& key)
const {
226 return key_hasher<std::remove_cvref_t<key_type>>::getHashKey(key) & (
static_cast<const value_type*
>(
this)->capacityVal - 1);
229 DCA_INLINE
static int8_t log2(uint64_t value) {
230 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,
231 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 };
236 value |= value >> 16;
237 value |= value >> 32;
238 return table[((value - (value >> 1)) * 0x07EDD5E59A4E28C2) >> 58];
241 DCA_INLINE
static uint64_t nextPowerOfTwo(uint64_t size) {
253 static int8_t computeMaxLookAheadDistance(uint64_t num_buckets) {
254 return log2(num_buckets);
258 template<
typename value_type_
internal_new>
class hash_iterator {
260 using iterator_category = std::forward_iterator_tag;
261 using value_type_internal = value_type_internal_new;
262 using value_type =
typename value_type_internal::value_type;
263 using reference = value_type&;
264 using pointer = value_type*;
265 using pointer_internal = value_type_internal*;
266 using size_type = uint64_t;
268 DCA_INLINE hash_iterator() =
default;
270 DCA_INLINE hash_iterator(pointer_internal valueNew, size_type currentIndexNew) : value{ valueNew }, currentIndex{ currentIndexNew } {};
272 DCA_INLINE hash_iterator& operator++() {
277 DCA_INLINE hash_iterator& operator--() {
282 DCA_INLINE hash_iterator& operator-(size_type amountToReverse) {
283 for (size_type x = 0; x < amountToReverse; ++x) {
289 DCA_INLINE hash_iterator& operator+(size_type amountToAdd) {
290 for (size_type x = 0; x < amountToAdd; ++x) {
296 DCA_INLINE pointer getRawPtr() {
297 return &value->data[currentIndex];
300 DCA_INLINE
bool operator==(
const hash_iterator&)
const {
301 return !value || value->sentinelVector[currentIndex] == -1;
304 DCA_INLINE pointer operator->() {
305 return &value->data[currentIndex];
308 DCA_INLINE reference operator*() {
309 return value->data[currentIndex];
313 pointer_internal value{};
314 size_type currentIndex{};
316 void skipEmptySlots() {
317 if (currentIndex < value->sentinelVector.size()) {
319 while (value && value->sentinelVector[currentIndex] == 0 && currentIndex < value->sentinelVector.size()) {
325 void skipEmptySlotsRev() {
326 if (
static_cast<int64_t
>(currentIndex) > 0) {
328 while (value && value->sentinelVector[currentIndex] == 0 &&
static_cast<int64_t
>(currentIndex) > 0) {
Data structure representing a single guild_member_data.
Data structure representing a single guild_member_data.
A class representing a snowflake identifier with various operations.
The main namespace for the forward-facing interfaces.
Struct representing an event delegate token, associated with an event.