aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Kamiński <tkaminsk@redhat.com>2025-07-08 10:04:41 +0200
committerTomasz Kamiński <tkaminsk@redhat.com>2025-07-08 17:08:46 +0200
commit70bd97e89ddf8fcb8c14e84a8fd580404536eeb1 (patch)
tree5fe7d1883c3590dfbfa1a61925d41d22e30e12d3
parent9c600a7e6cc588d2ee79d764cbf69ad677b1bac5 (diff)
downloadgcc-70bd97e89ddf8fcb8c14e84a8fd580404536eeb1.zip
gcc-70bd97e89ddf8fcb8c14e84a8fd580404536eeb1.tar.gz
gcc-70bd97e89ddf8fcb8c14e84a8fd580404536eeb1.tar.bz2
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.
-rw-r--r--libstdc++-v3/include/std/format4
-rw-r--r--libstdc++-v3/testsuite/std/format/ranges/pr119861_neg.cc52
2 files changed, 54 insertions, 2 deletions
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 5749aa1..d584b81 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 0000000..9a6ed16
--- /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 }