mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-04 13:42:55 +01:00
Add a dynamic format string function
This commit is contained in:
@@ -204,4 +204,47 @@ namespace OpenRCT2
|
||||
|
||||
template void FormatArgument(std::stringstream&, uint32_t, int32_t);
|
||||
template void FormatArgument(std::stringstream&, uint32_t, const char*);
|
||||
|
||||
void FormatArgumentAny(std::stringstream& ss, FormatToken token, const std::any& value)
|
||||
{
|
||||
if (value.type() == typeid(int32_t))
|
||||
{
|
||||
FormatArgument(ss, token, std::any_cast<int32_t>(value));
|
||||
}
|
||||
else if (value.type() == typeid(const char*))
|
||||
{
|
||||
FormatArgument(ss, token, std::any_cast<const char*>(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("No support for format argument type.");
|
||||
}
|
||||
}
|
||||
|
||||
std::string FormatStringAny(std::string_view fmt, const std::vector<std::any>& args)
|
||||
{
|
||||
thread_local std::stringstream ss;
|
||||
// Reset the buffer (reported as most efficient way)
|
||||
std::stringstream().swap(ss);
|
||||
|
||||
size_t argIndex = 0;
|
||||
auto fmtc = fmt;
|
||||
while (!fmtc.empty())
|
||||
{
|
||||
auto [part, token] = FormatNextPart(fmtc);
|
||||
if (CanFormatToken(token))
|
||||
{
|
||||
if (argIndex < args.size())
|
||||
{
|
||||
FormatArgumentAny(ss, token, args[argIndex]);
|
||||
}
|
||||
argIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << part;
|
||||
}
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
} // namespace OpenRCT2
|
||||
|
||||
@@ -12,10 +12,12 @@
|
||||
#include "../common.h"
|
||||
#include "Language.h"
|
||||
|
||||
#include <any>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace OpenRCT2
|
||||
{
|
||||
@@ -99,4 +101,6 @@ namespace OpenRCT2
|
||||
auto fmtc = language_convert_string_to_tokens(lang);
|
||||
return FormatString(fmtc, argN...);
|
||||
}
|
||||
|
||||
std::string FormatStringAny(std::string_view fmt, const std::vector<std::any>& args);
|
||||
} // namespace OpenRCT2
|
||||
|
||||
@@ -116,3 +116,10 @@ TEST_F(FormattingTests, velocity_mps)
|
||||
auto actual = FormatString("Train is going at {VELOCITY}.", 1024);
|
||||
ASSERT_EQ("Train is going at 457.7 m/s.", actual);
|
||||
}
|
||||
|
||||
TEST_F(FormattingTests, any_string_int_string)
|
||||
{
|
||||
auto actual = FormatStringAny(
|
||||
"{RED}{STRING} {INT32} has broken down due to '{STRING}'.", { "Twist", 2, "Mechanical failure" });
|
||||
ASSERT_EQ("{RED}Twist 2 has broken down due to 'Mechanical failure'.", actual);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user