-
Notifications
You must be signed in to change notification settings - Fork 0
/
linked_hash_map.hpp
85 lines (81 loc) · 1.79 KB
/
linked_hash_map.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#ifndef LINKED_HASH_MAP_HPP
#define LINKED_HASH_MAP_HPP
#include <unordered_map>
#include <list>
#include <utility>
template <class K, class V>
class linked_hash_map {
private:
typedef typename std::list<K const>::iterator list_iterator;
std::unordered_map< K, std::pair<V, list_iterator > > hash;
std::list<K const> ls;
public:
const unsigned long size() noexcept { return hash.size(); }
const bool empty() noexcept { return hash.empty(); }
void insert(std::pair<K,V>&& kv) {
auto const p = hash.find(kv.first);
if (p != hash.end()) {
p->second.first = std::move(kv.second);
} else {
auto const it = ls.insert(ls.end(), kv.first);
try {
hash.insert( std::make_pair(std::move(kv.first), std::make_pair(std::move(kv.second), it)));
}
catch (...) {
ls.erase(it);
throw;
}
}
}
void insert(std::pair<K,V> const& kv) {
auto const p = hash.find(kv.first);
if (p != hash.end()) {
p->second.first = std::move(kv.second);
} else {
ls.push_back(kv.first);
try {
auto it = ls.end(); --it;
hash.insert( std::make_pair(kv.first, std::make_pair(kv.second, it)));
}
catch (...) {
ls.pop_back();
throw;
}
}
}
void erase(K const& key) {
auto const p = hash.find(key);
if (p != hash.end()) {
ls.erase(p->second.second);
hash.erase(p);
}
}
void eraseEldest() {
if(!hash.empty()) {
hash.erase(ls.front());
ls.pop_front();
}
}
void eraseNewest() {
if(!hash.empty()) {
hash.erase(ls.back());
ls.pop_back();
}
}
V& at(K const& key) {
return hash.at(key).first;
}
V const& at(K const& key) const {
return hash.at(key).first;
}
V& operator[](K const& key) {
return hash[key].first;
}
V const& operator[](K const& key) const {
return hash[key].first;
}
std::list<K const> keyList() {
return ls;
}
};
#endif