-
-
Notifications
You must be signed in to change notification settings - Fork 113
/
Copy pathread_write_array.h
94 lines (79 loc) · 2.32 KB
/
read_write_array.h
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
86
87
88
89
90
91
92
93
94
#pragma once
#include "serialization.h"
#include "util.h"
template <typename Type, typename Param>
class ReadWriteArray {
public:
typedef unique_ptr<Type> PType;
typedef Type* WType;
ReadWriteArray(Rectangle bounds) : modified(bounds, -1), readonly(bounds, -1), types(bounds) {}
const Rectangle& getBounds() const {
return modified.getBounds();
}
void clearModified() {
unordered_set<int> used;
for (auto v : modified.getBounds())
used.insert(modified[v]);
for (int i : All(allModified))
if (!used.count(i))
allModified[i].reset();
}
WType getWritable(Vec2 pos) {
if (modified[pos] == -1)
if (auto type = types[pos])
putElem(pos, make_unique<Type>(*getReadonly(pos)));
if (modified[pos] > -1)
return allModified[modified[pos]].get();
else
return nullptr;
}
const WType getReadonly(Vec2 pos) const {
if (readonly[pos] > -1)
return allReadonly[readonly[pos]].get();
else if (modified[pos] > -1)
return allModified[modified[pos]].get();
else
return nullptr;
}
template <typename Generator>
void putElem(Vec2 pos, Param param, const Generator& generator) {
if (!readonlyMap.count(param)) {
allReadonly.push_back(generator(param));
CHECK(allReadonly.size() < 30000);
readonlyMap.insert(make_pair(param, allReadonly.size() - 1));
}
readonly[pos] = readonlyMap.at(param);
modified[pos] = -1;
types[pos] = param;
}
void putElem(Vec2 pos, PType s) {
allModified.push_back(std::move(s));
modified[pos] = allModified.size() - 1;
readonly[pos] = -1;
}
void clearElem(Vec2 pos) {
types[pos] = none;
modified[pos] = -1;
readonly[pos] = -1;
}
int getNumGenerated() const {
return allModified.size() + readonlyMap.size();
}
int getNumTotal() const {
return 0;
}
void shrinkToFit() {
allModified.shrink_to_fit();
allReadonly.shrink_to_fit();
}
SERIALIZE_ALL(allModified, modified, allReadonly, readonly, types, readonlyMap, numTotal)
SERIALIZATION_CONSTRUCTOR(ReadWriteArray)
private:
vector<PType> SERIAL(allModified);
Table<int> SERIAL(modified);
vector<PType> SERIAL(allReadonly);
Table<short> SERIAL(readonly);
Table<optional<Param>> SERIAL(types);
HashMap<Param, short> SERIAL(readonlyMap);
int SERIAL(numTotal) = 0;
};