diff options
Diffstat (limited to 'libstdc++-v3/testsuite')
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" |