From: Tomasz KamiƄski Date: Tue, 8 Jul 2025 08:04:41 +0000 (+0200) Subject: libstdc++: Do not expose set_brackets/set_separator for formatter with format_kind... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=70bd97e89ddf8fcb8c14e84a8fd580404536eeb1;p=thirdparty%2Fgcc.git libstdc++: Do not expose set_brackets/set_separator for formatter with format_kind other than sequence [PR119861] The standard defines separate specializations of range-default-formatter, out of which only one for range_format::sequence provide the set_brackets and set_separator methods. We implemented it as one specialization and exposed this method for range_format other than string or debug_string, i.e. when range_formatter was used as underlying formatter. PR libstdc++/119861 libstdc++-v3/ChangeLog: * include/std/format (formatter<_Rg, _CharT>::set_separator) (formatter<_Rg, _CharT>::set_brackets): Constrain with (format_kind<_Rg> == range_format::sequence). * testsuite/std/format/ranges/pr119861_neg.cc: New test. --- diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index 5749aa1995a..d584b81c78a 100644 --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -6030,13 +6030,13 @@ namespace __format constexpr void set_separator(basic_string_view<_CharT> __sep) noexcept - requires (!_S_range_format_is_string) + requires (format_kind<_Rg> == range_format::sequence) { _M_under.set_separator(__sep); } constexpr void set_brackets(basic_string_view<_CharT> __open, basic_string_view<_CharT> __close) noexcept - requires (!_S_range_format_is_string) + requires (format_kind<_Rg> == range_format::sequence) { _M_under.set_brackets(__open, __close); } // We deviate from standard, that declares this as template accepting diff --git a/libstdc++-v3/testsuite/std/format/ranges/pr119861_neg.cc b/libstdc++-v3/testsuite/std/format/ranges/pr119861_neg.cc new file mode 100644 index 00000000000..9a6ed16393e --- /dev/null +++ b/libstdc++-v3/testsuite/std/format/ranges/pr119861_neg.cc @@ -0,0 +1,52 @@ +// { dg-do compile { target c++23 } } + +#include +#include + +// only format_kind::sequence provides set_brackets and set_separator methods + +template +struct MyCont : std::vector +{ + using std::vector::vector; +}; + +template +constexpr std::range_format std::format_kind> = fk; + +void test_sequence() +{ + std::formatter, char> fmtter; + fmtter.set_brackets("{", "}"); + fmtter.set_separator(","); +} + +void test_map() +{ + std::formatter>, char> fmtter; + fmtter.set_brackets("{", "}"); // { dg-error "here" } + fmtter.set_separator(","); // { dg-error "here" } +} + +void test_set() +{ + std::formatter, char> fmtter; + fmtter.set_brackets("{", "}"); // { dg-error "here" } + fmtter.set_separator(","); // { dg-error "here" } +} + +void test_string() +{ + std::formatter, char> fmtter; + fmtter.set_brackets("{", "}"); // { dg-error "here" } + fmtter.set_separator(","); // { dg-error "here" } +} + +void test_debug_string() +{ + std::formatter, char> fmtter; + fmtter.set_brackets("{", "}"); // { dg-error "here" } + fmtter.set_separator(","); // { dg-error "here" } +} + +// { dg-error "no matching function for call to 'std::formatter<" "" { target *-*-* } 0 }