From aef87975224b0a4b5b103f241fd366b0e3a21360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kami=C5=84ski?= Date: Wed, 16 Apr 2025 13:39:04 +0200 Subject: libstdc++: Fix constification in range_formatter::format [PR109162] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The _Rg is deduced to lvalue reference for the lvalue arguments, and in such case __format::__maybe_const_range<_Rg, _CharT> is always _Rg (adding const to reference does not change behavior). Now we correctly check if _Range = remove_reference_t<_Rg> is const formattable range, furthermore as range_formatter can only format ranges of values of type (possibly const) _Tp, we additional check if the remove_cvref_t> is _Tp. The range_reference_t and range_reference_t have different types (modulo remove_cvref_t) for std::vector (::reference and bool) or flat_map (pair and pair). PR libstdc++/109162 libstdc++-v3/ChangeLog: * include/std/format (range_formatter::format): Format const range, only if reference type is not changed. * testsuite/std/format/ranges/formatter.cc: New tests. Reviewed-by: Jonathan Wakely Signed-off-by: Tomasz KamiƄski --- .../testsuite/std/format/ranges/formatter.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'libstdc++-v3/testsuite/std') diff --git a/libstdc++-v3/testsuite/std/format/ranges/formatter.cc b/libstdc++-v3/testsuite/std/format/ranges/formatter.cc index a4f5d92..00ce9f6 100644 --- a/libstdc++-v3/testsuite/std/format/ranges/formatter.cc +++ b/libstdc++-v3/testsuite/std/format/ranges/formatter.cc @@ -1,5 +1,6 @@ // { dg-do run { target c++23 } } +#include #include #include #include @@ -138,6 +139,26 @@ test_nested() VERIFY( res == "+<01; 02; 11; 12>+" ); } +struct MyFlatMap : std::flat_map +{ + using std::flat_map::flat_map; +}; + +template +struct std::formatter + // This cannot apply format BitVector const&, because formatted type would + // be std::pair, and formatter for + // pair cannot format it. + : std::range_formatter +{}; + +void test_const_ref_type_mismatch() +{ + MyFlatMap m{{1, 11}, {2, 22}}; + std::string res = std::format("{:m}", m); + VERIFY( res == "{1: 11, 2: 22}" ); +} + template using VectorFormatter = std::formatter, CharT>; @@ -146,4 +167,5 @@ int main() test_outputs(); test_outputs(); test_nested(); + test_const_ref_type_mismatch(); } -- cgit v1.1