diff options
-rw-r--r-- | generator/CMakeLists.txt | 2 | ||||
-rw-r--r-- | generator/generator.cpp | 13 | ||||
-rw-r--r-- | generator/generator.h | 7 | ||||
-rw-r--r-- | generator/group.cpp | 5 | ||||
-rw-r--r-- | generator/group.h | 4 | ||||
-rw-r--r-- | generator/lemma.h | 2 | ||||
-rw-r--r-- | generator/notion.h | 2 | ||||
-rw-r--r-- | generator/part.cpp | 1 | ||||
-rw-r--r-- | generator/part.h | 2 | ||||
-rw-r--r-- | generator/role.h | 35 | ||||
-rw-r--r-- | generator/selrestr.cpp | 288 | ||||
-rw-r--r-- | generator/selrestr.h | 88 | ||||
-rw-r--r-- | generator/word.h | 2 | ||||
-rw-r--r-- | lib/role.h | 60 | ||||
-rw-r--r-- | lib/selrestr.cpp | 309 | ||||
-rw-r--r-- | lib/selrestr.h | 90 |
16 files changed, 479 insertions, 431 deletions
diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt index 4f78eb8..5bbd82d 100644 --- a/generator/CMakeLists.txt +++ b/generator/CMakeLists.txt | |||
@@ -6,7 +6,7 @@ pkg_check_modules(sqlite3 sqlite3 REQUIRED) | |||
6 | find_package(libxml2 REQUIRED) | 6 | find_package(libxml2 REQUIRED) |
7 | 7 | ||
8 | include_directories(${sqlite3_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} ../vendor/json) | 8 | include_directories(${sqlite3_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} ../vendor/json) |
9 | add_executable(generator notion.cpp word.cpp lemma.cpp form.cpp pronunciation.cpp group.cpp frame.cpp part.cpp selrestr.cpp database.cpp field.cpp generator.cpp main.cpp) | 9 | add_executable(generator notion.cpp word.cpp lemma.cpp form.cpp pronunciation.cpp group.cpp frame.cpp part.cpp ../lib/selrestr.cpp database.cpp field.cpp generator.cpp main.cpp) |
10 | set_property(TARGET generator PROPERTY CXX_STANDARD 11) | 10 | set_property(TARGET generator PROPERTY CXX_STANDARD 11) |
11 | set_property(TARGET generator PROPERTY CXX_STANDARD_REQUIRED ON) | 11 | set_property(TARGET generator PROPERTY CXX_STANDARD_REQUIRED ON) |
12 | target_link_libraries(generator ${sqlite3_LIBRARIES} ${LIBXML2_LIBRARIES}) | 12 | target_link_libraries(generator ${sqlite3_LIBRARIES} ${LIBXML2_LIBRARIES}) |
diff --git a/generator/generator.cpp b/generator/generator.cpp index d88cb31..16183a2 100644 --- a/generator/generator.cpp +++ b/generator/generator.cpp | |||
@@ -5,10 +5,10 @@ | |||
5 | #include <regex> | 5 | #include <regex> |
6 | #include <dirent.h> | 6 | #include <dirent.h> |
7 | #include <fstream> | 7 | #include <fstream> |
8 | #include "enums.h" | 8 | #include "../lib/enums.h" |
9 | #include "progress.h" | 9 | #include "progress.h" |
10 | #include "selrestr.h" | 10 | #include "../lib/selrestr.h" |
11 | #include "role.h" | 11 | #include "../lib/role.h" |
12 | #include "part.h" | 12 | #include "part.h" |
13 | #include "field.h" | 13 | #include "field.h" |
14 | #include "../lib/util.h" | 14 | #include "../lib/util.h" |
@@ -1290,21 +1290,20 @@ namespace verbly { | |||
1290 | { | 1290 | { |
1291 | if (!xmlStrcmp(roletopnode->name, reinterpret_cast<const xmlChar*>("THEMROLE"))) | 1291 | if (!xmlStrcmp(roletopnode->name, reinterpret_cast<const xmlChar*>("THEMROLE"))) |
1292 | { | 1292 | { |
1293 | role r; | ||
1294 | |||
1295 | key = xmlGetProp(roletopnode, reinterpret_cast<const xmlChar*>("type")); | 1293 | key = xmlGetProp(roletopnode, reinterpret_cast<const xmlChar*>("type")); |
1296 | std::string roleName = reinterpret_cast<const char*>(key); | 1294 | std::string roleName = reinterpret_cast<const char*>(key); |
1297 | xmlFree(key); | 1295 | xmlFree(key); |
1298 | 1296 | ||
1297 | selrestr roleSelrestrs; | ||
1299 | for (xmlNodePtr rolenode = roletopnode->xmlChildrenNode; rolenode != nullptr; rolenode = rolenode->next) | 1298 | for (xmlNodePtr rolenode = roletopnode->xmlChildrenNode; rolenode != nullptr; rolenode = rolenode->next) |
1300 | { | 1299 | { |
1301 | if (!xmlStrcmp(rolenode->name, reinterpret_cast<const xmlChar*>("SELRESTRS"))) | 1300 | if (!xmlStrcmp(rolenode->name, reinterpret_cast<const xmlChar*>("SELRESTRS"))) |
1302 | { | 1301 | { |
1303 | r.setSelrestrs(parseSelrestr(rolenode)); | 1302 | roleSelrestrs = parseSelrestr(rolenode); |
1304 | } | 1303 | } |
1305 | } | 1304 | } |
1306 | 1305 | ||
1307 | grp.addRole(roleName, std::move(r)); | 1306 | grp.addRole({roleName, std::move(roleSelrestrs)}); |
1308 | } | 1307 | } |
1309 | } | 1308 | } |
1310 | } else if (!xmlStrcmp(node->name, reinterpret_cast<const xmlChar*>("FRAMES"))) | 1309 | } else if (!xmlStrcmp(node->name, reinterpret_cast<const xmlChar*>("FRAMES"))) |
diff --git a/generator/generator.h b/generator/generator.h index e2a7404..c829c21 100644 --- a/generator/generator.h +++ b/generator/generator.h | |||
@@ -16,10 +16,11 @@ | |||
16 | #include "frame.h" | 16 | #include "frame.h" |
17 | 17 | ||
18 | namespace verbly { | 18 | namespace verbly { |
19 | |||
20 | enum class part_of_speech; | ||
21 | class selrestr; | ||
22 | |||
19 | namespace generator { | 23 | namespace generator { |
20 | |||
21 | enum class part_of_speech; | ||
22 | class selrestr; | ||
23 | 24 | ||
24 | class generator { | 25 | class generator { |
25 | public: | 26 | public: |
diff --git a/generator/group.cpp b/generator/group.cpp index 7cbd4c8..334c2aa 100644 --- a/generator/group.cpp +++ b/generator/group.cpp | |||
@@ -23,10 +23,11 @@ namespace verbly { | |||
23 | parent_ = &parent; | 23 | parent_ = &parent; |
24 | } | 24 | } |
25 | 25 | ||
26 | void group::addRole(std::string name, role r) | 26 | void group::addRole(role r) |
27 | { | 27 | { |
28 | roleNames_.insert(name); | 28 | std::string name = r.getName(); |
29 | roles_[name] = std::move(r); | 29 | roles_[name] = std::move(r); |
30 | roleNames_.insert(std::move(name)); | ||
30 | } | 31 | } |
31 | 32 | ||
32 | void group::addFrame(const frame& f) | 33 | void group::addFrame(const frame& f) |
diff --git a/generator/group.h b/generator/group.h index efb8c5d..5084ea4 100644 --- a/generator/group.h +++ b/generator/group.h | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <set> | 5 | #include <set> |
6 | #include <string> | 6 | #include <string> |
7 | #include <cassert> | 7 | #include <cassert> |
8 | #include "role.h" | 8 | #include "../lib/role.h" |
9 | 9 | ||
10 | namespace verbly { | 10 | namespace verbly { |
11 | namespace generator { | 11 | namespace generator { |
@@ -24,7 +24,7 @@ namespace verbly { | |||
24 | 24 | ||
25 | void setParent(const group& parent); | 25 | void setParent(const group& parent); |
26 | 26 | ||
27 | void addRole(std::string name, role r); | 27 | void addRole(role r); |
28 | 28 | ||
29 | void addFrame(const frame& f); | 29 | void addFrame(const frame& f); |
30 | 30 | ||
diff --git a/generator/lemma.h b/generator/lemma.h index 6452e08..f68667f 100644 --- a/generator/lemma.h +++ b/generator/lemma.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <string> | 4 | #include <string> |
5 | #include <map> | 5 | #include <map> |
6 | #include <set> | 6 | #include <set> |
7 | #include "enums.h" | 7 | #include "../lib/enums.h" |
8 | 8 | ||
9 | namespace verbly { | 9 | namespace verbly { |
10 | namespace generator { | 10 | namespace generator { |
diff --git a/generator/notion.h b/generator/notion.h index 76210de..cc64c48 100644 --- a/generator/notion.h +++ b/generator/notion.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <cassert> | 4 | #include <cassert> |
5 | #include <list> | 5 | #include <list> |
6 | #include <string> | 6 | #include <string> |
7 | #include "enums.h" | 7 | #include "../lib/enums.h" |
8 | 8 | ||
9 | namespace verbly { | 9 | namespace verbly { |
10 | namespace generator { | 10 | namespace generator { |
diff --git a/generator/part.cpp b/generator/part.cpp index dbd4e11..b69ec65 100644 --- a/generator/part.cpp +++ b/generator/part.cpp | |||
@@ -1,6 +1,5 @@ | |||
1 | #include "part.h" | 1 | #include "part.h" |
2 | #include <stdexcept> | 2 | #include <stdexcept> |
3 | #include "selrestr.h" | ||
4 | 3 | ||
5 | namespace verbly { | 4 | namespace verbly { |
6 | namespace generator { | 5 | namespace generator { |
diff --git a/generator/part.h b/generator/part.h index d044630..86d5d57 100644 --- a/generator/part.h +++ b/generator/part.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #include <string> | 4 | #include <string> |
5 | #include <set> | 5 | #include <set> |
6 | #include "selrestr.h" | 6 | #include "../lib/selrestr.h" |
7 | 7 | ||
8 | namespace verbly { | 8 | namespace verbly { |
9 | namespace generator { | 9 | namespace generator { |
diff --git a/generator/role.h b/generator/role.h deleted file mode 100644 index 5fa68b8..0000000 --- a/generator/role.h +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | #ifndef ROLE_H_249F9A9C | ||
2 | #define ROLE_H_249F9A9C | ||
3 | |||
4 | #include "selrestr.h" | ||
5 | |||
6 | namespace verbly { | ||
7 | namespace generator { | ||
8 | |||
9 | class role { | ||
10 | public: | ||
11 | |||
12 | // Mutators | ||
13 | |||
14 | void setSelrestrs(selrestr selrestrs) | ||
15 | { | ||
16 | selrestrs_ = selrestrs; | ||
17 | } | ||
18 | |||
19 | // Accessors | ||
20 | |||
21 | const selrestr& getSelrestrs() const | ||
22 | { | ||
23 | return selrestrs_; | ||
24 | } | ||
25 | |||
26 | private: | ||
27 | |||
28 | selrestr selrestrs_; | ||
29 | |||
30 | }; | ||
31 | |||
32 | }; | ||
33 | }; | ||
34 | |||
35 | #endif /* end of include guard: ROLE_H_249F9A9C */ | ||
diff --git a/generator/selrestr.cpp b/generator/selrestr.cpp deleted file mode 100644 index 8bdd3f6..0000000 --- a/generator/selrestr.cpp +++ /dev/null | |||
@@ -1,288 +0,0 @@ | |||
1 | #include "selrestr.h" | ||
2 | |||
3 | namespace verbly { | ||
4 | namespace generator { | ||
5 | |||
6 | selrestr::selrestr(const selrestr& other) | ||
7 | { | ||
8 | type_ = other.type_; | ||
9 | |||
10 | switch (type_) | ||
11 | { | ||
12 | case type::singleton: | ||
13 | { | ||
14 | singleton_.pos = other.singleton_.pos; | ||
15 | new(&singleton_.restriction) std::string(other.singleton_.restriction); | ||
16 | |||
17 | break; | ||
18 | } | ||
19 | |||
20 | case type::group: | ||
21 | { | ||
22 | new(&group_.children) std::list<selrestr>(other.group_.children); | ||
23 | group_.orlogic = other.group_.orlogic; | ||
24 | |||
25 | break; | ||
26 | } | ||
27 | |||
28 | case type::empty: | ||
29 | { | ||
30 | break; | ||
31 | } | ||
32 | } | ||
33 | } | ||
34 | |||
35 | selrestr::selrestr(selrestr&& other) : selrestr() | ||
36 | { | ||
37 | swap(*this, other); | ||
38 | } | ||
39 | |||
40 | selrestr& selrestr::operator=(selrestr other) | ||
41 | { | ||
42 | swap(*this, other); | ||
43 | |||
44 | return *this; | ||
45 | } | ||
46 | |||
47 | void swap(selrestr& first, selrestr& second) | ||
48 | { | ||
49 | using type = selrestr::type; | ||
50 | |||
51 | type tempType = first.type_; | ||
52 | int tempPos; | ||
53 | std::string tempRestriction; | ||
54 | std::list<selrestr> tempChildren; | ||
55 | bool tempOrlogic; | ||
56 | |||
57 | switch (tempType) | ||
58 | { | ||
59 | case type::singleton: | ||
60 | { | ||
61 | tempPos = first.singleton_.pos; | ||
62 | tempRestriction = std::move(first.singleton_.restriction); | ||
63 | |||
64 | break; | ||
65 | } | ||
66 | |||
67 | case type::group: | ||
68 | { | ||
69 | tempChildren = std::move(first.group_.children); | ||
70 | tempOrlogic = first.group_.orlogic; | ||
71 | |||
72 | break; | ||
73 | } | ||
74 | |||
75 | case type::empty: | ||
76 | { | ||
77 | break; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | first.~selrestr(); | ||
82 | |||
83 | first.type_ = second.type_; | ||
84 | |||
85 | switch (first.type_) | ||
86 | { | ||
87 | case type::singleton: | ||
88 | { | ||
89 | first.singleton_.pos = second.singleton_.pos; | ||
90 | new(&first.singleton_.restriction) std::string(std::move(second.singleton_.restriction)); | ||
91 | |||
92 | break; | ||
93 | } | ||
94 | |||
95 | case type::group: | ||
96 | { | ||
97 | new(&first.group_.children) std::list<selrestr>(std::move(second.group_.children)); | ||
98 | first.group_.orlogic = second.group_.orlogic; | ||
99 | |||
100 | break; | ||
101 | } | ||
102 | |||
103 | case type::empty: | ||
104 | { | ||
105 | break; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | second.~selrestr(); | ||
110 | |||
111 | second.type_ = tempType; | ||
112 | |||
113 | switch (second.type_) | ||
114 | { | ||
115 | case type::singleton: | ||
116 | { | ||
117 | second.singleton_.pos = tempPos; | ||
118 | new(&second.singleton_.restriction) std::string(std::move(tempRestriction)); | ||
119 | |||
120 | break; | ||
121 | } | ||
122 | |||
123 | case type::group: | ||
124 | { | ||
125 | new(&second.group_.children) std::list<selrestr>(std::move(tempChildren)); | ||
126 | second.group_.orlogic = tempOrlogic; | ||
127 | |||
128 | break; | ||
129 | } | ||
130 | |||
131 | case type::empty: | ||
132 | { | ||
133 | break; | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | |||
138 | selrestr::~selrestr() | ||
139 | { | ||
140 | switch (type_) | ||
141 | { | ||
142 | case type::singleton: | ||
143 | { | ||
144 | using string_type = std::string; | ||
145 | singleton_.restriction.~string_type(); | ||
146 | |||
147 | break; | ||
148 | } | ||
149 | |||
150 | case type::group: | ||
151 | { | ||
152 | using list_type = std::list<selrestr>; | ||
153 | group_.children.~list_type(); | ||
154 | |||
155 | break; | ||
156 | } | ||
157 | |||
158 | case type::empty: | ||
159 | { | ||
160 | break; | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | |||
165 | selrestr::selrestr() : type_(type::empty) | ||
166 | { | ||
167 | } | ||
168 | |||
169 | selrestr::selrestr( | ||
170 | std::string restriction, | ||
171 | bool pos) : | ||
172 | type_(type::singleton) | ||
173 | { | ||
174 | new(&singleton_.restriction) std::string(std::move(restriction)); | ||
175 | singleton_.pos = pos; | ||
176 | } | ||
177 | |||
178 | std::string selrestr::getRestriction() const | ||
179 | { | ||
180 | if (type_ == type::singleton) | ||
181 | { | ||
182 | return singleton_.restriction; | ||
183 | } else { | ||
184 | throw std::domain_error("Only singleton selrestrs have restrictions"); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | bool selrestr::getPos() const | ||
189 | { | ||
190 | if (type_ == type::singleton) | ||
191 | { | ||
192 | return singleton_.pos; | ||
193 | } else { | ||
194 | throw std::domain_error("Only singleton selrestrs have positivity flags"); | ||
195 | } | ||
196 | } | ||
197 | |||
198 | selrestr::selrestr( | ||
199 | std::list<selrestr> children, | ||
200 | bool orlogic) : | ||
201 | type_(type::group) | ||
202 | { | ||
203 | new(&group_.children) std::list<selrestr>(std::move(children)); | ||
204 | group_.orlogic = orlogic; | ||
205 | } | ||
206 | |||
207 | std::list<selrestr> selrestr::getChildren() const | ||
208 | { | ||
209 | if (type_ == type::group) | ||
210 | { | ||
211 | return group_.children; | ||
212 | } else { | ||
213 | throw std::domain_error("Only group selrestrs have children"); | ||
214 | } | ||
215 | } | ||
216 | |||
217 | std::list<selrestr>::const_iterator selrestr::begin() const | ||
218 | { | ||
219 | if (type_ == type::group) | ||
220 | { | ||
221 | return std::begin(group_.children); | ||
222 | } else { | ||
223 | throw std::domain_error("Only group selrestrs have children"); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | std::list<selrestr>::const_iterator selrestr::end() const | ||
228 | { | ||
229 | if (type_ == type::group) | ||
230 | { | ||
231 | return std::end(group_.children); | ||
232 | } else { | ||
233 | throw std::domain_error("Only group selrestrs have children"); | ||
234 | } | ||
235 | } | ||
236 | |||
237 | bool selrestr::getOrlogic() const | ||
238 | { | ||
239 | if (type_ == type::group) | ||
240 | { | ||
241 | return group_.orlogic; | ||
242 | } else { | ||
243 | throw std::domain_error("Only group selrestrs have logic"); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | nlohmann::json selrestr::toJson() const | ||
248 | { | ||
249 | switch (type_) | ||
250 | { | ||
251 | case type::empty: | ||
252 | { | ||
253 | return {}; | ||
254 | } | ||
255 | |||
256 | case type::singleton: | ||
257 | { | ||
258 | return { | ||
259 | {"type", singleton_.restriction}, | ||
260 | {"pos", singleton_.pos} | ||
261 | }; | ||
262 | } | ||
263 | |||
264 | case type::group: | ||
265 | { | ||
266 | std::string logic; | ||
267 | if (group_.orlogic) | ||
268 | { | ||
269 | logic = "or"; | ||
270 | } else { | ||
271 | logic = "and"; | ||
272 | } | ||
273 | |||
274 | std::list<nlohmann::json> children; | ||
275 | std::transform(std::begin(group_.children), std::end(group_.children), std::back_inserter(children), [] (const selrestr& child) { | ||
276 | return child.toJson(); | ||
277 | }); | ||
278 | |||
279 | return { | ||
280 | {"logic", logic}, | ||
281 | {"children", children} | ||
282 | }; | ||
283 | } | ||
284 | } | ||
285 | } | ||
286 | |||
287 | }; | ||
288 | }; | ||
diff --git a/generator/selrestr.h b/generator/selrestr.h deleted file mode 100644 index 5000970..0000000 --- a/generator/selrestr.h +++ /dev/null | |||
@@ -1,88 +0,0 @@ | |||
1 | #ifndef SELRESTR_H_50652FB7 | ||
2 | #define SELRESTR_H_50652FB7 | ||
3 | |||
4 | #include <list> | ||
5 | #include <string> | ||
6 | #include <json.hpp> | ||
7 | |||
8 | namespace verbly { | ||
9 | namespace generator { | ||
10 | |||
11 | class selrestr { | ||
12 | public: | ||
13 | enum class type { | ||
14 | empty, | ||
15 | singleton, | ||
16 | group | ||
17 | }; | ||
18 | |||
19 | // Copy and move constructors | ||
20 | |||
21 | selrestr(const selrestr& other); | ||
22 | selrestr(selrestr&& other); | ||
23 | |||
24 | // Assignment | ||
25 | |||
26 | selrestr& operator=(selrestr other); | ||
27 | |||
28 | // Swap | ||
29 | |||
30 | friend void swap(selrestr& first, selrestr& second); | ||
31 | |||
32 | // Destructor | ||
33 | |||
34 | ~selrestr(); | ||
35 | |||
36 | // Generic accessors | ||
37 | |||
38 | type getType() const | ||
39 | { | ||
40 | return type_; | ||
41 | } | ||
42 | |||
43 | // Empty | ||
44 | |||
45 | selrestr(); | ||
46 | |||
47 | // Singleton | ||
48 | |||
49 | selrestr(std::string restriction, bool pos); | ||
50 | |||
51 | std::string getRestriction() const; | ||
52 | |||
53 | bool getPos() const; | ||
54 | |||
55 | // Group | ||
56 | |||
57 | selrestr(std::list<selrestr> children, bool orlogic); | ||
58 | |||
59 | std::list<selrestr> getChildren() const; | ||
60 | |||
61 | std::list<selrestr>::const_iterator begin() const; | ||
62 | |||
63 | std::list<selrestr>::const_iterator end() const; | ||
64 | |||
65 | bool getOrlogic() const; | ||
66 | |||
67 | // Helpers | ||
68 | |||
69 | nlohmann::json toJson() const; | ||
70 | |||
71 | private: | ||
72 | union { | ||
73 | struct { | ||
74 | bool pos; | ||
75 | std::string restriction; | ||
76 | } singleton_; | ||
77 | struct { | ||
78 | std::list<selrestr> children; | ||
79 | bool orlogic; | ||
80 | } group_; | ||
81 | }; | ||
82 | type type_; | ||
83 | }; | ||
84 | |||
85 | }; | ||
86 | }; | ||
87 | |||
88 | #endif /* end of include guard: SELRESTR_H_50652FB7 */ | ||
diff --git a/generator/word.h b/generator/word.h index bfed586..1d77ed3 100644 --- a/generator/word.h +++ b/generator/word.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #define WORD_H_91F99D46 | 2 | #define WORD_H_91F99D46 |
3 | 3 | ||
4 | #include <cassert> | 4 | #include <cassert> |
5 | #include "enums.h" | 5 | #include "../lib/enums.h" |
6 | 6 | ||
7 | namespace verbly { | 7 | namespace verbly { |
8 | namespace generator { | 8 | namespace generator { |
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 */ | ||