Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/nall/map.hpp
2 views
1
#ifndef NALL_MAP_HPP
2
#define NALL_MAP_HPP
3
4
#include <nall/vector.hpp>
5
6
namespace nall {
7
8
template<typename LHS, typename RHS>
9
struct map {
10
struct pair {
11
LHS name;
12
RHS data;
13
};
14
15
inline void reset() {
16
list.reset();
17
}
18
19
inline unsigned size() const {
20
return list.size();
21
}
22
23
//O(log n) find
24
inline optional<unsigned> find(const LHS &name) const {
25
signed first = 0, last = size() - 1;
26
while(first <= last) {
27
signed middle = (first + last) / 2;
28
if(name < list[middle].name) last = middle - 1; //search lower half
29
else if(list[middle].name < name) first = middle + 1; //search upper half
30
else return { true, middle }; //match found
31
}
32
return { false, 0u };
33
}
34
35
//O(n) insert + O(log n) find
36
inline RHS& insert(const LHS &name, const RHS &data) {
37
if(auto position = find(name)) {
38
list[position()].data = data;
39
return list[position()].data;
40
}
41
signed offset = size();
42
for(unsigned n = 0; n < size(); n++) {
43
if(name < list[n].name) { offset = n; break; }
44
}
45
list.insert(offset, { name, data });
46
return list[offset].data;
47
}
48
49
//O(log n) find
50
inline void modify(const LHS &name, const RHS &data) {
51
if(auto position = find(name)) list[position()].data = data;
52
}
53
54
//O(n) remove + O(log n) find
55
inline void remove(const LHS &name) {
56
if(auto position = find(name)) list.remove(position());
57
}
58
59
//O(log n) find
60
inline RHS& operator[](const LHS &name) {
61
if(auto position = find(name)) return list[position()].data;
62
throw;
63
}
64
65
inline const RHS& operator[](const LHS &name) const {
66
if(auto position = find(name)) return list[position()].data;
67
throw;
68
}
69
70
inline RHS& operator()(const LHS &name) {
71
return insert(name, RHS());
72
}
73
74
inline const RHS& operator()(const LHS &name, const RHS &data) const {
75
if(auto position = find(name)) return list[position()].data;
76
return data;
77
}
78
79
inline pair* begin() { return list.begin(); }
80
inline pair* end() { return list.end(); }
81
inline const pair* begin() const { return list.begin(); }
82
inline const pair* end() const { return list.end(); }
83
84
protected:
85
vector<pair> list;
86
};
87
88
template<typename LHS, typename RHS>
89
struct bidirectional_map {
90
const map<LHS, RHS> &lhs;
91
const map<RHS, LHS> &rhs;
92
93
inline void reset() {
94
llist.reset();
95
rlist.reset();
96
}
97
98
inline unsigned size() const {
99
return llist.size();
100
}
101
102
inline void insert(const LHS &ldata, const RHS &rdata) {
103
llist.insert(ldata, rdata);
104
rlist.insert(rdata, ldata);
105
}
106
107
inline bidirectional_map() : lhs(llist), rhs(rlist) {}
108
109
protected:
110
map<LHS, RHS> llist;
111
map<RHS, LHS> rlist;
112
};
113
114
}
115
116
#endif
117
118