* [committed] libstdc++: Add remaining C++20 additions to <sstream> [P0408R7]
@ 2020-11-10 19:41 Jonathan Wakely
0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2020-11-10 19:41 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 2064 bytes --]
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<C,T,SAlloc>&)):
Likewise.
(basic_stringbuf::str(basic_string<C,T,Alloc>&&)): 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.
Tested powerpc64le-linux. Committed to trunk.
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 53278 bytes --]
commit 95cb0fc8c51841cc6a0e51490cb3769eb80fa34c
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Tue Nov 10 15:57:04 2020
libstdc++: Add remaining C++20 additions to <sstream> [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<C,T,SAlloc>&)):
Likewise.
(basic_stringbuf::str(basic_string<C,T,Alloc>&&)): 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.
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 2d0f87aa7cc7..46769db15303 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 86d8ed221ff8..467311fc9177 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<typename _Alloc>
using _RequireNotAllocator
= typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
+
+#if __cpp_concepts >= 201907L
+ template<typename _Alloc>
+ 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 9c50e4e83281..8cddda297017 100644
--- a/libstdc++-v3/include/std/sstream
+++ b/libstdc++-v3/include/std/sstream
@@ -37,6 +37,13 @@
#include <istream>
#include <ostream>
+#include <bits/alloc_traits.h> // 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_<typename allocator_traits::propagate_on_container_swap,
+ typename allocator_traits::is_always_equal>;
+#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.</em> [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<char_type, traits_type>
+ 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<char_type, traits_type>
- view() const noexcept
- {
- using __sv_type = basic_string_view<char_type, traits_type>;
+#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<char_type, traits_type>
+ 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<char_type, traits_type>
- 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<char_type, traits_type>
+ 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<char_type, traits_type>
- 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<char_type, traits_type>
+ 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<char_type, traits_type>
- 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 <bits/sstream.tcc>
#endif /* _GLIBCXX_SSTREAM */
diff --git a/libstdc++-v3/src/c++20/sstream-inst.cc b/libstdc++-v3/src/c++20/sstream-inst.cc
index 7d275de5cc24..9e157d1b1bfb 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<char>::basic_stringbuf(basic_stringbuf&&,
__xfer_bufptrs&&);
template basic_stringbuf<char>::allocator_type
basic_stringbuf<char>::get_allocator() const noexcept;
+template string
+basic_stringbuf<char>::str() const &;
+template string
+basic_stringbuf<char>::str() &&;
template string_view
basic_stringbuf<char>::view() const noexcept;
+template void
+basic_stringbuf<char>::str(string&&);
template basic_istringstream<char>::basic_istringstream(ios_base::openmode,
const allocator_type&);
template basic_istringstream<char>::basic_istringstream(__string_type&&,
ios_base::openmode);
+template string
+basic_istringstream<char>::str() const &;
+template string
+basic_istringstream<char>::str() &&;
template string_view
basic_istringstream<char>::view() const noexcept;
+template void
+basic_istringstream<char>::str(string&&);
template basic_ostringstream<char>::basic_ostringstream(ios_base::openmode,
const allocator_type&);
template basic_ostringstream<char>::basic_ostringstream(__string_type&&,
ios_base::openmode);
+template string
+basic_ostringstream<char>::str() const &;
+template string
+basic_ostringstream<char>::str() &&;
template string_view
basic_ostringstream<char>::view() const noexcept;
+template void
+basic_ostringstream<char>::str(string&&);
template basic_stringstream<char>::basic_stringstream(ios_base::openmode,
const allocator_type&);
template basic_stringstream<char>::basic_stringstream(__string_type&&,
ios_base::openmode);
+template string
+basic_stringstream<char>::str() const &;
+template string
+basic_stringstream<char>::str() &&;
template string_view
basic_stringstream<char>::view() const noexcept;
+template void
+basic_stringstream<char>::str(string&&);
#ifdef _GLIBCXX_USE_WCHAR_T
template basic_stringbuf<wchar_t>::basic_stringbuf(const allocator_type&);
@@ -84,29 +108,53 @@ template basic_stringbuf<wchar_t>::basic_stringbuf(basic_stringbuf&&,
template basic_stringbuf<wchar_t>::allocator_type
basic_stringbuf<wchar_t>::get_allocator() const noexcept;
+template wstring
+basic_stringbuf<wchar_t>::str() const &;
+template wstring
+basic_stringbuf<wchar_t>::str() &&;
template wstring_view
basic_stringbuf<wchar_t>::view() const noexcept;
+template void
+basic_stringbuf<wchar_t>::str(wstring&&);
template basic_istringstream<wchar_t>::basic_istringstream(ios_base::openmode,
const allocator_type&);
template basic_istringstream<wchar_t>::basic_istringstream(__string_type&&,
ios_base::openmode);
+template wstring
+basic_istringstream<wchar_t>::str() const &;
+template wstring
+basic_istringstream<wchar_t>::str() &&;
template wstring_view
basic_istringstream<wchar_t>::view() const noexcept;
+template void
+basic_istringstream<wchar_t>::str(wstring&&);
template basic_ostringstream<wchar_t>::basic_ostringstream(ios_base::openmode,
const allocator_type&);
template basic_ostringstream<wchar_t>::basic_ostringstream(__string_type&&,
ios_base::openmode);
+template wstring
+basic_ostringstream<wchar_t>::str() const &;
+template wstring
+basic_ostringstream<wchar_t>::str() &&;
template wstring_view
basic_ostringstream<wchar_t>::view() const noexcept;
+template void
+basic_ostringstream<wchar_t>::str(wstring&&);
template basic_stringstream<wchar_t>::basic_stringstream(ios_base::openmode,
const allocator_type&);
template basic_stringstream<wchar_t>::basic_stringstream(__string_type&&,
ios_base::openmode);
+template wstring
+basic_stringstream<wchar_t>::str() const &;
+template wstring
+basic_stringstream<wchar_t>::str() &&;
template wstring_view
basic_stringstream<wchar_t>::view() const noexcept;
+template void
+basic_stringstream<wchar_t>::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 000000000000..58ee1d2367cb
--- /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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+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<char>;
+ const Alloc a1(1);
+ std::basic_string<char, std::char_traits<char>, 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<char>;
+ using Str = std::basic_string<char, std::char_traits<char>, 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 000000000000..595852741642
--- /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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+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<wchar_t>;
+ const Alloc a1(1);
+ std::basic_string<wchar_t, std::char_traits<wchar_t>, 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<wchar_t>;
+ using Str = std::basic_string<wchar_t, std::char_traits<wchar_t>, 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 091de5f7a797..c4550702005a 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
// <http://www.gnu.org/licenses/>.
-// 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<const std::istringstream&>(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 f6599643bd90..8efba0614544 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<const std::wistringstream&>(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 000000000000..23e961e6a1f0
--- /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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+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<char>;
+ const Alloc a1(1);
+ std::basic_string<char, std::char_traits<char>, 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<char>;
+ using Str = std::basic_string<char, std::char_traits<char>, 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 000000000000..7c354cbf7eb9
--- /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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+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<wchar_t>;
+ const Alloc a1(1);
+ std::basic_string<wchar_t, std::char_traits<wchar_t>, 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<wchar_t>;
+ using Str = std::basic_string<wchar_t, std::char_traits<wchar_t>, 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 a366363abb59..f072c16f28a8 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
// <http://www.gnu.org/licenses/>.
-// 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<const std::ostringstream&>(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 1ebf7c505e30..3fa2604e1e31 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
// <http://www.gnu.org/licenses/>.
-// 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<const std::wostringstream&>(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 000000000000..3a4b0c70b912
--- /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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+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<char>;
+ const Alloc a1(1);
+ std::basic_string<char, std::char_traits<char>, 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<char>;
+ using Str = std::basic_string<char, std::char_traits<char>, 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 000000000000..5d5187f9d527
--- /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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+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<wchar_t>;
+ const Alloc a1(1);
+ std::basic_string<wchar_t, std::char_traits<wchar_t>, 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<wchar_t>;
+ using Str = std::basic_string<wchar_t, std::char_traits<wchar_t>, 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 000000000000..917bd2115082
--- /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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+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<char>;
+ const Alloc a1(1);
+ std::basic_string<char, std::char_traits<char>, 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<char>;
+ using Str = std::basic_string<char, std::char_traits<char>, 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 000000000000..3a2a26cb58e9
--- /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
+// <http://www.gnu.org/licenses/>.
+
+// 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 <sstream>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+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<wchar_t>;
+ const Alloc a1(1);
+ std::basic_string<wchar_t, std::char_traits<wchar_t>, 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<wchar_t>;
+ using Str = std::basic_string<wchar_t, std::char_traits<wchar_t>, 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 f47035cf1481..942db75c0a9a 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
// <http://www.gnu.org/licenses/>.
-// 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<const std::stringstream&>(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 d707cfed2435..7c352993c4f7 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<const std::wstringstream&>(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 );
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-11-10 19:41 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-10 19:41 [committed] libstdc++: Add remaining C++20 additions to <sstream> [P0408R7] Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).