From f87ca7431de12f2121a3ae8c787a2044c593d833 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Fri, 22 Nov 2024 15:43:10 -0500 Subject: [PATCH] fixed some bugs --- Map.hpp | 48 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/Map.hpp b/Map.hpp index f649961..155360d 100644 --- a/Map.hpp +++ b/Map.hpp @@ -35,7 +35,7 @@ template struct BookKeeping { friend class Map; Map &container; ValueType value; - Ptr self; + // Ptr self; Color color; // nullptr indicates empty Self *parent; @@ -45,7 +45,7 @@ template struct BookKeeping { Self *next; BookKeeping(Map &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 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;