prime/include/rstl/red_black_tree.hpp

199 lines
5.4 KiB
C++
Raw Normal View History

#ifndef _RSTL_RED_BLACK_TREE
#define _RSTL_RED_BLACK_TREE
#include "types.h"
2022-10-25 12:50:23 +00:00
#include "rstl/pair.hpp"
#include "rstl/rmemory_allocator.hpp"
namespace rstl {
template < typename P >
2022-10-25 12:50:23 +00:00
struct select1st {
const P& operator()(const P& it) const { return it; }
};
template < typename K, typename V >
struct select1st< pair< K, V > > {
const K& operator()(const pair< K, V >& it) const { return it.first; }
};
template < typename T >
2022-10-25 12:50:23 +00:00
struct less {
bool operator()(const T& a, const T& b) const { return a < b; }
};
enum node_color {
kNC_Red,
kNC_Black,
};
2022-10-25 12:50:23 +00:00
void rbtree_rebalance(void*, void*);
2022-10-16 00:03:19 +00:00
void* rbtree_traverse_forward(const void*, void*);
template < typename T, typename P, int U, typename S = select1st< P >, typename Cmp = less< T >,
typename Alloc = rmemory_allocator >
class red_black_tree {
private:
struct node {
node* mLeft;
node* mRight;
2022-10-25 12:50:23 +00:00
node* mParent;
node_color mColor;
uchar mValue[sizeof(P)];
node(const P& value, node_color color = kNC_Red)
: mLeft(nullptr), mRight(nullptr), mColor(color), mParent(nullptr) {
construct(get_value(), value);
}
2022-10-25 12:50:23 +00:00
P* get_value() { return reinterpret_cast< P* >(&mValue); }
const P* get_value() const { return reinterpret_cast< const P* >(&mValue); }
node* get_left() { return mLeft; }
void set_left(node* n) { mLeft = n; }
node* get_right() { return mRight; }
void set_right(node* n) { mRight = n; }
};
2022-10-25 14:29:23 +00:00
struct header {
node* mNode;
};
2022-10-25 12:50:23 +00:00
struct unknown {
2022-10-25 14:29:23 +00:00
node* x0_node;
const header* x4_header;
2022-10-25 12:50:23 +00:00
bool x8_;
2022-10-25 14:29:23 +00:00
unknown(node* a, const header* h, bool b) : x0_node(a), x4_header(h), x8_(b) {}
2022-10-25 12:50:23 +00:00
};
public:
struct const_iterator {
node* mNode;
const header* mHeader;
2022-10-25 14:29:23 +00:00
const_iterator(node* node, const header* header)
: mNode(node), mHeader(header) {}
const P* operator->() const { return mNode->get_value(); }
bool operator==(const const_iterator& other) const {
return mNode == other.mNode && mHeader == other.mHeader;
}
bool operator!=(const const_iterator& other) const {
2022-10-16 00:03:19 +00:00
// return !(*this == other);
return mNode != other.mNode || mHeader != other.mHeader;
}
const_iterator& operator++() {
2022-10-25 12:50:23 +00:00
mNode = static_cast< node* >(rbtree_traverse_forward(static_cast< const void* >(mHeader),
static_cast< void* >(mNode)));
2022-10-16 00:03:19 +00:00
return *this;
}
const_iterator operator++(int) {
const_iterator result = *this;
2022-10-25 12:50:23 +00:00
mNode = static_cast< node* >(rbtree_traverse_forward(static_cast< const void* >(mHeader),
static_cast< void* >(mNode)));
2022-10-16 00:03:19 +00:00
return result;
}
};
2022-10-25 12:50:23 +00:00
unknown insert_into(node* n, const P& item);
unknown insert(const P& item) { return insert_into(x10_rootNode, item); }
2022-10-25 14:29:23 +00:00
const_iterator begin() const {
// TODO
return const_iterator(nullptr, nullptr);
}
const_iterator end() const {
// TODO
return const_iterator(nullptr, nullptr);
}
const_iterator find(const T& key) const {
node* n = x10_rootNode;
node* needle = nullptr;
while (n != nullptr) {
if (!x1_cmp(x2_selector(*n->get_value()), key)) {
needle = n;
n = n->get_left();
} else {
n = n->get_right();
}
}
bool noResult = false;
if (needle == nullptr || x1_cmp(key, x2_selector(*needle->get_value()))) {
noResult = true;
}
if (noResult) {
needle = nullptr;
}
return const_iterator(needle, nullptr);
}
private:
2022-10-25 12:50:23 +00:00
Alloc x0_allocator;
Cmp x1_cmp;
S x2_selector;
int x4_count;
2022-10-25 14:29:23 +00:00
header x8_headerA;
header xc_headerB;
2022-10-25 12:50:23 +00:00
node* x10_rootNode;
};
2022-10-25 12:50:23 +00:00
static bool kUnknownValueNewRoot = true;
static bool kUnknownValueEqualKey = false;
static bool kUnknownValueNewItem = true;
template < typename T, typename P, int U, typename S, typename Cmp, typename Alloc >
typename red_black_tree< T, P, U, S, Cmp, Alloc >::unknown
red_black_tree< T, P, U, S, Cmp, Alloc >::insert_into(node* n, const P& item) {
if (n == nullptr) {
x0_allocator.allocate(n, 1);
new (n) node(item);
x10_rootNode = n;
x4_count += 1;
2022-10-25 14:29:23 +00:00
x8_headerA.mNode = x10_rootNode;
xc_headerB.mNode = x10_rootNode;
return unknown(x10_rootNode, &x8_headerA, kUnknownValueNewRoot);
2022-10-25 12:50:23 +00:00
} else {
node* newNode = nullptr;
while (newNode == nullptr) {
bool firstComp = x1_cmp(x2_selector(*n->get_value()), x2_selector(item));
if (!firstComp && !x1_cmp(x2_selector(item), x2_selector(*n->get_value()))) {
2022-10-25 14:29:23 +00:00
return unknown(n, &x8_headerA, kUnknownValueEqualKey);
2022-10-25 12:50:23 +00:00
}
if (firstComp) {
if (n->get_left() == nullptr) {
x0_allocator.allocate(newNode, 1);
new (newNode) node(item, kNC_Black);
n->set_left(newNode);
2022-10-25 14:29:23 +00:00
if (n == x8_headerA.mNode) {
x8_headerA.mNode = newNode;
2022-10-25 12:50:23 +00:00
}
} else {
n = n->get_left();
}
} else {
if (n->get_right() == nullptr) {
x0_allocator.allocate(newNode, 1);
new (newNode) node(item, kNC_Black);
n->set_right(newNode);
2022-10-25 14:29:23 +00:00
if (n == xc_headerB.mNode) {
xc_headerB.mNode = newNode;
2022-10-25 12:50:23 +00:00
}
} else {
n = n->get_right();
}
}
}
x4_count += 1;
2022-10-25 14:29:23 +00:00
rbtree_rebalance(&x8_headerA, newNode);
return unknown(newNode, &x8_headerA, kUnknownValueNewItem);
2022-10-25 12:50:23 +00:00
}
}
}; // namespace rstl
#endif // _RSTL_RED_BLACK_TREE