Corrected iterators invalidation bug in BiMap class

This commit is contained in:
Nav
2022-08-30 02:00:01 +01:00
parent 6c436cbefc
commit fd68089214

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <map> #include <unordered_map>
namespace Bloom namespace Bloom
{ {
@@ -22,13 +22,8 @@ namespace Bloom
public: public:
BiMap(std::initializer_list<std::pair<TypeA, TypeB>> elements) { BiMap(std::initializer_list<std::pair<TypeA, TypeB>> elements) {
for (auto it = elements.begin(); it != elements.end(); ++it) { for (auto it = elements.begin(); it != elements.end(); ++it) {
auto insertResultPair = this->map.insert(std::pair<TypeA, TypeB>{it->first, it->second}); this->map.insert(std::pair<TypeA, TypeB>{it->first, it->second});
this->flippedMap.insert( this->flippedMap.insert(std::pair<TypeB, TypeA>(it->second, it->first));
std::pair<TypeB, typename std::unordered_map<TypeA, TypeB>::iterator>{
it->second,
insertResultPair.first
}
);
} }
} }
@@ -54,7 +49,7 @@ namespace Bloom
std::optional<TypeA> output; std::optional<TypeA> output;
if (this->contains(key)) { if (this->contains(key)) {
output = this->flippedMap.find(key)->second->first; output = this->flippedMap.find(key)->second;
} }
return output; return output;
@@ -65,7 +60,7 @@ namespace Bloom
} }
const TypeA& at(const TypeB& key) const { const TypeA& at(const TypeB& key) const {
return this->flippedMap.at(key)->first; return this->flippedMap.at(key);
} }
[[nodiscard]] std::unordered_map<TypeA, TypeB> getMap() const { [[nodiscard]] std::unordered_map<TypeA, TypeB> getMap() const {
@@ -74,14 +69,11 @@ namespace Bloom
void insert(const std::pair<TypeA, TypeB>& pair) { void insert(const std::pair<TypeA, TypeB>& pair) {
auto insertResultPair = this->map.insert(pair); auto insertResultPair = this->map.insert(pair);
this->flippedMap.insert(std::pair<TypeB, typename std::unordered_map<TypeA, TypeB>::iterator>( this->flippedMap.insert(std::pair<TypeB, TypeA>(pair.second, pair.first));
pair.second,
insertResultPair.first
));
} }
private: private:
std::unordered_map<TypeA, TypeB> map = {}; std::unordered_map<TypeA, TypeB> map = {};
std::unordered_map<TypeB, typename std::unordered_map<TypeA, TypeB>::iterator> flippedMap = {}; std::unordered_map<TypeB, TypeA> flippedMap = {};
}; };
} }