#ifndef HASH_MAP_H
#define HASH_MAP_H
#include "core/math/math_funcs.h"
#include "core/os/memory.h"
#include "core/templates/hashfuncs.h"
#include "core/templates/paged_allocator.h"
#include "core/templates/pair.h"
template <typename TKey, typename TValue>
struct HashMapElement { … };
bool _hashmap_variant_less_than(const Variant &p_left, const Variant &p_right);
template <typename TKey, typename TValue,
typename Hasher = HashMapHasherDefault,
typename Comparator = HashMapComparatorDefault<TKey>,
typename Allocator = DefaultTypedAllocator<HashMapElement<TKey, TValue>>>
class HashMap {
public:
static constexpr uint32_t MIN_CAPACITY_INDEX = 2;
static constexpr float MAX_OCCUPANCY = 0.75;
static constexpr uint32_t EMPTY_HASH = 0;
private:
Allocator element_alloc;
HashMapElement<TKey, TValue> **elements = nullptr;
uint32_t *hashes = nullptr;
HashMapElement<TKey, TValue> *head_element = nullptr;
HashMapElement<TKey, TValue> *tail_element = nullptr;
uint32_t capacity_index = 0;
uint32_t num_elements = 0;
_FORCE_INLINE_ uint32_t _hash(const TKey &p_key) const { … }
static _FORCE_INLINE_ uint32_t _get_probe_length(const uint32_t p_pos, const uint32_t p_hash, const uint32_t p_capacity, const uint64_t p_capacity_inv) { … }
bool _lookup_pos(const TKey &p_key, uint32_t &r_pos) const { … }
void _insert_with_hash(uint32_t p_hash, HashMapElement<TKey, TValue> *p_value) { … }
void _resize_and_rehash(uint32_t p_new_capacity_index) { … }
_FORCE_INLINE_ HashMapElement<TKey, TValue> *_insert(const TKey &p_key, const TValue &p_value, bool p_front_insert = false) { … }
public:
_FORCE_INLINE_ uint32_t get_capacity() const { … }
_FORCE_INLINE_ uint32_t size() const { … }
bool is_empty() const { … }
void clear() { … }
void sort() { … }
TValue &get(const TKey &p_key) { … }
const TValue &get(const TKey &p_key) const { … }
const TValue *getptr(const TKey &p_key) const { … }
TValue *getptr(const TKey &p_key) { … }
_FORCE_INLINE_ bool has(const TKey &p_key) const { … }
bool erase(const TKey &p_key) { … }
bool replace_key(const TKey &p_old_key, const TKey &p_new_key) { … }
void reserve(uint32_t p_new_capacity) { … }
struct ConstIterator {
_FORCE_INLINE_ const KeyValue<TKey, TValue> &operator*() const {
return E->data;
}
_FORCE_INLINE_ const KeyValue<TKey, TValue> *operator->() const { return &E->data; }
_FORCE_INLINE_ ConstIterator &operator++() {
if (E) {
E = E->next;
}
return *this;
}
_FORCE_INLINE_ ConstIterator &operator--() {
if (E) {
E = E->prev;
}
return *this;
}
_FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return E == b.E; }
_FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return E != b.E; }
_FORCE_INLINE_ explicit operator bool() const {
return E != nullptr;
}
_FORCE_INLINE_ ConstIterator(const HashMapElement<TKey, TValue> *p_E) { E = p_E; }
_FORCE_INLINE_ ConstIterator() {}
_FORCE_INLINE_ ConstIterator(const ConstIterator &p_it) { E = p_it.E; }
_FORCE_INLINE_ void operator=(const ConstIterator &p_it) {
E = p_it.E;
}
private:
const HashMapElement<TKey, TValue> *E = nullptr;
};
struct Iterator {
_FORCE_INLINE_ KeyValue<TKey, TValue> &operator*() const {
return E->data;
}
_FORCE_INLINE_ KeyValue<TKey, TValue> *operator->() const { return &E->data; }
_FORCE_INLINE_ Iterator &operator++() {
if (E) {
E = E->next;
}
return *this;
}
_FORCE_INLINE_ Iterator &operator--() {
if (E) {
E = E->prev;
}
return *this;
}
_FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
_FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }
_FORCE_INLINE_ explicit operator bool() const {
return E != nullptr;
}
_FORCE_INLINE_ Iterator(HashMapElement<TKey, TValue> *p_E) { E = p_E; }
_FORCE_INLINE_ Iterator() {}
_FORCE_INLINE_ Iterator(const Iterator &p_it) { E = p_it.E; }
_FORCE_INLINE_ void operator=(const Iterator &p_it) {
E = p_it.E;
}
operator ConstIterator() const {
return ConstIterator(E);
}
private:
HashMapElement<TKey, TValue> *E = nullptr;
};
_FORCE_INLINE_ Iterator begin() { … }
_FORCE_INLINE_ Iterator end() { … }
_FORCE_INLINE_ Iterator last() { … }
_FORCE_INLINE_ Iterator find(const TKey &p_key) { … }
_FORCE_INLINE_ void remove(const Iterator &p_iter) { … }
_FORCE_INLINE_ ConstIterator begin() const { … }
_FORCE_INLINE_ ConstIterator end() const { … }
_FORCE_INLINE_ ConstIterator last() const { … }
_FORCE_INLINE_ ConstIterator find(const TKey &p_key) const { … }
const TValue &operator[](const TKey &p_key) const { … }
TValue &operator[](const TKey &p_key) { … }
Iterator insert(const TKey &p_key, const TValue &p_value, bool p_front_insert = false) { … }
HashMap(const HashMap &p_other) { … }
void operator=(const HashMap &p_other) { … }
HashMap(uint32_t p_initial_capacity) { … }
HashMap() { … }
uint32_t debug_get_hash(uint32_t p_index) { … }
Iterator debug_get_element(uint32_t p_index) { … }
~HashMap() { … }
};
#endif