From e724bbea162839133b26a44313673bf14751fe3b Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 24 Aug 2022 10:00:12 -0700 Subject: [PATCH] Fix wchar_t corner cases --- include/fmt/core.h | 2 +- include/fmt/xchar.h | 12 +++++------- test/xchar-test.cc | 11 ++++++----- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 87444e03..b0eef0ae 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -3167,7 +3167,7 @@ template class basic_format_string { #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 // Workaround broken conversion on older gcc. template using format_string = string_view; -inline auto runtime(string_view s) -> basic_string_view { return s; } +inline auto runtime(string_view s) -> string_view { return s; } #else template using format_string = basic_format_string...>; diff --git a/include/fmt/xchar.h b/include/fmt/xchar.h index faadf230..3b5bc15c 100644 --- a/include/fmt/xchar.h +++ b/include/fmt/xchar.h @@ -29,9 +29,11 @@ using wmemory_buffer = basic_memory_buffer; #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 // Workaround broken conversion on older gcc. template using wformat_string = wstring_view; +inline auto runtime(wstring_view s) -> wstring_view { return s; } #else template using wformat_string = basic_format_string...>; +inline auto runtime(wstring_view s) -> basic_runtime { return {{s}}; } #endif template <> struct is_char : std::true_type {}; @@ -81,20 +83,16 @@ auto vformat(basic_string_view format_str, return to_string(buffer); } -#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 409 -template -using wformat_string = basic_format_string...>; -#endif - template auto format(wformat_string fmt, T&&... args) -> std::wstring { - return vformat(fmt, fmt::make_wformat_args(args...)); + return vformat(fmt::wstring_view(fmt), fmt::make_wformat_args(args...)); } // Pass char_t as a default template parameter instead of using // std::basic_string> to reduce the symbol size. template , - FMT_ENABLE_IF(!std::is_same::value)> + FMT_ENABLE_IF(!std::is_same::value && + !std::is_same::value)> auto format(const S& format_str, Args&&... args) -> std::basic_string { return vformat(detail::to_string_view(format_str), fmt::make_format_args>(args...)); diff --git a/test/xchar-test.cc b/test/xchar-test.cc index b3da1f55..290042a6 100644 --- a/test/xchar-test.cc +++ b/test/xchar-test.cc @@ -84,7 +84,7 @@ TEST(xchar_test, format) { EXPECT_EQ(L"4.2", fmt::format(L"{}", 4.2)); EXPECT_EQ(L"abc", fmt::format(L"{}", L"abc")); EXPECT_EQ(L"z", fmt::format(L"{}", L'z')); - EXPECT_THROW(fmt::format(L"{:*\x343E}", 42), fmt::format_error); + EXPECT_THROW(fmt::format(fmt::runtime(L"{:*\x343E}"), 42), fmt::format_error); EXPECT_EQ(L"true", fmt::format(L"{}", true)); EXPECT_EQ(L"a", fmt::format(L"{0}", 'a')); EXPECT_EQ(L"a", fmt::format(L"{0}", L'a')); @@ -98,8 +98,9 @@ TEST(xchar_test, is_formattable) { } TEST(xchar_test, compile_time_string) { + EXPECT_EQ(fmt::format(fmt::wformat_string(L"{}"), 42), L"42"); #if defined(FMT_USE_STRING_VIEW) && FMT_CPLUSPLUS >= 201703L - EXPECT_EQ(L"42", fmt::format(FMT_STRING(std::wstring_view(L"{}")), 42)); + EXPECT_EQ(fmt::format(FMT_STRING(std::wstring_view(L"{}")), 42), L"42"); #endif } @@ -246,7 +247,7 @@ TEST(xchar_test, sign_not_truncated) { wchar_t format_str[] = { L'{', L':', '+' | static_cast(1 << fmt::detail::num_bits()), L'}', 0}; - EXPECT_THROW(fmt::format(format_str, 42), fmt::format_error); + EXPECT_THROW(fmt::format(fmt::runtime(format_str), 42), fmt::format_error); } TEST(xchar_test, chrono) { @@ -311,8 +312,8 @@ TEST(chrono_test_wchar, time_point) { auto sys_output = system_wcsftime(spec, &tm); auto fmt_spec = fmt::format(L"{{:{}}}", spec); - EXPECT_EQ(sys_output, fmt::format(fmt_spec, t1)); - EXPECT_EQ(sys_output, fmt::format(fmt_spec, tm)); + EXPECT_EQ(sys_output, fmt::format(fmt::runtime(fmt_spec), t1)); + EXPECT_EQ(sys_output, fmt::format(fmt::runtime(fmt_spec), tm)); } }