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 |
