fixed some bugs
This commit is contained in:
parent
b5b03e5fbe
commit
f87ca7431d
1 changed files with 39 additions and 9 deletions
48
Map.hpp
48
Map.hpp
|
@ -35,7 +35,7 @@ template <typename Key_T, typename Mapped_T> struct BookKeeping {
|
|||
friend class Map<Key_T, Mapped_T>;
|
||||
Map<Key_T, Mapped_T> &container;
|
||||
ValueType value;
|
||||
Ptr self;
|
||||
// Ptr self;
|
||||
Color color;
|
||||
// nullptr indicates empty
|
||||
Self *parent;
|
||||
|
@ -45,7 +45,7 @@ template <typename Key_T, typename Mapped_T> struct BookKeeping {
|
|||
Self *next;
|
||||
BookKeeping(Map<Key_T, Mapped_T> &container) : container{container} {}
|
||||
BookKeeping(BookKeeping const &rhs)
|
||||
: container{rhs.container}, value{rhs.value}, self{rhs.self},
|
||||
: container{rhs.container}, value{rhs.value}, // self{rhs.self},
|
||||
color{rhs.color}, parent{rhs.parent}, left{rhs.left}, right{rhs.right},
|
||||
prev{rhs.prev}, next{rhs.next} {}
|
||||
// if pointing to different containers throws
|
||||
|
@ -55,7 +55,7 @@ template <typename Key_T, typename Mapped_T> struct BookKeeping {
|
|||
"values/iterators from the same map object"};
|
||||
}
|
||||
this->value = rhs.value;
|
||||
this->self = rhs.self;
|
||||
// this->self = rhs.self;
|
||||
this->color = rhs.color;
|
||||
this->parent = rhs.parent;
|
||||
this->left = rhs.left;
|
||||
|
@ -287,6 +287,9 @@ public:
|
|||
Map(const Map &rhs)
|
||||
: root{rhs.root}, min{nullptr}, max{nullptr}, nodes{rhs.nodes} {}
|
||||
Map &operator=(const Map &rhs) {
|
||||
// TODO: fix this so all the pointers in all the bookkeeping nodes are
|
||||
// updated in addition to root, min and max
|
||||
assert(false);
|
||||
this->root = rhs.root;
|
||||
this->min = rhs.min;
|
||||
this->max = rhs.max;
|
||||
|
@ -316,7 +319,7 @@ public:
|
|||
// it here
|
||||
auto [parent, dir] = this->locate_slot(key);
|
||||
if (parent == nullptr) {
|
||||
if (this->root->value.first == key) {
|
||||
if (this->root != nullptr && this->root->value.first == key) {
|
||||
return Iterator{root};
|
||||
} else {
|
||||
return this->end();
|
||||
|
@ -330,9 +333,26 @@ public:
|
|||
// implicit cast to ConstIterator from Iterator
|
||||
ConstIterator find(const Key_T &key) const { return this->find(key); }
|
||||
|
||||
Mapped_T &at(const Key_T &key) { return (this->find(key))->second; }
|
||||
const Mapped_T &at(const Key_T &key) const { return this->at(key); }
|
||||
Mapped_T &operator[](const Key_T &key) { return this->at(key); }
|
||||
Mapped_T &at(const Key_T &key) {
|
||||
auto ret = this->find(key);
|
||||
if (ret == this->end()) {
|
||||
throw std::out_of_range{"Key not in map"};
|
||||
}
|
||||
return ret->second;
|
||||
}
|
||||
const Mapped_T &at(const Key_T &key) const {
|
||||
auto ret = this->find(key);
|
||||
if (ret == this->end()) {
|
||||
throw std::out_of_range{"Key not in map"};
|
||||
}
|
||||
return ret->second;
|
||||
}
|
||||
Mapped_T &operator[](const Key_T &key) {
|
||||
Mapped_T v;
|
||||
auto insert_val = std::make_pair(key, v);
|
||||
auto [iter, key_no_exist] = this->insert(insert_val);
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
private:
|
||||
void handle_root_rotation(Node *grandparent, Node *parent, Node *inserting,
|
||||
|
@ -380,11 +400,13 @@ private:
|
|||
to_insert->next = parent;
|
||||
to_insert->prev = parent->prev;
|
||||
parent->prev = to_insert;
|
||||
parent->left = to_insert;
|
||||
break;
|
||||
case Direction::Right:
|
||||
to_insert->prev = parent;
|
||||
to_insert->next = parent->next;
|
||||
parent->next = to_insert;
|
||||
parent->right = to_insert;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -456,7 +478,7 @@ private:
|
|||
Direction dir;
|
||||
while (current != nullptr && current->value.first != key) {
|
||||
parent = current;
|
||||
if (current->value.first < key) {
|
||||
if (key < current->value.first) {
|
||||
dir = Direction::Left;
|
||||
current = current->left;
|
||||
} else {
|
||||
|
@ -481,14 +503,16 @@ public:
|
|||
Node to_insert{*this};
|
||||
to_insert.value = val;
|
||||
this->nodes.push_back(std::move(to_insert));
|
||||
this->nodes.back().self = (--this->nodes.end());
|
||||
// this->nodes.back().self = (--this->nodes.end());
|
||||
insert_helper(&nodes.back(), parent, dir);
|
||||
|
||||
if (min == nullptr || val.first < min->value.first) {
|
||||
min = &nodes.back();
|
||||
nodes.back().prev = nullptr;
|
||||
}
|
||||
if (max == nullptr || val.first > max->value.first) {
|
||||
max = &nodes.back();
|
||||
nodes.back().next = nullptr;
|
||||
}
|
||||
|
||||
return std::make_pair(Iterator(&nodes.back()), ret);
|
||||
|
@ -590,6 +614,12 @@ public:
|
|||
void erase(Iterator pos) {
|
||||
// simple cases
|
||||
Node *ref = pos.ref;
|
||||
if (ref == this->min) {
|
||||
this->min = ref->next;
|
||||
}
|
||||
if (ref == this->max) {
|
||||
this->max = ref->prev;
|
||||
}
|
||||
// 2 children
|
||||
if (ref->left != nullptr && ref->right != nullptr) {
|
||||
Node *next = ref->next;
|
||||
|
|
Loading…
Reference in a new issue