31#ifndef FENNEC_CONTAINERS_SET_H
32#define FENNEC_CONTAINERS_SET_H
38#include <fennec/lang/compare.h>
39#include <fennec/math/ext/primes.h>
41#include <fennec/lang/hashing.h>
67template<
typename TypeT,
class Hash = hash<TypeT>,
class Equals = equality<TypeT>,
class Alloc = allocator<TypeT>>
74 using equal_t = Equals;
78 static constexpr size_t npos = -1;
79 static constexpr double default_load = 0.8;
86 constexpr node() =
default;
87 constexpr ~node() =
default;
103 , _load(default_load) {
114 , _load(default_load) {
120 constexpr set(
const alloc_t& alloc)
125 , _load(default_load) {
132 constexpr set(
const hash_t&
hash,
const alloc_t& alloc)
137 , _load(default_load) {
147 , _sumpsl(
set._sumpsl)
155 : _alloc(fennec::move(
set._alloc))
156 , _hash(fennec::move(
set._hash))
157 , _size(fennec::move(
set._size))
158 , _sumpsl(
set._sumpsl)
165 for (
size_t i = 0; i <
capacity(); ++i) {
166 _alloc[i].value = nullopt;
180 constexpr size_t size()
const {
193 return _alloc.
size();
213 int psl = (_size != 0) ? _sumpsl / _size : 0;
218 if (_alloc[i].psl >= psl && _alloc[i].value) {
219 if (_equal(*_alloc[i].value, val)) {
229 int p0 = psl - n, p1 = psl + n;
230 bool c0 = p0 >= 0 && _alloc[i0].psl >= p0, c1 = _alloc[i1].psl >= p1;
232 if (c0 && _alloc[i0].value) {
233 if (_equal(*_alloc[i0].value, val)) {
238 if (c1 && _alloc[i1].value) {
239 if (_equal(*_alloc[i1].value, val)) {
257 return this->
find(val) !=
end();
269 if (not _alloc[it._i].value) {
272 return &*_alloc[it._i].value;
280 if (not _alloc[it._i].value)
return nullptr;
281 return &*_alloc[it._i].value;
295 return this->_insert(fennec::forward<elem_t>(val));
302 return this->_insert(val);
309 template<
typename...ArgsT>
311 return this->_insert(fennec::forward<ArgsT>(args)...);
322 if (not _alloc[i].value) {
326 _alloc[i].value = nullopt;
327 _sumpsl -= _alloc[i].psl;
330 while (_alloc[i = (i + 1) %
capacity()].value) {
331 if (_alloc[i].psl == 0)
break;
334 --_alloc[p].psl, --_sumpsl;
342 constexpr void erase(
const elem_t& val) {
348 constexpr void clear() {
349 for (
size_t i = 0; i < _alloc.
capacity(); ++i) {
366 if (not _alloc[it._i].value) {
395 while (++rhs._i < rhs._set->
capacity()) {
396 if (rhs._set->_alloc[rhs._i].value) {
410 constexpr const elem_t& operator*()
const {
411 return *_set->_alloc[_i].value;
414 constexpr const elem_t* operator->()
const {
415 if (not _set->_alloc[_i].value)
return nullptr;
416 return &*_set->_alloc[_i].value;
419 constexpr bool operator==(
const iterator& it)
const {
420 return _set == it._set and _i == it._i;
423 constexpr bool operator!=(
const iterator& it)
const {
424 return _set != it._set or _i != it._i;
427 constexpr size_t index()
const {
return _i; }
439 constexpr void _expand() {
442 fennec::next_prime2(_alloc.
capacity())
446 for (
size_t i = 0; i <
capacity(); ++i) {
447 if (_alloc[i].value) {
448 cpy.
insert(fennec::move(*_alloc[i].value));
453 fennec::swap(_alloc, cpy._alloc);
456 template<
typename...ArgsT>
457 constexpr iterator _insert(ArgsT&&...args) {
458 if (_size == 0 or
static_cast<float>(_size) /
capacity() >= _load) {
462 elem_t value(fennec::forward<ArgsT>(args)...);
463 size_t i = _hash(value) %
capacity();
465 while (_alloc[i].value) {
466 if (_equal(*_alloc[i].value, value)) {
467 return iterator(
this, i);
469 if (psl > _alloc[i].psl) {
470 _sumpsl += psl - _alloc[i].psl;
477 _sumpsl += (_alloc[i].psl = psl);
479 return iterator(
this, npos);
482 dynarray<node, alloc_t> _alloc;
This header contains structures and classes related to allocating blocks of memory.
Class for Iterating the Set.
Definition set.h:382
A header containing the definition for a container with an optionally present variable.
A header containing the definition for a set of unique values.
typename _rebind< Alloc, TypeT >::type rebind
Rebinds the allocator type to produce an element type of type TypeT
Definition allocator.h:134
constexpr size_t capacity() const
Definition dynarray.h:337
constexpr size_t size() const
Definition dynarray.h:331
constexpr void resize(size_t n)
Resize the dynarray, invoking the default constructor for all new elements.
Definition dynarray.h:512
Struct for hashing types, there is no default hashing function.
Definition hashing.h:32
Structure to hold an optional value.
Definition optional.h:51
wrapper for sets of elements
Definition set.h:68
constexpr iterator find(const elem_t &val) const
Find an Element.
Definition set.h:208
constexpr size_t size() const
Definition set.h:180
constexpr iterator insert(elem_t &&val)
Move Insertion.
Definition set.h:294
constexpr size_t capacity() const
Definition set.h:192
constexpr bool empty() const
Definition set.h:186
constexpr set(const set &set)
Set Copy Constructor.
Definition set.h:143
constexpr iterator emplace(ArgsT &&...args)
Emplace Insertion.
Definition set.h:310
constexpr ~set()
Destructor, destructs all elements and releases the allocation.
Definition set.h:164
constexpr set()
Default Constructor, initializes empty set.
Definition set.h:98
constexpr elem_t * at(const iterator &it)
Iterator Access.
Definition set.h:265
constexpr iterator begin() const
Definition set.h:364
constexpr iterator insert(const elem_t &val)
Copy Insertion.
Definition set.h:301
constexpr set(const hash_t &hash, const alloc_t &alloc)
Hash Alloc Copy Constructor, initializes empty set with a hash and allocator.
Definition set.h:132
constexpr void erase(const elem_t &val)
Element Erase.
Definition set.h:342
constexpr set(set &&set) noexcept
Set Move Constructor.
Definition set.h:154
constexpr const elem_t * at(const iterator &it) const
Iterator Const Access.
Definition set.h:279
constexpr set(const hash_t &hash)
Hash Copy Constructor, initializes empty set with a hash.
Definition set.h:109
constexpr bool contains(const elem_t &val) const
Check if a set contains a value.
Definition set.h:256
constexpr iterator end() const
Definition set.h:374
constexpr set(const alloc_t &alloc)
Alloc Copy Constructor, initializes empty set with an allocator.
Definition set.h:120
constexpr void erase(iterator it)
Element Erase.
Definition set.h:317
constexpr void swap(T &x, T &y) noexcept
Swaps x and y.
Definition utility.h:114
constexpr remove_reference_t< T > && move(T &&x) noexcept
produces an x-value type to indicate x may be "moved"
Definition utility.h:92