mirror of https://github.com/PrimeDecomp/prime.git
Add red_black_tree::insert
This commit is contained in:
parent
4db5549046
commit
ee58faa944
|
@ -14,12 +14,17 @@ public:
|
||||||
typedef pair< K, V > value_type;
|
typedef pair< K, V > value_type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef red_black_tree< K, value_type, 1, select1st< value_type >, Cmp, Alloc > rep_type;
|
// TODO: some things use a 0, others use a 1
|
||||||
|
typedef red_black_tree< K, value_type, 0, select1st< value_type >, Cmp, Alloc > rep_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// typedef typename rep_type::iterator iterator;
|
// typedef typename rep_type::iterator iterator;
|
||||||
typedef typename rep_type::const_iterator const_iterator;
|
typedef typename rep_type::const_iterator const_iterator;
|
||||||
|
|
||||||
|
void insert(const value_type& item) {
|
||||||
|
inner.insert(item);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
rep_type inner;
|
rep_type inner;
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,20 +3,31 @@
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
#include "rstl/pair.hpp"
|
||||||
#include "rstl/rmemory_allocator.hpp"
|
#include "rstl/rmemory_allocator.hpp"
|
||||||
|
|
||||||
namespace rstl {
|
namespace rstl {
|
||||||
template < typename P >
|
template < typename P >
|
||||||
struct select1st {};
|
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 >
|
template < typename T >
|
||||||
struct less {};
|
struct less {
|
||||||
|
bool operator()(const T& a, const T& b) const { return a < b; }
|
||||||
|
};
|
||||||
|
|
||||||
enum node_color {
|
enum node_color {
|
||||||
kNC_Red,
|
kNC_Red,
|
||||||
kNC_Black,
|
kNC_Black,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void rbtree_rebalance(void*, void*);
|
||||||
void* rbtree_traverse_forward(const void*, void*);
|
void* rbtree_traverse_forward(const void*, void*);
|
||||||
|
|
||||||
template < typename T, typename P, int U, typename S = select1st< P >, typename Cmp = less< T >,
|
template < typename T, typename P, int U, typename S = select1st< P >, typename Cmp = less< T >,
|
||||||
|
@ -24,16 +35,35 @@ template < typename T, typename P, int U, typename S = select1st< P >, typename
|
||||||
class red_black_tree {
|
class red_black_tree {
|
||||||
private:
|
private:
|
||||||
struct node {
|
struct node {
|
||||||
node_color mColor;
|
|
||||||
node* mParent;
|
|
||||||
node* mLeft;
|
node* mLeft;
|
||||||
node* mRight;
|
node* mRight;
|
||||||
P mValue;
|
node* mParent;
|
||||||
|
node_color mColor;
|
||||||
|
uchar mValue[sizeof(P)];
|
||||||
|
|
||||||
P& get_value() { return mValue; }
|
node(const P& value, node_color color = kNC_Red)
|
||||||
|
: mLeft(nullptr), mRight(nullptr), mColor(color), mParent(nullptr) {
|
||||||
|
construct(get_value(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
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; }
|
||||||
};
|
};
|
||||||
struct header {};
|
struct header {};
|
||||||
|
|
||||||
|
struct unknown {
|
||||||
|
node* x0_nodeA;
|
||||||
|
node** x4_nodeB;
|
||||||
|
bool x8_;
|
||||||
|
|
||||||
|
unknown(node* a, node** b, bool flag) : x0_nodeA(a), x4_nodeB(b), x8_(flag) {}
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct const_iterator {
|
struct const_iterator {
|
||||||
node* mNode;
|
node* mNode;
|
||||||
|
@ -49,25 +79,85 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator& operator++() {
|
const_iterator& operator++() {
|
||||||
mNode = static_cast<node*>(rbtree_traverse_forward(static_cast<const void*>(mHeader), static_cast<void*>(mNode)));
|
mNode = static_cast< node* >(rbtree_traverse_forward(static_cast< const void* >(mHeader),
|
||||||
|
static_cast< void* >(mNode)));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator operator++(int) {
|
const_iterator operator++(int) {
|
||||||
const_iterator result = *this;
|
const_iterator result = *this;
|
||||||
mNode = static_cast<node*>(rbtree_traverse_forward(static_cast<const void*>(mHeader), static_cast<void*>(mNode)));
|
mNode = static_cast< node* >(rbtree_traverse_forward(static_cast< const void* >(mHeader),
|
||||||
|
static_cast< void* >(mNode)));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unknown insert_into(node* n, const P& item);
|
||||||
|
unknown insert(const P& item) { return insert_into(x10_rootNode, item); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uchar x0_;
|
Alloc x0_allocator;
|
||||||
uchar x1_;
|
Cmp x1_cmp;
|
||||||
uint x4_;
|
S x2_selector;
|
||||||
uint x8_;
|
int x4_count;
|
||||||
uint xc_;
|
node* x8_nodeA;
|
||||||
uint x10_;
|
node* xc_nodeB;
|
||||||
|
node* x10_rootNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
x8_nodeA = x10_rootNode;
|
||||||
|
xc_nodeB = x10_rootNode;
|
||||||
|
return unknown(x10_rootNode, &x8_nodeA, kUnknownValueNewRoot);
|
||||||
|
|
||||||
|
} 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()))) {
|
||||||
|
return unknown(n, &x8_nodeA, kUnknownValueEqualKey);
|
||||||
|
}
|
||||||
|
if (firstComp) {
|
||||||
|
if (n->get_left() == nullptr) {
|
||||||
|
x0_allocator.allocate(newNode, 1);
|
||||||
|
new (newNode) node(item, kNC_Black);
|
||||||
|
n->set_left(newNode);
|
||||||
|
if (n == x8_nodeA) {
|
||||||
|
x8_nodeA = newNode;
|
||||||
|
}
|
||||||
|
} 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);
|
||||||
|
if (n == xc_nodeB) {
|
||||||
|
xc_nodeB = newNode;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
n = n->get_right();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x4_count += 1;
|
||||||
|
rbtree_rebalance(&x8_nodeA, newNode);
|
||||||
|
return unknown(newNode, &x8_nodeA, kUnknownValueNewItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}; // namespace rstl
|
}; // namespace rstl
|
||||||
|
|
||||||
#endif // _RSTL_RED_BLACK_TREE
|
#endif // _RSTL_RED_BLACK_TREE
|
||||||
|
|
Loading…
Reference in New Issue