-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoptional_flags.h
More file actions
120 lines (91 loc) · 2.71 KB
/
Copy pathoptional_flags.h
File metadata and controls
120 lines (91 loc) · 2.71 KB
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
#include <experimental/optional>
#include <unordered_map>
using namespace std::experimental;
class optional_flags {
public:
optional_flags() = default;
optional_flags(const optional_flags &) = default;
optional_flags &operator=(const optional_flags &) = default;
bool operator==(const optional_flags &rhs) const {
return engaged == rhs.engaged && (flags & engaged) == (rhs.flags && engaged);
}
bool operator!=(const optional_flags &rhs) const {
return engaged != rhs.engaged || (flags & engaged) != (rhs.flags && engaged);
}
bool operator<(const optional_flags &rhs) const {
if (engaged == rhs.engaged) return (flags & engaged) < (rhs.flags & engaged);
return engaged < rhs.engaged;
}
void reset(uint16_t mask) {
engaged &= ~mask;
}
void rep(uint16_t mask) {
engaged |= mask;
flags &= ~mask;
}
void sep(uint16_t mask) {
engaged |= mask;
flags |= mask;
}
struct proxy {
proxy &operator=(bool tf) {
if (tf) parent.flags |= mask;
else parent.flags &= ~mask;
parent.engaged |= mask;
return *this;
}
proxy &operator=(const std::experimental::nullopt_t) {
parent.engaged &= ~mask;
return *this;
}
operator bool() const {
return parent.engaged & mask;
}
bool operator!() const {
return !(parent.engaged & mask);
}
bool operator*() const {
return parent.flags & mask;
}
bool value() const {
if (parent.engaged & mask)
return parent.flags & mask;
throw std::experimental::bad_optional_access();
}
bool value_or(bool tf) const {
if (parent.engaged & mask)
return parent.flags & mask;
return tf;
}
private:
friend class optional_flags;
proxy(optional_flags &p, unsigned m) : parent(p), mask(m)
{}
optional_flags &parent;
unsigned mask;
};
proxy c() { return proxy(*this, 1 << 0); }
proxy z() { return proxy(*this, 1 << 1); }
proxy i() { return proxy(*this, 1 << 2); }
proxy d() { return proxy(*this, 1 << 3); }
proxy x() { return proxy(*this, 1 << 4); }
proxy m() { return proxy(*this, 1 << 5); }
proxy v() { return proxy(*this, 1 << 6); }
proxy n() { return proxy(*this, 1 << 7); }
proxy e() { return proxy(*this, 1 << 8); }
#if 0
const proxy c() const { return proxy(*this, 1 << 0); }
const proxy z() const { return proxy(*this, 1 << 1); }
const proxy i() const { return proxy(*this, 1 << 2); }
const proxy d() const { return proxy(*this, 1 << 3); }
const proxy x() const { return proxy(*this, 1 << 4); }
const proxy m() const { return proxy(*this, 1 << 5); }
const proxy v() const { return proxy(*this, 1 << 6); }
const proxy n() const { return proxy(*this, 1 << 7); }
const proxy e() const { return proxy(*this, 1 << 8); }
#endif
private:
friend struct proxy;
uint16_t flags = 0;
uint16_t engaged = 0;
};