- Fixed some missing and erroneous testing logic for containers
- Lots of bug-fixing for containers - Performance optimization for containers
This commit is contained in:
@@ -56,7 +56,6 @@ public:
|
||||
using value_t = TypeT;
|
||||
using alloc_t = allocator_traits<AllocT>::template rebind<node>;
|
||||
static constexpr size_t npos = -1;
|
||||
inline static size_t sink = npos;
|
||||
|
||||
friend class iterator;
|
||||
friend class const_iterator;
|
||||
@@ -189,7 +188,7 @@ public:
|
||||
/// \param i The node id
|
||||
/// \returns The parent of node `i`
|
||||
constexpr size_t parent(size_t i) const {
|
||||
return i >= _table.size() ? npos : _table[i].parent;
|
||||
return i == npos ? npos : _table[i].parent;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -205,7 +204,7 @@ public:
|
||||
/// \param i The node id
|
||||
/// \returns The left child of node `i`
|
||||
constexpr size_t left(size_t i) const {
|
||||
return i >= _table.size() ? npos : _table[i].left;
|
||||
return i == npos ? npos : _table[i].left;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -213,7 +212,7 @@ public:
|
||||
/// \param i The node id
|
||||
/// \returns The right child of node `i`
|
||||
constexpr size_t right(size_t i) const {
|
||||
return i >= _table.size() ? npos : _table[i].right;
|
||||
return i == npos ? npos : _table[i].right;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -230,11 +229,7 @@ public:
|
||||
/// \param i The node id
|
||||
/// \returns `true` if `i` is the right node of `parent(i)`, `false` otherwise
|
||||
constexpr bool direction(size_t i) const {
|
||||
size_t p = parent(i);
|
||||
if (p >= _table.capacity()) {
|
||||
return false;
|
||||
}
|
||||
return i == right(p);
|
||||
return i == npos ? false : i == right(parent(i));
|
||||
}
|
||||
|
||||
///
|
||||
@@ -245,15 +240,7 @@ public:
|
||||
size_t p = parent(i);
|
||||
size_t l = left(p);
|
||||
size_t r = right(p);
|
||||
return i == l ? l : r;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Short for "Parent Sibling," \f$O(1)\f$
|
||||
/// \param i The id of the node
|
||||
/// \returns The id of the parents' sibling of `i`
|
||||
constexpr size_t parsib(size_t i) const {
|
||||
return sibling(parent(i));
|
||||
return i == l ? r : l;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -305,22 +292,18 @@ public:
|
||||
/// \details \f$O(1)\f$
|
||||
/// \param i The node id
|
||||
/// \returns `nullptr` if node `i` does not exist, otherwise, a pointer to the value of node `i`
|
||||
constexpr value_t* operator[](size_t i) {
|
||||
if (i >= _table.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
return _table[i] ? &*_table[i] : nullptr;
|
||||
constexpr value_t& operator[](size_t i) {
|
||||
assertd(i < _table.size(), "Index out of bounds.");
|
||||
return _table[i].value;
|
||||
}
|
||||
|
||||
///
|
||||
/// \details Const Access, \f$O(1)\f$
|
||||
/// \param i The node id
|
||||
/// \returns `nullptr` if node `i` does not exist, otherwise, a pointer to the value of node `i`
|
||||
constexpr const value_t* operator[](size_t i) const {
|
||||
if (i >= _table.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
return _table[i] ? &*_table[i] : nullptr;
|
||||
constexpr const value_t& operator[](size_t i) const {
|
||||
assertd(i < _table.size(), "Index out of bounds.");
|
||||
return _table[i].value;
|
||||
}
|
||||
|
||||
/// @}
|
||||
@@ -458,14 +441,16 @@ public:
|
||||
size_t new_root = child(sub, not dir);
|
||||
size_t new_child = child(new_root, dir);
|
||||
|
||||
child(sub, not dir) = new_child;
|
||||
parent(new_child) = sub;
|
||||
child(new_root, dir) = sub;
|
||||
_child(sub, not dir) = new_child;
|
||||
if (new_child != npos) {
|
||||
_parent(new_child) = sub;
|
||||
}
|
||||
_child(new_root, dir) = sub;
|
||||
|
||||
parent(new_root) = sub_parent;
|
||||
parent(sub) = new_root;
|
||||
_parent(new_root) = sub_parent;
|
||||
_parent(sub) = new_root;
|
||||
if (sub_parent != npos) {
|
||||
child(sub_parent, sub == right(sub_parent)) = new_root;
|
||||
_child(sub_parent, sub == right(sub_parent)) = new_root;
|
||||
} else {
|
||||
_root = new_root;
|
||||
}
|
||||
@@ -516,13 +501,13 @@ public:
|
||||
/// \param visit The visiting object
|
||||
/// \param i The node to start at
|
||||
template<typename OrderT, typename VisitorT>
|
||||
constexpr void traverse(VisitorT&& visit, size_t i = root) {
|
||||
constexpr void traverse(VisitorT&& visit, size_t i) {
|
||||
OrderT order;
|
||||
i = order(*this, i);
|
||||
while (i != npos) {
|
||||
uint8_t mode = traversal_control_continue;
|
||||
if (_table[i].value) {
|
||||
mode = visit(*_table[i].value, i);
|
||||
mode = visit(_table[i].value, i);
|
||||
}
|
||||
if (mode == traversal_control_break) {
|
||||
break;
|
||||
@@ -581,7 +566,7 @@ public:
|
||||
return npos;
|
||||
}
|
||||
|
||||
size_t nxt = tree.sibling(node);
|
||||
size_t nxt = tree.right(tree.parent(node));
|
||||
size_t chd = tree.left(node);
|
||||
nxt = node == nxt ? npos : nxt;
|
||||
|
||||
@@ -618,19 +603,16 @@ public:
|
||||
return npos;
|
||||
}
|
||||
|
||||
size_t prnt = tree.parent(node);
|
||||
size_t next = tree.sibling(node);
|
||||
next = node == next ? npos : next;
|
||||
size_t parent = tree.parent(node);
|
||||
size_t pright = tree.right(parent);
|
||||
size_t next = tree.left_most(tree.right(node));
|
||||
|
||||
if (node != head) {
|
||||
if (tree.left(prnt) == node) {
|
||||
visit.push_back(prnt);
|
||||
if (next != npos) {
|
||||
visit.push_back(tree.left_most(next));
|
||||
}
|
||||
} else if (next != npos) {
|
||||
visit.push_front(tree.left_most(next));
|
||||
}
|
||||
if (node != pright && parent != npos) {
|
||||
visit.push_front(parent);
|
||||
}
|
||||
|
||||
if (next != npos) {
|
||||
visit.push_front(next);
|
||||
}
|
||||
|
||||
if (not visit.empty()) {
|
||||
@@ -648,9 +630,23 @@ public:
|
||||
list<size_t> visit;
|
||||
size_t head;
|
||||
|
||||
constexpr size_t successor(const bintree& tree, size_t n) {
|
||||
size_t s = tree.left_most(n);
|
||||
while (n == s) {
|
||||
size_t r = tree.right(n);
|
||||
if (r != npos) {
|
||||
n = r;
|
||||
s = tree.left_most(n);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return s == npos ? n : s;
|
||||
}
|
||||
|
||||
constexpr size_t operator()(const bintree& tree, size_t start) {
|
||||
head = start;
|
||||
return tree.left_most(start);
|
||||
return this->successor(tree, start);
|
||||
}
|
||||
|
||||
constexpr size_t operator[](const bintree& tree, size_t node, uint8_t) {
|
||||
@@ -658,16 +654,15 @@ public:
|
||||
return npos;
|
||||
}
|
||||
|
||||
size_t prnt = tree.parent(node);
|
||||
size_t next = tree.sibling(node);
|
||||
next = node == next ? npos : next;
|
||||
size_t parent = tree.parent(node);
|
||||
size_t pright = tree.right(parent);
|
||||
|
||||
if (node != head) {
|
||||
if (next != npos) {
|
||||
visit.push_front(tree.left_most(next));
|
||||
} else {
|
||||
visit.push_front(prnt);
|
||||
if (node == pright) {
|
||||
if (parent != npos) {
|
||||
visit.push_front(parent);
|
||||
}
|
||||
} else if (pright != npos) {
|
||||
visit.push_front(this->successor(tree, pright));
|
||||
}
|
||||
|
||||
if (not visit.empty()) {
|
||||
@@ -677,6 +672,7 @@ public:
|
||||
node = npos;
|
||||
}
|
||||
|
||||
|
||||
return node;
|
||||
}
|
||||
};
|
||||
@@ -690,6 +686,12 @@ public:
|
||||
size_t _n;
|
||||
|
||||
public:
|
||||
constexpr iterator(bintree* tree, size_t root)
|
||||
: _tree(tree)
|
||||
, _order()
|
||||
, _n(_order(*tree, root)) {
|
||||
}
|
||||
|
||||
constexpr iterator(bintree* tree, size_t root, size_t node)
|
||||
: _tree(tree)
|
||||
, _order()
|
||||
@@ -706,19 +708,19 @@ public:
|
||||
}
|
||||
|
||||
value_t& operator*() {
|
||||
return _tree[_n];
|
||||
return (*_tree)[_n];
|
||||
}
|
||||
|
||||
value_t* operator->() {
|
||||
return &_tree[_n];
|
||||
return &(*_tree)[_n];
|
||||
}
|
||||
|
||||
const value_t& operator*() const {
|
||||
return _tree[_n];
|
||||
return (*_tree)[_n];
|
||||
}
|
||||
|
||||
const value_t* operator->() const {
|
||||
return &_tree[_n];
|
||||
return &(*_tree)[_n];
|
||||
}
|
||||
|
||||
constexpr bool operator==(const iterator& it) {
|
||||
@@ -754,7 +756,8 @@ protected:
|
||||
|
||||
template<typename...ArgsT>
|
||||
constexpr size_t _insert_left(size_t p, ArgsT&&...args) {
|
||||
size_t i = p == npos ? _root : left(p);
|
||||
size_t i = p >= capacity() ? npos : p;
|
||||
i = i == npos ? _root : _left(i);
|
||||
if (i != npos) {
|
||||
_table[i].value = value_t(fennec::forward<ArgsT>(args)...);
|
||||
} else {
|
||||
@@ -764,6 +767,9 @@ protected:
|
||||
d = depth(p) + 1;
|
||||
_table[p].left = i;
|
||||
}
|
||||
if (_root == npos) {
|
||||
_root = i;
|
||||
}
|
||||
fennec::construct(&_table[i], p, npos, npos, d, fennec::forward<ArgsT>(args)...);
|
||||
}
|
||||
return i;
|
||||
@@ -771,7 +777,7 @@ protected:
|
||||
|
||||
template<typename...ArgsT>
|
||||
constexpr size_t _insert_right(size_t p, ArgsT&&...args) {
|
||||
size_t i = p == npos ? _root : right(p);
|
||||
size_t i = p == npos ? _root : _right(p);
|
||||
if (i != npos) {
|
||||
_table[i].value = value_t(fennec::forward<ArgsT>(args)...);
|
||||
if (p == npos || _root == npos) {
|
||||
@@ -784,42 +790,41 @@ protected:
|
||||
d = depth(p) + 1;
|
||||
_table[p].right = i;
|
||||
}
|
||||
if (_root == npos) {
|
||||
_root = i;
|
||||
}
|
||||
fennec::construct(&_table[i], p, npos, npos, d, fennec::forward<ArgsT>(args)...);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
constexpr size_t& parent(size_t i) {
|
||||
return i >= _table.size() ? sink : _table[i].parent;
|
||||
constexpr size_t& _parent(size_t i) {
|
||||
return _table[i].parent;
|
||||
}
|
||||
|
||||
constexpr size_t& grandparent(size_t i) {
|
||||
return parent(parent(i));
|
||||
constexpr size_t& _grandparent(size_t i) {
|
||||
return _parent(parent(i));
|
||||
}
|
||||
|
||||
constexpr size_t& left(size_t i) {
|
||||
return i >= _table.size() ? sink : _table[i].left;
|
||||
constexpr size_t& _left(size_t i) {
|
||||
return _table[i].left;
|
||||
}
|
||||
|
||||
constexpr size_t& right(size_t i) {
|
||||
return i >= _table.size() ? sink : _table[i].right;
|
||||
constexpr size_t& _right(size_t i) {
|
||||
return _table[i].right;
|
||||
}
|
||||
|
||||
constexpr size_t& child(size_t i, bool dir) {
|
||||
return dir ? right(i) : left(i);
|
||||
constexpr size_t& _child(size_t i, bool dir) {
|
||||
return dir ? _right(i) : _left(i);
|
||||
}
|
||||
|
||||
constexpr size_t& sibling(size_t i) {
|
||||
constexpr size_t& _sibling(size_t i) {
|
||||
size_t p = parent(i);
|
||||
size_t& l = left(p);
|
||||
size_t& r = right(p);
|
||||
size_t& l = _left(p);
|
||||
size_t& r = _right(p);
|
||||
return i == l ? l : r;
|
||||
}
|
||||
|
||||
constexpr size_t& parsib(size_t i) {
|
||||
return sibling(parent(i));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user