diff --git a/src/strings_internal.h b/src/strings_internal.h index 6584827e78..6fbe60067c 100644 --- a/src/strings_internal.h +++ b/src/strings_internal.h @@ -14,11 +14,11 @@ #include "string_func.h" #include "core/span_type.hpp" +#include + /** The data required to format and validate a single parameter of a string. */ struct StringParameter { - uint64_t data; ///< The data of the parameter. - const char *string_view; ///< The string value, if it has any. - std::unique_ptr string; ///< Copied string value, if it has any. + std::variant> data; ///< The data of the parameter: integer, non-owning string value, or owned string value. char32_t type; ///< The #StringControlCode to interpret this data with when it's the first parameter, otherwise '\0'. }; @@ -95,7 +95,12 @@ public: T GetNextParameter() { auto ptr = GetNextParameterPointer(); - return static_cast(ptr->data); + + if (std::holds_alternative(ptr->data)) { + return static_cast(std::get(ptr->data)); + } else { + throw std::out_of_range("Trying to read string parameter as integer"); + } } /** @@ -107,7 +112,14 @@ public: const char *GetNextParameterString() { auto ptr = GetNextParameterPointer(); - return ptr->string != nullptr ? ptr->string->c_str() : ptr->string_view; + + if (std::holds_alternative(ptr->data)) { + return std::get(ptr->data); + } else if (std::holds_alternative>(ptr->data)) { + return std::get>(ptr->data)->c_str(); + } else { + throw std::out_of_range("Trying to read string parameter as integer"); + } } /** @@ -152,8 +164,6 @@ public: { assert(n < this->parameters.size()); this->parameters[n].data = v; - this->parameters[n].string.reset(); - this->parameters[n].string_view = nullptr; } template ::value, int> = 0> @@ -165,9 +175,7 @@ public: void SetParam(size_t n, const char *str) { assert(n < this->parameters.size()); - this->parameters[n].data = 0; - this->parameters[n].string.reset(); - this->parameters[n].string_view = str; + this->parameters[n].data = str; } void SetParam(size_t n, const std::string &str) { this->SetParam(n, str.c_str()); } @@ -175,16 +183,14 @@ public: void SetParam(size_t n, std::string &&str) { assert(n < this->parameters.size()); - this->parameters[n].data = 0; - this->parameters[n].string = std::make_unique(std::move(str)); - this->parameters[n].string_view = nullptr; + this->parameters[n].data = std::make_unique(std::move(str)); } uint64_t GetParam(size_t n) const { assert(n < this->parameters.size()); - assert(this->parameters[n].string_view == nullptr && this->parameters[n].string == nullptr); - return this->parameters[n].data; + assert(std::holds_alternative(this->parameters[n].data)); + return std::get(this->parameters[n].data); } /** @@ -195,8 +201,14 @@ public: const char *GetParamStr(size_t n) const { assert(n < this->parameters.size()); - auto ¶m = this->parameters[n]; - return param.string != nullptr ? param.string->c_str() : param.string_view; + + if (std::holds_alternative(this->parameters[n].data)) { + return std::get(this->parameters[n].data); + } else if (std::holds_alternative>(this->parameters[n].data)) { + return std::get>(this->parameters[n].data)->c_str(); + } else { + return nullptr; + } } };