- Documentation of containers, core, and format
This commit is contained in:
@@ -48,18 +48,18 @@ template<typename TypeT, class AllocT = allocator<TypeT>>
|
||||
struct bintree {
|
||||
|
||||
// Definitions =========================================================================================================
|
||||
protected:
|
||||
private:
|
||||
struct node;
|
||||
|
||||
public:
|
||||
using value_t = TypeT;
|
||||
using alloc_t = allocator_traits<AllocT>::template rebind<node>;
|
||||
static constexpr size_t npos = -1;
|
||||
using value_t = TypeT; //!< The element type
|
||||
using alloc_t = allocator_traits<AllocT>::template rebind<node>; //!< The allocator type
|
||||
static constexpr size_t npos = -1; //!< null position constant
|
||||
|
||||
friend class iterator;
|
||||
friend class const_iterator;
|
||||
|
||||
protected:
|
||||
private:
|
||||
struct node {
|
||||
value_t value;
|
||||
size_t parent;
|
||||
@@ -144,7 +144,7 @@ public:
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns `true` when there are no elements in the tree, `false` otherwise.
|
||||
/// \returns \f$true\f$ when there are no elements in the tree, \f$false\f$ otherwise.
|
||||
constexpr bool empty() const {
|
||||
return _size == 0;
|
||||
}
|
||||
@@ -156,7 +156,7 @@ public:
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns The next id to be returned by `insert` or `emplace`.
|
||||
/// \returns The next id to be returned by \f$insert\f$ or \f$emplace\f$.
|
||||
constexpr size_t next_id() const {
|
||||
size_t i = _size;
|
||||
if (not _freed.empty()) {
|
||||
@@ -166,7 +166,7 @@ public:
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns The next id to be returned by `insert` or `emplace`.
|
||||
/// \returns The next id to be returned by \f$insert\f$ or \f$emplace\f$.
|
||||
constexpr size_t root() const {
|
||||
return _root;
|
||||
}
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
///
|
||||
/// \details \f$O(1)\f$
|
||||
/// \param i The node id
|
||||
/// \returns The parent of node `i`
|
||||
/// \returns The parent of node \f$i\f$
|
||||
constexpr size_t parent(size_t i) const {
|
||||
return i == npos ? npos : _table[i].parent;
|
||||
}
|
||||
@@ -190,7 +190,7 @@ public:
|
||||
///
|
||||
/// \details \f$O(1)\f$
|
||||
/// \param i The node id
|
||||
/// \returns The grandparent of node `i`
|
||||
/// \returns The grandparent of node \f$i\f$
|
||||
constexpr size_t grandparent(size_t i) const {
|
||||
return parent(parent(i));
|
||||
}
|
||||
@@ -198,7 +198,7 @@ public:
|
||||
///
|
||||
/// \details \f$O(1)\f$
|
||||
/// \param i The node id
|
||||
/// \returns The left child of node `i`
|
||||
/// \returns The left child of node \f$i\f$
|
||||
constexpr size_t left(size_t i) const {
|
||||
return i == npos ? npos : _table[i].child[false];
|
||||
}
|
||||
@@ -206,7 +206,7 @@ public:
|
||||
///
|
||||
/// \details \f$O(1)\f$
|
||||
/// \param i The node id
|
||||
/// \returns The right child of node `i`
|
||||
/// \returns The right child of node \f$i\f$
|
||||
constexpr size_t right(size_t i) const {
|
||||
return i == npos ? npos : _table[i].child[true];
|
||||
}
|
||||
@@ -214,8 +214,8 @@ public:
|
||||
///
|
||||
/// \details \f$O(1)\f$
|
||||
/// \param i The node id
|
||||
/// \param dir The direction to go `true` for right, `false` for left
|
||||
/// \returns The child in the direction specified by `dir`
|
||||
/// \param dir The direction to go \f$true\f$ for right, \f$false\f$ for left
|
||||
/// \returns The child in the direction specified by \f$dir\f$
|
||||
constexpr size_t child(size_t i, bool dir) const {
|
||||
return i == npos ? npos : _table[i].child[dir];
|
||||
}
|
||||
@@ -223,7 +223,7 @@ public:
|
||||
///
|
||||
/// \details \f$O(1)\f$
|
||||
/// \param i The node id
|
||||
/// \returns `true` if `i` is the right node of `parent(i)`, `false` otherwise
|
||||
/// \returns \f$true\f$ if \f$i\f$ is the right node of `parent(i)`, \f$false\f$ otherwise
|
||||
constexpr bool direction(size_t i) const {
|
||||
return i == npos ? false : i == right(_parent(i));
|
||||
}
|
||||
@@ -231,7 +231,7 @@ public:
|
||||
///
|
||||
/// \brief \f$O(1)\f$
|
||||
/// \param i The id of the node
|
||||
/// \returns The id of the sibling of `i`
|
||||
/// \returns The id of the sibling of \f$i\f$
|
||||
constexpr size_t sibling(size_t i) const {
|
||||
if (i == npos) {
|
||||
return npos;
|
||||
@@ -247,7 +247,7 @@ public:
|
||||
///
|
||||
/// \details \f$O(\log n)\f$
|
||||
/// \param i The node id
|
||||
/// \returns The depth of node `i`
|
||||
/// \returns The depth of node \f$i\f$
|
||||
constexpr size_t depth(size_t i) const {
|
||||
size_t d = 0;
|
||||
while (i != npos) {
|
||||
@@ -260,7 +260,7 @@ public:
|
||||
///
|
||||
/// \brief \f$O(\log n)\f$
|
||||
/// \param i The node id
|
||||
/// \returns The id of the left-most node of `i`
|
||||
/// \returns The id of the left-most node of \f$i\f$
|
||||
constexpr size_t left_most(size_t i) const {
|
||||
if (i >= _table.size()) {
|
||||
return npos;
|
||||
@@ -274,7 +274,7 @@ public:
|
||||
///
|
||||
/// \brief \f$O(\log n)\f$
|
||||
/// \param i The node id
|
||||
/// \returns The id of the right-most node of `i`
|
||||
/// \returns The id of the right-most node of \f$i\f$
|
||||
constexpr size_t right_most(size_t i) const {
|
||||
if (i >= _table.size()) {
|
||||
return npos;
|
||||
@@ -297,7 +297,7 @@ 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`
|
||||
/// \returns \f$nullptr\f$ if node \f$i\f$ does not exist, otherwise, a pointer to the value of node \f$i\f$
|
||||
constexpr value_t& operator[](size_t i) {
|
||||
assertd(i < _table.size(), "Index out of bounds.");
|
||||
return _table[i].value;
|
||||
@@ -306,7 +306,7 @@ public:
|
||||
///
|
||||
/// \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`
|
||||
/// \returns \f$nullptr\f$ if node \f$i\f$ does not exist, otherwise, a pointer to the value of node \f$i\f$
|
||||
constexpr const value_t& operator[](size_t i) const {
|
||||
assertd(i < _table.size(), "Index out of bounds.");
|
||||
return _table[i].value;
|
||||
@@ -320,8 +320,8 @@ public:
|
||||
/// @{
|
||||
|
||||
///
|
||||
/// \brief Move Left Insertion, constructs a new node as the left child of `p`
|
||||
/// \details If the left node of `p` already exists, the move assignment operator is used instead
|
||||
/// \brief Move Left Insertion, constructs a new node as the left child of \f$p\f$
|
||||
/// \details If the left node of \f$p\f$ already exists, the move assignment operator is used instead
|
||||
/// \param p The parent node
|
||||
/// \param val The object to move into the new node
|
||||
/// \returns The id of the new node
|
||||
@@ -330,8 +330,8 @@ public:
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Copy Left Insertion, constructs a new node as the left child of `p`
|
||||
/// \details If the left node of `p` already exists, the copy assignment operator is used instead
|
||||
/// \brief Copy Left Insertion, constructs a new node as the left child of \f$p\f$
|
||||
/// \details If the left node of \f$p\f$ already exists, the copy assignment operator is used instead
|
||||
/// \param p The parent node
|
||||
/// \param val The object to copy to the new node
|
||||
/// \returns The id of the new node
|
||||
@@ -340,8 +340,8 @@ public:
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Emplace Left Insertion, constructs a new node as the left child of `p`
|
||||
/// \details If the left node of `p` already exists, the move assignment operator is used instead
|
||||
/// \brief Emplace Left Insertion, constructs a new node as the left child of \f$p\f$
|
||||
/// \details If the left node of \f$p\f$ already exists, the move assignment operator is used instead
|
||||
/// \param p The parent node
|
||||
/// \param args The arguments to construct the new node with
|
||||
/// \returns The id of the new node
|
||||
@@ -351,8 +351,8 @@ public:
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Move Right Insertion, constructs a new node as the right child of `p`
|
||||
/// \details If the right node of `p` already exists, the move assignment operator is used instead
|
||||
/// \brief Move Right Insertion, constructs a new node as the right child of \f$p\f$
|
||||
/// \details If the right node of \f$p\f$ already exists, the move assignment operator is used instead
|
||||
/// \param p The parent node
|
||||
/// \param val The object to move into the new node
|
||||
/// \returns The id of the new node
|
||||
@@ -361,8 +361,8 @@ public:
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Copy Right Insertion, constructs a new node as the right child of `p`
|
||||
/// \details If the right node of `p` already exists, the copy assignment operator is used instead
|
||||
/// \brief Copy Right Insertion, constructs a new node as the right child of \f$p\f$
|
||||
/// \details If the right node of \f$p\f$ already exists, the copy assignment operator is used instead
|
||||
/// \param p The parent node
|
||||
/// \param val The object to copy to the new node
|
||||
/// \returns The id of the new node
|
||||
@@ -371,8 +371,8 @@ public:
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Emplace Right Insertion, constructs a new node as the right child of `p`
|
||||
/// \details If the right node of `p` already exists, the move assignment operator is used instead
|
||||
/// \brief Emplace Right Insertion, constructs a new node as the right child of \f$p\f$
|
||||
/// \details If the right node of \f$p\f$ already exists, the move assignment operator is used instead
|
||||
/// \param p The parent node
|
||||
/// \param args The arguments to construct the new node with
|
||||
/// \returns The id of the new node
|
||||
@@ -384,9 +384,9 @@ public:
|
||||
|
||||
|
||||
///
|
||||
/// \brief Perform a Tree Rotation at `i` in the specified direction
|
||||
/// \brief Perform a Tree Rotation at \f$i\f$ in the specified direction
|
||||
/// \param sub The root node for the rotation
|
||||
/// \param dir The direction to rotate, `true` for right, `false` for left
|
||||
/// \param dir The direction to rotate, \f$true\f$ for right, \f$false\f$ for left
|
||||
/// \returns the new root
|
||||
constexpr size_t rotate(size_t sub, bool dir) {
|
||||
if (sub == npos) {
|
||||
@@ -413,8 +413,8 @@ public:
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Move Insertion, bool d, constructs a new node as the child of `p`
|
||||
/// \details If the child of `p` already exists, the move assignment operator is used instead
|
||||
/// \brief Move Insertion, bool d, constructs a new node as the child of \f$p\f$
|
||||
/// \details If the child of \f$p\f$ already exists, the move assignment operator is used instead
|
||||
/// \param p The parent node
|
||||
/// \param d The direction to insert
|
||||
/// \param val The object to move into the new node
|
||||
@@ -424,8 +424,8 @@ public:
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Copy Insertion, bool d, constructs a new node as the child of `p`
|
||||
/// \details If the child of `p` already exists, the copy assignment operator is used instead
|
||||
/// \brief Copy Insertion, bool d, constructs a new node as the child of \f$p\f$
|
||||
/// \details If the child of \f$p\f$ already exists, the copy assignment operator is used instead
|
||||
/// \param p The parent node
|
||||
/// \param d The direction to insert
|
||||
/// \param val The object to copy to the new node
|
||||
@@ -435,8 +435,8 @@ public:
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Emplace Insertion, constructs a new node as the child of `p`
|
||||
/// \details If the child of `p` already exists, the move assignment operator is used instead
|
||||
/// \brief Emplace Insertion, constructs a new node as the child of \f$p\f$
|
||||
/// \details If the child of \f$p\f$ already exists, the move assignment operator is used instead
|
||||
/// \param p The parent node
|
||||
/// \param d The direction to insert
|
||||
/// \param args The arguments to construct the new node with
|
||||
@@ -482,7 +482,7 @@ public:
|
||||
/// \brief Traverse the tree using a specified order and visiting functor
|
||||
///
|
||||
/// \details
|
||||
/// The visitor should accept a reference to a value of type `TypeT` and a `size_t` which contains the node's id.
|
||||
/// The visitor should accept a reference to a value of type \f$TypeT\f$ and a `size_t` which contains the node's id.
|
||||
/// The visitor should return one of the following values in the `fennec::traversal_control_` enum
|
||||
///
|
||||
/// \tparam OrderT The order with which to traverse the tree.
|
||||
@@ -508,13 +508,21 @@ public:
|
||||
///
|
||||
/// \brief Traverser pattern for breadth-first traversal
|
||||
struct breadth_first {
|
||||
list<size_t> visit;
|
||||
size_t head;
|
||||
|
||||
///
|
||||
/// \brief Traversal Init
|
||||
/// \param start The node in the tree to start at
|
||||
/// \returns The first index of the specified order
|
||||
size_t operator()(const bintree&, size_t start) {
|
||||
return head = start;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Traverser Step
|
||||
/// \param tree The tree we are operating on
|
||||
/// \param node The current node
|
||||
/// \param mode The mode specifying branch conditions
|
||||
/// \returns The next index according to the traversal order
|
||||
size_t operator[](const bintree& tree, size_t node, uint8_t mode) {
|
||||
if (node == npos) {
|
||||
return npos;
|
||||
@@ -541,19 +549,31 @@ public:
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private:
|
||||
list<size_t> visit;
|
||||
size_t head;
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Traverser pattern for pre-order traversal
|
||||
struct pre_order {
|
||||
list<size_t> visit;
|
||||
size_t head;
|
||||
|
||||
///
|
||||
/// \brief Traversal Init
|
||||
/// \param start The node in the tree to start at
|
||||
/// \returns The first index of the specified order
|
||||
constexpr size_t operator()(const bintree&, size_t start) {
|
||||
head = start;
|
||||
return start;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Traverser Step
|
||||
/// \param tree The tree we are operating on
|
||||
/// \param node The current node
|
||||
/// \param mode The mode specifying branch conditions
|
||||
/// \returns The next index according to the traversal order
|
||||
constexpr size_t operator[](const bintree& tree, size_t node, uint8_t mode) {
|
||||
if (node == npos) {
|
||||
return npos;
|
||||
@@ -580,19 +600,31 @@ public:
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private:
|
||||
list<size_t> visit;
|
||||
size_t head;
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Traverser pattern for in-order traversal
|
||||
struct in_order {
|
||||
list<size_t> visit;
|
||||
size_t head;
|
||||
|
||||
///
|
||||
/// \brief Traversal Init
|
||||
/// \param tree The tree we are operating on
|
||||
/// \param start The node in the tree to start at
|
||||
/// \returns The first index of the specified order
|
||||
constexpr size_t operator()(const bintree& tree, size_t start) {
|
||||
head = start;
|
||||
return tree.left_most(start);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Traverser Step
|
||||
/// \param tree The tree we are operating on
|
||||
/// \param node The current node
|
||||
/// \returns The next index according to the traversal order
|
||||
constexpr size_t operator[](const bintree& tree, size_t node, uint8_t) {
|
||||
if (node == npos) {
|
||||
return npos;
|
||||
@@ -619,33 +651,31 @@ public:
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private:
|
||||
list<size_t> visit;
|
||||
size_t head;
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Traverser pattern for post-order traversal
|
||||
struct post_order {
|
||||
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;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Traversal Init
|
||||
/// \param tree The tree we are operating on
|
||||
/// \param start The node in the tree to start at
|
||||
/// \returns The first index of the specified order
|
||||
constexpr size_t operator()(const bintree& tree, size_t start) {
|
||||
head = start;
|
||||
return this->successor(tree, start);
|
||||
return this->_successor(tree, start);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Traverser Step
|
||||
/// \param tree The tree we are operating on
|
||||
/// \param node The current node
|
||||
/// \returns The next index according to the traversal order
|
||||
constexpr size_t operator[](const bintree& tree, size_t node, uint8_t) {
|
||||
if (node == npos) {
|
||||
return npos;
|
||||
@@ -659,7 +689,7 @@ public:
|
||||
visit.push_front(parent);
|
||||
}
|
||||
} else if (pright != npos) {
|
||||
visit.push_front(this->successor(tree, pright));
|
||||
visit.push_front(this->_successor(tree, pright));
|
||||
}
|
||||
|
||||
if (not visit.empty()) {
|
||||
@@ -672,23 +702,50 @@ public:
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private:
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
// Iterator ============================================================================================================
|
||||
|
||||
|
||||
///
|
||||
/// \brief C++ Iterator Specification `iterator`
|
||||
/// \details Performs pre-order traversal
|
||||
class iterator {
|
||||
protected:
|
||||
bintree* _tree;
|
||||
in_order _order;
|
||||
size_t _n;
|
||||
|
||||
public:
|
||||
///
|
||||
/// \brief bintree iterator constructor
|
||||
/// \param tree A reference to the tree
|
||||
/// \param root The root node for iteration
|
||||
constexpr iterator(bintree* tree, size_t root)
|
||||
: _tree(tree)
|
||||
, _order()
|
||||
, _n(_order(*tree, root)) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief bintree iterator constructor
|
||||
/// \param tree A reference to the tree
|
||||
/// \param root The root node for iteration
|
||||
/// \param node The node to jump to
|
||||
constexpr iterator(bintree* tree, size_t root, size_t node)
|
||||
: _tree(tree)
|
||||
, _order()
|
||||
@@ -696,42 +753,171 @@ public:
|
||||
_order.head = root;
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns The index of the current node
|
||||
size_t index() const {
|
||||
return _n;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief iterator pre-increment operator
|
||||
/// \returns A reference to self after having stepped to the next node
|
||||
iterator& operator++() {
|
||||
return _n = _order[*_tree, _n, traversal_control_continue], *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief dereference operator
|
||||
/// \returns the value held in the current node
|
||||
value_t& operator*() {
|
||||
return (*_tree)[_n];
|
||||
}
|
||||
|
||||
value_t* operator->() {
|
||||
return &(*_tree)[_n];
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns the value held in the current node
|
||||
const value_t& operator*() const {
|
||||
return (*_tree)[_n];
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief pointer access operator
|
||||
/// \returns a reference to the value held in the current node
|
||||
value_t* operator->() {
|
||||
return &(*_tree)[_n];
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns a reference to the value held in the current node
|
||||
const value_t* operator->() const {
|
||||
return &(*_tree)[_n];
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief iterator equality operator
|
||||
/// \param it the iterator to compare with
|
||||
/// \returns \f$true\f$ if iterators are identical, \f$false\f$ otherwise
|
||||
constexpr bool operator==(const iterator& it) {
|
||||
return _tree == it._tree and _n == it._n;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief iterator inequality operator
|
||||
/// \param it the iterator to compare with
|
||||
/// \returns \f$true\f$ if iterators are different, \f$false\f$ otherwise
|
||||
constexpr bool operator!=(const iterator& it) {
|
||||
return _tree != it._tree or _n != it._n;
|
||||
}
|
||||
|
||||
private:
|
||||
bintree* _tree;
|
||||
in_order _order;
|
||||
size_t _n;
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// \brief C++ Iterator Specification `iterator`
|
||||
/// \details Performs pre-order traversal
|
||||
class const_iterator {
|
||||
|
||||
public:
|
||||
///
|
||||
/// \brief bintree iterator constructor
|
||||
/// \param tree A reference to the tree
|
||||
/// \param root The root node for iteration
|
||||
constexpr const_iterator(bintree* tree, size_t root)
|
||||
: _tree(tree)
|
||||
, _order()
|
||||
, _n(_order(*tree, root)) {
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief bintree iterator constructor
|
||||
/// \param tree A reference to the tree
|
||||
/// \param root The root node for iteration
|
||||
/// \param node The node to jump to
|
||||
constexpr const_iterator(bintree* tree, size_t root, size_t node)
|
||||
: _tree(tree)
|
||||
, _order()
|
||||
, _n(node) {
|
||||
_order.head = root;
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns The index of the current node
|
||||
size_t index() const {
|
||||
return _n;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief iterator pre-increment operator
|
||||
/// \returns A reference to self after having stepped to the next node
|
||||
const_iterator& operator++() {
|
||||
return _n = _order[*_tree, _n, traversal_control_continue], *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns the value held in the current node
|
||||
const value_t& operator*() const {
|
||||
return (*_tree)[_n];
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns a reference to the value held in the current node
|
||||
const value_t* operator->() const {
|
||||
return &(*_tree)[_n];
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief iterator equality operator
|
||||
/// \param it the iterator to compare with
|
||||
/// \returns \f$true\f$ if iterators are identical, \f$false\f$ otherwise
|
||||
constexpr bool operator==(const iterator& it) {
|
||||
return _tree == it._tree and _n == it._n;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief iterator inequality operator
|
||||
/// \param it the iterator to compare with
|
||||
/// \returns \f$true\f$ if iterators are different, \f$false\f$ otherwise
|
||||
constexpr bool operator!=(const iterator& it) {
|
||||
return _tree != it._tree or _n != it._n;
|
||||
}
|
||||
|
||||
private:
|
||||
bintree* _tree;
|
||||
in_order _order;
|
||||
size_t _n;
|
||||
};
|
||||
|
||||
///
|
||||
/// \returns an iterator at the first element in pre-order traversal
|
||||
iterator begin() {
|
||||
return iterator(this, _root);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief C++ Iterator Specification `begin()`
|
||||
/// \returns an iterator at the first element in pre-order traversal
|
||||
const_iterator begin() const {
|
||||
return iterator(this, _root);
|
||||
}
|
||||
|
||||
///
|
||||
/// \returns an iterator at the first element in pre-order traversal
|
||||
iterator end() {
|
||||
return iterator(this, _root, nullid);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief C++ Iterator Specification `begin()`
|
||||
/// \returns an iterator at the first element in pre-order traversal
|
||||
const_iterator end() const {
|
||||
return iterator(this, _root, nullid);
|
||||
}
|
||||
|
||||
// Fields ==============================================================================================================
|
||||
protected:
|
||||
private:
|
||||
table_t _table;
|
||||
freed_t _freed;
|
||||
size_t _root, _size;
|
||||
|
||||
Reference in New Issue
Block a user