diff options
| -rw-r--r-- | generator/part.cpp | 305 | ||||
| -rw-r--r-- | generator/part.h | 88 |
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 | ||
| 8 | namespace verbly { | 9 | namespace 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 | ||
