diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/role.h | 60 | ||||
-rw-r--r-- | lib/selrestr.cpp | 309 | ||||
-rw-r--r-- | lib/selrestr.h | 90 |
3 files changed, 459 insertions, 0 deletions
diff --git a/lib/role.h b/lib/role.h new file mode 100644 index 0000000..8653710 --- /dev/null +++ b/lib/role.h | |||
@@ -0,0 +1,60 @@ | |||
1 | #ifndef ROLE_H_249F9A9C | ||
2 | #define ROLE_H_249F9A9C | ||
3 | |||
4 | #include <stdexcept> | ||
5 | #include <string> | ||
6 | #include "../lib/selrestr.h" | ||
7 | |||
8 | namespace verbly { | ||
9 | |||
10 | class role { | ||
11 | public: | ||
12 | |||
13 | // Default constructor | ||
14 | |||
15 | role() = default; | ||
16 | |||
17 | // Constructor | ||
18 | |||
19 | role( | ||
20 | std::string name, | ||
21 | selrestr selrestrs = {}) : | ||
22 | valid_(true), | ||
23 | name_(name), | ||
24 | selrestrs_(selrestrs) | ||
25 | { | ||
26 | } | ||
27 | |||
28 | // Accessors | ||
29 | |||
30 | const std::string& getName() const | ||
31 | { | ||
32 | if (!valid_) | ||
33 | { | ||
34 | throw std::domain_error("Bad access to invalid role"); | ||
35 | } | ||
36 | |||
37 | return name_; | ||
38 | } | ||
39 | |||
40 | const selrestr& getSelrestrs() const | ||
41 | { | ||
42 | if (!valid_) | ||
43 | { | ||
44 | throw std::domain_error("Bad access to invalid role"); | ||
45 | } | ||
46 | |||
47 | return selrestrs_; | ||
48 | } | ||
49 | |||
50 | private: | ||
51 | |||
52 | bool valid_ = false; | ||
53 | std::string name_; | ||
54 | selrestr selrestrs_; | ||
55 | |||
56 | }; | ||
57 | |||
58 | }; | ||
59 | |||
60 | #endif /* end of include guard: ROLE_H_249F9A9C */ | ||
diff --git a/lib/selrestr.cpp b/lib/selrestr.cpp new file mode 100644 index 0000000..74ea726 --- /dev/null +++ b/lib/selrestr.cpp | |||
@@ -0,0 +1,309 @@ | |||
1 | #include "selrestr.h" | ||
2 | |||
3 | namespace verbly { | ||
4 | |||
5 | selrestr::selrestr(nlohmann::json data) | ||
6 | { | ||
7 | if (data.find("children") != data.end()) | ||
8 | { | ||
9 | type_ = type::group; | ||
10 | new(&group_.children) std::list<selrestr>(); | ||
11 | |||
12 | for (const nlohmann::json& child : data["children"]) | ||
13 | { | ||
14 | group_.children.emplace_back(child); | ||
15 | } | ||
16 | |||
17 | group_.orlogic = (data["logic"] == "or"); | ||
18 | } else if (data.find("type") != data.end()) | ||
19 | { | ||
20 | type_ = type::singleton; | ||
21 | singleton_.pos = data["pos"].get<bool>(); | ||
22 | new(&singleton_.restriction) std::string(data["type"].get<std::string>()); | ||
23 | } else { | ||
24 | type_ = type::empty; | ||
25 | } | ||
26 | } | ||
27 | |||
28 | selrestr::selrestr(const selrestr& other) | ||
29 | { | ||
30 | type_ = other.type_; | ||
31 | |||
32 | switch (type_) | ||
33 | { | ||
34 | case type::singleton: | ||
35 | { | ||
36 | singleton_.pos = other.singleton_.pos; | ||
37 | new(&singleton_.restriction) std::string(other.singleton_.restriction); | ||
38 | |||
39 | break; | ||
40 | } | ||
41 | |||
42 | case type::group: | ||
43 | { | ||
44 | new(&group_.children) std::list<selrestr>(other.group_.children); | ||
45 | group_.orlogic = other.group_.orlogic; | ||
46 | |||
47 | break; | ||
48 | } | ||
49 | |||
50 | case type::empty: | ||
51 | { | ||
52 | break; | ||
53 | } | ||
54 | } | ||
55 | } | ||
56 | |||
57 | selrestr::selrestr(selrestr&& other) : selrestr() | ||
58 | { | ||
59 | swap(*this, other); | ||
60 | } | ||
61 | |||
62 | selrestr& selrestr::operator=(selrestr other) | ||
63 | { | ||
64 | swap(*this, other); | ||
65 | |||
66 | return *this; | ||
67 | } | ||
68 | |||
69 | void swap(selrestr& first, selrestr& second) | ||
70 | { | ||
71 | using type = selrestr::type; | ||
72 | |||
73 | type tempType = first.type_; | ||
74 | int tempPos; | ||
75 | std::string tempRestriction; | ||
76 | std::list<selrestr> tempChildren; | ||
77 | bool tempOrlogic; | ||
78 | |||
79 | switch (tempType) | ||
80 | { | ||
81 | case type::singleton: | ||
82 | { | ||
83 | tempPos = first.singleton_.pos; | ||
84 | tempRestriction = std::move(first.singleton_.restriction); | ||
85 | |||
86 | break; | ||
87 | } | ||
88 | |||
89 | case type::group: | ||
90 | { | ||
91 | tempChildren = std::move(first.group_.children); | ||
92 | tempOrlogic = first.group_.orlogic; | ||
93 | |||
94 | break; | ||
95 | } | ||
96 | |||
97 | case type::empty: | ||
98 | { | ||
99 | break; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | first.~selrestr(); | ||
104 | |||
105 | first.type_ = second.type_; | ||
106 | |||
107 | switch (first.type_) | ||
108 | { | ||
109 | case type::singleton: | ||
110 | { | ||
111 | first.singleton_.pos = second.singleton_.pos; | ||
112 | new(&first.singleton_.restriction) std::string(std::move(second.singleton_.restriction)); | ||
113 | |||
114 | break; | ||
115 | } | ||
116 | |||
117 | case type::group: | ||
118 | { | ||
119 | new(&first.group_.children) std::list<selrestr>(std::move(second.group_.children)); | ||
120 | first.group_.orlogic = second.group_.orlogic; | ||
121 | |||
122 | break; | ||
123 | } | ||
124 | |||
125 | case type::empty: | ||
126 | { | ||
127 | break; | ||
128 | } | ||
129 | } | ||
130 | |||
131 | second.~selrestr(); | ||
132 | |||
133 | second.type_ = tempType; | ||
134 | |||
135 | switch (second.type_) | ||
136 | { | ||
137 | case type::singleton: | ||
138 | { | ||
139 | second.singleton_.pos = tempPos; | ||
140 | new(&second.singleton_.restriction) std::string(std::move(tempRestriction)); | ||
141 | |||
142 | break; | ||
143 | } | ||
144 | |||
145 | case type::group: | ||
146 | { | ||
147 | new(&second.group_.children) std::list<selrestr>(std::move(tempChildren)); | ||
148 | second.group_.orlogic = tempOrlogic; | ||
149 | |||
150 | break; | ||
151 | } | ||
152 | |||
153 | case type::empty: | ||
154 | { | ||
155 | break; | ||
156 | } | ||
157 | } | ||
158 | } | ||
159 | |||
160 | selrestr::~selrestr() | ||
161 | { | ||
162 | switch (type_) | ||
163 | { | ||
164 | case type::singleton: | ||
165 | { | ||
166 | using string_type = std::string; | ||
167 | singleton_.restriction.~string_type(); | ||
168 | |||
169 | break; | ||
170 | } | ||
171 | |||
172 | case type::group: | ||
173 | { | ||
174 | using list_type = std::list<selrestr>; | ||
175 | group_.children.~list_type(); | ||
176 | |||
177 | break; | ||
178 | } | ||
179 | |||
180 | case type::empty: | ||
181 | { | ||
182 | break; | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | |||
187 | selrestr::selrestr() : type_(type::empty) | ||
188 | { | ||
189 | } | ||
190 | |||
191 | selrestr::selrestr( | ||
192 | std::string restriction, | ||
193 | bool pos) : | ||
194 | type_(type::singleton) | ||
195 | { | ||
196 | new(&singleton_.restriction) std::string(std::move(restriction)); | ||
197 | singleton_.pos = pos; | ||
198 | } | ||
199 | |||
200 | std::string selrestr::getRestriction() const | ||
201 | { | ||
202 | if (type_ == type::singleton) | ||
203 | { | ||
204 | return singleton_.restriction; | ||
205 | } else { | ||
206 | throw std::domain_error("Only singleton selrestrs have restrictions"); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | bool selrestr::getPos() const | ||
211 | { | ||
212 | if (type_ == type::singleton) | ||
213 | { | ||
214 | return singleton_.pos; | ||
215 | } else { | ||
216 | throw std::domain_error("Only singleton selrestrs have positivity flags"); | ||
217 | } | ||
218 | } | ||
219 | |||
220 | selrestr::selrestr( | ||
221 | std::list<selrestr> children, | ||
222 | bool orlogic) : | ||
223 | type_(type::group) | ||
224 | { | ||
225 | new(&group_.children) std::list<selrestr>(std::move(children)); | ||
226 | group_.orlogic = orlogic; | ||
227 | } | ||
228 | |||
229 | std::list<selrestr> selrestr::getChildren() const | ||
230 | { | ||
231 | if (type_ == type::group) | ||
232 | { | ||
233 | return group_.children; | ||
234 | } else { | ||
235 | throw std::domain_error("Only group selrestrs have children"); | ||
236 | } | ||
237 | } | ||
238 | |||
239 | std::list<selrestr>::const_iterator selrestr::begin() const | ||
240 | { | ||
241 | if (type_ == type::group) | ||
242 | { | ||
243 | return std::begin(group_.children); | ||
244 | } else { | ||
245 | throw std::domain_error("Only group selrestrs have children"); | ||
246 | } | ||
247 | } | ||
248 | |||
249 | std::list<selrestr>::const_iterator selrestr::end() const | ||
250 | { | ||
251 | if (type_ == type::group) | ||
252 | { | ||
253 | return std::end(group_.children); | ||
254 | } else { | ||
255 | throw std::domain_error("Only group selrestrs have children"); | ||
256 | } | ||
257 | } | ||
258 | |||
259 | bool selrestr::getOrlogic() const | ||
260 | { | ||
261 | if (type_ == type::group) | ||
262 | { | ||
263 | return group_.orlogic; | ||
264 | } else { | ||
265 | throw std::domain_error("Only group selrestrs have logic"); | ||
266 | } | ||
267 | } | ||
268 | |||
269 | nlohmann::json selrestr::toJson() const | ||
270 | { | ||
271 | switch (type_) | ||
272 | { | ||
273 | case type::empty: | ||
274 | { | ||
275 | return {}; | ||
276 | } | ||
277 | |||
278 | case type::singleton: | ||
279 | { | ||
280 | return { | ||
281 | {"type", singleton_.restriction}, | ||
282 | {"pos", singleton_.pos} | ||
283 | }; | ||
284 | } | ||
285 | |||
286 | case type::group: | ||
287 | { | ||
288 | std::string logic; | ||
289 | if (group_.orlogic) | ||
290 | { | ||
291 | logic = "or"; | ||
292 | } else { | ||
293 | logic = "and"; | ||
294 | } | ||
295 | |||
296 | std::list<nlohmann::json> children; | ||
297 | std::transform(std::begin(group_.children), std::end(group_.children), std::back_inserter(children), [] (const selrestr& child) { | ||
298 | return child.toJson(); | ||
299 | }); | ||
300 | |||
301 | return { | ||
302 | {"logic", logic}, | ||
303 | {"children", children} | ||
304 | }; | ||
305 | } | ||
306 | } | ||
307 | } | ||
308 | |||
309 | }; | ||
diff --git a/lib/selrestr.h b/lib/selrestr.h new file mode 100644 index 0000000..9f82e3e --- /dev/null +++ b/lib/selrestr.h | |||
@@ -0,0 +1,90 @@ | |||
1 | #ifndef SELRESTR_H_50652FB7 | ||
2 | #define SELRESTR_H_50652FB7 | ||
3 | |||
4 | #include <list> | ||
5 | #include <string> | ||
6 | #include "../vendor/json/json.hpp" | ||
7 | |||
8 | namespace verbly { | ||
9 | |||
10 | class selrestr { | ||
11 | public: | ||
12 | enum class type { | ||
13 | empty, | ||
14 | singleton, | ||
15 | group | ||
16 | }; | ||
17 | |||
18 | // Construct from json | ||
19 | |||
20 | explicit selrestr(nlohmann::json json); | ||
21 | |||
22 | // Copy and move constructors | ||
23 | |||
24 | selrestr(const selrestr& other); | ||
25 | selrestr(selrestr&& other); | ||
26 | |||
27 | // Assignment | ||
28 | |||
29 | selrestr& operator=(selrestr other); | ||
30 | |||
31 | // Swap | ||
32 | |||
33 | friend void swap(selrestr& first, selrestr& second); | ||
34 | |||
35 | // Destructor | ||
36 | |||
37 | ~selrestr(); | ||
38 | |||
39 | // Generic accessors | ||
40 | |||
41 | type getType() const | ||
42 | { | ||
43 | return type_; | ||
44 | } | ||
45 | |||
46 | // Empty | ||
47 | |||
48 | selrestr(); | ||
49 | |||
50 | // Singleton | ||
51 | |||
52 | selrestr(std::string restriction, bool pos); | ||
53 | |||
54 | std::string getRestriction() const; | ||
55 | |||
56 | bool getPos() const; | ||
57 | |||
58 | // Group | ||
59 | |||
60 | selrestr(std::list<selrestr> children, bool orlogic); | ||
61 | |||
62 | std::list<selrestr> getChildren() const; | ||
63 | |||
64 | std::list<selrestr>::const_iterator begin() const; | ||
65 | |||
66 | std::list<selrestr>::const_iterator end() const; | ||
67 | |||
68 | bool getOrlogic() const; | ||
69 | |||
70 | // Helpers | ||
71 | |||
72 | nlohmann::json toJson() const; | ||
73 | |||
74 | private: | ||
75 | union { | ||
76 | struct { | ||
77 | bool pos; | ||
78 | std::string restriction; | ||
79 | } singleton_; | ||
80 | struct { | ||
81 | std::list<selrestr> children; | ||
82 | bool orlogic; | ||
83 | } group_; | ||
84 | }; | ||
85 | type type_; | ||
86 | }; | ||
87 | |||
88 | }; | ||
89 | |||
90 | #endif /* end of include guard: SELRESTR_H_50652FB7 */ | ||