From 5cc5072aa68c48a8c67f4d09ef1b9fcb9ab15a26 Mon Sep 17 00:00:00 2001 From: Soumik15630m Date: Fri, 30 Jan 2026 20:09:00 +0530 Subject: [PATCH] Fix range suppresor formatter (#4660) --- include/fmt/ranges.h | 12 ++++++++++-- test/ranges-test.cc | 30 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index 89cdbc80..d67f59af 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -746,7 +746,6 @@ struct formatter, Char, return do_format(value, ctx, std::integral_constant()); } }; - namespace detail { // Check if T has an interface like a container adaptor (e.g. std::stack, // std::queue, std::priority_queue). @@ -766,10 +765,19 @@ template struct all { }; } // namespace detail +/** + * returns "true" if "T" is a container adaptor (like "std::stack") + * that should be formatted by iterating over the underlying container. + * */ + +FMT_EXPORT +template +struct is_container_adaptor : detail::is_container_adaptor_like {}; + template struct formatter< T, Char, - enable_if_t, + enable_if_t, bool_constant::value == range_format::disabled>>::value>> : formatter, Char> { diff --git a/test/ranges-test.cc b/test/ranges-test.cc index d65037fa..f82569b2 100644 --- a/test/ranges-test.cc +++ b/test/ranges-test.cc @@ -797,3 +797,33 @@ struct not_range { void end() const {} }; static_assert(!fmt::is_formattable{}, ""); + +namespace test_detail { + template + struct partial_opt_out_wrapper { + using container_type = std::vector; + std::vector c = {1, 2, 3}; + }; +} // namespace test_detail + +namespace fmt { + template + struct is_container_adaptor> : std::false_type {}; + + template + struct formatter> { + constexpr fmt::format_parse_context::iterator parse(fmt::format_parse_context& ctx) const { + return ctx.begin(); + } + + fmt::format_context::iterator format(const test_detail::partial_opt_out_wrapper& val, + fmt::format_context& ctx) const { + return fmt::format_to(ctx.out(), "PartialOptOut(size={})", val.c.size()); + } + }; +} // namespace fmt + +TEST(ranges_test, container_adaptor_partial_specialization) { + test_detail::partial_opt_out_wrapper obj; + EXPECT_EQ(fmt::format("{}", obj), "PartialOptOut(size=3)"); +} \ No newline at end of file