aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/testsuite')
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc195
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc6
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc194
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc6
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc205
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc6
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringstream/cons/char/string_view.cc204
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc6
8 files changed, 822 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc
new file mode 100644
index 0000000..27f65aa
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc
@@ -0,0 +1,195 @@
+// C++26 [istringstream.general]
+
+// { dg-do run { target c++26 } }
+
+#include <sstream>
+#include <string>
+#include <string_view>
+#include <testsuite_allocator.h>
+#include <testsuite_hooks.h>
+
+// Check C++26 P2495 istringstream ctors and members str(s) that accept a
+// string_view, or anything convertible to a string_view, in place of a
+// string object. Mostly just verify plumbing.
+
+#ifndef C
+# define C char
+# define L(a) a
+#endif
+
+using string = std::basic_string<C>;
+using string_view = std::basic_string_view<C>;
+using istringstream = std::basic_istringstream<C>;
+
+struct convertible_to_string_view {
+ string s;
+ operator string_view() const { return s; }
+};
+
+const string str(L("This is a test string"));
+convertible_to_string_view cstr{str}; // a copy
+const convertible_to_string_view ccstr{str}; // another copy
+
+template <typename istringstream = std::basic_istringstream<C>>
+void
+test01()
+{
+ // Test C++26 constructor and str(s) taking a generalized string_view
+
+ static_assert(! requires { istringstream(1); },
+ "istringstream ctor should reject what cannot be converted to a string_view");
+ static_assert(! requires { istringstream().str(1); },
+ "istringstream::str(s) should reject what cannot be converted to a string_view");
+
+ static_assert(!std::is_convertible_v<string_view, istringstream>,
+ "istringstream(string_view, ios::openmode) is explicit");
+ static_assert(!std::is_convertible_v<const string_view, istringstream>,
+ "istringstream(string_view, ios::openmode) is explicit");
+ static_assert(!std::is_convertible_v<convertible_to_string_view, istringstream>,
+ "istringstream(convertible_to_string_view, ios::openmode) is explicit");
+ static_assert(!std::is_convertible_v<const convertible_to_string_view, istringstream>,
+ "istringstream(convertible_to_string_view, ios::openmode) is explicit");
+
+ {
+ istringstream istr(cstr);
+ VERIFY( istr.str() == cstr.s );
+ VERIFY( istr.get() == cstr.s[0] );
+ }
+ {
+ istringstream istr(ccstr);
+ VERIFY( istr.str() == ccstr.s );
+ VERIFY( istr.get() == ccstr.s[0] );
+ }
+ {
+ istringstream istr(cstr, std::ios_base::in);
+ VERIFY( istr.str() == cstr.s );
+ VERIFY( istr.get() == cstr.s[0] );
+ VERIFY( istr.rdbuf()->sputc('X') != 'X' );
+ }
+ {
+ istringstream istr(cstr, std::ios_base::out);
+ VERIFY( istr.str() == cstr.s );
+ VERIFY( istr.get() == cstr.s[0] );
+ VERIFY( istr.rdbuf()->sputc('X') == 'X' );
+ }
+}
+
+void
+test02()
+{
+ // Test various C++26 constructors taking string views
+ // and mix of other arguments
+
+ auto const mode = std::ios_base::in | std::ios_base::out;
+
+ {
+ // template <typename T>
+ // basic_istringstream(const T&, ios_base::openmode, const allocator_type&)
+
+ istringstream::allocator_type a;
+ {
+ istringstream istr(cstr, mode, a); // ={} checks for non-explicit ctor
+ VERIFY( istr.str() == cstr.s );
+ }
+ {
+ istringstream istr(cstr, std::ios::in, a);
+ VERIFY( istr.str() == cstr.s );
+ VERIFY( istr.get() == cstr.s[0] );
+ VERIFY( istr.rdbuf()->sputc('X') != 'X' );
+ }
+ {
+ istringstream istr(cstr, std::ios::out, a);
+ VERIFY( istr.str() == cstr.s );
+ VERIFY( istr.get() == cstr.s[0] );
+ VERIFY( istr.rdbuf()->sputc('X') == 'X' );
+ }
+ }
+
+ {
+ // template <typename T>
+ // basic_istringstream(const T&, ios_base::openmode)
+ {
+ istringstream istr(cstr, mode);
+ VERIFY( istr.str() == cstr.s );
+ VERIFY( istr.get() == cstr.s[0] );
+ VERIFY( istr.rdbuf()->sputc('X') == 'X' );
+ }
+ {
+ istringstream istr(cstr, std::ios::in);
+ VERIFY( istr.str() == cstr.s );
+ VERIFY( istr.get() == cstr.s[0] );
+ VERIFY( istr.rdbuf()->sputc('X') != 'X' );
+ }
+ {
+ istringstream istr(cstr, std::ios::out);
+ VERIFY( istr.str() == cstr.s );
+ VERIFY( istr.get() == cstr.s[0] );
+ VERIFY( istr.rdbuf()->sputc('X') == 'X' );
+ }
+ }
+
+ {
+ // template <typename T>
+ // explicit
+ // basic_istringstream(const T&, ios_base::openmode = ios_base::in)
+
+ istringstream istr(cstr);
+ VERIFY( istr.str() == cstr.s );
+ VERIFY( istr.get() == cstr.s[0] );
+ VERIFY( istr.rdbuf()->sputc('X') != 'X' );
+ }
+}
+
+using alloc_type = __gnu_test::uneq_allocator<C>;
+
+template<typename Alloc, typename CC = typename Alloc::value_type>
+ using istringstream_with_alloc
+ = std::basic_istringstream<CC, std::char_traits<CC>, Alloc>;
+
+void test03()
+{
+ alloc_type a{1};
+ {
+ istringstream_with_alloc<alloc_type> istr(cstr, a);
+ VERIFY( istr.rdbuf()->get_allocator() == a );
+ VERIFY( string_view{istr.str()} == cstr );
+ VERIFY( istr.get() == cstr.s[0] );
+ }
+ {
+ istringstream_with_alloc<alloc_type> istr(cstr, std::ios::in, a);
+ VERIFY( istr.rdbuf()->get_allocator() == a );
+ VERIFY( string_view{istr.str()} == cstr );
+ VERIFY( istr.get() == cstr.s[0] );
+ VERIFY( istr.rdbuf()->sputc('X') != 'X' );
+ }
+ {
+ istringstream_with_alloc<alloc_type> istr(cstr, std::ios::out, a);
+ VERIFY( istr.rdbuf()->get_allocator() == a );
+ VERIFY( string_view{istr.str()} == cstr );
+ VERIFY( istr.get() == cstr.s[0] );
+ VERIFY( istr.rdbuf()->sputc('X') == 'X' );
+ }
+}
+
+void test04()
+{
+ {
+ istringstream istr;
+ istr.str( cstr );
+ VERIFY( istr.str() == cstr.s );
+ }
+ {
+ istringstream istr;
+ istr.str( ccstr );
+ VERIFY( istr.str() == ccstr.s );
+ }
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc
new file mode 100644
index 0000000..62fb03c
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/wchar_t/string_view.cc
@@ -0,0 +1,6 @@
+// C++26 [istringstream.general]
+// { dg-do run { target c++26 } }
+
+#define C wchar_t
+#define L(a) L##a
+#include "../char/string_view.cc"
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc
new file mode 100644
index 0000000..731e97e
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc
@@ -0,0 +1,194 @@
+// C++26 [ostringstream.general]
+
+// { dg-do run { target c++26 } }
+
+#include <sstream>
+#include <string>
+#include <string_view>
+#include <testsuite_allocator.h>
+#include <testsuite_hooks.h>
+
+// Check C++26 P2495 ostringstream ctors and members str(s) that accept a
+// string_view, or anything convertible to a string_view, in place of a
+// string object. Mostly just verify plumbing.
+
+#ifndef C
+# define C char
+# define L(a) a
+#endif
+
+using string = std::basic_string<C>;
+using string_view = std::basic_string_view<C>;
+using ostringstream = std::basic_ostringstream<C>;
+
+struct convertible_to_string_view {
+ string s;
+ operator string_view() const { return s; }
+};
+
+const string str(L("This is a test string"));
+convertible_to_string_view cstr{str}; // a copy
+const convertible_to_string_view ccstr{str}; // another copy
+
+template <typename ostringstream = std::basic_ostringstream<C>>
+void
+test01()
+{
+ // Test C++26 constructor and str(s) taking a generalized string_view
+
+ static_assert(! requires { ostringstream(1); },
+ "ostringstream ctor should reject what cannot be converted to a string_view");
+ static_assert(! requires { ostringstream().str(1); },
+ "ostringstream::str(s) should reject what cannot be converted to a string_view");
+
+ static_assert(!std::is_convertible_v<string_view, ostringstream>,
+ "ostringstream(string_view, ios::openmode) is explicit");
+ static_assert(!std::is_convertible_v<const string_view, ostringstream>,
+ "ostringstream(string_view, ios::openmode) is explicit");
+ static_assert(!std::is_convertible_v<convertible_to_string_view, ostringstream>,
+ "ostringstream(convertible_to_string_view, ios::openmode) is explicit");
+ static_assert(!std::is_convertible_v<const convertible_to_string_view, ostringstream>,
+ "ostringstream(convertible_to_string_view, ios::openmode) is explicit");
+
+ {
+ ostringstream ostrstr(cstr);
+ VERIFY( ostrstr.str() == cstr.s );
+ VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() );
+ }
+ {
+ ostringstream ostrstr(ccstr);
+ VERIFY( ostrstr.str() == ccstr.s );
+ VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() );
+ }
+ {
+ ostringstream ostrstr(cstr, std::ios_base::in);
+ VERIFY( ostrstr.str() == cstr.s );
+ VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]);
+ VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit );
+ }
+ {
+ ostringstream ostrstr(cstr, std::ios_base::out);
+ VERIFY( ostrstr.str() == cstr.s );
+ VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() );
+ VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit );
+ }
+}
+
+void
+test02()
+{
+ // Test plumbing of C++26 various constructors taking string views
+
+ auto const mode = std::ios_base::in | std::ios_base::out;
+
+ {
+ ostringstream::allocator_type a;
+ // template <typename T>
+ // basic_ostringstream(const T&, ios_base::openmode, const allocator_type&)
+ {
+ ostringstream ostrstr(cstr, mode, a); // ={} checks for non-explicit ctor
+ VERIFY( ostrstr.str() == cstr.s );
+ }
+ {
+ ostringstream ostrstr(cstr, std::ios::in, a);
+ VERIFY( ostrstr.str() == cstr.s );
+ VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]);
+ VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit );
+ }
+ {
+ ostringstream ostrstr(cstr, std::ios::out, a);
+ VERIFY( ostrstr.str() == cstr.s );
+ VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() );
+ VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit );
+ }
+ }
+
+ {
+ // template <typename T>
+ // basic_ostringstream(const T&, ios_base::openmode)
+ {
+ ostringstream ostrstr(cstr, mode);
+ VERIFY( ostrstr.str() == cstr.s );
+ VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]);
+ VERIFY( ostrstr.put('Y').good() );
+ }
+ {
+ ostringstream ostrstr(cstr, std::ios::in);
+ VERIFY( ostrstr.str() == cstr.s );
+ VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]);
+ VERIFY( ostrstr.put('X').good() );
+ }
+ {
+ ostringstream ostrstr(cstr, std::ios::out);
+ VERIFY( ostrstr.str() == cstr.s );
+ VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() );
+ VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit );
+ }
+ }
+
+ {
+ // template <typename T>
+ // explicit
+ // basic_ostringstream(const T&, ios_base::openmode = ios_base::out)
+
+ ostringstream ostrstr(cstr);
+ VERIFY( ostrstr.str() == cstr.s );
+ VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() );
+ VERIFY( ostrstr.put('Y').good() );
+ }
+}
+
+using alloc_type = __gnu_test::uneq_allocator<C>;
+
+template<typename Alloc, typename CC = typename Alloc::value_type>
+ using ostringstream_with_alloc
+ = std::basic_ostringstream<CC, std::char_traits<CC>, Alloc>;
+
+void test03()
+{
+ alloc_type a{1};
+ {
+ ostringstream_with_alloc<alloc_type> ostrstr(cstr, a);
+ VERIFY( ostrstr.rdbuf()->get_allocator() == a );
+ VERIFY( string_view{ostrstr.str()} == cstr );
+ VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() );
+ VERIFY( ostrstr.put('X').good() );
+ }
+ {
+ ostringstream_with_alloc<alloc_type> ostrstr(cstr, std::ios::in, a);
+ VERIFY( ostrstr.rdbuf()->get_allocator() == a );
+ VERIFY( string_view{ostrstr.str()} == cstr );
+ VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]);
+ VERIFY( ostrstr.put('X').good() );
+ }
+ {
+ ostringstream_with_alloc<alloc_type> ostrstr(cstr, std::ios::out, a);
+ VERIFY( ostrstr.rdbuf()->get_allocator() == a );
+ VERIFY( string_view{ostrstr.str()} == cstr );
+ VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() );
+ VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit );
+ }
+}
+
+void test04()
+{
+ {
+ ostringstream ostrstr;
+ ostrstr.str(cstr);
+ VERIFY( ostrstr.str() == cstr.s );
+ }
+ {
+ ostringstream ostrstr;
+ ostrstr.str(ccstr);
+ VERIFY( ostrstr.str() == ccstr.s );
+ }
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc
new file mode 100644
index 0000000..ee6ac8d
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/wchar_t/string_view.cc
@@ -0,0 +1,6 @@
+// C++26 [ostringstream.general]
+// { dg-do run { target c++26 } }
+
+#define C wchar_t
+#define L(a) L##a
+#include "../char/string_view.cc"
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc
new file mode 100644
index 0000000..7843269
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc
@@ -0,0 +1,205 @@
+// C++26 31.8.2.1 [stringbuf.general]
+
+// { dg-do run { target c++26 } }
+
+#include <sstream>
+#include <string>
+#include <string_view>
+#include <testsuite_allocator.h>
+#include <testsuite_hooks.h>
+
+// Check C++26 P2495 stringbuf ctors and members str(s) that accept a
+// string_view, or anything convertible to a string_view, in place of a
+// string object.
+
+#ifndef C
+# define C char
+# define L(a) a
+#endif
+
+using string = std::basic_string<C>;
+using string_view = std::basic_string_view<C>;
+using stringbuf = std::basic_stringbuf<C>;
+
+struct convertible_to_string_view {
+ string s;
+ operator string_view() const { return s; }
+};
+
+const string str(L("This is a test string"));
+convertible_to_string_view cstr{str}; // a copy
+const convertible_to_string_view ccstr{str}; // another copy
+
+template <typename stringbuf = std::basic_stringbuf<C>>
+void
+test01()
+{
+ // Test C++26 constructor and str(s) taking a generalized string_view
+
+ static_assert(! requires { stringbuf(1); },
+ "stringbuf ctor should reject what cannot be converted to a string_view");
+ static_assert(! requires { stringbuf().str(1); },
+ "stringbuf::str(s) should reject what cannot be converted to a string_view");
+
+ static_assert(!std::is_convertible_v<string_view, stringbuf>,
+ "stringbuf(string_view, ios::openmode) is explicit");
+ static_assert(!std::is_convertible_v<const string_view, stringbuf>,
+ "stringbuf(string_view, ios::openmode) is explicit");
+ static_assert(!std::is_convertible_v<convertible_to_string_view, stringbuf>,
+ "stringbuf(convertible_to_string_view, ios::openmode) is explicit");
+ static_assert(
+ !std::is_convertible_v<const convertible_to_string_view, stringbuf>,
+ "stringbuf(convertible_to_string_view, ios::openmode) is explicit");
+
+ {
+ stringbuf sbuf(cstr);
+ VERIFY( sbuf.str() == cstr.s );
+ VERIFY( sbuf.sgetc() == cstr.s[0] );
+ }
+ {
+ stringbuf sbuf(ccstr);
+ VERIFY( sbuf.str() == ccstr.s );
+ VERIFY( sbuf.sgetc() == ccstr.s[0] );
+ }
+ {
+ stringbuf sbuf(cstr, std::ios_base::in);
+ VERIFY( sbuf.str() == cstr.s );
+ VERIFY( sbuf.sgetc() == cstr.s[0] );
+ VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() );
+ }
+ {
+ stringbuf sbuf(ccstr, std::ios_base::in);
+ VERIFY( sbuf.str() == ccstr.s );
+ VERIFY( sbuf.sgetc() == ccstr.s[0] );
+ VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() );
+ }
+ {
+ stringbuf sbuf(cstr, std::ios_base::out);
+ VERIFY( sbuf.str() == cstr.s );
+ VERIFY( sbuf.sputc('Y') == 'Y' );
+ VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() );
+ }
+ {
+ stringbuf sbuf(ccstr, std::ios_base::out);
+ VERIFY( sbuf.str() == ccstr.s );
+ VERIFY( sbuf.sputc('Y') == 'Y' );
+ VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() );
+ }
+}
+
+void
+test02()
+{
+ // Test C++26 constructors taking string views using different allocators
+
+ auto const mode = std::ios_base::in | std::ios_base::out;
+
+ {
+ // template <typename T>
+ // basic_stringbuf(const T&, ios_base::openmode, const allocator_type&)
+
+ stringbuf::allocator_type a;
+ {
+ stringbuf sbuf(cstr, mode, a); // ={} checks for non-explicit ctor
+ VERIFY( sbuf.str() == cstr.s );
+ }
+ {
+ stringbuf sbuf(cstr, std::ios::in, a);
+ VERIFY( sbuf.str() == cstr.s );
+ VERIFY( sbuf.sgetc() == cstr.s[0] );
+ VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() );
+ }
+
+ {
+ stringbuf sbuf(cstr, std::ios::out, a);
+ VERIFY( sbuf.str() == cstr.s );
+ VERIFY( sbuf.sputc('X') == 'X' );
+ VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() );
+ }
+ }
+
+ {
+ // template <typename T>
+ // basic_stringbuf(const T&, ios_base::openmode)
+ {
+ stringbuf sbuf(cstr, mode);
+ VERIFY( sbuf.str() == cstr.s );
+ }
+ {
+ stringbuf sbuf(cstr, std::ios::in);
+ VERIFY( sbuf.str() == cstr.s );
+ VERIFY( sbuf.sgetc() == cstr.s[0] );
+ VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() );
+ }
+ {
+ stringbuf sbuf(cstr, std::ios::out);
+ VERIFY( sbuf.str() == cstr.s );
+ VERIFY( sbuf.sputc('X') == 'X' );
+ VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() );
+ }
+ }
+
+ {
+ // template <typename T>
+ // explicit
+ // basic_stringbuf(const T&, ios_base::openmode = ios_base::in|ios_base::out)
+
+ stringbuf sbuf(cstr);
+ VERIFY( sbuf.str() == cstr.s );
+ VERIFY( sbuf.sgetc() == cstr.s[0] );
+ }
+}
+
+using alloc_type = __gnu_test::uneq_allocator<C>;
+
+template<typename Alloc, typename CC = typename Alloc::value_type>
+ using stringbuf_with_alloc
+ = std::basic_stringbuf<CC, std::char_traits<CC>, Alloc>;
+
+void test03()
+{
+ alloc_type a{1};
+ {
+ stringbuf_with_alloc<alloc_type> sbuf(cstr, a);
+ VERIFY( sbuf.get_allocator() == a );
+ VERIFY( string_view{sbuf.str()} == cstr );
+ VERIFY( sbuf.sgetc() == cstr.s[0] );
+ }
+ {
+ stringbuf_with_alloc<alloc_type> sbuf(cstr, std::ios::in, a);
+ VERIFY( sbuf.get_allocator() == a );
+ VERIFY( string_view{sbuf.str()} == cstr );
+ VERIFY( sbuf.sgetc() == cstr.s[0] );
+ VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() );
+ }
+ {
+ stringbuf_with_alloc<alloc_type> sbuf(cstr, std::ios::out, a);
+ VERIFY( sbuf.get_allocator() == a );
+ VERIFY( string_view{sbuf.str()} == cstr );
+ VERIFY( sbuf.sputc('X') == 'X' );
+ VERIFY( sbuf.sgetc() == stringbuf::traits_type::eof() );
+ }
+}
+
+void test04()
+{
+ {
+ stringbuf sbuf;
+ sbuf.str(cstr);
+ VERIFY( sbuf.str() == cstr.s );
+ }
+ {
+ stringbuf sbuf;
+ sbuf.str(ccstr);
+ VERIFY( sbuf.str() == ccstr.s );
+ }
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc
new file mode 100644
index 0000000..c428491
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/wchar_t/string_view.cc
@@ -0,0 +1,6 @@
+// C++26 [stringbuf.general]
+// { dg-do run { target c++26 } }
+
+#define C wchar_t
+#define L(a) L##a
+#include "../char/string_view.cc"
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/char/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/char/string_view.cc
new file mode 100644
index 0000000..7208523
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/char/string_view.cc
@@ -0,0 +1,204 @@
+// C++26 31.8.2.1 [stringstream.general]
+
+// { dg-do run { target c++26 } }
+
+#include <sstream>
+#include <string>
+#include <string_view>
+#include <testsuite_allocator.h>
+#include <testsuite_hooks.h>
+
+// Check C++26 P2495 stringstream ctors and members str(s) that accept a
+// string_view, or anything convertible to a string_view, in place of a
+// string object. Mostly just verify plumbing.
+
+#ifndef C
+# define C char
+# define L(a) a
+#endif
+
+using string = std::basic_string<C>;
+using string_view = std::basic_string_view<C>;
+using stringstream = std::basic_stringstream<C>;
+
+struct convertible_to_string_view {
+ string s;
+ operator string_view() const { return s; }
+};
+
+const string str(L("This is a test string"));
+convertible_to_string_view cstr{str}; // a copy
+const convertible_to_string_view ccstr{str}; // another copy
+
+template <typename stringstream = std::basic_stringstream<C>>
+void
+test01()
+{
+ // Test C++26 constructor and str(s) taking a generalized string_view
+
+ static_assert(! requires { stringstream(1); },
+ "stringstream ctor should reject what cannot be converted to a string_view");
+ static_assert(! requires { stringstream().str(1); },
+ "stringstream::str(s) should reject what cannot be converted to a string_view");
+
+ static_assert(!std::is_convertible_v<string_view, stringstream>,
+ "stringstream(string_view, ios::openmode) is explicit");
+ static_assert(!std::is_convertible_v<const string_view, stringstream>,
+ "stringstream(string_view, ios::openmode) is explicit");
+ static_assert(!std::is_convertible_v<convertible_to_string_view, stringstream>,
+ "stringstream(convertible_to_string_view, ios::openmode) is explicit");
+ static_assert(!std::is_convertible_v<const convertible_to_string_view, stringstream>,
+ "stringstream(convertible_to_string_view, ios::openmode) is explicit");
+
+ {
+ stringstream strstr(cstr);
+ VERIFY( strstr.str() == cstr.s );
+ VERIFY( strstr.get() == cstr.s[0] );
+ }
+ {
+ stringstream strstr(ccstr);
+ VERIFY( strstr.str() == ccstr.s );
+ VERIFY( strstr.get() == ccstr.s[0] );
+ }
+ {
+ stringstream strstr(cstr, std::ios_base::in);
+ VERIFY( strstr.str() == cstr.s );
+ VERIFY( strstr.get() == cstr.s[0] );
+ VERIFY( strstr.put('X').rdstate() == strstr.badbit );
+ }
+ {
+ stringstream strstr(cstr, std::ios_base::out);
+ VERIFY( strstr.str() == cstr.s );
+ VERIFY( strstr.put('Y').good() );
+ VERIFY( strstr.get() == stringstream::traits_type::eof());
+ }
+}
+
+void
+test02()
+{
+ // Test C++26 various constructors taking string views
+
+ auto const mode = std::ios_base::in | std::ios_base::out;
+
+ {
+ // template <typename T>
+ // basic_stringstream(const T&, ios_base::openmode, const allocator_type&)
+
+ stringstream::allocator_type a;
+ {
+ stringstream strstr(cstr, mode, a); // ={} checks for non-explicit ctor
+ VERIFY( strstr.str() == cstr.s );
+ }
+ {
+ stringstream strstr(cstr, std::ios::in, a);
+ VERIFY( strstr.str() == cstr.s );
+ VERIFY( strstr.get() == cstr.s[0] );
+ VERIFY( strstr.put('X').rdstate() == strstr.badbit );
+ }
+ {
+ stringstream strstr(cstr, std::ios::out, a);
+ VERIFY( strstr.str() == cstr.s );
+ VERIFY( strstr.put('X').good() );
+ VERIFY( strstr.get() == stringstream::traits_type::eof());
+ }
+ }
+
+ {
+ // template <typename T>
+ // basic_stringstream(const T&, ios_base::openmode)
+
+ {
+ stringstream strstr(cstr, mode);
+ VERIFY( strstr.str() == cstr.s );
+ VERIFY( strstr.get() == cstr.s[0] );
+ VERIFY( strstr.put('X').good() );
+ }
+ {
+ stringstream strstr(cstr, std::ios::in);
+ VERIFY( strstr.str() == cstr.s );
+ VERIFY( strstr.get() == cstr.s[0] );
+ VERIFY( strstr.put('X').rdstate() == strstr.badbit );
+ }
+ {
+ stringstream strstr(cstr, std::ios::out);
+ VERIFY( strstr.str() == cstr.s );
+ VERIFY( strstr.put('X').good() );
+ VERIFY( strstr.get() == stringstream::traits_type::eof());
+ }
+ }
+
+ {
+ // template <typename T>
+ // explicit
+ // basic_stringstream(const T&, ios_base::openmode = ios_base::in|ios_base::out)
+
+ stringstream strstr(cstr);
+ VERIFY( strstr.str() == cstr.s );
+ VERIFY( strstr.get() == cstr.s[0] );
+ VERIFY( strstr.put('X').good() );
+ }
+}
+
+// A minimal allocator with no default constructor
+template<typename T>
+ struct NoDefaultCons : __gnu_test::SimpleAllocator<T>
+ {
+ using __gnu_test::SimpleAllocator<T>::SimpleAllocator;
+ NoDefaultCons() = delete;
+ NoDefaultCons(int) { }
+ };
+
+using alloc_type = __gnu_test::uneq_allocator<C>;
+
+template<typename Alloc, typename CC = typename Alloc::value_type>
+ using stringstream_with_alloc
+ = std::basic_stringstream<CC, std::char_traits<CC>, Alloc>;
+
+void test03()
+{
+ alloc_type a{1};
+ {
+ stringstream_with_alloc<alloc_type> strstr(cstr, a);
+ VERIFY( strstr.rdbuf()->get_allocator() == a );
+ VERIFY( string_view{strstr.str()} == cstr );
+ VERIFY( strstr.get() == cstr.s[0] );
+ }
+ {
+ stringstream_with_alloc<alloc_type> strstr(cstr, std::ios::in, a);
+ VERIFY( strstr.rdbuf()->get_allocator() == a );
+ VERIFY( string_view{strstr.str()} == cstr );
+ VERIFY( strstr.get() == cstr.s[0] );
+ VERIFY( strstr.put('X').rdstate() == strstr.badbit );
+ }
+ {
+ stringstream_with_alloc<alloc_type> strstr(cstr, std::ios::out, a);
+ VERIFY( strstr.rdbuf()->get_allocator() == a );
+ VERIFY( string_view{strstr.str()} == cstr );
+ VERIFY( strstr.put('X').good() );
+ VERIFY( strstr.get() == stringstream::traits_type::eof());
+ }
+}
+
+void test04()
+{
+ {
+ stringstream strstr;
+ strstr.str( cstr );
+ VERIFY( strstr.str() == cstr.s );
+ }
+ {
+ stringstream strstr;
+ strstr.str( ccstr );
+ VERIFY( strstr.str() == ccstr.s );
+ }
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc
new file mode 100644
index 0000000..921c0fe
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/cons/wchar_t/string_view.cc
@@ -0,0 +1,6 @@
+// C++26 [stringstream.general]
+// { dg-do run { target c++26 } }
+
+#define C wchar_t
+#define L(a) L##a
+#include "../char/string_view.cc"