diff --git a/include/fmt/std.h b/include/fmt/std.h index 2bab00f2..d0c22f0d 100644 --- a/include/fmt/std.h +++ b/include/fmt/std.h @@ -404,6 +404,15 @@ struct formatter, Char, std::enable_if_t<(std::is_void::value || is_formattable::value) && is_formattable::value>> { + private: + static constexpr basic_string_view expected_prefix = + detail::string_literal{}; + static constexpr basic_string_view unexpected_prefix = + detail::string_literal{}; + + public: FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { return ctx.begin(); } @@ -414,11 +423,11 @@ struct formatter, Char, auto out = ctx.out(); if (value.has_value()) { - out = detail::write(out, "expected("); + out = detail::write(out, expected_prefix); if constexpr (!std::is_void::value) out = detail::write_escaped_alternative(out, *value, ctx); } else { - out = detail::write(out, "unexpected("); + out = detail::write(out, unexpected_prefix); out = detail::write_escaped_alternative(out, value.error(), ctx); } *out++ = ')'; @@ -429,6 +438,12 @@ struct formatter, Char, template struct formatter, Char, std::enable_if_t::value>> { + private: + static constexpr basic_string_view unexpected_prefix = + detail::string_literal{}; + + public: FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { return ctx.begin(); } @@ -438,7 +453,7 @@ struct formatter, Char, -> decltype(ctx.out()) { auto out = ctx.out(); - out = detail::write(out, "unexpected("); + out = detail::write(out, unexpected_prefix); out = detail::write_escaped_alternative(out, value.error(), ctx); *out++ = ')'; @@ -474,6 +489,12 @@ template struct is_variant_like { }; template struct formatter { + private: + static constexpr basic_string_view monostate_str = + detail::string_literal{}; + + public: FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { return ctx.begin(); } @@ -481,7 +502,7 @@ template struct formatter { template FMT_CONSTEXPR auto format(const std::monostate&, FormatContext& ctx) const -> decltype(ctx.out()) { - return detail::write(ctx.out(), "monostate"); + return detail::write(ctx.out(), monostate_str); } }; @@ -490,6 +511,15 @@ struct formatter, detail::is_variant_formattable>>> { + private: + static constexpr basic_string_view variant_prefix = + detail::string_literal{}; + static constexpr basic_string_view valueless_str = + detail::string_literal{}; + + public: FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { return ctx.begin(); } @@ -499,7 +529,7 @@ struct formatter decltype(ctx.out()) { auto out = ctx.out(); - out = detail::write(out, "variant("); + out = detail::write(out, variant_prefix); FMT_TRY { std::visit( [&](const auto& v) { @@ -508,7 +538,7 @@ struct formatter(out, "valueless by exception"); + detail::write(out, valueless_str); } *out++ = ')'; return out; diff --git a/test/xchar-test.cc b/test/xchar-test.cc index 6fc174ef..987f58ac 100644 --- a/test/xchar-test.cc +++ b/test/xchar-test.cc @@ -455,4 +455,21 @@ TEST(std_test_xchar, optional) { # endif } +TEST(std_test_xchar, 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 +} + +TEST(std_test_xchar, expected) { +# ifdef __cpp_lib_expected + EXPECT_EQ(fmt::format(L"{}", std::expected{1}), L"expected(1)"); + EXPECT_EQ(fmt::format(L"{}", std::expected{std::unexpected(1)}), + L"unexpected(1)"); + EXPECT_EQ(fmt::format(L"{}", std::unexpected(1)), L"unexpected(1)"); +# endif +} + #endif // FMT_STATIC_THOUSANDS_SEPARATOR