diff --git a/include/fmt/core.h b/include/fmt/core.h index 6cd41636..90999c3a 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1778,11 +1778,18 @@ template class basic_format_context { FMT_CONSTEXPR auto put(char_type c) -> iterator { *out_++ = c; - return out; + return out_; } FMT_CONSTEXPR auto put(basic_string_view sv) -> iterator { - detail::copy_str(sv.data(), sv.data() + sv.size(), out); - return out; + detail::copy_str(sv.data(), sv.data() + sv.size(), out_); + return out_; + } + + template >::value)> + FMT_CONSTEXPR auto put(formatter& f, U& object) -> iterator { + advance_to(f.format(object, *this)); + return out_; } FMT_CONSTEXPR auto locale() -> detail::locale_ref { return loc_; } diff --git a/test/format-test.cc b/test/format-test.cc index 7b64abea..2b94c155 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -2194,3 +2194,30 @@ TEST(format_int_test, format_int) { os << max_value(); EXPECT_EQ(os.str(), fmt::format_int(max_value()).str()); } + +struct put_on_the_ritz { + int i; +}; + +FMT_BEGIN_NAMESPACE +template <> struct formatter { + formatter underlying; + + FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return underlying.parse(ctx); + } + + auto format(put_on_the_ritz r, format_context& ctx) -> decltype(ctx.out()) { + ctx.put('{'); + ctx.put(".i="); + ctx.put(underlying, r.i); + ctx.put('}'); + return ctx.out(); + } +}; +FMT_END_NAMESPACE + +TEST(format_test, format_context_put) { + EXPECT_EQ(fmt::format("[{}]", put_on_the_ritz{42}), "[{.i=42}]"); + EXPECT_EQ(fmt::format("[{:#x}]", put_on_the_ritz{42}), "[{.i=0x2a}]"); +}