diff --git a/include/fmt/os.h b/include/fmt/os.h index 482b1a81dc4a7..ed22399043aee 100644 --- a/include/fmt/os.h +++ b/include/fmt/os.h @@ -129,6 +129,24 @@ class error_code { int get() const FMT_NOEXCEPT { return value_; } }; +// A formatter specialization for std::error_code. +template struct formatter { + template + FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + template + FMT_CONSTEXPR auto format(const std::error_code& ec, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); + out = detail::write(out, to_string_view(ec.category().name())); + out = detail::write(out, Char(':')); + out = detail::write(out, ec.value()); + return out; + } +}; + #ifdef _WIN32 namespace detail { // A converter from UTF-16 to UTF-8. diff --git a/test/compile-test.cc b/test/compile-test.cc index 71eddc920e4f5..c5ad45c076a68 100644 --- a/test/compile-test.cc +++ b/test/compile-test.cc @@ -6,6 +6,7 @@ // For the license information refer to format.h. #include "fmt/compile.h" +#include "fmt/os.h" #include @@ -84,6 +85,9 @@ TEST(compile_test, format_default) { # ifdef __cpp_lib_byte EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), std::byte{42})); # endif + EXPECT_EQ("generic:42", + fmt::format(FMT_COMPILE("{}"), + std::error_code(42, std::generic_category()))); } TEST(compile_test, format_wide_string) { diff --git a/test/os-test.cc b/test/os-test.cc index 52b8532f1db3f..f82f17d5cf5a9 100644 --- a/test/os-test.cc +++ b/test/os-test.cc @@ -69,6 +69,24 @@ TEST(util_test, utf16_to_utf8_convert) { u.convert(fmt::wstring_view(L"foo", INT_MAX + 1u))); } +TEST(os_test, format_std_error_code) { + EXPECT_EQ("generic:42", + fmt::format("{0}", std::error_code(42, std::generic_category()))); + EXPECT_EQ("system:42", + fmt::format("{0}", std::error_code(42, std::system_category()))); + EXPECT_EQ("system:-42", + fmt::format("{0}", std::error_code(-42, std::system_category()))); +} + +TEST(os_test, format_std_error_code_wide) { + EXPECT_EQ(L"generic:42", + fmt::format(L"{0}", std::error_code(42, std::generic_category()))); + EXPECT_EQ(L"system:42", + fmt::format(L"{0}", std::error_code(42, std::system_category()))); + EXPECT_EQ(L"system:-42", + fmt::format(L"{0}", std::error_code(-42, std::system_category()))); +} + TEST(os_test, format_windows_error) { LPWSTR message = 0; auto result = FormatMessageW(