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 <robin.oger.work@gmail.com>
This commit is contained in:
Stéén 2026-02-12 00:06:59 +01:00 committed by GitHub
parent f99d530247
commit b35de87ad9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 1 deletions

View File

@ -454,6 +454,26 @@ struct formatter<std::expected<T, E>, Char,
return out; return out;
} }
}; };
template <typename E, typename Char>
struct formatter<std::unexpected<E>, Char,
std::enable_if_t<is_formattable<E, Char>::value>> {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
return ctx.begin();
}
template <typename FormatContext>
auto format(const std::unexpected<E>& value, FormatContext& ctx) const
-> decltype(ctx.out()) {
auto out = ctx.out();
out = detail::write<Char>(out, "unexpected(");
out = detail::write_escaped_alternative<Char>(out, value.error(), ctx);
*out++ = ')';
return out;
}
};
#endif // __cpp_lib_expected #endif // __cpp_lib_expected
#ifdef __cpp_lib_source_location #ifdef __cpp_lib_source_location

View File

@ -12,7 +12,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "fmt/os.h" // fmt::system_category #include "fmt/os.h" // fmt::system_category
#include "fmt/ranges.h" #include "fmt/ranges.h"
#include "gtest-extra.h" // StartsWith #include "gtest-extra.h" // StartsWith
@ -176,6 +176,14 @@ TEST(std_test, expected) {
(fmt::is_formattable<std::expected<int, unformattable2>>::value)); (fmt::is_formattable<std::expected<int, unformattable2>>::value));
EXPECT_TRUE((fmt::is_formattable<std::expected<int, int>>::value)); EXPECT_TRUE((fmt::is_formattable<std::expected<int, int>>::value));
EXPECT_TRUE((fmt::is_formattable<std::expected<void, int>>::value)); EXPECT_TRUE((fmt::is_formattable<std::expected<void, int>>::value));
EXPECT_EQ(fmt::format("{}", std::unexpected{1}), "unexpected(1)");
EXPECT_EQ(fmt::format("{}", std::unexpected<std::string>{"test"}),
"unexpected(\"test\")");
EXPECT_EQ(fmt::format("{}", std::unexpected<char>{'a'}), "unexpected('a')");
EXPECT_FALSE((fmt::is_formattable<std::unexpected<unformattable2>>::value));
#endif #endif
} }