From 95cb0fc8c51841cc6a0e51490cb3769eb80fa34c Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 10 Nov 2020 15:57:04 +0000 Subject: [PATCH] libstdc++: Add remaining C++20 additions to [P0408R7] This adds the new overloads of basic_stringbuf::str, and the corresponding overloads to basic_istringstream, basic_ostringstream and basic_stringstream. libstdc++-v3/ChangeLog: * config/abi/pre/gnu.ver (GLIBCXX_3.4.21): Tighten patterns. (GLIBCXX_3.4.29): Export new symbols. * include/bits/alloc_traits.h (__allocator_like): New concept. * include/std/sstream (basic_stringbuf::swap): Add exception specification. (basic_stringbuf::str() const): Add ref-qualifier. Use new _M_high_mark function. (basic_stringbuf::str(const SAlloc&) const): Define new function. (basic_stringbuf::str() &&): Likewise. (basic_stringbuf::str(const basic_string&)): Likewise. (basic_stringbuf::str(basic_string&&)): Likewise. (basic_stringbuf::view() const): Use _M_high_mark. (basic_istringstream::str, basic_ostringstream::str) (basic_stringstream::str): Define new overloads. * src/c++20/sstream-inst.cc (basic_stringbuf::str) (basic_istringstream::str, basic_ostringstream::str) (basic_stringstream::str): Explicit instantiation definitions for new overloads. * testsuite/27_io/basic_istringstream/view/char/1.cc: Add more checks. * testsuite/27_io/basic_istringstream/view/wchar_t/1.cc: Likewise. * testsuite/27_io/basic_ostringstream/view/char/1.cc: Likewise. * testsuite/27_io/basic_ostringstream/view/wchar_t/1.cc: Likewise. * testsuite/27_io/basic_stringstream/view/char/1.cc: Likewise. * testsuite/27_io/basic_stringstream/view/wchar_t/1.cc: Likewise. * testsuite/27_io/basic_istringstream/str/char/2.cc: New test. * testsuite/27_io/basic_istringstream/str/wchar_t/2.cc: New test. * testsuite/27_io/basic_ostringstream/str/char/3.cc: New test. * testsuite/27_io/basic_ostringstream/str/wchar_t/3.cc: New test. * testsuite/27_io/basic_stringbuf/str/char/4.cc: New test. * testsuite/27_io/basic_stringbuf/str/wchar_t/4.cc: New test. * testsuite/27_io/basic_stringstream/str/char/5.cc: New test. * testsuite/27_io/basic_stringstream/str/wchar_t/5.cc.cc: New test. --- libstdc++-v3/config/abi/pre/gnu.ver | 21 +- libstdc++-v3/include/bits/alloc_traits.h | 8 + libstdc++-v3/include/std/sstream | 223 ++++++++++++++---- libstdc++-v3/src/c++20/sstream-inst.cc | 48 ++++ .../27_io/basic_istringstream/str/char/2.cc | 94 ++++++++ .../basic_istringstream/str/wchar_t/2.cc | 94 ++++++++ .../27_io/basic_istringstream/view/char/1.cc | 16 +- .../basic_istringstream/view/wchar_t/1.cc | 14 +- .../27_io/basic_ostringstream/str/char/3.cc | 94 ++++++++ .../basic_ostringstream/str/wchar_t/3.cc | 94 ++++++++ .../27_io/basic_ostringstream/view/char/1.cc | 12 +- .../basic_ostringstream/view/wchar_t/1.cc | 12 +- .../27_io/basic_stringbuf/str/char/4.cc | 94 ++++++++ .../27_io/basic_stringbuf/str/wchar_t/4.cc | 94 ++++++++ .../27_io/basic_stringstream/str/char/5.cc | 94 ++++++++ .../basic_stringstream/str/wchar_t/5.cc.cc | 94 ++++++++ .../27_io/basic_stringstream/view/char/1.cc | 16 +- .../basic_stringstream/view/wchar_t/1.cc | 14 +- 18 files changed, 1082 insertions(+), 54 deletions(-) create mode 100644 libstdc++-v3/testsuite/27_io/basic_istringstream/str/char/2.cc create mode 100644 libstdc++-v3/testsuite/27_io/basic_istringstream/str/wchar_t/2.cc create mode 100644 libstdc++-v3/testsuite/27_io/basic_ostringstream/str/char/3.cc create mode 100644 libstdc++-v3/testsuite/27_io/basic_ostringstream/str/wchar_t/3.cc create mode 100644 libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/4.cc create mode 100644 libstdc++-v3/testsuite/27_io/basic_stringbuf/str/wchar_t/4.cc create mode 100644 libstdc++-v3/testsuite/27_io/basic_stringstream/str/char/5.cc create mode 100644 libstdc++-v3/testsuite/27_io/basic_stringstream/str/wchar_t/5.cc.cc diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 2d0f87aa7cc..46769db1530 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -1776,14 +1776,16 @@ GLIBCXX_3.4.21 { _ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EED[012]Ev; _ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EOS4_ONS4_14__xfer_bufptrsE; _ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]14__xfer_bufptrs[CD][12]*; - _ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[a1346789]*; + _ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE[a146789]*; + _ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE3strERK*; # _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]*; _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EOS4_; _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EOSa*; _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKNS_12basic_stringI[cw]S2_S3_EESt13_Ios_Openmode; _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ESt13_Ios_Openmode; _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EED[012]Ev; - _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE[a34]*; + _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE[a4]*; + _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strERK*; # _ZNSt7__cxx1119basic_istringstreamI[cw]St11char_traitsI[cw]*; # _ZNSt7__cxx1119basic_ostringstreamI[cw]St11char_traitsI[cw]*; _ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EOS4_; @@ -1791,7 +1793,8 @@ GLIBCXX_3.4.21 { _ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKNS_12basic_stringI[cw]S2_S3_EESt13_Ios_Openmode; _ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ESt13_Ios_Openmode; _ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EED[012]Ev; - _ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE[a34]*; + _ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE[a4]*; + _ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strERK*; _ZNKSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv; _ZNKSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv; _ZNKSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE5rdbufEv; @@ -2354,6 +2357,10 @@ GLIBCXX_3.4.29 { # basic_stringbuf::view() _ZNKSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE4viewEv; + # basic_stringbuf::str + _ZNOSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv; + _ZNKRSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv; + _ZNSt7__cxx1115basic_stringbufI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEONS_12basic_stringI[cw]S2_S3_EE; # basic_[io]stringstream::basic_[io]stringstream(basic_string&&, ios_base::openmode) _ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EONS_12basic_stringI[cw]S2_S3_EESt13_Ios_Openmode; @@ -2363,6 +2370,10 @@ GLIBCXX_3.4.29 { # basic_[io]stringstream::view() _ZNKSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE4viewEv; + # basic_[io]stringstream::str + _ZNOSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv; + _ZNKRSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv; + _ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEONS_12basic_stringI[cw]S2_S3_EE; # basic_stringstream::basic_stringstream(basic_string&&, ios_base::openmode) _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EONS_12basic_stringI[cw]S2_S3_EESt13_Ios_Openmode; @@ -2372,6 +2383,10 @@ GLIBCXX_3.4.29 { # basic_stringstream::view() _ZNKSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE4viewEv; + # basic_stringstream::str + _ZNOSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv; + _ZNKRSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEv; + _ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3strEONS_12basic_stringI[cw]S2_S3_EE; # std::once_flag::_M_activate() _ZNSt9once_flag11_M_activateEv; diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h index 86d8ed221ff..467311fc917 100644 --- a/libstdc++-v3/include/bits/alloc_traits.h +++ b/libstdc++-v3/include/bits/alloc_traits.h @@ -708,6 +708,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template using _RequireNotAllocator = typename enable_if::value, _Alloc>::type; + +#if __cpp_concepts >= 201907L + template + concept __allocator_like = requires (_Alloc& __a) { + typename _Alloc::value_type; + __a.deallocate(__a.allocate(1u), 1u); + }; +#endif #endif // C++11 /** diff --git a/libstdc++-v3/include/std/sstream b/libstdc++-v3/include/std/sstream index 9c50e4e8328..8cddda29701 100644 --- a/libstdc++-v3/include/std/sstream +++ b/libstdc++-v3/include/std/sstream @@ -37,6 +37,13 @@ #include #include +#include // allocator_traits, __allocator_like + +#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI +# define _GLIBCXX_LVAL_REF_QUAL & +#else +# define _GLIBCXX_LVAL_REF_QUAL +#endif namespace std _GLIBCXX_VISIBILITY(default) { @@ -65,6 +72,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 class basic_stringbuf : public basic_streambuf<_CharT, _Traits> { struct __xfer_bufptrs; + +#if __cplusplus >= 201103L + using allocator_traits = std::allocator_traits<_Alloc>; + using _Noexcept_swap + = __or_; +#endif + public: // Types: typedef _CharT char_type; @@ -153,7 +168,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } void - swap(basic_stringbuf& __rhs) + swap(basic_stringbuf& __rhs) noexcept(_Noexcept_swap::value) { __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)}; __xfer_bufptrs __r_st{__rhs, this}; @@ -161,9 +176,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 __streambuf_type::swap(__base); __rhs.pubimbue(this->pubimbue(__rhs.getloc())); std::swap(_M_mode, __rhs._M_mode); - std::swap(_M_string, __rhs._M_string); + std::swap(_M_string, __rhs._M_string); // XXX not exception safe } -#endif +#endif // C++11 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI explicit @@ -213,7 +228,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { return _M_string.get_allocator(); } #endif - // Get and set: + // Getters and setters: + /** * @brief Copying out the string buffer. * @return A copy of one of the underlying sequences. @@ -223,23 +239,51 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * is equal to the output sequence. [27.7.1.2]/1 */ __string_type - str() const + str() const _GLIBCXX_LVAL_REF_QUAL { __string_type __ret(_M_string.get_allocator()); - if (char_type* __pptr = this->pptr()) - { - char_type* __egptr = this->egptr(); - // The current egptr() may not be the actual string end. - if (!__egptr || __pptr > __egptr) - __ret.assign(this->pbase(), __pptr); - else - __ret.assign(this->pbase(), __egptr); - } + if (char_type* __hi = _M_high_mark()) + __ret.assign(this->pbase(), __hi); else __ret = _M_string; return __ret; } +#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI +#if __cpp_concepts + template<__allocator_like _SAlloc> + basic_string<_CharT, _Traits, _SAlloc> + str(const _SAlloc& __sa) const + { + auto __sv = view(); + return { __sv.data(), __sv.size(), __sa }; + } +#endif + + __string_type + str() && + { + if (char_type* __hi = _M_high_mark()) + { + // Set length to end of character sequence and add null terminator. + _M_string._M_set_length(_M_high_mark() - this->pbase()); + } + auto __str = std::move(_M_string); + _M_string.clear(); + _M_sync(_M_string.data(), 0, 0); + return __str; + } + + basic_string_view + view() const noexcept + { + if (char_type* __hi = _M_high_mark()) + return { this->pbase(), __hi }; + else + return _M_string; + } +#endif + /** * @brief Setting a new buffer. * @param __s The string to use as a new sequence. @@ -257,21 +301,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI - basic_string_view - view() const noexcept - { - using __sv_type = basic_string_view; +#if __cpp_concepts + template<__allocator_like _SAlloc> + requires (!is_same_v<_SAlloc, _Alloc>) + void + str(const basic_string<_CharT, _Traits, _SAlloc>& __s) + { + _M_string.assign(__s.data(), __s.size()); + _M_stringbuf_init(_M_mode); + } +#endif - if (this->pptr()) - { - // The current egptr() may not be the actual string end. - if (this->pptr() > this->egptr()) - return __sv_type(this->pbase(), this->pptr()); - else - return __sv_type(this->pbase(), this->egptr()); - } - else - return static_cast<__sv_type>(_M_string); + void + str(__string_type&& __s) + { + _M_string = std::move(__s); + _M_stringbuf_init(_M_mode); } #endif @@ -376,6 +421,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off); private: + // Return a pointer to the end of the underlying character sequence. + // This might not be the same character as _M_string.end() because + // basic_stringbuf::overflow might have written to unused capacity + // in _M_string without updating its length. + char_type* + _M_high_mark() const _GLIBCXX_NOEXCEPT + { + if (char_type* __pptr = this->pptr()) + { + char_type* __egptr = this->egptr(); + if (!__egptr || __pptr > __egptr) + return __pptr; // Underlying sequence is [pbase, pptr). + else + return __egptr; // Underlying sequence is [pbase, egptr). + } + return 0; // Underlying character sequence is just _M_string. + } + #if __cplusplus >= 201103L #if _GLIBCXX_USE_CXX11_ABI // This type captures the state of the gptr / pptr pointers as offsets @@ -629,9 +692,26 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * @return @c rdbuf()->str() */ __string_type - str() const + str() const _GLIBCXX_LVAL_REF_QUAL { return _M_stringbuf.str(); } +#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI +#if __cpp_concepts + template<__allocator_like _SAlloc> + basic_string<_CharT, _Traits, _SAlloc> + str(const _SAlloc& __sa) const + { return _M_stringbuf.str(__sa); } +#endif + + __string_type + str() && + { return std::move(_M_stringbuf).str(); } + + basic_string_view + view() const noexcept + { return _M_stringbuf.view(); } +#endif + /** * @brief Setting a new buffer. * @param __s The string to use as a new sequence. @@ -643,9 +723,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { _M_stringbuf.str(__s); } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI - basic_string_view - view() const noexcept - { return _M_stringbuf.view(); } +#if __cpp_concepts + template<__allocator_like _SAlloc> + requires (!is_same_v<_SAlloc, _Alloc>) + void + str(const basic_string<_CharT, _Traits, _SAlloc>& __s) + { _M_stringbuf.str(__s); } +#endif + + void + str(__string_type&& __s) + { _M_stringbuf.str(std::move(__s)); } #endif }; @@ -825,9 +913,26 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * @return @c rdbuf()->str() */ __string_type - str() const + str() const _GLIBCXX_LVAL_REF_QUAL { return _M_stringbuf.str(); } +#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI +#if __cpp_concepts + template<__allocator_like _SAlloc> + basic_string<_CharT, _Traits, _SAlloc> + str(const _SAlloc& __sa) const + { return _M_stringbuf.str(__sa); } +#endif + + __string_type + str() && + { return std::move(_M_stringbuf).str(); } + + basic_string_view + view() const noexcept + { return _M_stringbuf.view(); } +#endif + /** * @brief Setting a new buffer. * @param __s The string to use as a new sequence. @@ -839,9 +944,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { _M_stringbuf.str(__s); } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI - basic_string_view - view() const noexcept - { return _M_stringbuf.view(); } +#if __cpp_concepts + template<__allocator_like _SAlloc> + requires (!is_same_v<_SAlloc, _Alloc>) + void + str(const basic_string<_CharT, _Traits, _SAlloc>& __s) + { _M_stringbuf.str(__s); } +#endif + + void + str(__string_type&& __s) + { _M_stringbuf.str(std::move(__s)); } #endif }; @@ -1019,9 +1132,26 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * @return @c rdbuf()->str() */ __string_type - str() const + str() const _GLIBCXX_LVAL_REF_QUAL { return _M_stringbuf.str(); } +#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI +#if __cpp_concepts + template<__allocator_like _SAlloc> + basic_string<_CharT, _Traits, _SAlloc> + str(const _SAlloc& __sa) const + { return _M_stringbuf.str(__sa); } +#endif + + __string_type + str() && + { return std::move(_M_stringbuf).str(); } + + basic_string_view + view() const noexcept + { return _M_stringbuf.view(); } +#endif + /** * @brief Setting a new buffer. * @param __s The string to use as a new sequence. @@ -1033,9 +1163,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { _M_stringbuf.str(__s); } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI - basic_string_view - view() const noexcept - { return _M_stringbuf.view(); } +#if __cpp_concepts + template<__allocator_like _SAlloc> + requires (!is_same_v<_SAlloc, _Alloc>) + void + str(const basic_string<_CharT, _Traits, _SAlloc>& __s) + { _M_stringbuf.str(__s); } +#endif + + void + str(__string_type&& __s) + { _M_stringbuf.str(std::move(__s)); } #endif }; @@ -1045,6 +1183,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 inline void swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x, basic_stringbuf<_CharT, _Traits, _Allocator>& __y) + noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } /// Swap specialization for istringstreams. @@ -1067,12 +1206,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x, basic_stringstream<_CharT, _Traits, _Allocator>& __y) { __x.swap(__y); } -#endif +#endif // C++11 _GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace +#undef _GLIBCXX_LVAL_REF_QUAL + #include #endif /* _GLIBCXX_SSTREAM */ diff --git a/libstdc++-v3/src/c++20/sstream-inst.cc b/libstdc++-v3/src/c++20/sstream-inst.cc index 7d275de5cc2..9e157d1b1bf 100644 --- a/libstdc++-v3/src/c++20/sstream-inst.cc +++ b/libstdc++-v3/src/c++20/sstream-inst.cc @@ -46,29 +46,53 @@ template basic_stringbuf::basic_stringbuf(basic_stringbuf&&, __xfer_bufptrs&&); template basic_stringbuf::allocator_type basic_stringbuf::get_allocator() const noexcept; +template string +basic_stringbuf::str() const &; +template string +basic_stringbuf::str() &&; template string_view basic_stringbuf::view() const noexcept; +template void +basic_stringbuf::str(string&&); template basic_istringstream::basic_istringstream(ios_base::openmode, const allocator_type&); template basic_istringstream::basic_istringstream(__string_type&&, ios_base::openmode); +template string +basic_istringstream::str() const &; +template string +basic_istringstream::str() &&; template string_view basic_istringstream::view() const noexcept; +template void +basic_istringstream::str(string&&); template basic_ostringstream::basic_ostringstream(ios_base::openmode, const allocator_type&); template basic_ostringstream::basic_ostringstream(__string_type&&, ios_base::openmode); +template string +basic_ostringstream::str() const &; +template string +basic_ostringstream::str() &&; template string_view basic_ostringstream::view() const noexcept; +template void +basic_ostringstream::str(string&&); template basic_stringstream::basic_stringstream(ios_base::openmode, const allocator_type&); template basic_stringstream::basic_stringstream(__string_type&&, ios_base::openmode); +template string +basic_stringstream::str() const &; +template string +basic_stringstream::str() &&; template string_view basic_stringstream::view() const noexcept; +template void +basic_stringstream::str(string&&); #ifdef _GLIBCXX_USE_WCHAR_T template basic_stringbuf::basic_stringbuf(const allocator_type&); @@ -84,29 +108,53 @@ template basic_stringbuf::basic_stringbuf(basic_stringbuf&&, template basic_stringbuf::allocator_type basic_stringbuf::get_allocator() const noexcept; +template wstring +basic_stringbuf::str() const &; +template wstring +basic_stringbuf::str() &&; template wstring_view basic_stringbuf::view() const noexcept; +template void +basic_stringbuf::str(wstring&&); template basic_istringstream::basic_istringstream(ios_base::openmode, const allocator_type&); template basic_istringstream::basic_istringstream(__string_type&&, ios_base::openmode); +template wstring +basic_istringstream::str() const &; +template wstring +basic_istringstream::str() &&; template wstring_view basic_istringstream::view() const noexcept; +template void +basic_istringstream::str(wstring&&); template basic_ostringstream::basic_ostringstream(ios_base::openmode, const allocator_type&); template basic_ostringstream::basic_ostringstream(__string_type&&, ios_base::openmode); +template wstring +basic_ostringstream::str() const &; +template wstring +basic_ostringstream::str() &&; template wstring_view basic_ostringstream::view() const noexcept; +template void +basic_ostringstream::str(wstring&&); template basic_stringstream::basic_stringstream(ios_base::openmode, const allocator_type&); template basic_stringstream::basic_stringstream(__string_type&&, ios_base::openmode); +template wstring +basic_stringstream::str() const &; +template wstring +basic_stringstream::str() &&; template wstring_view basic_stringstream::view() const noexcept; +template void +basic_stringstream::str(wstring&&); #endif _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/str/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/str/char/2.cc new file mode 100644 index 00000000000..58ee1d2367c --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/str/char/2.cc @@ -0,0 +1,94 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 29.8.3.4 basic_istringstream member functions [istringstream.members] + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-effective-target cxx11-abi } + +#include +#include +#include + +void test01() +{ + const std::string s0 = "this is not a short string"; + std::istringstream ss; + ss.str(s0); + VERIFY( ss.str() == s0 ); + VERIFY( ss.str() == s0 ); + + using Alloc = __gnu_test::uneq_allocator; + const Alloc a1(1); + std::basic_string, Alloc> s1 = ss.str(a1); + VERIFY( s1.get_allocator() == a1 ); + VERIFY( ss.str(a1).get_allocator() == a1 ); + VERIFY( ss.str(a1) == s1 ); + VERIFY( std::move(ss).str(a1) == s1 ); + VERIFY( std::move(ss).str(a1) == s1 ); + + const Alloc a2(2); + VERIFY( ss.str(a2).get_allocator() == a2 ); + VERIFY( ss.str(a2) == s1 ); + + VERIFY( std::move(ss).str() == s0 ); + VERIFY( std::move(ss).str().empty() ); + VERIFY( ss.str().empty() ); + VERIFY( ss.str(a1).empty() ); +} + +void test02() +{ + std::istringstream ss("123"); + std::string str = "ABCDEF"; + ss.str(str); + VERIFY( ss.str() == str ); + VERIFY( std::move(ss).str() == str ); + VERIFY( std::move(ss).str().empty() ); +} + +void test03() +{ + std::istringstream ss; + using Alloc = __gnu_test::tracker_allocator; + using Str = std::basic_string, Alloc>; + Str s1 = "string that is not short, quite long even"; + auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + ss.str(s1); + auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + VERIFY( count1 == count2 ); + VERIFY( ss.str() == s1.c_str() ); +} + +void test04() +{ + std::istringstream ss; + const std::string str = "Another quite long string, not at all short"; + std::string str2 = str; + ss.str(std::move(str2)); + VERIFY( str2.empty() ); + VERIFY( ss.str() == str ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/str/wchar_t/2.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/str/wchar_t/2.cc new file mode 100644 index 00000000000..59585274164 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/str/wchar_t/2.cc @@ -0,0 +1,94 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 29.8.3.4 basic_istringstream member functions [istringstream.members] + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-effective-target cxx11-abi } + +#include +#include +#include + +void test01() +{ + const std::wstring s0 = L"this is not a short string"; + std::wistringstream ss; + ss.str(s0); + VERIFY( ss.str() == s0 ); + VERIFY( ss.str() == s0 ); + + using Alloc = __gnu_test::uneq_allocator; + const Alloc a1(1); + std::basic_string, Alloc> s1 = ss.str(a1); + VERIFY( s1.get_allocator() == a1 ); + VERIFY( ss.str(a1).get_allocator() == a1 ); + VERIFY( ss.str(a1) == s1 ); + VERIFY( std::move(ss).str(a1) == s1 ); + VERIFY( std::move(ss).str(a1) == s1 ); + + const Alloc a2(2); + VERIFY( ss.str(a2).get_allocator() == a2 ); + VERIFY( ss.str(a2) == s1 ); + + VERIFY( std::move(ss).str() == s0 ); + VERIFY( std::move(ss).str().empty() ); + VERIFY( ss.str().empty() ); + VERIFY( ss.str(a1).empty() ); +} + +void test02() +{ + std::wistringstream ss(L"123"); + std::wstring str = L"ABCDEF"; + ss.str(str); + VERIFY( ss.str() == str ); + VERIFY( std::move(ss).str() == str ); + VERIFY( std::move(ss).str().empty() ); +} + +void test03() +{ + std::wistringstream ss; + using Alloc = __gnu_test::tracker_allocator; + using Str = std::basic_string, Alloc>; + Str s1 = L"string that is not short, quite long even"; + auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + ss.str(s1); + auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + VERIFY( count1 == count2 ); + VERIFY( ss.str() == s1.c_str() ); +} + +void test04() +{ + std::wistringstream ss; + const std::wstring str = L"Another quite long string, not at all short"; + std::wstring str2 = str; + ss.str(std::move(str2)); + VERIFY( str2.empty() ); + VERIFY( ss.str() == str ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/view/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/view/char/1.cc index 091de5f7a79..c4550702005 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istringstream/view/char/1.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/view/char/1.cc @@ -15,7 +15,7 @@ // with this library; see the file COPYING3. If not see // . -// 27.7.1.1 basic_stringbuf constructors [lib.stringbuf.cons] +// 29.8.3.4 basic_istringstream member functions [istringstream.members] // { dg-options "-std=gnu++2a" } // { dg-do run { target c++2a } } @@ -31,5 +31,17 @@ main() std::string s("This is a test"); std::istringstream stm(s); VERIFY( stm.view() == s ); - return 0; + VERIFY( stm.view() == const_cast(stm).view() ); + + s = "This is another test with a longer string"; + stm.str(s); + VERIFY( stm.view() == s ); + + s = "This is a shorter string"; + stm.str(s); + VERIFY( stm.view() == s ); + + std::string s2; + stm >> s2; + VERIFY( stm.view() == s ); } diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/view/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/view/wchar_t/1.cc index f6599643bd9..8efba061454 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istringstream/view/wchar_t/1.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/view/wchar_t/1.cc @@ -31,5 +31,17 @@ main() std::wstring s(L"This is a test"); std::wistringstream stm(s); VERIFY( stm.view() == s ); - return 0; + VERIFY( stm.view() == const_cast(stm).view() ); + + s = L"This is another test with a longer string"; + stm.str(s); + VERIFY( stm.view() == s ); + + s = L"This is a shorter string"; + stm.str(s); + VERIFY( stm.view() == s ); + + std::wstring s2; + stm >> s2; + VERIFY( stm.view() == s ); } diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/str/char/3.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/str/char/3.cc new file mode 100644 index 00000000000..23e961e6a1f --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/str/char/3.cc @@ -0,0 +1,94 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 29.8.4.4 basic_ostringstream member functions [ostringstream.members] + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-effective-target cxx11-abi } + +#include +#include +#include + +void test01() +{ + const std::string s0 = "this is not a short string"; + std::ostringstream ss; + ss.str(s0); + VERIFY( ss.str() == s0 ); + VERIFY( ss.str() == s0 ); + + using Alloc = __gnu_test::uneq_allocator; + const Alloc a1(1); + std::basic_string, Alloc> s1 = ss.str(a1); + VERIFY( s1.get_allocator() == a1 ); + VERIFY( ss.str(a1).get_allocator() == a1 ); + VERIFY( ss.str(a1) == s1 ); + VERIFY( std::move(ss).str(a1) == s1 ); + VERIFY( std::move(ss).str(a1) == s1 ); + + const Alloc a2(2); + VERIFY( ss.str(a2).get_allocator() == a2 ); + VERIFY( ss.str(a2) == s1 ); + + VERIFY( std::move(ss).str() == s0 ); + VERIFY( std::move(ss).str().empty() ); + VERIFY( ss.str().empty() ); + VERIFY( ss.str(a1).empty() ); +} + +void test02() +{ + std::ostringstream ss("123"); + std::string str = "ABCDEF"; + ss << str; + VERIFY( ss.str() == str ); + VERIFY( std::move(ss).str() == str ); + VERIFY( std::move(ss).str().empty() ); +} + +void test03() +{ + std::ostringstream ss; + using Alloc = __gnu_test::tracker_allocator; + using Str = std::basic_string, Alloc>; + Str s1 = "string that is not short, quite long even"; + auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + ss.str(s1); + auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + VERIFY( count1 == count2 ); + VERIFY( ss.str() == s1.c_str() ); +} + +void test04() +{ + std::ostringstream ss; + const std::string str = "Another quite long string, not at all short"; + std::string str2 = str; + ss.str(std::move(str2)); + VERIFY( str2.empty() ); + VERIFY( ss.str() == str ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/str/wchar_t/3.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/str/wchar_t/3.cc new file mode 100644 index 00000000000..7c354cbf7eb --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/str/wchar_t/3.cc @@ -0,0 +1,94 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 29.8.4.4 basic_ostringstream member functions [ostringstream.members] + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-effective-target cxx11-abi } + +#include +#include +#include + +void test01() +{ + const std::wstring s0 = L"this is not a short string"; + std::wostringstream ss; + ss.str(s0); + VERIFY( ss.str() == s0 ); + VERIFY( ss.str() == s0 ); + + using Alloc = __gnu_test::uneq_allocator; + const Alloc a1(1); + std::basic_string, Alloc> s1 = ss.str(a1); + VERIFY( s1.get_allocator() == a1 ); + VERIFY( ss.str(a1).get_allocator() == a1 ); + VERIFY( ss.str(a1) == s1 ); + VERIFY( std::move(ss).str(a1) == s1 ); + VERIFY( std::move(ss).str(a1) == s1 ); + + const Alloc a2(2); + VERIFY( ss.str(a2).get_allocator() == a2 ); + VERIFY( ss.str(a2) == s1 ); + + VERIFY( std::move(ss).str() == s0 ); + VERIFY( std::move(ss).str().empty() ); + VERIFY( ss.str().empty() ); + VERIFY( ss.str(a1).empty() ); +} + +void test02() +{ + std::wostringstream ss(L"123"); + std::wstring str = L"ABCDEF"; + ss << str; + VERIFY( ss.str() == str ); + VERIFY( std::move(ss).str() == str ); + VERIFY( std::move(ss).str().empty() ); +} + +void test03() +{ + std::wostringstream ss; + using Alloc = __gnu_test::tracker_allocator; + using Str = std::basic_string, Alloc>; + Str s1 = L"string that is not short, quite long even"; + auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + ss.str(s1); + auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + VERIFY( count1 == count2 ); + VERIFY( ss.str() == s1.c_str() ); +} + +void test04() +{ + std::wostringstream ss; + const std::wstring str = L"Another quite long string, not at all short"; + std::wstring str2 = str; + ss.str(std::move(str2)); + VERIFY( str2.empty() ); + VERIFY( ss.str() == str ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/char/1.cc index a366363abb5..f072c16f28a 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/char/1.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/char/1.cc @@ -15,7 +15,7 @@ // with this library; see the file COPYING3. If not see // . -// 27.7.1.1 basic_stringbuf constructors [lib.stringbuf.cons] +// 29.8.4.4 basic_ostringstream member functions [ostringstream.members] // { dg-options "-std=gnu++2a" } // { dg-do run { target c++2a } } @@ -31,5 +31,13 @@ main() std::string s("This is a test"); std::ostringstream stm(s); VERIFY( stm.view() == s ); - return 0; + VERIFY( stm.view() == const_cast(stm).view() ); + + s += " with a longer string"; + stm << s; + VERIFY( stm.view() == s ); + + s = "This is a shorter string"; + stm.str(s); + VERIFY( stm.view() == s ); } diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/wchar_t/1.cc index 1ebf7c505e3..3fa2604e1e3 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/wchar_t/1.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/view/wchar_t/1.cc @@ -15,7 +15,7 @@ // with this library; see the file COPYING3. If not see // . -// 27.7.1.1 basic_stringbuf constructors [lib.stringbuf.cons] +// 29.8.4.4 basic_ostringstream member functions [ostringstream.members] // { dg-options "-std=gnu++2a" } // { dg-do run { target c++2a } } @@ -31,5 +31,13 @@ main() std::wstring s(L"This is a test"); std::wostringstream stm(s); VERIFY( stm.view() == s ); - return 0; + VERIFY( stm.view() == const_cast(stm).view() ); + + s += L" with a longer string"; + stm << s; + VERIFY( stm.view() == s ); + + s = L"This is a shorter string"; + stm.str(s); + VERIFY( stm.view() == s ); } diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/4.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/4.cc new file mode 100644 index 00000000000..3a4b0c70b91 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/4.cc @@ -0,0 +1,94 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 29.8.2.4 basic_stringbuf member functions [stringbuf.members] + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-effective-target cxx11-abi } + +#include +#include +#include + +void test01() +{ + const std::string s0 = "this is not a short string"; + std::stringbuf sb; + sb.str(s0); + VERIFY( sb.str() == s0 ); + VERIFY( sb.str() == s0 ); + + using Alloc = __gnu_test::uneq_allocator; + const Alloc a1(1); + std::basic_string, Alloc> s1 = sb.str(a1); + VERIFY( s1.get_allocator() == a1 ); + VERIFY( sb.str(a1).get_allocator() == a1 ); + VERIFY( sb.str(a1) == s1 ); + VERIFY( std::move(sb).str(a1) == s1 ); + VERIFY( std::move(sb).str(a1) == s1 ); + + const Alloc a2(2); + VERIFY( sb.str(a2).get_allocator() == a2 ); + VERIFY( sb.str(a2) == s1 ); + + VERIFY( std::move(sb).str() == s0 ); + VERIFY( std::move(sb).str().empty() ); + VERIFY( sb.str().empty() ); + VERIFY( sb.str(a1).empty() ); +} + +void test02() +{ + std::stringbuf sb("123"); + std::string str = "ABCDEF"; + sb.sputn(str.c_str(), str.size()); + VERIFY( sb.str() == str ); + VERIFY( std::move(sb).str() == str ); + VERIFY( std::move(sb).str().empty() ); +} + +void test03() +{ + std::stringbuf sb; + using Alloc = __gnu_test::tracker_allocator; + using Str = std::basic_string, Alloc>; + Str s1("string that is not short, quite long even"); + auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + sb.str(s1); + auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + VERIFY( count1 == count2 ); + VERIFY( sb.str() == s1.c_str() ); +} + +void test04() +{ + std::stringbuf sb; + const std::string str = "Another quite long string, not at all short"; + std::string str2 = str; + sb.str(std::move(str2)); + VERIFY( str2.empty() ); + VERIFY( sb.str() == str ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/wchar_t/4.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/wchar_t/4.cc new file mode 100644 index 00000000000..5d5187f9d52 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/str/wchar_t/4.cc @@ -0,0 +1,94 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 29.8.2.4 basic_stringbuf member functions [stringbuf.members] + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-effective-target cxx11-abi } + +#include +#include +#include + +void test01() +{ + const std::wstring s0 = L"this is not a short string"; + std::wstringbuf sb; + sb.str(s0); + VERIFY( sb.str() == s0 ); + VERIFY( sb.str() == s0 ); + + using Alloc = __gnu_test::uneq_allocator; + const Alloc a1(1); + std::basic_string, Alloc> s1 = sb.str(a1); + VERIFY( s1.get_allocator() == a1 ); + VERIFY( sb.str(a1).get_allocator() == a1 ); + VERIFY( sb.str(a1) == s1 ); + VERIFY( std::move(sb).str(a1) == s1 ); + VERIFY( std::move(sb).str(a1) == s1 ); + + const Alloc a2(2); + VERIFY( sb.str(a2).get_allocator() == a2 ); + VERIFY( sb.str(a2) == s1 ); + + VERIFY( std::move(sb).str() == s0 ); + VERIFY( std::move(sb).str().empty() ); + VERIFY( sb.str().empty() ); + VERIFY( sb.str(a1).empty() ); +} + +void test02() +{ + std::wstringbuf sb(L"123"); + std::wstring str = L"ABCDEF"; + sb.sputn(str.c_str(), str.size()); + VERIFY( sb.str() == str ); + VERIFY( std::move(sb).str() == str ); + VERIFY( std::move(sb).str().empty() ); +} + +void test03() +{ + std::wstringbuf sb; + using Alloc = __gnu_test::tracker_allocator; + using Str = std::basic_string, Alloc>; + Str s1 = L"string that is not short, quite long even"; + auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + sb.str(s1); + auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + VERIFY( count1 == count2 ); + VERIFY( sb.str() == s1.c_str() ); +} + +void test04() +{ + std::wstringbuf sb; + const std::wstring str = L"Another quite long string, not at all short"; + std::wstring str2 = str; + sb.str(std::move(str2)); + VERIFY( str2.empty() ); + VERIFY( sb.str() == str ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/str/char/5.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/str/char/5.cc new file mode 100644 index 00000000000..917bd211508 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/str/char/5.cc @@ -0,0 +1,94 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 29.8.5.4 basic_stringstream member functions [stringstream.members] + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-effective-target cxx11-abi } + +#include +#include +#include + +void test01() +{ + const std::string s0 = "this is not a short string"; + std::stringstream ss; + ss.str(s0); + VERIFY( ss.str() == s0 ); + VERIFY( ss.str() == s0 ); + + using Alloc = __gnu_test::uneq_allocator; + const Alloc a1(1); + std::basic_string, Alloc> s1 = ss.str(a1); + VERIFY( s1.get_allocator() == a1 ); + VERIFY( ss.str(a1).get_allocator() == a1 ); + VERIFY( ss.str(a1) == s1 ); + VERIFY( std::move(ss).str(a1) == s1 ); + VERIFY( std::move(ss).str(a1) == s1 ); + + const Alloc a2(2); + VERIFY( ss.str(a2).get_allocator() == a2 ); + VERIFY( ss.str(a2) == s1 ); + + VERIFY( std::move(ss).str() == s0 ); + VERIFY( std::move(ss).str().empty() ); + VERIFY( ss.str().empty() ); + VERIFY( ss.str(a1).empty() ); +} + +void test02() +{ + std::stringstream ss("123"); + std::string str = "ABCDEF"; + ss << str; + VERIFY( ss.str() == str ); + VERIFY( std::move(ss).str() == str ); + VERIFY( std::move(ss).str().empty() ); +} + +void test03() +{ + std::stringstream ss; + using Alloc = __gnu_test::tracker_allocator; + using Str = std::basic_string, Alloc>; + Str s1 = "string that is not short, quite long even"; + auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + ss.str(s1); + auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + VERIFY( count1 == count2 ); + VERIFY( ss.str() == s1.c_str() ); +} + +void test04() +{ + std::stringstream ss; + const std::string str = "Another quite long string, not at all short"; + std::string str2 = str; + ss.str(std::move(str2)); + VERIFY( str2.empty() ); + VERIFY( ss.str() == str ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/str/wchar_t/5.cc.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/str/wchar_t/5.cc.cc new file mode 100644 index 00000000000..3a2a26cb58e --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/str/wchar_t/5.cc.cc @@ -0,0 +1,94 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 29.8.5.4 basic_stringstream member functions [stringstream.members] + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-effective-target cxx11-abi } + +#include +#include +#include + +void test01() +{ + const std::wstring s0 = L"this is not a short string"; + std::wstringstream ss; + ss.str(s0); + VERIFY( ss.str() == s0 ); + VERIFY( ss.str() == s0 ); + + using Alloc = __gnu_test::uneq_allocator; + const Alloc a1(1); + std::basic_string, Alloc> s1 = ss.str(a1); + VERIFY( s1.get_allocator() == a1 ); + VERIFY( ss.str(a1).get_allocator() == a1 ); + VERIFY( ss.str(a1) == s1 ); + VERIFY( std::move(ss).str(a1) == s1 ); + VERIFY( std::move(ss).str(a1) == s1 ); + + const Alloc a2(2); + VERIFY( ss.str(a2).get_allocator() == a2 ); + VERIFY( ss.str(a2) == s1 ); + + VERIFY( std::move(ss).str() == s0 ); + VERIFY( std::move(ss).str().empty() ); + VERIFY( ss.str().empty() ); + VERIFY( ss.str(a1).empty() ); +} + +void test02() +{ + std::wstringstream ss(L"123"); + std::wstring str = L"ABCDEF"; + ss << str; + VERIFY( ss.str() == str ); + VERIFY( std::move(ss).str() == str ); + VERIFY( std::move(ss).str().empty() ); +} + +void test03() +{ + std::wstringstream ss; + using Alloc = __gnu_test::tracker_allocator; + using Str = std::basic_string, Alloc>; + Str s1 = L"string that is not short, quite long even"; + auto count1 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + ss.str(s1); + auto count2 = __gnu_test::tracker_allocator_counter::get_allocation_count(); + VERIFY( count1 == count2 ); + VERIFY( ss.str() == s1.c_str() ); +} + +void test04() +{ + std::wstringstream ss; + const std::wstring str = L"Another quite long string, not at all short"; + std::wstring str2 = str; + ss.str(std::move(str2)); + VERIFY( str2.empty() ); + VERIFY( ss.str() == str ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/view/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/view/char/1.cc index f47035cf148..942db75c0a9 100644 --- a/libstdc++-v3/testsuite/27_io/basic_stringstream/view/char/1.cc +++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/view/char/1.cc @@ -15,7 +15,7 @@ // with this library; see the file COPYING3. If not see // . -// 27.7.1.1 basic_stringbuf constructors [lib.stringbuf.cons] +// 29.8.5.4 basic_stringstream member functions [stringstream.members] // { dg-options "-std=gnu++2a" } // { dg-do run { target c++2a } } @@ -31,5 +31,17 @@ main() std::string s("This is a test"); std::stringstream stm(s); VERIFY( stm.view() == s ); - return 0; + VERIFY( stm.view() == const_cast(stm).view() ); + + s += " with a longer string"; + stm << s; + VERIFY( stm.view() == s ); + + s = "This is a shorter string"; + stm.str(s); + VERIFY( stm.view() == s ); + + std::string s2; + stm >> s2; + VERIFY( stm.view() == s ); } diff --git a/libstdc++-v3/testsuite/27_io/basic_stringstream/view/wchar_t/1.cc b/libstdc++-v3/testsuite/27_io/basic_stringstream/view/wchar_t/1.cc index d707cfed243..7c352993c4f 100644 --- a/libstdc++-v3/testsuite/27_io/basic_stringstream/view/wchar_t/1.cc +++ b/libstdc++-v3/testsuite/27_io/basic_stringstream/view/wchar_t/1.cc @@ -31,5 +31,17 @@ main() std::wstring s(L"This is a test"); std::wstringstream stm(s); VERIFY( stm.view() == s ); - return 0; + VERIFY( stm.view() == const_cast(stm).view() ); + + s += L" with a longer string"; + stm << s; + VERIFY( stm.view() == s ); + + s = L"This is a shorter string"; + stm.str(s); + VERIFY( stm.view() == s ); + + std::wstring s2; + stm >> s2; + VERIFY( stm.view() == s ); } -- 2.30.2