- Adjusted Formatting of tests

- Finished map implementation and unit tests

 TODO: Threading
This commit is contained in:
2025-07-23 12:05:02 -04:00
parent 73333b4c67
commit 5ab2952e83
63 changed files with 2703 additions and 2187 deletions

View File

@@ -22,6 +22,7 @@
// https://programming.guide/robin-hood-hashing.html
#include <fennec/containers/optional.h>
#include <fennec/lang/compare.h>
#include <fennec/math/ext/primes.h>
#include <fennec/memory/allocator.h>
#include <fennec/lang/hashing.h>
@@ -31,15 +32,17 @@ namespace fennec
// TODO: Document
template<typename T, class Hash = hash<T>, class Alloc = allocator<T>>
template<typename T, class Hash = hash<T>, class Equals = equality<T>, class Alloc = allocator<T>>
struct set {
public:
using alloc_t = typename allocator_traits<Alloc>::template rebind<T>;
using hash_t = Hash;
using equal_t = Equals;
using elem_t = T;
class iterator;
static constexpr size_t npos = -1;
static constexpr double default_load = 0.8;
private:
struct node {
@@ -54,60 +57,71 @@ public:
constexpr set()
: _alloc()
, _hash()
, _size(0) {
, _size(0)
, _load(default_load) {
};
constexpr set(const hash_t& hash)
: _alloc()
, _hash(hash)
, _size(0) {
, _size(0)
, _load(default_load) {
}
constexpr set(hash_t&& hash) noexcept
: _alloc()
, _hash(hash)
, _size(0) {
, _size(0)
, _load(default_load) {
}
constexpr set(const alloc_t& alloc)
: _alloc(alloc)
, _hash()
, _size(0) {
, _size(0)
, _load(default_load) {
}
constexpr set(alloc_t&& alloc) noexcept
: _alloc(alloc)
, _hash()
, _size(0) {
, _size(0)
, _load(default_load) {
}
constexpr set(const hash_t& hash, const alloc_t& alloc)
: _alloc(alloc)
, _hash(hash)
, _size(0) {
, _size(0)
, _load(default_load) {
}
constexpr set(const hash_t& hash, alloc_t&& alloc) noexcept
: _alloc(alloc)
, _hash(hash)
, _size(0) {
, _size(0)
, _load(default_load) {
}
constexpr set(hash_t&& hash, alloc_t&& alloc) noexcept
: _alloc(alloc)
, _hash(hash)
, _size(0) {
, _size(0)
, _load(default_load) {
}
constexpr set(hash_t&& hash, const alloc_t& alloc) noexcept
: _alloc(alloc)
, _hash(hash)
, _size(0) {}
, _size(0)
, _load(default_load) {
}
constexpr set(const set& set)
: _alloc(set._alloc)
, _hash(set._hash)
, _size(set._size) {
, _size(set._size)
, _load(default_load) {
}
constexpr set(set&& set) noexcept
@@ -127,7 +141,7 @@ public:
}
constexpr void insert(elem_t&& val) {
if (_size >= capacity()) { // expand when full
if (_size == 0 or double(_size) / capacity() >= _load) { // expand when full
_expand();
}
@@ -135,7 +149,7 @@ public:
size_t i = _hash(value) % capacity(); // Initial search index
int psl = 0;
while (_alloc[i].value) { // Search for empty cell
if (*_alloc[i].value == val) { // Check to see if this element is already inserted
if (_equal(*_alloc[i].value, val)) { // Check to see if this element is already inserted
return;
}
if (psl >= _alloc[i].psl) { // When psl is higher, swap
@@ -165,8 +179,8 @@ public:
int psl = 0;
// Loop while there is a value and its psl is greater than our probe
while (_alloc[i].value && _alloc[i].psl > psl) {
if (*_alloc[i].value == val) {
while (_alloc[i].value && _alloc[i].psl <= psl) {
if (_equal(*_alloc[i].value, val)) {
return iterator(this, i);
}
i = (i + 1) % capacity(); ++psl;
@@ -175,6 +189,20 @@ public:
return iterator(this, npos);
}
constexpr elem_t* at(const iterator& it) {
size_t i = it._i;
if (i >= capacity()) return nullptr;
if (not _alloc[i].value) return nullptr;
return &*_alloc[i].value;
}
constexpr const elem_t* at(const iterator& it) const {
size_t i = it._i;
if (i >= capacity()) return nullopt;
if (not _alloc[i].value) return nullopt;
return &*_alloc[i].value;
}
constexpr bool contains(const elem_t& val) const {
return this->find(val) != end();
}
@@ -251,6 +279,7 @@ public:
private:
const set* _set;
size_t _i;
friend set;
};
constexpr iterator begin() const {
@@ -271,10 +300,9 @@ public:
private:
constexpr void _expand() {
set cpy; // Create a new set
cpy._alloc.allocate(
cpy._alloc.callocate(
fennec::next_prime2(_alloc.capacity())
);
fennec::memset(cpy._alloc.data(), 0, cpy._alloc.size());
// rehash
for (size_t i = 0; i < capacity(); ++i) {
@@ -289,7 +317,9 @@ private:
allocation<node, alloc_t> _alloc;
hash_t _hash;
equal_t _equal;
size_t _size;
double _load;
};
}