diff options
Diffstat (limited to 'lib/part.cpp')
-rw-r--r-- | lib/part.cpp | 350 |
1 files changed, 71 insertions, 279 deletions
diff --git a/lib/part.cpp b/lib/part.cpp index e7e467b..bd8501a 100644 --- a/lib/part.cpp +++ b/lib/part.cpp | |||
@@ -1,6 +1,5 @@ | |||
1 | #include "part.h" | 1 | #include "part.h" |
2 | #include <stdexcept> | 2 | #include <stdexcept> |
3 | #include <sqlite3.h> | ||
4 | #include <hkutil/string.h> | 3 | #include <hkutil/string.h> |
5 | #include "database.h" | 4 | #include "database.h" |
6 | 5 | ||
@@ -26,15 +25,19 @@ namespace verbly { | |||
26 | const part::selrestr_field part::selrestrs = {}; | 25 | const part::selrestr_field part::selrestrs = {}; |
27 | const part::synrestr_field part::synrestrs = {}; | 26 | const part::synrestr_field part::synrestrs = {}; |
28 | 27 | ||
29 | part part::createNounPhrase(std::string role, std::set<std::string> selrestrs, std::set<std::string> synrestrs) | 28 | part part::createNounPhrase( |
29 | std::string role, | ||
30 | std::set<std::string> selrestrs, | ||
31 | std::set<std::string> synrestrs) | ||
30 | { | 32 | { |
31 | part p(part_type::noun_phrase); | 33 | return part { |
32 | 34 | part_type::noun_phrase, | |
33 | new(&p.noun_phrase_.role) std::string(std::move(role)); | 35 | np_type { |
34 | new(&p.noun_phrase_.selrestrs) std::set<std::string>(std::move(selrestrs)); | 36 | std::move(role), |
35 | new(&p.noun_phrase_.synrestrs) std::set<std::string>(std::move(synrestrs)); | 37 | std::move(selrestrs), |
36 | 38 | std::move(synrestrs) | |
37 | return p; | 39 | } |
40 | }; | ||
38 | } | 41 | } |
39 | 42 | ||
40 | part part::createVerb() | 43 | part part::createVerb() |
@@ -44,12 +47,13 @@ namespace verbly { | |||
44 | 47 | ||
45 | part part::createPreposition(std::vector<std::string> choices, bool literal) | 48 | part part::createPreposition(std::vector<std::string> choices, bool literal) |
46 | { | 49 | { |
47 | part p(part_type::preposition); | 50 | return part { |
48 | 51 | part_type::preposition, | |
49 | new(&p.preposition_.choices) std::vector<std::string>(std::move(choices)); | 52 | prep_type { |
50 | p.preposition_.literal = literal; | 53 | std::move(choices), |
51 | 54 | literal | |
52 | return p; | 55 | } |
56 | }; | ||
53 | } | 57 | } |
54 | 58 | ||
55 | part part::createAdjective() | 59 | part part::createAdjective() |
@@ -64,83 +68,53 @@ namespace verbly { | |||
64 | 68 | ||
65 | part part::createLiteral(std::string value) | 69 | part part::createLiteral(std::string value) |
66 | { | 70 | { |
67 | part p(part_type::literal); | 71 | return part { |
68 | 72 | part_type::literal, | |
69 | new(&p.literal_) std::string(std::move(value)); | 73 | std::move(value) |
70 | 74 | }; | |
71 | return p; | ||
72 | } | 75 | } |
73 | 76 | ||
74 | part::part(const database& db, sqlite3_stmt* row) | 77 | part::part(const database& db, hatkirby::row row) |
75 | { | 78 | { |
76 | int id = sqlite3_column_int(row, 0); | 79 | int id = mpark::get<int>(row[0]); |
77 | 80 | ||
78 | type_ = static_cast<part_type>(sqlite3_column_int(row, 3)); | 81 | type_ = static_cast<part_type>(mpark::get<int>(row[3])); |
79 | 82 | ||
80 | switch (type_) | 83 | switch (type_) |
81 | { | 84 | { |
82 | case part_type::noun_phrase: | 85 | case part_type::noun_phrase: |
83 | { | 86 | { |
84 | new(&noun_phrase_.role) std::string(reinterpret_cast<const char*>(sqlite3_column_blob(row, 4))); | 87 | variant_ = np_type { |
85 | new(&noun_phrase_.selrestrs) std::set<std::string>(db.selrestrs(id)); | 88 | mpark::get<std::string>(row[4]), |
86 | new(&noun_phrase_.synrestrs) std::set<std::string>(db.synrestrs(id)); | 89 | db.selrestrs(id), |
90 | db.synrestrs(id) | ||
91 | }; | ||
87 | 92 | ||
88 | break; | 93 | break; |
89 | } | 94 | } |
90 | 95 | ||
91 | case part_type::preposition: | 96 | case part_type::preposition: |
92 | { | 97 | { |
93 | std::string serializedChoices(reinterpret_cast<const char*>(sqlite3_column_blob(row, 5))); | 98 | hatkirby::blob_type raw = |
94 | new(&preposition_.choices) std::vector<std::string>(hatkirby::split<std::vector<std::string>>(serializedChoices, ",")); | 99 | mpark::get<hatkirby::blob_type>(row[5]); |
95 | |||
96 | preposition_.literal = (sqlite3_column_int(row, 6) == 1); | ||
97 | |||
98 | break; | ||
99 | } | ||
100 | |||
101 | case part_type::literal: | ||
102 | { | ||
103 | new(&literal_) std::string(reinterpret_cast<const char*>(sqlite3_column_blob(row, 7))); | ||
104 | 100 | ||
105 | break; | 101 | std::string serializedChoices( |
106 | } | 102 | std::begin(raw), |
103 | std::end(raw)); | ||
107 | 104 | ||
108 | case part_type::verb: | 105 | variant_ = prep_type { |
109 | case part_type::adjective: | 106 | hatkirby::split<std::vector<std::string>>( |
110 | case part_type::adverb: | 107 | std::move(serializedChoices), |
111 | case part_type::invalid: | 108 | ","), |
112 | { | 109 | (mpark::get<int>(row[6]) == 1) |
113 | break; | 110 | }; |
114 | } | ||
115 | } | ||
116 | } | ||
117 | |||
118 | part::part(const part& other) | ||
119 | { | ||
120 | type_ = other.type_; | ||
121 | |||
122 | switch (type_) | ||
123 | { | ||
124 | case part_type::noun_phrase: | ||
125 | { | ||
126 | new(&noun_phrase_.role) std::string(other.noun_phrase_.role); | ||
127 | new(&noun_phrase_.selrestrs) std::set<std::string>(other.noun_phrase_.selrestrs); | ||
128 | new(&noun_phrase_.synrestrs) std::set<std::string>(other.noun_phrase_.synrestrs); | ||
129 | |||
130 | break; | ||
131 | } | ||
132 | |||
133 | case part_type::preposition: | ||
134 | { | ||
135 | new(&preposition_.choices) std::vector<std::string>(other.preposition_.choices); | ||
136 | preposition_.literal = other.preposition_.literal; | ||
137 | 111 | ||
138 | break; | 112 | break; |
139 | } | 113 | } |
140 | 114 | ||
141 | case part_type::literal: | 115 | case part_type::literal: |
142 | { | 116 | { |
143 | new(&literal_) std::string(other.literal_); | 117 | variant_ = mpark::get<std::string>(row[7]); |
144 | 118 | ||
145 | break; | 119 | break; |
146 | } | 120 | } |
@@ -155,256 +129,74 @@ namespace verbly { | |||
155 | } | 129 | } |
156 | } | 130 | } |
157 | 131 | ||
158 | part::part(part&& other) : part() | 132 | const std::string& part::getNounRole() const |
159 | { | 133 | { |
160 | swap(*this, other); | 134 | if (type_ != part_type::noun_phrase) |
161 | } | ||
162 | |||
163 | part& part::operator=(part other) | ||
164 | { | ||
165 | swap(*this, other); | ||
166 | |||
167 | return *this; | ||
168 | } | ||
169 | |||
170 | void swap(part& first, part& second) | ||
171 | { | ||
172 | using type = part_type; | ||
173 | |||
174 | type tempType = first.type_; | ||
175 | std::string tempRole; | ||
176 | std::set<std::string> tempSelrestrs; | ||
177 | std::set<std::string> tempSynrestrs; | ||
178 | std::vector<std::string> tempChoices; | ||
179 | bool tempPrepLiteral; | ||
180 | std::string tempLiteralValue; | ||
181 | |||
182 | switch (tempType) | ||
183 | { | ||
184 | case type::noun_phrase: | ||
185 | { | ||
186 | tempRole = std::move(first.noun_phrase_.role); | ||
187 | tempSelrestrs = std::move(first.noun_phrase_.selrestrs); | ||
188 | tempSynrestrs = std::move(first.noun_phrase_.synrestrs); | ||
189 | |||
190 | break; | ||
191 | } | ||
192 | |||
193 | case type::preposition: | ||
194 | { | ||
195 | tempChoices = std::move(first.preposition_.choices); | ||
196 | tempPrepLiteral = first.preposition_.literal; | ||
197 | |||
198 | break; | ||
199 | } | ||
200 | |||
201 | case type::literal: | ||
202 | { | ||
203 | tempLiteralValue = std::move(first.literal_); | ||
204 | |||
205 | break; | ||
206 | } | ||
207 | |||
208 | case type::verb: | ||
209 | case type::adjective: | ||
210 | case type::adverb: | ||
211 | case type::invalid: | ||
212 | { | ||
213 | break; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | first.~part(); | ||
218 | |||
219 | first.type_ = second.type_; | ||
220 | |||
221 | switch (first.type_) | ||
222 | { | 135 | { |
223 | case type::noun_phrase: | 136 | throw std::domain_error("part is not a noun phrase"); |
224 | { | ||
225 | new(&first.noun_phrase_.role) std::string(std::move(second.noun_phrase_.role)); | ||
226 | new(&first.noun_phrase_.selrestrs) std::set<std::string>(std::move(second.noun_phrase_.selrestrs)); | ||
227 | new(&first.noun_phrase_.synrestrs) std::set<std::string>(std::move(second.noun_phrase_.synrestrs)); | ||
228 | |||
229 | break; | ||
230 | } | ||
231 | |||
232 | case type::preposition: | ||
233 | { | ||
234 | new(&first.preposition_.choices) std::vector<std::string>(std::move(second.preposition_.choices)); | ||
235 | first.preposition_.literal = second.preposition_.literal; | ||
236 | |||
237 | break; | ||
238 | } | ||
239 | |||
240 | case type::literal: | ||
241 | { | ||
242 | new(&first.literal_) std::string(std::move(second.literal_)); | ||
243 | |||
244 | break; | ||
245 | } | ||
246 | |||
247 | case type::verb: | ||
248 | case type::adjective: | ||
249 | case type::adverb: | ||
250 | case type::invalid: | ||
251 | { | ||
252 | break; | ||
253 | } | ||
254 | } | 137 | } |
255 | 138 | ||
256 | second.~part(); | 139 | return mpark::get<np_type>(variant_).role; |
257 | |||
258 | second.type_ = tempType; | ||
259 | |||
260 | switch (second.type_) | ||
261 | { | ||
262 | case type::noun_phrase: | ||
263 | { | ||
264 | new(&second.noun_phrase_.role) std::string(std::move(tempRole)); | ||
265 | new(&second.noun_phrase_.selrestrs) std::set<std::string>(std::move(tempSelrestrs)); | ||
266 | new(&second.noun_phrase_.synrestrs) std::set<std::string>(std::move(tempSynrestrs)); | ||
267 | |||
268 | break; | ||
269 | } | ||
270 | |||
271 | case type::preposition: | ||
272 | { | ||
273 | new(&second.preposition_.choices) std::vector<std::string>(std::move(tempChoices)); | ||
274 | second.preposition_.literal = tempPrepLiteral; | ||
275 | |||
276 | break; | ||
277 | } | ||
278 | |||
279 | case type::literal: | ||
280 | { | ||
281 | new(&second.literal_) std::string(std::move(tempLiteralValue)); | ||
282 | |||
283 | break; | ||
284 | } | ||
285 | |||
286 | case type::verb: | ||
287 | case type::adjective: | ||
288 | case type::adverb: | ||
289 | case type::invalid: | ||
290 | { | ||
291 | break; | ||
292 | } | ||
293 | } | ||
294 | } | 140 | } |
295 | 141 | ||
296 | part::~part() | 142 | const std::set<std::string>& part::getNounSelrestrs() const |
297 | { | 143 | { |
298 | switch (type_) | 144 | if (type_ != part_type::noun_phrase) |
299 | { | 145 | { |
300 | case part_type::noun_phrase: | 146 | throw std::domain_error("part is not a noun phrase"); |
301 | { | ||
302 | using string_type = std::string; | ||
303 | using set_type = std::set<std::string>; | ||
304 | |||
305 | noun_phrase_.role.~string_type(); | ||
306 | noun_phrase_.selrestrs.~set_type(); | ||
307 | noun_phrase_.synrestrs.~set_type(); | ||
308 | |||
309 | break; | ||
310 | } | ||
311 | |||
312 | case part_type::preposition: | ||
313 | { | ||
314 | using vector_type = std::vector<std::string>; | ||
315 | |||
316 | preposition_.choices.~vector_type(); | ||
317 | |||
318 | break; | ||
319 | } | ||
320 | |||
321 | case part_type::literal: | ||
322 | { | ||
323 | using string_type = std::string; | ||
324 | |||
325 | literal_.~string_type(); | ||
326 | |||
327 | break; | ||
328 | } | ||
329 | |||
330 | case part_type::verb: | ||
331 | case part_type::adjective: | ||
332 | case part_type::adverb: | ||
333 | case part_type::invalid: | ||
334 | { | ||
335 | break; | ||
336 | } | ||
337 | } | 147 | } |
338 | } | ||
339 | 148 | ||
340 | std::string part::getNounRole() const | 149 | return mpark::get<np_type>(variant_).selrestrs; |
341 | { | ||
342 | if (type_ == part_type::noun_phrase) | ||
343 | { | ||
344 | return noun_phrase_.role; | ||
345 | } else { | ||
346 | throw std::domain_error("part::getNounRole is only valid for noun phrase parts"); | ||
347 | } | ||
348 | } | 150 | } |
349 | 151 | ||
350 | std::set<std::string> part::getNounSelrestrs() const | 152 | const std::set<std::string>& part::getNounSynrestrs() const |
351 | { | 153 | { |
352 | if (type_ == part_type::noun_phrase) | 154 | if (type_ != part_type::noun_phrase) |
353 | { | 155 | { |
354 | return noun_phrase_.selrestrs; | 156 | throw std::domain_error("part is not a noun phrase"); |
355 | } else { | ||
356 | throw std::domain_error("part::getNounSelrestrs is only valid for noun phrase parts"); | ||
357 | } | 157 | } |
358 | } | ||
359 | 158 | ||
360 | std::set<std::string> part::getNounSynrestrs() const | 159 | return mpark::get<np_type>(variant_).synrestrs; |
361 | { | ||
362 | if (type_ == part_type::noun_phrase) | ||
363 | { | ||
364 | return noun_phrase_.synrestrs; | ||
365 | } else { | ||
366 | throw std::domain_error("part::getNounSynrestrs is only valid for noun phrase parts"); | ||
367 | } | ||
368 | } | 160 | } |
369 | 161 | ||
370 | bool part::nounHasSynrestr(std::string synrestr) const | 162 | bool part::nounHasSynrestr(std::string synrestr) const |
371 | { | 163 | { |
372 | if (type_ != part_type::noun_phrase) | 164 | if (type_ != part_type::noun_phrase) |
373 | { | 165 | { |
374 | throw std::domain_error("part::nounHasSynrestr is only valid for noun phrase parts"); | 166 | throw std::domain_error("part is not a noun phrase"); |
375 | } | 167 | } |
376 | 168 | ||
377 | return (noun_phrase_.synrestrs.count(synrestr) == 1); | 169 | return mpark::get<np_type>(variant_).synrestrs.count(synrestr); |
378 | } | 170 | } |
379 | 171 | ||
380 | std::vector<std::string> part::getPrepositionChoices() const | 172 | const std::vector<std::string>& part::getPrepositionChoices() const |
381 | { | 173 | { |
382 | if (type_ == part_type::preposition) | 174 | if (type_ != part_type::preposition) |
383 | { | 175 | { |
384 | return preposition_.choices; | 176 | throw std::domain_error("part is not a preposition"); |
385 | } else { | ||
386 | throw std::domain_error("part::getPrepositionChoices is only valid for preposition parts"); | ||
387 | } | 177 | } |
178 | |||
179 | return mpark::get<prep_type>(variant_).choices; | ||
388 | } | 180 | } |
389 | 181 | ||
390 | bool part::isPrepositionLiteral() const | 182 | bool part::isPrepositionLiteral() const |
391 | { | 183 | { |
392 | if (type_ == part_type::preposition) | 184 | if (type_ != part_type::preposition) |
393 | { | 185 | { |
394 | return preposition_.literal; | 186 | throw std::domain_error("part is not a preposition"); |
395 | } else { | ||
396 | throw std::domain_error("part::isPrepositionLiteral is only valid for preposition parts"); | ||
397 | } | 187 | } |
188 | |||
189 | return mpark::get<prep_type>(variant_).literal; | ||
398 | } | 190 | } |
399 | 191 | ||
400 | std::string part::getLiteralValue() const | 192 | const std::string& part::getLiteralValue() const |
401 | { | 193 | { |
402 | if (type_ == part_type::literal) | 194 | if (type_ != part_type::literal) |
403 | { | 195 | { |
404 | return literal_; | 196 | throw std::domain_error("part is not a literal"); |
405 | } else { | ||
406 | throw std::domain_error("part::getLiteralValue is only valid for literal parts"); | ||
407 | } | 197 | } |
198 | |||
199 | return mpark::get<std::string>(variant_); | ||
408 | } | 200 | } |
409 | 201 | ||
410 | filter part::synrestr_field::operator%=(std::string synrestr) const | 202 | filter part::synrestr_field::operator%=(std::string synrestr) const |