summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/role.h60
-rw-r--r--lib/selrestr.cpp309
-rw-r--r--lib/selrestr.h90
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
8namespace 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
3namespace 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
8namespace 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 */