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>;
|
friend class Map<Key_T, Mapped_T>;
|
||||||
Map<Key_T, Mapped_T> &container;
|
Map<Key_T, Mapped_T> &container;
|
||||||
ValueType value;
|
ValueType value;
|
||||||
Ptr self;
|
// Ptr self;
|
||||||
Color color;
|
Color color;
|
||||||
// nullptr indicates empty
|
// nullptr indicates empty
|
||||||
Self *parent;
|
Self *parent;
|
||||||
|
@ -45,7 +45,7 @@ template <typename Key_T, typename Mapped_T> struct BookKeeping {
|
||||||
Self *next;
|
Self *next;
|
||||||
BookKeeping(Map<Key_T, Mapped_T> &container) : container{container} {}
|
BookKeeping(Map<Key_T, Mapped_T> &container) : container{container} {}
|
||||||
BookKeeping(BookKeeping const &rhs)
|
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},
|
color{rhs.color}, parent{rhs.parent}, left{rhs.left}, right{rhs.right},
|
||||||
prev{rhs.prev}, next{rhs.next} {}
|
prev{rhs.prev}, next{rhs.next} {}
|
||||||
// if pointing to different containers throws
|
// 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"};
|
"values/iterators from the same map object"};
|
||||||
}
|
}
|
||||||
this->value = rhs.value;
|
this->value = rhs.value;
|
||||||
this->self = rhs.self;
|
// this->self = rhs.self;
|
||||||
this->color = rhs.color;
|
this->color = rhs.color;
|
||||||
this->parent = rhs.parent;
|
this->parent = rhs.parent;
|
||||||
this->left = rhs.left;
|
this->left = rhs.left;
|
||||||
|
@ -287,6 +287,9 @@ public:
|
||||||
Map(const Map &rhs)
|
Map(const Map &rhs)
|
||||||
: root{rhs.root}, min{nullptr}, max{nullptr}, nodes{rhs.nodes} {}
|
: root{rhs.root}, min{nullptr}, max{nullptr}, nodes{rhs.nodes} {}
|
||||||
Map &operator=(const Map &rhs) {
|
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->root = rhs.root;
|
||||||
this->min = rhs.min;
|
this->min = rhs.min;
|
||||||
this->max = rhs.max;
|
this->max = rhs.max;
|
||||||
|
@ -316,7 +319,7 @@ public:
|
||||||
// it here
|
// it here
|
||||||
auto [parent, dir] = this->locate_slot(key);
|
auto [parent, dir] = this->locate_slot(key);
|
||||||
if (parent == nullptr) {
|
if (parent == nullptr) {
|
||||||
if (this->root->value.first == key) {
|
if (this->root != nullptr && this->root->value.first == key) {
|
||||||
return Iterator{root};
|
return Iterator{root};
|
||||||
} else {
|
} else {
|
||||||
return this->end();
|
return this->end();
|
||||||
|
@ -330,9 +333,26 @@ public:
|
||||||
// implicit cast to ConstIterator from Iterator
|
// implicit cast to ConstIterator from Iterator
|
||||||
ConstIterator find(const Key_T &key) const { return this->find(key); }
|
ConstIterator find(const Key_T &key) const { return this->find(key); }
|
||||||
|
|
||||||
Mapped_T &at(const Key_T &key) { return (this->find(key))->second; }
|
Mapped_T &at(const Key_T &key) {
|
||||||
const Mapped_T &at(const Key_T &key) const { return this->at(key); }
|
auto ret = this->find(key);
|
||||||
Mapped_T &operator[](const Key_T &key) { return this->at(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:
|
private:
|
||||||
void handle_root_rotation(Node *grandparent, Node *parent, Node *inserting,
|
void handle_root_rotation(Node *grandparent, Node *parent, Node *inserting,
|
||||||
|
@ -380,11 +400,13 @@ private:
|
||||||
to_insert->next = parent;
|
to_insert->next = parent;
|
||||||
to_insert->prev = parent->prev;
|
to_insert->prev = parent->prev;
|
||||||
parent->prev = to_insert;
|
parent->prev = to_insert;
|
||||||
|
parent->left = to_insert;
|
||||||
break;
|
break;
|
||||||
case Direction::Right:
|
case Direction::Right:
|
||||||
to_insert->prev = parent;
|
to_insert->prev = parent;
|
||||||
to_insert->next = parent->next;
|
to_insert->next = parent->next;
|
||||||
parent->next = to_insert;
|
parent->next = to_insert;
|
||||||
|
parent->right = to_insert;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,7 +478,7 @@ private:
|
||||||
Direction dir;
|
Direction dir;
|
||||||
while (current != nullptr && current->value.first != key) {
|
while (current != nullptr && current->value.first != key) {
|
||||||
parent = current;
|
parent = current;
|
||||||
if (current->value.first < key) {
|
if (key < current->value.first) {
|
||||||
dir = Direction::Left;
|
dir = Direction::Left;
|
||||||
current = current->left;
|
current = current->left;
|
||||||
} else {
|
} else {
|
||||||
|
@ -481,14 +503,16 @@ public:
|
||||||
Node to_insert{*this};
|
Node to_insert{*this};
|
||||||
to_insert.value = val;
|
to_insert.value = val;
|
||||||
this->nodes.push_back(std::move(to_insert));
|
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);
|
insert_helper(&nodes.back(), parent, dir);
|
||||||
|
|
||||||
if (min == nullptr || val.first < min->value.first) {
|
if (min == nullptr || val.first < min->value.first) {
|
||||||
min = &nodes.back();
|
min = &nodes.back();
|
||||||
|
nodes.back().prev = nullptr;
|
||||||
}
|
}
|
||||||
if (max == nullptr || val.first > max->value.first) {
|
if (max == nullptr || val.first > max->value.first) {
|
||||||
max = &nodes.back();
|
max = &nodes.back();
|
||||||
|
nodes.back().next = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_pair(Iterator(&nodes.back()), ret);
|
return std::make_pair(Iterator(&nodes.back()), ret);
|
||||||
|
@ -590,6 +614,12 @@ public:
|
||||||
void erase(Iterator pos) {
|
void erase(Iterator pos) {
|
||||||
// simple cases
|
// simple cases
|
||||||
Node *ref = pos.ref;
|
Node *ref = pos.ref;
|
||||||
|
if (ref == this->min) {
|
||||||
|
this->min = ref->next;
|
||||||
|
}
|
||||||
|
if (ref == this->max) {
|
||||||
|
this->max = ref->prev;
|
||||||
|
}
|
||||||
// 2 children
|
// 2 children
|
||||||
if (ref->left != nullptr && ref->right != nullptr) {
|
if (ref->left != nullptr && ref->right != nullptr) {
|
||||||
Node *next = ref->next;
|
Node *next = ref->next;
|
||||||
|
|
Loading…
Reference in a new issue