fix(format): Poco::format and C++20 #3733

This commit is contained in:
Alex Fabijanic 2022-08-06 22:24:41 +02:00
parent cedb34d3c3
commit 42b6d3ace4
3 changed files with 45 additions and 30 deletions

View File

@ -106,20 +106,26 @@ std::string Foundation_API format(const std::string& fmt, const Any& value);
/// std::string s2 = format("second: %[1]d, first: %[0]d", 1, 2); /// std::string s2 = format("second: %[1]d, first: %[0]d", 1, 2);
void Foundation_API format(std::string& result, const char *fmt, const std::vector<Any>& values); void Foundation_API format(std::string& result, const char *fmt, const std::vector<Any>& values);
/// Supports a variable number of arguments and is used by /// Supports a variable number of arguments.
/// all other variants of format().
void Foundation_API format(std::string& result, const std::string& fmt, const std::vector<Any>& values); void Foundation_API format(std::string& result, const std::string& fmt, const std::vector<Any>& values);
/// Supports a variable number of arguments.
inline void formatAny(std::string& result, const std::string& fmt, const std::vector<Any>& values)
/// Supports a variable number of arguments and is used by /// Supports a variable number of arguments and is used by
/// all other variants of format(). /// all other variants of format().
{
format(result, fmt, values);
}
inline void formatAny(std::string& result, const char *fmt, const std::vector<Any>& values)
/// Supports a variable number of arguments and is used by
/// all other variants of format().
{
format(result, fmt, values);
}
template < template <typename T, typename... Args>
typename T,
#ifdef __cpp_lib_remove_cvref
typename std::enable_if_t<!std::is_same_v<std::remove_cvref_t<T>, std::vector<Any>>>,
#endif
typename... Args>
void format(std::string& result, const std::string& fmt, T arg1, Args... args) void format(std::string& result, const std::string& fmt, T arg1, Args... args)
/// Appends the formatted string to result. /// Appends the formatted string to result.
{ {
@ -127,16 +133,11 @@ void format(std::string& result, const std::string& fmt, T arg1, Args... args)
values.reserve(sizeof...(Args) + 1); values.reserve(sizeof...(Args) + 1);
values.emplace_back(arg1); values.emplace_back(arg1);
values.insert(values.end(), { args... }); values.insert(values.end(), { args... });
format(result, fmt, values); formatAny(result, fmt, values);
} }
template < template <typename T, typename... Args>
typename T,
#ifdef __cpp_lib_remove_cvref
typename std::enable_if_t<!std::is_same_v<std::remove_cvref_t<T>, std::vector<Any>>>,
#endif
typename... Args>
void format(std::string& result, const char* fmt, T arg1, Args... args) void format(std::string& result, const char* fmt, T arg1, Args... args)
/// Appends the formatted string to result. /// Appends the formatted string to result.
{ {
@ -144,16 +145,11 @@ void format(std::string& result, const char* fmt, T arg1, Args... args)
values.reserve(sizeof...(Args) + 1); values.reserve(sizeof...(Args) + 1);
values.emplace_back(arg1); values.emplace_back(arg1);
values.insert(values.end(), { args... }); values.insert(values.end(), { args... });
format(result, fmt, values); formatAny(result, fmt, values);
} }
template < template <typename T, typename... Args>
typename T,
#ifdef __cpp_lib_remove_cvref
typename std::enable_if_t<!std::is_same_v<std::remove_cvref_t<T>, std::vector<Any>>>,
#endif
typename... Args>
std::string format(const std::string& fmt, T arg1, Args... args) std::string format(const std::string& fmt, T arg1, Args... args)
/// Returns the formatted string. /// Returns the formatted string.
{ {
@ -162,17 +158,12 @@ std::string format(const std::string& fmt, T arg1, Args... args)
values.emplace_back(arg1); values.emplace_back(arg1);
values.insert(values.end(), { args... }); values.insert(values.end(), { args... });
std::string result; std::string result;
format(result, fmt, values); formatAny(result, fmt, values);
return result; return result;
} }
template < template <typename T, typename... Args>
typename T,
#ifdef __cpp_lib_remove_cvref
typename std::enable_if_t<!std::is_same_v<std::remove_cvref_t<T>, std::vector<Any>>>,
#endif
typename... Args>
std::string format(const char* fmt, T arg1, Args... args) std::string format(const char* fmt, T arg1, Args... args)
/// Returns the formatted string. /// Returns the formatted string.
{ {
@ -181,7 +172,7 @@ std::string format(const char* fmt, T arg1, Args... args)
values.emplace_back(arg1); values.emplace_back(arg1);
values.insert(values.end(), { args... }); values.insert(values.end(), { args... });
std::string result; std::string result;
format(result, fmt, values); formatAny(result, fmt, values);
return result; return result;
} }

View File

@ -20,6 +20,7 @@ using Poco::format;
using Poco::BadCastException; using Poco::BadCastException;
using Poco::Int64; using Poco::Int64;
using Poco::UInt64; using Poco::UInt64;
using Poco::Any;
FormatTest::FormatTest(const std::string& name): CppUnit::TestCase(name) FormatTest::FormatTest(const std::string& name): CppUnit::TestCase(name)
@ -453,6 +454,27 @@ void FormatTest::testIndex()
} }
void FormatTest::testAny()
{
Any a = 42;
std::string s(format("%d", a));
assertTrue (s == "42");
a = std::string("42");
s = format("%s", a);
assertTrue (s == "42");
a = 42.;
s = format("%f", a);
assertTrue (s.find("42.0") == 0);
s.clear();
std::vector<Any> av{ 42, std::string("42"), 42. };
format(s, "%d '%s' %f", av);
assertTrue (s.find("42 '42' 42.0") == 0);
}
void FormatTest::setUp() void FormatTest::setUp()
{ {
} }
@ -476,6 +498,7 @@ CppUnit::Test* FormatTest::suite()
CppUnit_addTest(pSuite, FormatTest, testString); CppUnit_addTest(pSuite, FormatTest, testString);
CppUnit_addTest(pSuite, FormatTest, testMultiple); CppUnit_addTest(pSuite, FormatTest, testMultiple);
CppUnit_addTest(pSuite, FormatTest, testIndex); CppUnit_addTest(pSuite, FormatTest, testIndex);
CppUnit_addTest(pSuite, FormatTest, testAny);
return pSuite; return pSuite;
} }

View File

@ -30,6 +30,7 @@ public:
void testString(); void testString();
void testMultiple(); void testMultiple();
void testIndex(); void testIndex();
void testAny();
void setUp(); void setUp();
void tearDown(); void tearDown();