From d7ac9af2d98b4fa266291c688644b5518df29306 Mon Sep 17 00:00:00 2001 From: sunmy2019 <59365878+sunmy2019@users.noreply.github.com> Date: Sat, 14 Mar 2026 12:37:00 +0800 Subject: [PATCH 1/9] Support fmt::runtime with wchar_t in fmt::format_to_n --- include/fmt/base.h | 16 ++++++++++++++++ include/fmt/xchar.h | 2 +- test/xchar-test.cc | 20 ++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/include/fmt/base.h b/include/fmt/base.h index 70f18c23271c..51976becced4 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -906,6 +906,9 @@ class locale_ref { FMT_END_EXPORT +// forward declaration +template class runtime_format_string; + namespace detail { // Specifies if `T` is a code unit type. @@ -935,6 +938,19 @@ constexpr auto to_string_view(basic_string_view s) -> basic_string_view { return s; } +template +constexpr auto to_string_view(runtime_format_string s) + -> basic_string_view { + return s.str; +} +// forward declaration of internal compile-time string type base +class compile_string; +template ::value&& + std::is_same::value)> +constexpr auto to_string_view(const S& s) -> basic_string_view { + return basic_string_view(s); +} template struct has_to_string_view : std::false_type {}; diff --git a/include/fmt/xchar.h b/include/fmt/xchar.h index 31706f96eaf6..acb6688ec004 100644 --- a/include/fmt/xchar.h +++ b/include/fmt/xchar.h @@ -285,7 +285,7 @@ template ::value)> inline auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args) -> format_to_n_result { - return vformat_to_n(out, n, fmt::basic_string_view(fmt), + return vformat_to_n(out, n, detail::to_string_view(fmt), fmt::make_format_args>(args...)); } diff --git a/test/xchar-test.cc b/test/xchar-test.cc index cfe8389da625..f6620ddf44be 100644 --- a/test/xchar-test.cc +++ b/test/xchar-test.cc @@ -146,6 +146,26 @@ TEST(format_test, wide_format_to_n) { EXPECT_EQ(L"BC x", fmt::wstring_view(buffer, 4)); } +TEST(format_test, wide_format_to_n_runtime) { + wchar_t buffer[4]; + buffer[3] = L'x'; + auto result = fmt::format_to_n(buffer, 3, fmt::runtime(L"{}"), 12345); + EXPECT_EQ(5u, result.size); + EXPECT_EQ(buffer + 3, result.out); + EXPECT_EQ(L"123x", fmt::wstring_view(buffer, 4)); + buffer[0] = L'x'; + buffer[1] = L'x'; + buffer[2] = L'x'; + result = fmt::format_to_n(buffer, 3, fmt::runtime(L"{}"), L'A'); + EXPECT_EQ(1u, result.size); + EXPECT_EQ(buffer + 1, result.out); + EXPECT_EQ(L"Axxx", fmt::wstring_view(buffer, 4)); + result = fmt::format_to_n(buffer, 3, fmt::runtime(L"{}{} "), L'B', L'C'); + EXPECT_EQ(3u, result.size); + EXPECT_EQ(buffer + 3, result.out); + EXPECT_EQ(L"BC x", fmt::wstring_view(buffer, 4)); +} + TEST(xchar_test, named_arg_udl) { using namespace fmt::literals; auto udl_a = From 670ddcdd042a575411582c1d469ea947b779a86f Mon Sep 17 00:00:00 2001 From: sunmy2019 <59365878+sunmy2019@users.noreply.github.com> Date: Sat, 14 Mar 2026 12:51:00 +0800 Subject: [PATCH 2/9] Change runtime_format_string and compile_string from class to struct --- include/fmt/base.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fmt/base.h b/include/fmt/base.h index 51976becced4..1aa34e2f62ff 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -907,7 +907,7 @@ class locale_ref { FMT_END_EXPORT // forward declaration -template class runtime_format_string; +template struct runtime_format_string; namespace detail { @@ -944,7 +944,7 @@ constexpr auto to_string_view(runtime_format_string s) return s.str; } // forward declaration of internal compile-time string type base -class compile_string; +struct compile_string; template ::value&& std::is_same::value)> From a7f568e740c9a041f6f9d958a2c570f1923b841a Mon Sep 17 00:00:00 2001 From: sunmy2019 <59365878+sunmy2019@users.noreply.github.com> Date: Wed, 18 Mar 2026 14:33:11 +0800 Subject: [PATCH 3/9] revert previous fix --- include/fmt/base.h | 16 ---------------- include/fmt/xchar.h | 2 +- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/include/fmt/base.h b/include/fmt/base.h index 1aa34e2f62ff..70f18c23271c 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -906,9 +906,6 @@ class locale_ref { FMT_END_EXPORT -// forward declaration -template struct runtime_format_string; - namespace detail { // Specifies if `T` is a code unit type. @@ -938,19 +935,6 @@ constexpr auto to_string_view(basic_string_view s) -> basic_string_view { return s; } -template -constexpr auto to_string_view(runtime_format_string s) - -> basic_string_view { - return s.str; -} -// forward declaration of internal compile-time string type base -struct compile_string; -template ::value&& - std::is_same::value)> -constexpr auto to_string_view(const S& s) -> basic_string_view { - return basic_string_view(s); -} template struct has_to_string_view : std::false_type {}; diff --git a/include/fmt/xchar.h b/include/fmt/xchar.h index acb6688ec004..31706f96eaf6 100644 --- a/include/fmt/xchar.h +++ b/include/fmt/xchar.h @@ -285,7 +285,7 @@ template ::value)> inline auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args) -> format_to_n_result { - return vformat_to_n(out, n, detail::to_string_view(fmt), + return vformat_to_n(out, n, fmt::basic_string_view(fmt), fmt::make_format_args>(args...)); } From c138aa21650d2646ef89a47d9d45859312866aca Mon Sep 17 00:00:00 2001 From: sunmy2019 <59365878+sunmy2019@users.noreply.github.com> Date: Wed, 18 Mar 2026 14:40:44 +0800 Subject: [PATCH 4/9] Refactor format_to_n to use wformat_string --- include/fmt/xchar.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/include/fmt/xchar.h b/include/fmt/xchar.h index 31706f96eaf6..b26ab574137a 100644 --- a/include/fmt/xchar.h +++ b/include/fmt/xchar.h @@ -279,14 +279,11 @@ inline auto vformat_to_n(OutputIt out, size_t n, basic_string_view fmt, return {buf.out(), buf.count()}; } -template , - FMT_ENABLE_IF(detail::is_output_iterator::value&& - detail::is_exotic_char::value)> -inline auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args) - -> format_to_n_result { - return vformat_to_n(out, n, fmt::basic_string_view(fmt), - fmt::make_format_args>(args...)); +template ::value)> +FMT_INLINE auto format_to_n(OutputIt out, size_t n, wformat_string fmt, + T&&... args) -> format_to_n_result { + return vformat_to_n(out, n, fmt.get(), fmt::make_wformat_args(args...)); } template Date: Fri, 20 Mar 2026 21:34:11 +0800 Subject: [PATCH 5/9] Add overload for format_to_n supporting non-char and non-wchar_t output iterators --- include/fmt/xchar.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/fmt/xchar.h b/include/fmt/xchar.h index b26ab574137a..6d95a7377972 100644 --- a/include/fmt/xchar.h +++ b/include/fmt/xchar.h @@ -286,6 +286,17 @@ FMT_INLINE auto format_to_n(OutputIt out, size_t n, wformat_string fmt, return vformat_to_n(out, n, fmt.get(), fmt::make_wformat_args(args...)); } +template , + FMT_ENABLE_IF(detail::is_output_iterator::value && + !std::is_same::value && + !std::is_same::value)> +inline auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args) + -> format_to_n_result { + return vformat_to_n(out, n, fmt::basic_string_view(fmt), + fmt::make_format_args>(args...)); +} + template , FMT_ENABLE_IF(detail::is_exotic_char::value)> From ada3f1d7bfcf2f982f36074379e442264c7a6be4 Mon Sep 17 00:00:00 2001 From: sunmy2019 <59365878+sunmy2019@users.noreply.github.com> Date: Sat, 21 Mar 2026 02:44:20 +0800 Subject: [PATCH 6/9] Add tests for format_to and format_to_n with wchar_t, char16_t, and char32_t --- test/xchar-test.cc | 77 +++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 25 deletions(-) diff --git a/test/xchar-test.cc b/test/xchar-test.cc index f6620ddf44be..2ff0f9b8bb27 100644 --- a/test/xchar-test.cc +++ b/test/xchar-test.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "fmt/chrono.h" @@ -97,11 +98,23 @@ TEST(xchar_test, compile_time_string) { #endif } -TEST(xchar_test, format_to) { - auto buf = std::vector(); - fmt::format_to(std::back_inserter(buf), L"{}{}", 42, L'\0'); - EXPECT_STREQ(buf.data(), L"42"); -} +#define WLIT(x) L##x +#define U16LIT(x) u##x +#define U32LIT(x) U##x + +#define DEFINE_FORMAT_TO_TEST(SUITE, NAME, CHAR_TYPE, LIT) \ + TEST(SUITE, NAME) { \ + auto buf = std::vector(); \ + fmt::format_to(std::back_inserter(buf), LIT("{}{}"), 42, LIT('\0')); \ + auto expected = std::vector{LIT('4'), LIT('2'), LIT('\0')}; \ + EXPECT_EQ(buf, expected); \ + } + +DEFINE_FORMAT_TO_TEST(xchar_test, wchar_format_to, wchar_t, WLIT) +DEFINE_FORMAT_TO_TEST(xchar_test, char16_format_to, char16_t, U16LIT) +DEFINE_FORMAT_TO_TEST(xchar_test, char32_format_to, char32_t, U32LIT) + +#undef DEFINE_FORMAT_TO_TEST TEST(xchar_test, compile_time_string_format_to) { std::wstring ws; @@ -126,27 +139,41 @@ TEST(xchar_test, format_as) { EXPECT_EQ(fmt::format(L"{}", test::struct_as_wstring_view()), L"foo"); } -TEST(format_test, wide_format_to_n) { - wchar_t buffer[4]; - buffer[3] = L'x'; - auto result = fmt::format_to_n(buffer, 3, L"{}", 12345); - EXPECT_EQ(5u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ(L"123x", fmt::wstring_view(buffer, 4)); - buffer[0] = L'x'; - buffer[1] = L'x'; - buffer[2] = L'x'; - result = fmt::format_to_n(buffer, 3, L"{}", L'A'); - EXPECT_EQ(1u, result.size); - EXPECT_EQ(buffer + 1, result.out); - EXPECT_EQ(L"Axxx", fmt::wstring_view(buffer, 4)); - result = fmt::format_to_n(buffer, 3, L"{}{} ", L'B', L'C'); - EXPECT_EQ(3u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ(L"BC x", fmt::wstring_view(buffer, 4)); -} +#define DEFINE_FORMAT_TO_N_TEST(SUITE, NAME, CHAR_TYPE, LIT) \ + TEST(SUITE, NAME) { \ + CHAR_TYPE buffer[4]; \ + buffer[3] = LIT('x'); \ + auto result = fmt::format_to_n(buffer, 3, LIT("{}"), 12345); \ + EXPECT_EQ(5u, result.size); \ + EXPECT_EQ(buffer + 3, result.out); \ + EXPECT_EQ(std::basic_string(LIT("123x")), \ + std::basic_string(buffer, 4)); \ + buffer[0] = LIT('x'); \ + buffer[1] = LIT('x'); \ + buffer[2] = LIT('x'); \ + result = fmt::format_to_n(buffer, 3, LIT("{}"), LIT('A')); \ + EXPECT_EQ(1u, result.size); \ + EXPECT_EQ(buffer + 1, result.out); \ + EXPECT_EQ(std::basic_string(LIT("Axxx")), \ + std::basic_string(buffer, 4)); \ + result = fmt::format_to_n(buffer, 3, LIT("{}{} "), LIT('B'), LIT('C')); \ + EXPECT_EQ(3u, result.size); \ + EXPECT_EQ(buffer + 3, result.out); \ + EXPECT_EQ(std::basic_string(LIT("BC x")), \ + std::basic_string(buffer, 4)); \ + } + +DEFINE_FORMAT_TO_N_TEST(xchar_test, wchar_format_to_n, wchar_t, WLIT) +DEFINE_FORMAT_TO_N_TEST(xchar_test, char16_format_to_n, char16_t, U16LIT) +DEFINE_FORMAT_TO_N_TEST(xchar_test, char32_format_to_n, char32_t, U32LIT) + +#undef DEFINE_FORMAT_TO_N_TEST + +#undef U32LIT +#undef U16LIT +#undef WLIT -TEST(format_test, wide_format_to_n_runtime) { +TEST(xchar_test, wchar_format_to_n_runtime) { wchar_t buffer[4]; buffer[3] = L'x'; auto result = fmt::format_to_n(buffer, 3, fmt::runtime(L"{}"), 12345); From dab57dcde374c3a48ab2fdfe575943f62753f12d Mon Sep 17 00:00:00 2001 From: sunmy2019 <59365878+sunmy2019@users.noreply.github.com> Date: Sat, 21 Mar 2026 03:16:03 +0800 Subject: [PATCH 7/9] Refactor xchar tests to use xchar_helpers for format_to and format_to_n --- test/xchar-test.cc | 106 +++++++++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 43 deletions(-) diff --git a/test/xchar-test.cc b/test/xchar-test.cc index 2ff0f9b8bb27..4ea199803491 100644 --- a/test/xchar-test.cc +++ b/test/xchar-test.cc @@ -98,23 +98,51 @@ TEST(xchar_test, compile_time_string) { #endif } +template struct xchar_helpers; + +#define DEFINE_XCHAR_HELPERS(CHAR_TYPE, LIT) \ + template <> struct xchar_helpers { \ + static constexpr const CHAR_TYPE* fmt1() { return LIT("{}"); } \ + static constexpr const CHAR_TYPE* fmt2() { return LIT("{}{}"); } \ + static constexpr const CHAR_TYPE* fmt2sp() { return LIT("{}{} "); } \ + static constexpr const CHAR_TYPE* s123x() { return LIT("123x"); } \ + static constexpr const CHAR_TYPE* sAxxx() { return LIT("Axxx"); } \ + static constexpr const CHAR_TYPE* sBCx() { return LIT("BC x"); } \ + } + #define WLIT(x) L##x #define U16LIT(x) u##x #define U32LIT(x) U##x -#define DEFINE_FORMAT_TO_TEST(SUITE, NAME, CHAR_TYPE, LIT) \ - TEST(SUITE, NAME) { \ - auto buf = std::vector(); \ - fmt::format_to(std::back_inserter(buf), LIT("{}{}"), 42, LIT('\0')); \ - auto expected = std::vector{LIT('4'), LIT('2'), LIT('\0')}; \ - EXPECT_EQ(buf, expected); \ - } +DEFINE_XCHAR_HELPERS(wchar_t, WLIT); +DEFINE_XCHAR_HELPERS(char16_t, U16LIT); +DEFINE_XCHAR_HELPERS(char32_t, U32LIT); + +#undef U32LIT +#undef U16LIT +#undef WLIT +#undef DEFINE_XCHAR_HELPERS + +template class xchar_format_test : public testing::Test {}; + +using wide_char_types = testing::Types; +TYPED_TEST_SUITE(xchar_format_test, wide_char_types); -DEFINE_FORMAT_TO_TEST(xchar_test, wchar_format_to, wchar_t, WLIT) -DEFINE_FORMAT_TO_TEST(xchar_test, char16_format_to, char16_t, U16LIT) -DEFINE_FORMAT_TO_TEST(xchar_test, char32_format_to, char32_t, U32LIT) +TYPED_TEST(xchar_format_test, format_to) { + using H = xchar_helpers; + auto buf = std::vector(); + fmt::format_to(std::back_inserter(buf), H::fmt2(), 42, TypeParam('\0')); + auto expected = + std::vector{TypeParam('4'), TypeParam('2'), TypeParam('\0')}; + EXPECT_EQ(buf, expected); +} -#undef DEFINE_FORMAT_TO_TEST +TEST(xchar_test, wchar_format_to_runtime) { + auto buf = std::vector(); + fmt::format_to(std::back_inserter(buf), fmt::runtime(L"{}{}"), 42, L'\0'); + auto expected = std::vector{L'4', L'2', L'\0'}; + EXPECT_EQ(buf, expected); +} TEST(xchar_test, compile_time_string_format_to) { std::wstring ws; @@ -139,39 +167,31 @@ TEST(xchar_test, format_as) { EXPECT_EQ(fmt::format(L"{}", test::struct_as_wstring_view()), L"foo"); } -#define DEFINE_FORMAT_TO_N_TEST(SUITE, NAME, CHAR_TYPE, LIT) \ - TEST(SUITE, NAME) { \ - CHAR_TYPE buffer[4]; \ - buffer[3] = LIT('x'); \ - auto result = fmt::format_to_n(buffer, 3, LIT("{}"), 12345); \ - EXPECT_EQ(5u, result.size); \ - EXPECT_EQ(buffer + 3, result.out); \ - EXPECT_EQ(std::basic_string(LIT("123x")), \ - std::basic_string(buffer, 4)); \ - buffer[0] = LIT('x'); \ - buffer[1] = LIT('x'); \ - buffer[2] = LIT('x'); \ - result = fmt::format_to_n(buffer, 3, LIT("{}"), LIT('A')); \ - EXPECT_EQ(1u, result.size); \ - EXPECT_EQ(buffer + 1, result.out); \ - EXPECT_EQ(std::basic_string(LIT("Axxx")), \ - std::basic_string(buffer, 4)); \ - result = fmt::format_to_n(buffer, 3, LIT("{}{} "), LIT('B'), LIT('C')); \ - EXPECT_EQ(3u, result.size); \ - EXPECT_EQ(buffer + 3, result.out); \ - EXPECT_EQ(std::basic_string(LIT("BC x")), \ - std::basic_string(buffer, 4)); \ - } - -DEFINE_FORMAT_TO_N_TEST(xchar_test, wchar_format_to_n, wchar_t, WLIT) -DEFINE_FORMAT_TO_N_TEST(xchar_test, char16_format_to_n, char16_t, U16LIT) -DEFINE_FORMAT_TO_N_TEST(xchar_test, char32_format_to_n, char32_t, U32LIT) - -#undef DEFINE_FORMAT_TO_N_TEST +TYPED_TEST(xchar_format_test, format_to_n) { + using H = xchar_helpers; + TypeParam buffer[4]; + buffer[3] = TypeParam('x'); + auto result = fmt::format_to_n(buffer, 3, H::fmt1(), 12345); + EXPECT_EQ(5u, result.size); + EXPECT_EQ(buffer + 3, result.out); + EXPECT_EQ(std::basic_string(H::s123x()), + std::basic_string(buffer, 4)); + buffer[0] = TypeParam('x'); + buffer[1] = TypeParam('x'); + buffer[2] = TypeParam('x'); + result = fmt::format_to_n(buffer, 3, H::fmt1(), TypeParam('A')); + EXPECT_EQ(1u, result.size); + EXPECT_EQ(buffer + 1, result.out); + EXPECT_EQ(std::basic_string(H::sAxxx()), + std::basic_string(buffer, 4)); + result = + fmt::format_to_n(buffer, 3, H::fmt2sp(), TypeParam('B'), TypeParam('C')); + EXPECT_EQ(3u, result.size); + EXPECT_EQ(buffer + 3, result.out); + EXPECT_EQ(std::basic_string(H::sBCx()), + std::basic_string(buffer, 4)); +} -#undef U32LIT -#undef U16LIT -#undef WLIT TEST(xchar_test, wchar_format_to_n_runtime) { wchar_t buffer[4]; From 1775d0e139abf23aba40cf0e687aabe308f578ba Mon Sep 17 00:00:00 2001 From: sunmy2019 <59365878+sunmy2019@users.noreply.github.com> Date: Sat, 21 Mar 2026 05:23:03 +0800 Subject: [PATCH 8/9] Revert "Refactor xchar tests to use xchar_helpers for format_to and format_to_n" This reverts commit dab57dcde374c3a48ab2fdfe575943f62753f12d. --- test/xchar-test.cc | 106 ++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 63 deletions(-) diff --git a/test/xchar-test.cc b/test/xchar-test.cc index 4ea199803491..2ff0f9b8bb27 100644 --- a/test/xchar-test.cc +++ b/test/xchar-test.cc @@ -98,51 +98,23 @@ TEST(xchar_test, compile_time_string) { #endif } -template struct xchar_helpers; - -#define DEFINE_XCHAR_HELPERS(CHAR_TYPE, LIT) \ - template <> struct xchar_helpers { \ - static constexpr const CHAR_TYPE* fmt1() { return LIT("{}"); } \ - static constexpr const CHAR_TYPE* fmt2() { return LIT("{}{}"); } \ - static constexpr const CHAR_TYPE* fmt2sp() { return LIT("{}{} "); } \ - static constexpr const CHAR_TYPE* s123x() { return LIT("123x"); } \ - static constexpr const CHAR_TYPE* sAxxx() { return LIT("Axxx"); } \ - static constexpr const CHAR_TYPE* sBCx() { return LIT("BC x"); } \ - } - #define WLIT(x) L##x #define U16LIT(x) u##x #define U32LIT(x) U##x -DEFINE_XCHAR_HELPERS(wchar_t, WLIT); -DEFINE_XCHAR_HELPERS(char16_t, U16LIT); -DEFINE_XCHAR_HELPERS(char32_t, U32LIT); - -#undef U32LIT -#undef U16LIT -#undef WLIT -#undef DEFINE_XCHAR_HELPERS - -template class xchar_format_test : public testing::Test {}; - -using wide_char_types = testing::Types; -TYPED_TEST_SUITE(xchar_format_test, wide_char_types); +#define DEFINE_FORMAT_TO_TEST(SUITE, NAME, CHAR_TYPE, LIT) \ + TEST(SUITE, NAME) { \ + auto buf = std::vector(); \ + fmt::format_to(std::back_inserter(buf), LIT("{}{}"), 42, LIT('\0')); \ + auto expected = std::vector{LIT('4'), LIT('2'), LIT('\0')}; \ + EXPECT_EQ(buf, expected); \ + } -TYPED_TEST(xchar_format_test, format_to) { - using H = xchar_helpers; - auto buf = std::vector(); - fmt::format_to(std::back_inserter(buf), H::fmt2(), 42, TypeParam('\0')); - auto expected = - std::vector{TypeParam('4'), TypeParam('2'), TypeParam('\0')}; - EXPECT_EQ(buf, expected); -} +DEFINE_FORMAT_TO_TEST(xchar_test, wchar_format_to, wchar_t, WLIT) +DEFINE_FORMAT_TO_TEST(xchar_test, char16_format_to, char16_t, U16LIT) +DEFINE_FORMAT_TO_TEST(xchar_test, char32_format_to, char32_t, U32LIT) -TEST(xchar_test, wchar_format_to_runtime) { - auto buf = std::vector(); - fmt::format_to(std::back_inserter(buf), fmt::runtime(L"{}{}"), 42, L'\0'); - auto expected = std::vector{L'4', L'2', L'\0'}; - EXPECT_EQ(buf, expected); -} +#undef DEFINE_FORMAT_TO_TEST TEST(xchar_test, compile_time_string_format_to) { std::wstring ws; @@ -167,31 +139,39 @@ TEST(xchar_test, format_as) { EXPECT_EQ(fmt::format(L"{}", test::struct_as_wstring_view()), L"foo"); } -TYPED_TEST(xchar_format_test, format_to_n) { - using H = xchar_helpers; - TypeParam buffer[4]; - buffer[3] = TypeParam('x'); - auto result = fmt::format_to_n(buffer, 3, H::fmt1(), 12345); - EXPECT_EQ(5u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ(std::basic_string(H::s123x()), - std::basic_string(buffer, 4)); - buffer[0] = TypeParam('x'); - buffer[1] = TypeParam('x'); - buffer[2] = TypeParam('x'); - result = fmt::format_to_n(buffer, 3, H::fmt1(), TypeParam('A')); - EXPECT_EQ(1u, result.size); - EXPECT_EQ(buffer + 1, result.out); - EXPECT_EQ(std::basic_string(H::sAxxx()), - std::basic_string(buffer, 4)); - result = - fmt::format_to_n(buffer, 3, H::fmt2sp(), TypeParam('B'), TypeParam('C')); - EXPECT_EQ(3u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ(std::basic_string(H::sBCx()), - std::basic_string(buffer, 4)); -} +#define DEFINE_FORMAT_TO_N_TEST(SUITE, NAME, CHAR_TYPE, LIT) \ + TEST(SUITE, NAME) { \ + CHAR_TYPE buffer[4]; \ + buffer[3] = LIT('x'); \ + auto result = fmt::format_to_n(buffer, 3, LIT("{}"), 12345); \ + EXPECT_EQ(5u, result.size); \ + EXPECT_EQ(buffer + 3, result.out); \ + EXPECT_EQ(std::basic_string(LIT("123x")), \ + std::basic_string(buffer, 4)); \ + buffer[0] = LIT('x'); \ + buffer[1] = LIT('x'); \ + buffer[2] = LIT('x'); \ + result = fmt::format_to_n(buffer, 3, LIT("{}"), LIT('A')); \ + EXPECT_EQ(1u, result.size); \ + EXPECT_EQ(buffer + 1, result.out); \ + EXPECT_EQ(std::basic_string(LIT("Axxx")), \ + std::basic_string(buffer, 4)); \ + result = fmt::format_to_n(buffer, 3, LIT("{}{} "), LIT('B'), LIT('C')); \ + EXPECT_EQ(3u, result.size); \ + EXPECT_EQ(buffer + 3, result.out); \ + EXPECT_EQ(std::basic_string(LIT("BC x")), \ + std::basic_string(buffer, 4)); \ + } + +DEFINE_FORMAT_TO_N_TEST(xchar_test, wchar_format_to_n, wchar_t, WLIT) +DEFINE_FORMAT_TO_N_TEST(xchar_test, char16_format_to_n, char16_t, U16LIT) +DEFINE_FORMAT_TO_N_TEST(xchar_test, char32_format_to_n, char32_t, U32LIT) + +#undef DEFINE_FORMAT_TO_N_TEST +#undef U32LIT +#undef U16LIT +#undef WLIT TEST(xchar_test, wchar_format_to_n_runtime) { wchar_t buffer[4]; From acead0300076e785ed1f67c62b6b3f9e93732d8f Mon Sep 17 00:00:00 2001 From: sunmy2019 <59365878+sunmy2019@users.noreply.github.com> Date: Sat, 21 Mar 2026 05:23:05 +0800 Subject: [PATCH 9/9] Revert "Add tests for format_to and format_to_n with wchar_t, char16_t, and char32_t" This reverts commit ada3f1d7bfcf2f982f36074379e442264c7a6be4. --- test/xchar-test.cc | 77 +++++++++++++++------------------------------- 1 file changed, 25 insertions(+), 52 deletions(-) diff --git a/test/xchar-test.cc b/test/xchar-test.cc index 2ff0f9b8bb27..f6620ddf44be 100644 --- a/test/xchar-test.cc +++ b/test/xchar-test.cc @@ -10,7 +10,6 @@ #include #include #include -#include #include #include "fmt/chrono.h" @@ -98,23 +97,11 @@ TEST(xchar_test, compile_time_string) { #endif } -#define WLIT(x) L##x -#define U16LIT(x) u##x -#define U32LIT(x) U##x - -#define DEFINE_FORMAT_TO_TEST(SUITE, NAME, CHAR_TYPE, LIT) \ - TEST(SUITE, NAME) { \ - auto buf = std::vector(); \ - fmt::format_to(std::back_inserter(buf), LIT("{}{}"), 42, LIT('\0')); \ - auto expected = std::vector{LIT('4'), LIT('2'), LIT('\0')}; \ - EXPECT_EQ(buf, expected); \ - } - -DEFINE_FORMAT_TO_TEST(xchar_test, wchar_format_to, wchar_t, WLIT) -DEFINE_FORMAT_TO_TEST(xchar_test, char16_format_to, char16_t, U16LIT) -DEFINE_FORMAT_TO_TEST(xchar_test, char32_format_to, char32_t, U32LIT) - -#undef DEFINE_FORMAT_TO_TEST +TEST(xchar_test, format_to) { + auto buf = std::vector(); + fmt::format_to(std::back_inserter(buf), L"{}{}", 42, L'\0'); + EXPECT_STREQ(buf.data(), L"42"); +} TEST(xchar_test, compile_time_string_format_to) { std::wstring ws; @@ -139,41 +126,27 @@ TEST(xchar_test, format_as) { EXPECT_EQ(fmt::format(L"{}", test::struct_as_wstring_view()), L"foo"); } -#define DEFINE_FORMAT_TO_N_TEST(SUITE, NAME, CHAR_TYPE, LIT) \ - TEST(SUITE, NAME) { \ - CHAR_TYPE buffer[4]; \ - buffer[3] = LIT('x'); \ - auto result = fmt::format_to_n(buffer, 3, LIT("{}"), 12345); \ - EXPECT_EQ(5u, result.size); \ - EXPECT_EQ(buffer + 3, result.out); \ - EXPECT_EQ(std::basic_string(LIT("123x")), \ - std::basic_string(buffer, 4)); \ - buffer[0] = LIT('x'); \ - buffer[1] = LIT('x'); \ - buffer[2] = LIT('x'); \ - result = fmt::format_to_n(buffer, 3, LIT("{}"), LIT('A')); \ - EXPECT_EQ(1u, result.size); \ - EXPECT_EQ(buffer + 1, result.out); \ - EXPECT_EQ(std::basic_string(LIT("Axxx")), \ - std::basic_string(buffer, 4)); \ - result = fmt::format_to_n(buffer, 3, LIT("{}{} "), LIT('B'), LIT('C')); \ - EXPECT_EQ(3u, result.size); \ - EXPECT_EQ(buffer + 3, result.out); \ - EXPECT_EQ(std::basic_string(LIT("BC x")), \ - std::basic_string(buffer, 4)); \ - } - -DEFINE_FORMAT_TO_N_TEST(xchar_test, wchar_format_to_n, wchar_t, WLIT) -DEFINE_FORMAT_TO_N_TEST(xchar_test, char16_format_to_n, char16_t, U16LIT) -DEFINE_FORMAT_TO_N_TEST(xchar_test, char32_format_to_n, char32_t, U32LIT) - -#undef DEFINE_FORMAT_TO_N_TEST - -#undef U32LIT -#undef U16LIT -#undef WLIT +TEST(format_test, wide_format_to_n) { + wchar_t buffer[4]; + buffer[3] = L'x'; + auto result = fmt::format_to_n(buffer, 3, L"{}", 12345); + EXPECT_EQ(5u, result.size); + EXPECT_EQ(buffer + 3, result.out); + EXPECT_EQ(L"123x", fmt::wstring_view(buffer, 4)); + buffer[0] = L'x'; + buffer[1] = L'x'; + buffer[2] = L'x'; + result = fmt::format_to_n(buffer, 3, L"{}", L'A'); + EXPECT_EQ(1u, result.size); + EXPECT_EQ(buffer + 1, result.out); + EXPECT_EQ(L"Axxx", fmt::wstring_view(buffer, 4)); + result = fmt::format_to_n(buffer, 3, L"{}{} ", L'B', L'C'); + EXPECT_EQ(3u, result.size); + EXPECT_EQ(buffer + 3, result.out); + EXPECT_EQ(L"BC x", fmt::wstring_view(buffer, 4)); +} -TEST(xchar_test, wchar_format_to_n_runtime) { +TEST(format_test, wide_format_to_n_runtime) { wchar_t buffer[4]; buffer[3] = L'x'; auto result = fmt::format_to_n(buffer, 3, fmt::runtime(L"{}"), 12345);