summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--generator/part.cpp305
-rw-r--r--generator/part.h88
2 files changed, 73 insertions, 320 deletions
diff --git a/generator/part.cpp b/generator/part.cpp index d3e6656..c354a07 100644 --- a/generator/part.cpp +++ b/generator/part.cpp
@@ -8,13 +8,11 @@ namespace verbly {
8 8
9 part part::createNounPhrase(std::string role, std::set<std::string> selrestrs, std::set<std::string> synrestrs) 9 part part::createNounPhrase(std::string role, std::set<std::string> selrestrs, std::set<std::string> synrestrs)
10 { 10 {
11 part p(type::noun_phrase); 11 return part(type::noun_phrase, noun_phrase_type {
12 12 .role = std::move(role),
13 new(&p.noun_phrase_.role) std::string(std::move(role)); 13 .selrestrs = std::move(selrestrs),
14 new(&p.noun_phrase_.selrestrs) std::set<std::string>(std::move(selrestrs)); 14 .synrestrs = std::move(synrestrs)
15 new(&p.noun_phrase_.synrestrs) std::set<std::string>(std::move(synrestrs)); 15 });
16
17 return p;
18 } 16 }
19 17
20 part part::createVerb() 18 part part::createVerb()
@@ -24,12 +22,10 @@ namespace verbly {
24 22
25 part part::createPreposition(std::set<std::string> choices, bool literal) 23 part part::createPreposition(std::set<std::string> choices, bool literal)
26 { 24 {
27 part p(type::preposition); 25 return part(type::preposition, preposition_type {
28 26 .choices = std::move(choices),
29 new(&p.preposition_.choices) std::set<std::string>(std::move(choices)); 27 .literal = literal
30 p.preposition_.literal = literal; 28 });
31
32 return p;
33 } 29 }
34 30
35 part part::createAdjective() 31 part part::createAdjective()
@@ -44,286 +40,19 @@ namespace verbly {
44 40
45 part part::createLiteral(std::string value) 41 part part::createLiteral(std::string value)
46 { 42 {
47 part p(type::literal); 43 return part(type::literal, std::move(value));
48
49 new(&p.literal_) std::string(std::move(value));
50
51 return p;
52 } 44 }
53 45
54 part part::duplicate(const part& other) 46 part part::duplicate(const part& other)
55 { 47 {
56 part result(other.type_); 48 return part(other.type_, other.variant_);
57
58 switch (result.type_)
59 {
60 case type::noun_phrase:
61 {
62 new(&result.noun_phrase_.role) std::string(other.noun_phrase_.role);
63 new(&result.noun_phrase_.selrestrs) std::set<std::string>(other.noun_phrase_.selrestrs);
64 new(&result.noun_phrase_.synrestrs) std::set<std::string>(other.noun_phrase_.synrestrs);
65
66 break;
67 }
68
69 case type::preposition:
70 {
71 new(&result.preposition_.choices) std::set<std::string>(other.preposition_.choices);
72 result.preposition_.literal = other.preposition_.literal;
73
74 break;
75 }
76
77 case type::literal:
78 {
79 new(&result.literal_) std::string(other.literal_);
80
81 break;
82 }
83
84 case type::verb:
85 case type::adjective:
86 case type::adverb:
87 case type::invalid:
88 {
89 break;
90 }
91 }
92
93 return result;
94 }
95
96 part::part(const part& other)
97 {
98 type_ = other.type_;
99 id_ = other.id_;
100
101 switch (type_)
102 {
103 case type::noun_phrase:
104 {
105 new(&noun_phrase_.role) std::string(other.noun_phrase_.role);
106 new(&noun_phrase_.selrestrs) std::set<std::string>(other.noun_phrase_.selrestrs);
107 new(&noun_phrase_.synrestrs) std::set<std::string>(other.noun_phrase_.synrestrs);
108
109 break;
110 }
111
112 case type::preposition:
113 {
114 new(&preposition_.choices) std::set<std::string>(other.preposition_.choices);
115 preposition_.literal = other.preposition_.literal;
116
117 break;
118 }
119
120 case type::literal:
121 {
122 new(&literal_) std::string(other.literal_);
123
124 break;
125 }
126
127 case type::verb:
128 case type::adjective:
129 case type::adverb:
130 case type::invalid:
131 {
132 break;
133 }
134 }
135 }
136
137 part::part(part&& other) : part()
138 {
139 swap(*this, other);
140 }
141
142 part& part::operator=(part other)
143 {
144 swap(*this, other);
145
146 return *this;
147 }
148
149 void swap(part& first, part& second)
150 {
151 using type = part::type;
152
153 type tempType = first.type_;
154 int tempId = first.id_;
155 std::string tempRole;
156 std::set<std::string> tempSelrestrs;
157 std::set<std::string> tempSynrestrs;
158 std::set<std::string> tempChoices;
159 bool tempPrepLiteral;
160 std::string tempLiteralValue;
161
162 switch (tempType)
163 {
164 case type::noun_phrase:
165 {
166 tempRole = std::move(first.noun_phrase_.role);
167 tempSelrestrs = std::move(first.noun_phrase_.selrestrs);
168 tempSynrestrs = std::move(first.noun_phrase_.synrestrs);
169
170 break;
171 }
172
173 case type::preposition:
174 {
175 tempChoices = std::move(first.preposition_.choices);
176 tempPrepLiteral = first.preposition_.literal;
177
178 break;
179 }
180
181 case type::literal:
182 {
183 tempLiteralValue = std::move(first.literal_);
184
185 break;
186 }
187
188 case type::verb:
189 case type::adjective:
190 case type::adverb:
191 case type::invalid:
192 {
193 break;
194 }
195 }
196
197 first.~part();
198
199 first.type_ = second.type_;
200 first.id_ = second.id_;
201
202 switch (first.type_)
203 {
204 case type::noun_phrase:
205 {
206 new(&first.noun_phrase_.role) std::string(std::move(second.noun_phrase_.role));
207 new(&first.noun_phrase_.selrestrs) std::set<std::string>(std::move(second.noun_phrase_.selrestrs));
208 new(&first.noun_phrase_.synrestrs) std::set<std::string>(std::move(second.noun_phrase_.synrestrs));
209
210 break;
211 }
212
213 case type::preposition:
214 {
215 new(&first.preposition_.choices) std::set<std::string>(std::move(second.preposition_.choices));
216 first.preposition_.literal = second.preposition_.literal;
217
218 break;
219 }
220
221 case type::literal:
222 {
223 new(&first.literal_) std::string(std::move(second.literal_));
224
225 break;
226 }
227
228 case type::verb:
229 case type::adjective:
230 case type::adverb:
231 case type::invalid:
232 {
233 break;
234 }
235 }
236
237 second.~part();
238
239 second.type_ = tempType;
240 second.id_ = tempId;
241
242 switch (second.type_)
243 {
244 case type::noun_phrase:
245 {
246 new(&second.noun_phrase_.role) std::string(std::move(tempRole));
247 new(&second.noun_phrase_.selrestrs) std::set<std::string>(std::move(tempSelrestrs));
248 new(&second.noun_phrase_.synrestrs) std::set<std::string>(std::move(tempSynrestrs));
249
250 break;
251 }
252
253 case type::preposition:
254 {
255 new(&second.preposition_.choices) std::set<std::string>(std::move(tempChoices));
256 second.preposition_.literal = tempPrepLiteral;
257
258 break;
259 }
260
261 case type::literal:
262 {
263 new(&second.literal_) std::string(std::move(tempLiteralValue));
264
265 break;
266 }
267
268 case type::verb:
269 case type::adjective:
270 case type::adverb:
271 case type::invalid:
272 {
273 break;
274 }
275 }
276 }
277
278 part::~part()
279 {
280 switch (type_)
281 {
282 case type::noun_phrase:
283 {
284 using string_type = std::string;
285 using set_type = std::set<std::string>;
286
287 noun_phrase_.role.~string_type();
288 noun_phrase_.selrestrs.~set_type();
289 noun_phrase_.synrestrs.~set_type();
290
291 break;
292 }
293
294 case type::preposition:
295 {
296 using set_type = std::set<std::string>;
297
298 preposition_.choices.~set_type();
299
300 break;
301 }
302
303 case type::literal:
304 {
305 using string_type = std::string;
306
307 literal_.~string_type();
308
309 break;
310 }
311
312 case type::verb:
313 case type::adjective:
314 case type::adverb:
315 case type::invalid:
316 {
317 break;
318 }
319 }
320 } 49 }
321 50
322 std::string part::getNounRole() const 51 std::string part::getNounRole() const
323 { 52 {
324 if (type_ == type::noun_phrase) 53 if (type_ == type::noun_phrase)
325 { 54 {
326 return noun_phrase_.role; 55 return std::get<noun_phrase_type>(variant_).role;
327 } else { 56 } else {
328 throw std::domain_error("part::getNounRole is only valid for noun phrase parts"); 57 throw std::domain_error("part::getNounRole is only valid for noun phrase parts");
329 } 58 }
@@ -333,7 +62,7 @@ namespace verbly {
333 { 62 {
334 if (type_ == type::noun_phrase) 63 if (type_ == type::noun_phrase)
335 { 64 {
336 return noun_phrase_.selrestrs; 65 return std::get<noun_phrase_type>(variant_).selrestrs;
337 } else { 66 } else {
338 throw std::domain_error("part::getNounSelrestrs is only valid for noun phrase parts"); 67 throw std::domain_error("part::getNounSelrestrs is only valid for noun phrase parts");
339 } 68 }
@@ -343,7 +72,7 @@ namespace verbly {
343 { 72 {
344 if (type_ == type::noun_phrase) 73 if (type_ == type::noun_phrase)
345 { 74 {
346 return noun_phrase_.synrestrs; 75 return std::get<noun_phrase_type>(variant_).synrestrs;
347 } else { 76 } else {
348 throw std::domain_error("part::getNounSynrestrs is only valid for noun phrase parts"); 77 throw std::domain_error("part::getNounSynrestrs is only valid for noun phrase parts");
349 } 78 }
@@ -353,7 +82,7 @@ namespace verbly {
353 { 82 {
354 if (type_ == type::preposition) 83 if (type_ == type::preposition)
355 { 84 {
356 return preposition_.choices; 85 return std::get<preposition_type>(variant_).choices;
357 } else { 86 } else {
358 throw std::domain_error("part::getPrepositionChoices is only valid for preposition parts"); 87 throw std::domain_error("part::getPrepositionChoices is only valid for preposition parts");
359 } 88 }
@@ -363,7 +92,7 @@ namespace verbly {
363 { 92 {
364 if (type_ == type::preposition) 93 if (type_ == type::preposition)
365 { 94 {
366 return preposition_.literal; 95 return std::get<preposition_type>(variant_).literal;
367 } else { 96 } else {
368 throw std::domain_error("part::isPrepositionLiteral is only valid for preposition parts"); 97 throw std::domain_error("part::isPrepositionLiteral is only valid for preposition parts");
369 } 98 }
@@ -373,7 +102,7 @@ namespace verbly {
373 { 102 {
374 if (type_ == type::literal) 103 if (type_ == type::literal)
375 { 104 {
376 return literal_; 105 return std::get<literal_type>(variant_);
377 } else { 106 } else {
378 throw std::domain_error("part::getLiteralValue is only valid for literal parts"); 107 throw std::domain_error("part::getLiteralValue is only valid for literal parts");
379 } 108 }
diff --git a/generator/part.h b/generator/part.h index 01791f5..550f95f 100644 --- a/generator/part.h +++ b/generator/part.h
@@ -3,6 +3,7 @@
3 3
4#include <string> 4#include <string>
5#include <set> 5#include <set>
6#include <variant>
6#include "../lib/enums.h" 7#include "../lib/enums.h"
7 8
8namespace verbly { 9namespace verbly {
@@ -32,24 +33,6 @@ namespace verbly {
32 33
33 static part duplicate(const part& other); 34 static part duplicate(const part& other);
34 35
35 // Copy and move constructors
36
37 part(const part& other);
38
39 part(part&& other);
40
41 // Assignment
42
43 part& operator=(part other);
44
45 // Swap
46
47 friend void swap(part& first, part& second);
48
49 // Destructor
50
51 ~part();
52
53 // General accessors 36 // General accessors
54 37
55 int getId() const 38 int getId() const
@@ -82,6 +65,26 @@ namespace verbly {
82 65
83 private: 66 private:
84 67
68 struct noun_phrase_type {
69 std::string role;
70 std::set<std::string> selrestrs;
71 std::set<std::string> synrestrs;
72 };
73
74 struct preposition_type {
75 std::set<std::string> choices;
76 bool literal;
77 };
78
79 using literal_type = std::string;
80
81 using variant_type =
82 std::variant<
83 std::monostate,
84 noun_phrase_type,
85 preposition_type,
86 literal_type>;
87
85 static int nextId_; 88 static int nextId_;
86 89
87 int id_; 90 int id_;
@@ -92,26 +95,47 @@ namespace verbly {
92 { 95 {
93 } 96 }
94 97
95 part(type t) : 98 part(type t, variant_type variant = {}) :
96 id_(nextId_++), 99 id_(nextId_++),
97 type_(t) 100 type_(t),
101 variant_(std::move(variant))
98 { 102 {
103 bool valid_type = false;
104 switch (type_)
105 {
106 case part_type::noun_phrase:
107 {
108 valid_type = std::holds_alternative<noun_phrase_type>(variant_);
109 break;
110 }
111 case part_type::preposition:
112 {
113 valid_type = std::holds_alternative<preposition_type>(variant_);
114 break;
115 }
116 case part_type::literal:
117 {
118 valid_type = std::holds_alternative<literal_type>(variant_);
119 break;
120 }
121 case part_type::invalid:
122 case part_type::verb:
123 case part_type::adjective:
124 case part_type::adverb:
125 {
126 valid_type = std::holds_alternative<std::monostate>(variant_);
127 break;
128 }
129 }
130 if (!valid_type)
131 {
132 throw std::invalid_argument("Invalid variant provided for part");
133 }
99 } 134 }
100 135
101 // Data 136 // Data
102 137
103 union { 138 variant_type variant_;
104 struct {
105 std::string role;
106 std::set<std::string> selrestrs;
107 std::set<std::string> synrestrs;
108 } noun_phrase_;
109 struct {
110 std::set<std::string> choices;
111 bool literal;
112 } preposition_;
113 std::string literal_;
114 };
115 139
116 type type_ = type::invalid; 140 type type_ = type::invalid;
117 141