summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--generator/CMakeLists.txt2
-rw-r--r--generator/generator.cpp13
-rw-r--r--generator/generator.h7
-rw-r--r--generator/group.cpp5
-rw-r--r--generator/group.h4
-rw-r--r--generator/lemma.h2
-rw-r--r--generator/notion.h2
-rw-r--r--generator/part.cpp1
-rw-r--r--generator/part.h2
-rw-r--r--generator/role.h35
-rw-r--r--generator/selrestr.cpp288
-rw-r--r--generator/selrestr.h88
-rw-r--r--generator/word.h2
-rw-r--r--lib/role.h60
-rw-r--r--lib/selrestr.cpp309
-rw-r--r--lib/selrestr.h90
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)
6find_package(libxml2 REQUIRED) 6find_package(libxml2 REQUIRED)
7 7
8include_directories(${sqlite3_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} ../vendor/json) 8include_directories(${sqlite3_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} ../vendor/json)
9add_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) 9add_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)
10set_property(TARGET generator PROPERTY CXX_STANDARD 11) 10set_property(TARGET generator PROPERTY CXX_STANDARD 11)
11set_property(TARGET generator PROPERTY CXX_STANDARD_REQUIRED ON) 11set_property(TARGET generator PROPERTY CXX_STANDARD_REQUIRED ON)
12target_link_libraries(generator ${sqlite3_LIBRARIES} ${LIBXML2_LIBRARIES}) 12target_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
18namespace verbly { 18namespace 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
10namespace verbly { 10namespace 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
9namespace verbly { 9namespace 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
9namespace verbly { 9namespace 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
5namespace verbly { 4namespace 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
8namespace verbly { 8namespace 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
6namespace 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
3namespace 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
8namespace 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
7namespace verbly { 7namespace 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
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 */