#ifndef HASH_SET_H
#define HASH_SET_H
#include "core/math/math_funcs.h"
#include "core/os/memory.h"
#include "core/templates/hash_map.h"
#include "core/templates/hashfuncs.h"
#include "core/templates/paged_allocator.h"
template <typename TKey,
typename Hasher = HashMapHasherDefault,
typename Comparator = HashMapComparatorDefault<TKey>>
class HashSet {
public:
static constexpr uint32_t MIN_CAPACITY_INDEX = 2;
static constexpr float MAX_OCCUPANCY = 0.75;
static constexpr uint32_t EMPTY_HASH = 0;
private:
TKey *keys = nullptr;
uint32_t *hash_to_key = nullptr;
uint32_t *key_to_hash = nullptr;
uint32_t *hashes = 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 { … }
uint32_t _insert_with_hash(uint32_t p_hash, uint32_t p_index) { … }
void _resize_and_rehash(uint32_t p_new_capacity_index) { … }
_FORCE_INLINE_ int32_t _insert(const TKey &p_key) { … }
void _init_from(const HashSet &p_other) { … }
public:
_FORCE_INLINE_ uint32_t get_capacity() const { … }
_FORCE_INLINE_ uint32_t size() const { … }
bool is_empty() const { … }
void clear() { … }
_FORCE_INLINE_ bool has(const TKey &p_key) const { … }
bool erase(const TKey &p_key) { … }
void reserve(uint32_t p_new_capacity) { … }
struct Iterator {
_FORCE_INLINE_ const TKey &operator*() const {
return keys[index];
}
_FORCE_INLINE_ const TKey *operator->() const {
return &keys[index];
}
_FORCE_INLINE_ Iterator &operator++() {
index++;
if (index >= (int32_t)num_keys) {
index = -1;
keys = nullptr;
num_keys = 0;
}
return *this;
}
_FORCE_INLINE_ Iterator &operator--() {
index--;
if (index < 0) {
index = -1;
keys = nullptr;
num_keys = 0;
}
return *this;
}
_FORCE_INLINE_ bool operator==(const Iterator &b) const { return keys == b.keys && index == b.index; }
_FORCE_INLINE_ bool operator!=(const Iterator &b) const { return keys != b.keys || index != b.index; }
_FORCE_INLINE_ explicit operator bool() const {
return keys != nullptr;
}
_FORCE_INLINE_ Iterator(const TKey *p_keys, uint32_t p_num_keys, int32_t p_index = -1) {
keys = p_keys;
num_keys = p_num_keys;
index = p_index;
}
_FORCE_INLINE_ Iterator() {}
_FORCE_INLINE_ Iterator(const Iterator &p_it) {
keys = p_it.keys;
num_keys = p_it.num_keys;
index = p_it.index;
}
_FORCE_INLINE_ void operator=(const Iterator &p_it) {
keys = p_it.keys;
num_keys = p_it.num_keys;
index = p_it.index;
}
private:
const TKey *keys = nullptr;
uint32_t num_keys = 0;
int32_t index = -1;
};
_FORCE_INLINE_ Iterator begin() const { … }
_FORCE_INLINE_ Iterator end() const { … }
_FORCE_INLINE_ Iterator last() const { … }
_FORCE_INLINE_ Iterator find(const TKey &p_key) const { … }
_FORCE_INLINE_ void remove(const Iterator &p_iter) { … }
Iterator insert(const TKey &p_key) { … }
HashSet(const HashSet &p_other) { … }
void operator=(const HashSet &p_other) { … }
HashSet(uint32_t p_initial_capacity) { … }
HashSet() { … }
void reset() { … }
~HashSet() { … }
};
#endif