https://gcc.gnu.org/g:0d4ab66aaf1f2ade8b6deab07f37b3137f5f5763

commit r16-5496-g0d4ab66aaf1f2ade8b6deab07f37b3137f5f5763
Author: Yuao Ma <[email protected]>
Date:   Sun Nov 2 15:39:38 2025 +0800

    libstdc++: Implement P3223R2 Making std::istream::ignore less surprising
    
    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 <[email protected]>

Diff:
---
 libstdc++-v3/include/std/istream                   | 12 +++++++++++-
 .../testsuite/27_io/basic_istream/ignore/char/4.cc | 22 ++++++++++++++++++++++
 .../27_io/basic_istream/ignore/char/93672.cc       |  8 ++++----
 3 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream
index d5bb1876001d..285c41cf02ba 100644
--- a/libstdc++-v3/include/std/istream
+++ b/libstdc++-v3/include/std/istream
@@ -42,6 +42,10 @@
 #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
index 000000000000..6f0b643a49c4
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/4.cc
@@ -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;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/93672.cc 
b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/93672.cc
index 96737485b83d..608b794be4ba 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/93672.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/93672.cc
@@ -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,

Reply via email to