From 5ef93a9f8055bd684a54e14e562ab009db401e0d Mon Sep 17 00:00:00 2001 From: Justin Riddell Date: Sun, 14 Jul 2024 17:51:49 +0100 Subject: [PATCH] Expand FMT_FORMAT_AS to include implicit conversions (#4055) Allows (for example) types convertible to std::string_view to inherit from the fmt::formatter to work etc. --- include/fmt/format.h | 12 +++++++++--- test/format-test.cc | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index cb88180b..0903667c 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -3976,9 +3976,15 @@ struct formatter::value>> } }; -#define FMT_FORMAT_AS(Type, Base) \ - template \ - struct formatter : formatter {} +#define FMT_FORMAT_AS(Type, Base) \ + template \ + struct formatter : formatter { \ + template \ + auto format(Type value, FormatContext& ctx) const -> decltype(ctx.out()) { \ + using base = formatter; \ + return base::format(value, ctx); \ + } \ + } FMT_FORMAT_AS(signed char, int); FMT_FORMAT_AS(unsigned char, unsigned); diff --git a/test/format-test.cc b/test/format-test.cc index a9ef19fc..b16f11cc 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1650,6 +1650,20 @@ TEST(format_test, format_explicitly_convertible_to_std_string_view) { EXPECT_EQ("'foo'", fmt::format("{}", explicitly_convertible_to_std_string_view())); } + +struct convertible_to_std_string_view { + operator std::string_view() const noexcept { return "Hi there"; } +}; +FMT_BEGIN_NAMESPACE +template <> +class formatter + : public formatter {}; +FMT_END_NAMESPACE + +TEST(format_test, format_implicitly_convertible_and_inherits_string_view) { + static_assert(fmt::is_formattable{}, ""); + EXPECT_EQ("Hi there", fmt::format("{}", convertible_to_std_string_view{})); +} #endif class Answer {};