/
raw.hpp
144 lines (113 loc) · 2.58 KB
/
raw.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#ifndef R_UM_HDR_RAW
#define R_UM_HDR_RAW
#include <cstring>
#include "um.hpp"
#include "log.hpp"
R_UM_NS_START
class RawBlock {
friend class TestSuite;
friend class LazyBlock;
protected:
RawBlock(Word blockSize): refcnt_(1), size_(blockSize),
block_(new Word[size_]) {
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
assert(isValidSize());
assert(isValidBlock());
#endif
std::memset(block_, 0, size_ * sizeof(Word));
}
RawBlock(const RawBlock &sourceBlock): refcnt_(1),
size_(sourceBlock.size_), block_(new Word[size_]) {
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
assert(isValidSize());
assert(isValidBlock());
assert(sourceBlock.isValidBlock());
assert(size_ == sourceBlock.size_);
#endif
std::memcpy(block_, sourceBlock.block_,
size_ * sizeof(Word));
}
~RawBlock() {
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
assert(isValidBlock());
assert(! isValidRefcnt());
#endif
delete[] block_;
}
const Word &operator[](Word offset) const {
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
assert(isWithinBounds(offset));
assert(isReadable());
#endif
return block_[offset];
}
Word &operator[](Word offset) {
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
assert(isWithinBounds(offset));
assert(isWritable());
#endif
return block_[offset];
}
void grab() {
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
assert(isValidRefcnt());
#endif
++ refcnt_;
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
assert(isValidRefcnt());
#endif
}
void release() {
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
assert(isValidRefcnt());
#endif
if (! (-- refcnt_)) delete this;
}
bool isReadable() const {
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
assert(isValidRefcnt());
assert(isValidBlock());
#endif
return true;
}
bool isWritable() const {
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
assert(isReadable());
#endif
return refcnt_ == 1;
}
private:
bool isValidRefcnt() const {
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
return refcnt_ > 0;
#else
return false;
#endif
}
bool isValidSize() const {
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
return true;
#else
return false;
#endif
}
bool isValidBlock() const {
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
return block_ != NULL;
#else
return false;
#endif
}
bool isWithinBounds(Word offset) const {
#ifdef R_UM_OPT_ENFORCE_LOWLEV_VALIDITY
return offset < size_;
#else
return offset && false;
#endif
}
Word refcnt_;
Word size_;
Word *block_;
};
R_UM_NS_END
#endif