Files
BloomPatched/src/Helpers/BiMap.hpp

88 lines
2.6 KiB
C++
Raw Normal View History

2021-04-04 21:04:12 +01:00
#pragma once
#include <memory>
#include <map>
namespace Bloom
{
/**
* Simple bidirectional map
*
* This should only be used for small maps, with small elements (enums, string literals, etc).
*
* TODO: This needs some work - was written as a quick implementation with minimal requirements.
* TODO: Add support for inserting/deleting elements (outside of construction).
*
* @tparam TypeA
* @tparam TypeB
*/
template<typename TypeA, typename TypeB>
class BiMap
{
public:
BiMap(std::initializer_list<std::pair<TypeA, TypeB>> elements) {
for (auto it = elements.begin(); it != elements.end(); ++it) {
auto insertResultPair = this->map.insert(std::pair<TypeA, TypeB>{it->first, it->second});
this->flippedMap.insert(
std::pair<TypeB, typename std::unordered_map<TypeA, TypeB>::iterator>{
it->second,
insertResultPair.first
}
);
}
}
2022-01-15 13:37:24 +00:00
bool contains(const TypeA& key) const {
2021-04-04 21:04:12 +01:00
return this->map.find(key) != this->map.end();
}
2022-01-15 13:37:24 +00:00
bool contains(const TypeB& key) const {
2021-04-04 21:04:12 +01:00
return this->flippedMap.find(key) != this->flippedMap.end();
}
2022-01-15 13:37:24 +00:00
std::optional<TypeB> valueAt(const TypeA& key) const {
2021-04-04 21:04:12 +01:00
std::optional<TypeB> output;
if (this->contains(key)) {
output = this->map.find(key)->second;
}
return output;
}
2022-01-15 13:37:24 +00:00
std::optional<TypeA> valueAt(const TypeB& key) const {
2021-04-04 21:04:12 +01:00
std::optional<TypeA> output;
if (this->contains(key)) {
output = this->flippedMap.find(key)->second->first;
}
return output;
}
2022-01-15 13:37:24 +00:00
const TypeB& at(const TypeA& key) const {
return this->map.at(key);
}
2022-01-15 13:37:24 +00:00
const TypeA& at(const TypeB& key) const {
return this->flippedMap.at(key)->first;
}
2022-01-15 13:37:24 +00:00
[[nodiscard]] std::unordered_map<TypeA, TypeB> getMap() const {
2021-04-04 21:04:12 +01:00
return this->map;
}
void insert(const std::pair<TypeA, TypeB>& pair) {
auto insertResultPair = this->map.insert(pair);
this->flippedMap.insert(std::pair<TypeB, typename std::unordered_map<TypeA, TypeB>::iterator>(
pair.second,
insertResultPair.first
));
}
private:
std::unordered_map<TypeA, TypeB> map = {};
std::unordered_map<TypeB, typename std::unordered_map<TypeA, TypeB>::iterator> flippedMap = {};
2021-04-04 21:04:12 +01:00
};
}