]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Implement P3223R2 Making std::istream::ignore less surprising
authorYuao Ma <c8ef@outlook.com>
Sun, 2 Nov 2025 07:39:38 +0000 (15:39 +0800)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 21 Nov 2025 15:30:50 +0000 (15:30 +0000)
libstdc++-v3/ChangeLog:

* include/std/istream (ignore): Add an overload for char.
* testsuite/27_io/basic_istream/ignore/char/93672.cc: Adjust
expected behaviour for C++26 mode.
* testsuite/27_io/basic_istream/ignore/char/4.cc: New test.

Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/include/std/istream
libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/4.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/93672.cc

index d5bb1876001d05f9aea59cab00302143a04aa197..285c41cf02baf4e3c126f424d261b940a943f3af 100644 (file)
 #include <ios>
 #include <ostream>
 
+#if __cplusplus > 202302L
+#include <concepts>
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -537,7 +541,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *    is extracted); note that this condition will never occur if
        *    @a __delim equals @c traits::eof().
        *
-       *  NB: Provide three overloads, instead of the single function
+       *  NB: Provide four overloads, instead of the single function
        *  (with defaults) mandated by the Standard: this leads to a
        *  better performing implementation, while still conforming to
        *  the Standard.
@@ -551,6 +555,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __istream_type&
       ignore();
 
+#if __cplusplus > 202302L
+      __istream_type&
+      ignore(streamsize __n, char __delim) requires same_as<_CharT, char>
+      { return ignore(__n, traits_type::to_int_type(__delim)); }
+#endif
+
       /**
        *  @brief  Looking ahead in the stream
        *  @return  The next character, or eof().
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/4.cc b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/4.cc
new file mode 100644 (file)
index 0000000..6f0b643
--- /dev/null
@@ -0,0 +1,22 @@
+// { dg-do run { target c++26 } }
+
+#include <istream>
+#include <sstream>
+#include <string>
+#include <testsuite_hooks.h>
+
+void test01() {
+  std::istringstream in("\xF0\x9F\xA4\xA1 Clown Face");
+  in.ignore(100, '\xA1');
+  VERIFY(in.gcount() == 4);
+  VERIFY(in.peek() == ' ');
+
+  std::string str;
+  in >> str;
+  VERIFY(str == "Clown");
+}
+
+int main() {
+  test01();
+  return 0;
+}
index 96737485b83d6f9c5d3e81b36c05d681e4acc1f5..608b794be4ba85960d2eae34c5f18009df4a7d4e 100644 (file)
@@ -20,9 +20,9 @@ test_pr93672() // std::basic_istream::ignore hangs if delim MSB is set
   VERIFY( in.gcount() == 3 );
   VERIFY( ! in.eof() );
 
-  // This only works if char is unsigned.
+  // Prior to C++26 (P3223R2), this only works if char is unsigned.
   in.ignore(100, '\xfe');
-  if (std::numeric_limits<char>::is_signed)
+  if (std::numeric_limits<char>::is_signed && __cplusplus <= 202302L)
   {
     // When char is signed, '\xfe' != traits_type::to_int_type('\xfe')
     // so the delimiter does not match the character in the input sequence,
@@ -69,9 +69,9 @@ test_primary_template()
   VERIFY( in.gcount() == 3 );
   VERIFY( ! in.eof() );
 
-  // This only works if char is unsigned.
+  // Prior to C++26 (P3223R2), this only works if char is unsigned.
   in.ignore(100, '\xfe');
-  if (std::numeric_limits<char>::is_signed)
+  if (std::numeric_limits<char>::is_signed && __cplusplus <= 202302L)
   {
     // When char is signed, '\xfe' != traits_type::to_int_type('\xfe')
     // so the delimiter does not match the character in the input sequence,