From 88fe83765bc2f8b4b10d284bda3a031e4398f9a8 Mon Sep 17 00:00:00 2001 From: timsong-cpp Date: Fri, 18 Mar 2022 12:58:57 -0500 Subject: [PATCH] Only use format_as if no formatter is available --- include/fmt/core.h | 4 +++- test/core-test.cc | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 106fd6fe..6d30bc41 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1423,7 +1423,9 @@ template struct arg_mapper { } template ::value&& std::is_integral::value)> + FMT_ENABLE_IF(std::is_enum::value && std::is_integral::value && + !has_formatter::value && + !has_fallback_formatter::value)> FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> decltype(std::declval().map(U())) { return map(format_as(val)); diff --git a/test/core-test.cc b/test/core-test.cc index a040d241..76d09d47 100644 --- a/test/core-test.cc +++ b/test/core-test.cc @@ -761,11 +761,28 @@ namespace test { enum class formattable_scoped_enum {}; auto format_as(formattable_scoped_enum) -> int { return 42; } +enum class formattable_formatter_scoped_enum {}; +auto format_as(formattable_formatter_scoped_enum) -> int { return 24; } + struct convertible_to_enum { operator formattable_scoped_enum() const { return {}; } }; } // namespace test +FMT_BEGIN_NAMESPACE +template <> struct formatter<::test::formattable_formatter_scoped_enum> { + auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + auto format(::test::formattable_formatter_scoped_enum, format_context& ctx) const + -> decltype(ctx.out()) { + auto name = string_view("formattable_formatter_scoped_enum"); + return std::copy_n(name.data(), name.size(), ctx.out()); + } +}; +FMT_END_NAMESPACE + TEST(core_test, is_formattable) { #if 0 // This should be enabled once corresponding map overloads are gone. @@ -820,6 +837,9 @@ TEST(core_test, format_to) { TEST(core_test, format_as) { EXPECT_EQ(fmt::format("{}", test::formattable_scoped_enum()), "42"); + EXPECT_EQ(fmt::format("{}", test::formattable_formatter_scoped_enum()), "formattable_formatter_scoped_enum"); + const test::formattable_formatter_scoped_enum x{}; + EXPECT_EQ(fmt::format("{}", x), "formattable_formatter_scoped_enum"); } struct convertible_to_int {