31#ifndef FENNEC_CONTAINERS_SEQUENCE_H
32#define FENNEC_CONTAINERS_SEQUENCE_H
42#include <fennec/lang/compare.h>
82template<
typename TypeT,
typename CompareT = less<TypeT>,
class AllocT = allocator<pair<TypeT,
bool>>>
90 using value_t = TypeT;
93 using compare_t = CompareT;
116 template<
typename...ArgsT>
117 constexpr _node(ArgsT&&...args)
119 , child {
nullptr,
nullptr }
120 , key(fennec::forward<ArgsT>(args)...)
124 template<
typename...ArgsT>
125 constexpr _node(node p, node l, node r, ArgsT&&...args)
128 , key(fennec::forward<ArgsT>(args)...)
142 constexpr value_t& _key(node n) {
146 constexpr bool& _color(node n) {
150 constexpr node& _parent(node n) {
154 constexpr node& _child(node n,
bool dir) {
155 return n->child[dir];
158 constexpr node& _left(node n) {
159 return n->child[dir_left];
162 constexpr node& _right(node n) {
163 return n->child[dir_right];
170 constexpr const value_t& key(node n)
const {
174 constexpr bool color(node n) {
175 return n ? n->color : (bool)black;
178 constexpr node parent(node n) {
179 return n ? n->parent :
nullptr;
182 constexpr node child(node n,
bool dir) {
183 return n ? n->child[dir] :
nullptr;
186 constexpr node left(node n) {
187 return n ? n->child[dir_left] :
nullptr;
190 constexpr node right(node n) {
191 return n ? n->child[dir_right] :
nullptr;
194 constexpr node leftmost(node n) {
199 while (this->_left(n)) {
205 constexpr node rightmost(node n) {
210 while (this->_right(n)) {
224 : _root(nullptr), _size(0) {
252 constexpr iterator
find(
const value_t& val) {
255 if (_compare(val, _key(node))) {
257 }
else if (_compare(_key(node), val)) {
260 return sequence::iterator(
this, _root, node);
263 return sequence::iterator(
this, _root, node);
284 constexpr size_t size()
const {
305 node i = _insert_bst(fennec::forward<value_t>(val));
312 constexpr void insert(
const value_t& val) {
313 node i = _insert_bst(val);
321 template<
typename...ArgsT>
323 node i = _insert_bst(fennec::forward<ArgsT>(args)...);
327 constexpr void erase(
const value_t& val) {
328 _erase(
find(val)._node);
335 for (iterator it =
begin(); it !=
end(); ++it) {
338 for (node n : visit) {
352 return sequence::iterator(
this, _root);
357 constexpr iterator
end() {
358 return sequence::iterator(
this, _root,
nullptr);
370 constexpr iterator(
sequence* seq, node start)
373 , _node(seq->leftmost(start)) {
376 constexpr iterator(sequence* seq, node root, node start)
382 iterator& operator++() {
383 if (_node ==
nullptr) {
387 node parent = _seq->_parent(_node);
388 node pright = _seq->right(parent);
389 node next = _seq->leftmost(_seq->right(_node));
391 if (_node != pright && parent !=
nullptr) {
395 if (next !=
nullptr) {
399 if (not _visit.
empty()) {
400 _node = _visit.
front();
409 iterator operator++(
int) {
410 iterator prev = *
this;
415 const value_t& operator*()
const {
419 const value_t* operator->()
const {
423 constexpr friend bool operator==(
const iterator& lhs,
const iterator& rhs) {
424 return lhs._node == rhs._node;
427 friend struct sequence;
441 template<
typename...ArgsT>
442 constexpr node _make_node(ArgsT&&...args) {
443 node res = _alloc.allocate(1);
444 fennec::construct(res, fennec::forward<ArgsT>(args)...);
448 constexpr void _free_node(node n) {
450 _alloc.deallocate(n);
453 constexpr node _rotate(node sub,
bool dir) {
454 if (sub ==
nullptr) {
457 node sub_parent = _parent(sub);
458 node new_root = _child(sub, not dir);
459 node new_child = _child(new_root, dir);
461 _child(sub, not dir) = new_child;
462 if (new_child !=
nullptr) {
463 _parent(new_child) = sub;
465 _child(new_root, dir) = sub;
467 _parent(new_root) = sub_parent;
468 _parent(sub) = new_root;
469 if (sub_parent !=
nullptr) {
470 _child(sub_parent, sub == _right(sub_parent)) = new_root;
477 constexpr void _recolor(node n) {
478 bool c = color(n) == black;
482 _color(_left(n)) = !_color(_left(n)) ;
483 _color(_right(n)) = !_color(_right(n));
487 template<
typename...ArgsT>
488 constexpr node _insert_bst(ArgsT&&...args) {
489 node res = _make_node(fennec::forward<ArgsT>(args)...);
491 if (_root ==
nullptr) {
500 while (i !=
nullptr) {
503 if (_compare(_key(res), _key(i))) {
506 }
else if (_compare(_key(i), _key(res))) {
524 constexpr void _fix_insert(node n) {
530 while (n != _root && color(n) == red && color(p) == red) {
532 bool d = n == _right(p);
533 bool r = p == _right(g);
534 node u = _child(g, !r);
536 if (color(u) == red) {
554 _color(_root) = black;
557 constexpr void _swap_val(node a, node b) {
561 constexpr node _red_child(node x) {
565 if (color(l) == red) {
569 if (color(r) == red) {
576 constexpr void _fix_erase(node n) {
593 bool d = n == _right(p);
594 node c = _red_child(n);
596 if (_color(n) == red || c !=
nullptr) {
614 if (_color(s) == red) {
621 node nc = _child(s, d);
622 node nf = _child(s, !d);
624 if (color(nc) == black && color(nf) == black) {
626 if (_color(p) == red) {
634 if (color(nf) == black) {
641 _color(s) = _color(p);
655 _color(_root) = black;
661 constexpr void _erase(node n) {
670 if (l !=
nullptr && r !=
nullptr) {
671 node s = leftmost(r);
679 bool d = n == right(p);
680 node c = l !=
nullptr ? l : r;
700 if (p ==
nullptr || c !=
nullptr || _color(n) == red) {
This header contains structures and classes related to allocating blocks of memory.
A header containing the definition for a container holding a pair of values.
typename _rebind< Alloc, TypeT >::type rebind
Rebinds the allocator type to produce an element type of type TypeT
Definition allocator.h:134
Data Structure defining lists of elements.
Definition list.h:67
constexpr void pop_front()
Pop Front, erases first element.
Definition list.h:380
constexpr bool empty() const
Definition list.h:181
constexpr size_t push_back(const value_t &x)
Push Back Copy.
Definition list.h:342
constexpr size_t push_front(const value_t &x)
Push Front Copy.
Definition list.h:319
constexpr value_t & front()
Access Front Element.
Definition list.h:222
Struct for holding a pair of values.
Definition pair.h:48
wrapper for ordered sets of elements, called sequences in mathematics
Definition sequence.h:83
constexpr sequence(sequence &&) noexcept=default
Move Constructor, takes ownership of a sequence.
bool contains(const value_t &val)
Value Contains Function, checks if the sequence contains a value.
Definition sequence.h:270
constexpr void emplace(ArgsT &&...args)
Emplacement, constructs and adds a value into the sequence.
Definition sequence.h:322
constexpr void clear()
Destructs all elements, in-order, contained in the sequence.
Definition sequence.h:333
constexpr iterator find(const value_t &val)
Value Find Function, finds the iterator position for val, otherwise returns end()
Definition sequence.h:252
constexpr size_t size() const
Definition sequence.h:284
constexpr iterator begin()
Definition sequence.h:351
constexpr void insert(value_t &&val)
Move Insertion, moves val into the sequence.
Definition sequence.h:304
constexpr iterator end()
Definition sequence.h:357
constexpr sequence()
Default Constructor, initializes an empty sequence.
Definition sequence.h:223
constexpr bool empty() const
Definition sequence.h:290
constexpr void insert(const value_t &val)
Copy Insertion, inserts a copy of val into the sequence.
Definition sequence.h:312
constexpr void swap(T &x, T &y) noexcept
Swaps x and y.
Definition utility.h:114