https://gcc.gnu.org/g:70bd97e89ddf8fcb8c14e84a8fd580404536eeb1

commit r16-2107-g70bd97e89ddf8fcb8c14e84a8fd580404536eeb1
Author: Tomasz KamiƄski <tkami...@redhat.com>
Date:   Tue Jul 8 10:04:41 2025 +0200

    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:
---
 libstdc++-v3/include/std/format                    |  4 +-
 .../testsuite/std/format/ranges/pr119861_neg.cc    | 52 ++++++++++++++++++++++
 2 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 5749aa1995a9..d584b81c78a1 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 000000000000..9a6ed16393ee
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/format/ranges/pr119861_neg.cc
@@ -0,0 +1,52 @@
+// { dg-do compile { target c++23 } }
+
+#include <format>
+#include <vector>
+
+// only format_kind::sequence provides set_brackets and set_separator methods 
+
+template<std::range_format fk, typename T>
+struct MyCont : std::vector<T>
+{
+  using std::vector<T>::vector;
+};
+
+template<std::range_format fk, typename T>
+constexpr std::range_format std::format_kind<MyCont<fk, T>> = fk;
+
+void test_sequence()
+{
+  std::formatter<MyCont<std::range_format::sequence, int>, char> fmtter;
+  fmtter.set_brackets("{", "}");
+  fmtter.set_separator(",");
+}
+
+void test_map()
+{
+  std::formatter<MyCont<std::range_format::map, std::pair<int, int>>, char> 
fmtter;
+  fmtter.set_brackets("{", "}"); // { dg-error "here" }
+  fmtter.set_separator(","); // { dg-error "here" }
+}
+
+void test_set()
+{
+  std::formatter<MyCont<std::range_format::set, int>, char> fmtter;
+  fmtter.set_brackets("{", "}"); // { dg-error "here" }
+  fmtter.set_separator(","); // { dg-error "here" }
+}
+
+void test_string()
+{
+  std::formatter<MyCont<std::range_format::string, char>, char> fmtter;
+  fmtter.set_brackets("{", "}"); // { dg-error "here" }
+  fmtter.set_separator(","); // { dg-error "here" }
+}
+
+void test_debug_string()
+{
+  std::formatter<MyCont<std::range_format::debug_string, char>, 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 }

Reply via email to