From 3e488465f8c959b168d4d41c46d3f99884d00e68 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Tue, 27 Jun 2023 16:59:44 +0200 Subject: [PATCH] Codechange: allow string temporaries in a StringParameter --- src/strings.cpp | 12 ++++++++++++ src/strings_func.h | 2 +- src/strings_internal.h | 20 ++++++++++++++++---- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/strings.cpp b/src/strings.cpp index 1e243b42da..b052814eae 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -363,6 +363,18 @@ void SetDParamStr(size_t n, const std::string &str) _global_string_params.SetParam(n, str); } +/** + * This function is used to "bind" the std::string to a OpenTTD dparam slot. + * Contrary to the other \c SetDParamStr functions, this moves the string into + * the parameter slot. + * @param n slot of the string + * @param str string to bind + */ +void SetDParamStr(size_t n, std::string &&str) +{ + _global_string_params.SetParam(n, std::move(str)); +} + /** * Format a number into a string. * @param builder the string builder to write to diff --git a/src/strings_func.h b/src/strings_func.h index afabbe33ea..9806661656 100644 --- a/src/strings_func.h +++ b/src/strings_func.h @@ -84,7 +84,7 @@ void SetDParamMaxDigits(size_t n, uint count, FontSize size = FS_NORMAL); void SetDParamStr(size_t n, const char *str); void SetDParamStr(size_t n, const std::string &str); -void SetDParamStr(size_t n, std::string &&str) = delete; // block passing temporaries to SetDParamStr +void SetDParamStr(size_t n, std::string &&str); void CopyInDParam(const span backup); void CopyOutDParam(std::vector &backup, size_t num); diff --git a/src/strings_internal.h b/src/strings_internal.h index 3759c9bfab..6dc0f086db 100644 --- a/src/strings_internal.h +++ b/src/strings_internal.h @@ -18,6 +18,7 @@ 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. WChar type; ///< The #StringControlCode to interpret this data with when it's the first parameter, otherwise '\0'. }; @@ -102,7 +103,8 @@ public: const char *GetNextParameterString() { auto ptr = GetNextParameterPointer(); - return ptr == nullptr ? nullptr : ptr->string_view; + if (ptr == nullptr) return nullptr; + return ptr->string != nullptr ? ptr->string->c_str() : ptr->string_view; } /** @@ -147,6 +149,7 @@ public: { assert(n < this->parameters.size()); this->parameters[n].data = v; + this->parameters[n].string.reset(); this->parameters[n].string_view = nullptr; } @@ -154,16 +157,24 @@ public: { assert(n < this->parameters.size()); this->parameters[n].data = 0; + this->parameters[n].string.reset(); this->parameters[n].string_view = str; } void SetParam(size_t n, const std::string &str) { this->SetParam(n, str.c_str()); } - void SetParam(size_t n, std::string &&str) = delete; // block passing temporaries to SetDParam + + 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; + } uint64 GetParam(size_t n) const { assert(n < this->parameters.size()); - assert(this->parameters[n].string_view == nullptr); + assert(this->parameters[n].string_view == nullptr && this->parameters[n].string == nullptr); return this->parameters[n].data; } @@ -175,7 +186,8 @@ public: const char *GetParamStr(size_t n) const { assert(n < this->parameters.size()); - return this->parameters[n].string_view; + auto ¶m = this->parameters[n]; + return param.string != nullptr ? param.string->c_str() : param.string_view; } };