2#include <unordered_map>
15template <
typename T,
typename U>
26 template <
typename S
ideKey,
typename S
ideValue>
45 const SideValue&
at(
const SideKey& key)
const {
46 auto it =
map.find(key);
47 if (it ==
map.end()) {
48 throw std::out_of_range(
"Key not found in BidirectionalMap::Side::at");
59 return map.count(key) > 0;
82 typename std::unordered_map<SideKey, SideValue>::const_iterator
begin()
const {
return map.begin(); }
88 typename std::unordered_map<SideKey, SideValue>::const_iterator
end()
const {
return map.end(); }
91 std::unordered_map<SideKey, SideValue>
map;
135 void insert(
const T& key,
const U& value) {
136 auto it_left_key =
left.map.find(key);
137 if (it_left_key !=
left.map.end()) {
138 U old_value = std::move(it_left_key->second);
139 left.map.erase(it_left_key);
140 right.map.erase(old_value);
143 auto it_right_value =
right.map.find(value);
144 if (it_right_value !=
right.map.end()) {
145 T old_key = std::move(it_right_value->second);
146 right.map.erase(it_right_value);
147 left.map.erase(old_key);
150 left.map.insert_or_assign( key, value );
151 right.map.insert_or_assign( value, key );
161 template <
typename KT,
typename KU>
163 auto it_left_key =
left.map.find(key);
164 if (it_left_key !=
left.map.end()) {
165 right.map.erase(it_left_key->second);
166 left.map.erase(it_left_key);
169 auto it_right_value =
right.map.find(value);
170 if (it_right_value !=
right.map.end()) {
171 left.map.erase(it_right_value->second);
172 right.map.erase(it_right_value);
175 left.map.emplace(key, value);
176 right.map.emplace(std::forward<KU>(value), std::forward<KT>(key));
184 auto it_left =
left.map.find(key);
185 if (it_left !=
left.map.end()) {
186 U value = it_left->second;
187 left.map.erase(it_left);
188 right.map.erase(value);
197 auto it_right =
right.map.find(key);
198 if (it_right !=
right.map.end()) {
199 T value = it_right->second;
200 right.map.erase(it_right);
201 left.map.erase(value);
209 left.clear_map_only();
210 right.clear_map_only();
219 right.map.reserve(n);
Read-only view for one direction of the map.
const SideValue & at(const SideKey &key) const
Gets the value associated with a key.
Side()=default
Default constructor.
bool contains(const SideKey &key) const
Checks whether a key exists on this side.
bool empty() const
Checks whether this side has no mappings.
size_t size() const
Gets the number of mappings on this side.
std::unordered_map< T, U > map
std::unordered_map< SideKey, SideValue >::const_iterator end() const
Gets an iterator past the last mapping on this side.
std::unordered_map< SideKey, SideValue >::const_iterator begin() const
Gets an iterator to the first mapping on this side.
LeftSideType & get_left()
Gets the left-to-right view.
void emplace(KT &&key, KU &&value)
Constructs or replaces a one-to-one mapping in place.
Side< U, T > RightSideType
Read-only view that maps U to T.
Side< T, U > LeftSideType
Read-only view that maps T to U.
void insert(const T &key, const U &value)
Inserts or replaces a one-to-one mapping.
const LeftSideType & get_left() const
Gets the left-to-right view.
void reserve(size_t n)
Reserves storage for mappings on both sides.
void remove_right(const U &key)
Removes a mapping by right-side key.
RightSideType & get_right()
Gets the right-to-left view.
BidirectionalMap()=default
Creates an empty bidirectional map.
const RightSideType & get_right() const
Gets the right-to-left view.
void clear()
Removes all mappings from both sides.
void remove_left(const T &key)
Removes a mapping by left-side key.