From 03596c07406ea33f76a0fbb3e004df50b8b832e6 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Wed, 14 Dec 2022 10:33:34 -0500 Subject: Converted verbly::generator::part to std::variant fixes #5 --- generator/CMakeLists.txt | 2 +- generator/part.cpp | 305 +++-------------------------------------------- generator/part.h | 88 +++++++++----- 3 files changed, 74 insertions(+), 321 deletions(-) diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt index 8c070d2..5d2f977 100644 --- a/generator/CMakeLists.txt +++ b/generator/CMakeLists.txt @@ -11,6 +11,6 @@ include_directories( ../vendor/hkutil) add_executable(generator notion.cpp word.cpp lemma.cpp form.cpp pronunciation.cpp group.cpp frame.cpp part.cpp generator.cpp main.cpp) -set_property(TARGET generator PROPERTY CXX_STANDARD 11) +set_property(TARGET generator PROPERTY CXX_STANDARD 17) set_property(TARGET generator PROPERTY CXX_STANDARD_REQUIRED ON) target_link_libraries(generator ${sqlite3_LIBRARIES} ${LIBXML2_LIBRARIES}) 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 { part part::createNounPhrase(std::string role, std::set selrestrs, std::set synrestrs) { - part p(type::noun_phrase); - - new(&p.noun_phrase_.role) std::string(std::move(role)); - new(&p.noun_phrase_.selrestrs) std::set(std::move(selrestrs)); - new(&p.noun_phrase_.synrestrs) std::set(std::move(synrestrs)); - - return p; + return part(type::noun_phrase, noun_phrase_type { + .role = std::move(role), + .selrestrs = std::move(selrestrs), + .synrestrs = std::move(synrestrs) + }); } part part::createVerb() @@ -24,12 +22,10 @@ namespace verbly { part part::createPreposition(std::set choices, bool literal) { - part p(type::preposition); - - new(&p.preposition_.choices) std::set(std::move(choices)); - p.preposition_.literal = literal; - - return p; + return part(type::preposition, preposition_type { + .choices = std::move(choices), + .literal = literal + }); } part part::createAdjective() @@ -44,286 +40,19 @@ namespace verbly { part part::createLiteral(std::string value) { - part p(type::literal); - - new(&p.literal_) std::string(std::move(value)); - - return p; + return part(type::literal, std::move(value)); } part part::duplicate(const part& other) { - part result(other.type_); - - switch (result.type_) - { - case type::noun_phrase: - { - new(&result.noun_phrase_.role) std::string(other.noun_phrase_.role); - new(&result.noun_phrase_.selrestrs) std::set(other.noun_phrase_.selrestrs); - new(&result.noun_phrase_.synrestrs) std::set(other.noun_phrase_.synrestrs); - - break; - } - - case type::preposition: - { - new(&result.preposition_.choices) std::set(other.preposition_.choices); - result.preposition_.literal = other.preposition_.literal; - - break; - } - - case type::literal: - { - new(&result.literal_) std::string(other.literal_); - - break; - } - - case type::verb: - case type::adjective: - case type::adverb: - case type::invalid: - { - break; - } - } - - return result; - } - - part::part(const part& other) - { - type_ = other.type_; - id_ = other.id_; - - switch (type_) - { - case type::noun_phrase: - { - new(&noun_phrase_.role) std::string(other.noun_phrase_.role); - new(&noun_phrase_.selrestrs) std::set(other.noun_phrase_.selrestrs); - new(&noun_phrase_.synrestrs) std::set(other.noun_phrase_.synrestrs); - - break; - } - - case type::preposition: - { - new(&preposition_.choices) std::set(other.preposition_.choices); - preposition_.literal = other.preposition_.literal; - - break; - } - - case type::literal: - { - new(&literal_) std::string(other.literal_); - - break; - } - - case type::verb: - case type::adjective: - case type::adverb: - case type::invalid: - { - break; - } - } - } - - part::part(part&& other) : part() - { - swap(*this, other); - } - - part& part::operator=(part other) - { - swap(*this, other); - - return *this; - } - - void swap(part& first, part& second) - { - using type = part::type; - - type tempType = first.type_; - int tempId = first.id_; - std::string tempRole; - std::set tempSelrestrs; - std::set tempSynrestrs; - std::set tempChoices; - bool tempPrepLiteral; - std::string tempLiteralValue; - - switch (tempType) - { - case type::noun_phrase: - { - tempRole = std::move(first.noun_phrase_.role); - tempSelrestrs = std::move(first.noun_phrase_.selrestrs); - tempSynrestrs = std::move(first.noun_phrase_.synrestrs); - - break; - } - - case type::preposition: - { - tempChoices = std::move(first.preposition_.choices); - tempPrepLiteral = first.preposition_.literal; - - break; - } - - case type::literal: - { - tempLiteralValue = std::move(first.literal_); - - break; - } - - case type::verb: - case type::adjective: - case type::adverb: - case type::invalid: - { - break; - } - } - - first.~part(); - - first.type_ = second.type_; - first.id_ = second.id_; - - switch (first.type_) - { - case type::noun_phrase: - { - new(&first.noun_phrase_.role) std::string(std::move(second.noun_phrase_.role)); - new(&first.noun_phrase_.selrestrs) std::set(std::move(second.noun_phrase_.selrestrs)); - new(&first.noun_phrase_.synrestrs) std::set(std::move(second.noun_phrase_.synrestrs)); - - break; - } - - case type::preposition: - { - new(&first.preposition_.choices) std::set(std::move(second.preposition_.choices)); - first.preposition_.literal = second.preposition_.literal; - - break; - } - - case type::literal: - { - new(&first.literal_) std::string(std::move(second.literal_)); - - break; - } - - case type::verb: - case type::adjective: - case type::adverb: - case type::invalid: - { - break; - } - } - - second.~part(); - - second.type_ = tempType; - second.id_ = tempId; - - switch (second.type_) - { - case type::noun_phrase: - { - new(&second.noun_phrase_.role) std::string(std::move(tempRole)); - new(&second.noun_phrase_.selrestrs) std::set(std::move(tempSelrestrs)); - new(&second.noun_phrase_.synrestrs) std::set(std::move(tempSynrestrs)); - - break; - } - - case type::preposition: - { - new(&second.preposition_.choices) std::set(std::move(tempChoices)); - second.preposition_.literal = tempPrepLiteral; - - break; - } - - case type::literal: - { - new(&second.literal_) std::string(std::move(tempLiteralValue)); - - break; - } - - case type::verb: - case type::adjective: - case type::adverb: - case type::invalid: - { - break; - } - } - } - - part::~part() - { - switch (type_) - { - case type::noun_phrase: - { - using string_type = std::string; - using set_type = std::set; - - noun_phrase_.role.~string_type(); - noun_phrase_.selrestrs.~set_type(); - noun_phrase_.synrestrs.~set_type(); - - break; - } - - case type::preposition: - { - using set_type = std::set; - - preposition_.choices.~set_type(); - - break; - } - - case type::literal: - { - using string_type = std::string; - - literal_.~string_type(); - - break; - } - - case type::verb: - case type::adjective: - case type::adverb: - case type::invalid: - { - break; - } - } + return part(other.type_, other.variant_); } std::string part::getNounRole() const { if (type_ == type::noun_phrase) { - return noun_phrase_.role; + return std::get(variant_).role; } else { throw std::domain_error("part::getNounRole is only valid for noun phrase parts"); } @@ -333,7 +62,7 @@ namespace verbly { { if (type_ == type::noun_phrase) { - return noun_phrase_.selrestrs; + return std::get(variant_).selrestrs; } else { throw std::domain_error("part::getNounSelrestrs is only valid for noun phrase parts"); } @@ -343,7 +72,7 @@ namespace verbly { { if (type_ == type::noun_phrase) { - return noun_phrase_.synrestrs; + return std::get(variant_).synrestrs; } else { throw std::domain_error("part::getNounSynrestrs is only valid for noun phrase parts"); } @@ -353,7 +82,7 @@ namespace verbly { { if (type_ == type::preposition) { - return preposition_.choices; + return std::get(variant_).choices; } else { throw std::domain_error("part::getPrepositionChoices is only valid for preposition parts"); } @@ -363,7 +92,7 @@ namespace verbly { { if (type_ == type::preposition) { - return preposition_.literal; + return std::get(variant_).literal; } else { throw std::domain_error("part::isPrepositionLiteral is only valid for preposition parts"); } @@ -373,7 +102,7 @@ namespace verbly { { if (type_ == type::literal) { - return literal_; + return std::get(variant_); } else { throw std::domain_error("part::getLiteralValue is only valid for literal parts"); } 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 @@ #include #include +#include #include "../lib/enums.h" namespace verbly { @@ -32,24 +33,6 @@ namespace verbly { static part duplicate(const part& other); - // Copy and move constructors - - part(const part& other); - - part(part&& other); - - // Assignment - - part& operator=(part other); - - // Swap - - friend void swap(part& first, part& second); - - // Destructor - - ~part(); - // General accessors int getId() const @@ -82,6 +65,26 @@ namespace verbly { private: + struct noun_phrase_type { + std::string role; + std::set selrestrs; + std::set synrestrs; + }; + + struct preposition_type { + std::set choices; + bool literal; + }; + + using literal_type = std::string; + + using variant_type = + std::variant< + std::monostate, + noun_phrase_type, + preposition_type, + literal_type>; + static int nextId_; int id_; @@ -92,26 +95,47 @@ namespace verbly { { } - part(type t) : + part(type t, variant_type variant = {}) : id_(nextId_++), - type_(t) + type_(t), + variant_(std::move(variant)) { + bool valid_type = false; + switch (type_) + { + case part_type::noun_phrase: + { + valid_type = std::holds_alternative(variant_); + break; + } + case part_type::preposition: + { + valid_type = std::holds_alternative(variant_); + break; + } + case part_type::literal: + { + valid_type = std::holds_alternative(variant_); + break; + } + case part_type::invalid: + case part_type::verb: + case part_type::adjective: + case part_type::adverb: + { + valid_type = std::holds_alternative(variant_); + break; + } + } + if (!valid_type) + { + throw std::invalid_argument("Invalid variant provided for part"); + } } // Data - union { - struct { - std::string role; - std::set selrestrs; - std::set synrestrs; - } noun_phrase_; - struct { - std::set choices; - bool literal; - } preposition_; - std::string literal_; - }; + variant_type variant_; type type_ = type::invalid; -- cgit 1.4.1