From 080b1d0219b9f90a7faf311dfa0fb613c34d552b Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 7 Nov 2026 07:27:07 -0800 Subject: [PATCH] Avoid a path string copy and move wide path tests to xchar-test FMT_STATIC_THOUSANDS_SEPARATOR has had no effect since 11.1.0, so drop its guard. --- include/fmt/std.h | 2 +- test/std-test.cc | 9 +-------- test/xchar-test.cc | 27 ++++++++++++++++++--------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/include/fmt/std.h b/include/fmt/std.h index 88783618..162e369f 100644 --- a/include/fmt/std.h +++ b/include/fmt/std.h @@ -107,7 +107,7 @@ auto get_path_string(const std::basic_string& native) { std::is_same_v) { return to_utf8(native, to_utf8_error_policy::wtf); } else if constexpr (std::is_same_v) { - return native; + return basic_string_view(native); } else { return std::filesystem::path(native).string(); } diff --git a/test/std-test.cc b/test/std-test.cc index 7d992584..96c08664 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -14,7 +14,6 @@ #include "fmt/os.h" // fmt::system_category #include "fmt/ranges.h" -#include "fmt/xchar.h" #include "gtest-extra.h" // StartsWith #ifdef __cpp_lib_filesystem @@ -35,16 +34,10 @@ TEST(std_test, path) { EXPECT_EQ(fmt::format("{:g}", path("/usr/bin")), "/usr/bin"); // libstdc++ collapses repeated separators in the generic format. - const path repeated = "a//b"; - EXPECT_EQ(fmt::format("{:g}", repeated), repeated.generic_string()); - EXPECT_EQ(fmt::format(L"{:g}", repeated), repeated.generic_wstring()); - EXPECT_EQ(fmt::format(L"{:?g}", repeated), - L"\"" + repeated.generic_wstring() + L"\""); + EXPECT_EQ(fmt::format("{:g}", path("a//b")), path("a//b").generic_string()); # ifdef _WIN32 EXPECT_EQ(fmt::format("{}", path("C:\\foo")), "C:\\foo"); EXPECT_EQ(fmt::format("{:g}", path("C:\\foo")), "C:/foo"); - EXPECT_EQ(fmt::format(L"{}", path(L"C:\\foo")), L"C:\\foo"); - EXPECT_EQ(fmt::format(L"{:g}", path(L"C:\\foo")), L"C:/foo"); EXPECT_EQ(fmt::format("{}", path(L"\x0428\x0447\x0443\x0447\x044B\x043D\x0448" L"\x0447\x044B\x043D\x0430")), diff --git a/test/xchar-test.cc b/test/xchar-test.cc index 8de9fdef..df59f780 100644 --- a/test/xchar-test.cc +++ b/test/xchar-test.cc @@ -300,8 +300,6 @@ TEST(xchar_test, escape_string) { TEST(xchar_test, to_wstring) { EXPECT_EQ(L"42", fmt::to_wstring(42)); } -#ifndef FMT_STATIC_THOUSANDS_SEPARATOR - template struct numpunct : std::numpunct { protected: Char do_decimal_point() const override { return '?'; } @@ -451,26 +449,37 @@ TEST(std_test_xchar, complex) { } TEST(std_test_xchar, optional) { -# ifdef __cpp_lib_optional +#ifdef __cpp_lib_optional EXPECT_EQ(fmt::format(L"{}", std::optional{L'C'}), L"optional(\'C\')"); EXPECT_EQ(fmt::format(L"{}", std::optional{std::wstring{L"wide string"}}), L"optional(\"wide string\")"); -# endif +#endif } TEST(std_test_xchar, variant) { -# ifdef __cpp_lib_variant +#ifdef __cpp_lib_variant EXPECT_EQ(fmt::format(L"{}", std::monostate{}), L"monostate"); EXPECT_EQ(fmt::format(L"{}", std::variant{L"wide"}), L"variant(\"wide\")"); -# endif +#endif } TEST(std_test_xchar, expected) { -# ifdef __cpp_lib_expected +#ifdef __cpp_lib_expected EXPECT_EQ(fmt::format(L"{}", std::expected{1}), L"expected(1)"); EXPECT_EQ(fmt::format(L"{}", std::unexpected(1)), L"unexpected(1)"); -# endif +#endif } -#endif // FMT_STATIC_THOUSANDS_SEPARATOR +TEST(std_test_xchar, path) { +#ifdef __cpp_lib_filesystem + using std::filesystem::path; + // libstdc++ collapses repeated separators in the generic format. + auto p = path("a//b"); + EXPECT_EQ(fmt::format(L"{:g}", p), p.generic_wstring()); + EXPECT_EQ(fmt::format(L"{:?g}", p), L"\"" + p.generic_wstring() + L"\""); + // The generic format uses slashes on Windows. + auto q = path("C:\\foo"); + EXPECT_EQ(fmt::format(L"{:g}", q), q.generic_wstring()); +#endif +}