From b35de87ad91951c8269fe533dca6aebc3e0a25ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9=C3=A9n?= <43650869+17steen@users.noreply.github.com> Date: Thu, 12 Feb 2026 00:06:59 +0100 Subject: [PATCH] std.h: Allow formatting std::unexpected type. (#4675) In some cases, people might want to format the std::unexpected type itself, independent of the value type, this commit makes it possible. Co-authored-by: Robin Oger --- include/fmt/std.h | 20 ++++++++++++++++++++ test/std-test.cc | 10 +++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/include/fmt/std.h b/include/fmt/std.h index 8a9dd8c4..b6b98bb7 100644 --- a/include/fmt/std.h +++ b/include/fmt/std.h @@ -454,6 +454,26 @@ struct formatter, Char, return out; } }; + +template +struct formatter, Char, + std::enable_if_t::value>> { + FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { + return ctx.begin(); + } + + template + auto format(const std::unexpected& value, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); + + out = detail::write(out, "unexpected("); + out = detail::write_escaped_alternative(out, value.error(), ctx); + + *out++ = ')'; + return out; + } +}; #endif // __cpp_lib_expected #ifdef __cpp_lib_source_location diff --git a/test/std-test.cc b/test/std-test.cc index a3c54dc8..1684a5ed 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -12,7 +12,7 @@ #include #include -#include "fmt/os.h" // fmt::system_category +#include "fmt/os.h" // fmt::system_category #include "fmt/ranges.h" #include "gtest-extra.h" // StartsWith @@ -176,6 +176,14 @@ TEST(std_test, expected) { (fmt::is_formattable>::value)); EXPECT_TRUE((fmt::is_formattable>::value)); EXPECT_TRUE((fmt::is_formattable>::value)); + + EXPECT_EQ(fmt::format("{}", std::unexpected{1}), "unexpected(1)"); + EXPECT_EQ(fmt::format("{}", std::unexpected{"test"}), + "unexpected(\"test\")"); + + EXPECT_EQ(fmt::format("{}", std::unexpected{'a'}), "unexpected('a')"); + + EXPECT_FALSE((fmt::is_formattable>::value)); #endif }