On Sun, 02 Nov 2025 at 15:45 +0800, Yuao Ma wrote:
Hi all,
This patch implements paper P3223R2, which adds a new overload to
std::istream::ignore for char_type.
Since this function dates back to C++98, I've used type_traits from
the ext rather than the std header to maintain compatibility.
Please take a look when you have time.
I (along with other libstdc++ devs) was at the WG21 meeting for the
past week and am still recovering from jetlag.
Thanks,
Yuao
From 80f609ffb64c4aba74df13c97f99ad72c2abf1bb Mon Sep 17 00:00:00 2001
From: Yuao Ma <[email protected]>
Date: Sun, 2 Nov 2025 15:39:38 +0800
Subject: [PATCH] libstdc++: Implement P3223R2 Making std::istream::ignore less
surprising
libstdc++-v3/ChangeLog:
* include/std/istream: Add a overload for char_type.
* testsuite/27_io/basic_istream/ignore/char/4.cc: New test.
---
libstdc++-v3/include/std/istream | 8 +++++-
.../27_io/basic_istream/ignore/char/4.cc | 25 +++++++++++++++++++
2 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/4.cc
diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream
index d5bb1876001..8a392782d68 100644
--- a/libstdc++-v3/include/std/istream
+++ b/libstdc++-v3/include/std/istream
@@ -38,6 +38,7 @@
#endif
#include <bits/requires_hosted.h> // iostreams
+#include <ext/type_traits.h> // __enable_if
#include <ios>
#include <ostream>
@@ -537,11 +538,16 @@ _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.
*/
+ template<typename _Tp>
+ typename __gnu_cxx::__enable_if<__are_same<_Tp, char>::__value,
__istream_type&>::__type
This seems to add std::wistream::ignore(streamsize, char) which is not
what the paper says.
The new ignore should only be present for basic_istream<char, traits>
and not other specializations. The Constraints: element means the
function is only present for the char specializations, it doesn't
mean that the overload is only enabled when the second argument is
char.
I was intending something like:
#if __cplusplus > 202302L
basic_istream&
ignore(streamsize __n, char __delim) requires same_as<_CharT, char>
#else
template<typename _Tp = _CharT>
typename
__gnu_cxx::__enable_if<__are_same<_Tp, char>::__value,
basic_istream&>::__type
#endif
This makes it only present for char_type == char, and only makes
in.ignore(100, -1L) ambiguous for C++26 (and not for the backported
DR). I'm not sure if that's what we want though, I seem to recall some
discussion about not making it a DR at all.
+ ignore(streamsize __n, _Tp __delim)
+ { return ignore(__n, traits_type::to_int_type(__delim)); }
+
__istream_type&
ignore(streamsize __n, int_type __delim);
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 00000000000..2fb5c74fac3
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/4.cc
@@ -0,0 +1,25 @@
+#include <testsuite_hooks.h>
+
+#include <istream>
+#include <sstream>
+#include <string>
+
+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");
+
+ in.ignore(100, -1L);
This would be ambiguous using the 'requires same_as<_CharT, char>'
constraint above.
+ VERIFY(in.eof());
+ VERIFY(in.gcount() == 5);
+}
+
+int main() {
+ test01();
+ return 0;
+}
--
2.43.0