diff --git a/libcxx/include/sstream b/libcxx/include/sstream --- a/libcxx/include/sstream +++ b/libcxx/include/sstream @@ -41,6 +41,7 @@ // [stringbuf.members] Member functions: basic_string str() const; void str(const basic_string& s); + basic_string_view view() const noexcept; // C++20 protected: // [stringbuf.virtuals] Overridden virtual functions: @@ -92,6 +93,7 @@ basic_stringbuf* rdbuf() const; basic_string str() const; void str(const basic_string& s); + basic_string_view view() const noexcept; // C++20 }; template @@ -132,6 +134,7 @@ basic_stringbuf* rdbuf() const; basic_string str() const; void str(const basic_string& s); + basic_string_view view() const noexcept; // C++20 }; template @@ -172,6 +175,7 @@ basic_stringbuf* rdbuf() const; basic_string str() const; void str(const basic_string& str); + basic_string_view view() const noexcept; // C++20 }; template @@ -252,6 +256,7 @@ // [stringbuf.members] Member functions: string_type str() const; void str(const string_type& __s); + basic_string_view view() const noexcept; // C++20 protected: // [stringbuf.virtuals] Overridden virtual functions: @@ -446,15 +451,7 @@ basic_string<_CharT, _Traits, _Allocator> basic_stringbuf<_CharT, _Traits, _Allocator>::str() const { - if (__mode_ & ios_base::out) - { - if (__hm_ < this->pptr()) - __hm_ = this->pptr(); - return string_type(this->pbase(), __hm_, __str_.get_allocator()); - } - else if (__mode_ & ios_base::in) - return string_type(this->eback(), this->egptr(), __str_.get_allocator()); - return string_type(__str_.get_allocator()); + return string_type(this->view(), __str_.get_allocator()); } template @@ -490,6 +487,21 @@ } } +template +basic_string_view<_CharT, _Traits> +basic_stringbuf<_CharT, _Traits, _Allocator>::view() const noexcept +{ + if (__mode_ & ios_base::out) + { + if (__hm_ < this->pptr()) + __hm_ = this->pptr(); + return basic_string_view<_CharT, _Traits>(this->pbase(), __hm_ - this->pbase()); + } + else if (__mode_ & ios_base::in) + return basic_string_view<_CharT, _Traits>(this->eback(), this->egptr() - this->eback()); + return basic_string_view<_CharT, _Traits>(); +} + template typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type basic_stringbuf<_CharT, _Traits, _Allocator>::underflow() @@ -693,6 +705,10 @@ void str(const string_type& __s) { __sb_.str(__s); } + _LIBCPP_HIDE_FROM_ABI + basic_string_view view() const noexcept { + return __sb_.view(); + } }; template @@ -774,6 +790,10 @@ void str(const string_type& __s) { __sb_.str(__s); } + _LIBCPP_HIDE_FROM_ABI + basic_string_view view() const noexcept { + return __sb_.view(); + } }; template @@ -854,6 +874,10 @@ void str(const string_type& __s) { __sb_.str(__s); } + _LIBCPP_HIDE_FROM_ABI + basic_string_view view() const noexcept { + return __sb_.view(); + } }; template diff --git a/libcxx/test/std/input.output/string.streams/istringstream/istringstream.members/str.pass.cpp b/libcxx/test/std/input.output/string.streams/istringstream/istringstream.members/str.pass.cpp --- a/libcxx/test/std/input.output/string.streams/istringstream/istringstream.members/str.pass.cpp +++ b/libcxx/test/std/input.output/string.streams/istringstream/istringstream.members/str.pass.cpp @@ -25,6 +25,7 @@ assert(ss.rdbuf() != 0); assert(ss.good()); assert(ss.str() == " 123 456"); + assert(ss.view() == " 123 456"); int i = 0; ss >> i; assert(i == 123); @@ -34,6 +35,7 @@ ss.clear(); assert(ss.good()); assert(ss.str() == " 789"); + assert(ss.view() == " 789"); ss >> i; assert(i == 789); } @@ -43,6 +45,7 @@ assert(ss.rdbuf() != 0); assert(ss.good()); assert(ss.str() == L" 123 456"); + assert(ss.view() == L" 123 456"); int i = 0; ss >> i; assert(i == 123); @@ -52,6 +55,7 @@ ss.clear(); assert(ss.good()); assert(ss.str() == L" 789"); + assert(ss.view() == L" 789"); ss >> i; assert(i == 789); } diff --git a/libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.members/str.pass.cpp b/libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.members/str.pass.cpp --- a/libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.members/str.pass.cpp +++ b/libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.members/str.pass.cpp @@ -25,15 +25,20 @@ assert(ss.rdbuf() != 0); assert(ss.good()); assert(ss.str() == " 123 456"); + assert(ss.view() == " 123 456"); int i = 0; ss << i; assert(ss.str() == "0123 456"); + assert(ss.view() == "0123 456"); ss << 456; assert(ss.str() == "0456 456"); + assert(ss.view() == "0456 456"); ss.str(" 789"); assert(ss.str() == " 789"); + assert(ss.view() == " 789"); ss << "abc"; assert(ss.str() == "abc9"); + assert(ss.view() == "abc9"); } #ifndef TEST_HAS_NO_WIDE_CHARACTERS { @@ -41,15 +46,20 @@ assert(ss.rdbuf() != 0); assert(ss.good()); assert(ss.str() == L" 123 456"); + assert(ss.view() == L" 123 456"); int i = 0; ss << i; assert(ss.str() == L"0123 456"); + assert(ss.view() == L"0123 456"); ss << 456; assert(ss.str() == L"0456 456"); + assert(ss.view() == L"0456 456"); ss.str(L" 789"); assert(ss.str() == L" 789"); + assert(ss.view() == L" 789"); ss << L"abc"; assert(ss.str() == L"abc9"); + assert(ss.view() == L"abc9"); } #endif diff --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.pass.cpp --- a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.pass.cpp +++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/str.pass.cpp @@ -23,15 +23,19 @@ { std::stringbuf buf("testing"); assert(buf.str() == "testing"); + assert(buf.view() == "testing"); buf.str("another test"); assert(buf.str() == "another test"); + assert(buf.view() == "another test"); } #ifndef TEST_HAS_NO_WIDE_CHARACTERS { std::wstringbuf buf(L"testing"); assert(buf.str() == L"testing"); + assert(buf.view() == L"testing"); buf.str(L"another test"); assert(buf.str() == L"another test"); + assert(buf.view() == L"another test"); } #endif diff --git a/libcxx/test/std/input.output/string.streams/stringstream.members/str.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream.members/str.pass.cpp --- a/libcxx/test/std/input.output/string.streams/stringstream.members/str.pass.cpp +++ b/libcxx/test/std/input.output/string.streams/stringstream.members/str.pass.cpp @@ -25,6 +25,7 @@ assert(ss.rdbuf() != 0); assert(ss.good()); assert(ss.str() == " 123 456 "); + assert(ss.view() == " 123 456 "); int i = 0; ss >> i; assert(i == 123); @@ -32,6 +33,7 @@ assert(i == 456); ss << i << ' ' << 123; assert(ss.str() == "456 1236 "); + assert(ss.view() == "456 1236 "); ss.str("5466 89 "); ss >> i; assert(i == 5466); @@ -39,6 +41,7 @@ assert(i == 89); ss << i << ' ' << 321; assert(ss.str() == "89 3219 "); + assert(ss.view() == "89 3219 "); } #ifndef TEST_HAS_NO_WIDE_CHARACTERS { @@ -46,6 +49,7 @@ assert(ss.rdbuf() != 0); assert(ss.good()); assert(ss.str() == L" 123 456 "); + assert(ss.view() == L" 123 456 "); int i = 0; ss >> i; assert(i == 123); @@ -53,6 +57,7 @@ assert(i == 456); ss << i << ' ' << 123; assert(ss.str() == L"456 1236 "); + assert(ss.view() == L"456 1236 "); ss.str(L"5466 89 "); ss >> i; assert(i == 5466); @@ -60,12 +65,14 @@ assert(i == 89); ss << i << ' ' << 321; assert(ss.str() == L"89 3219 "); + assert(ss.view() == L"89 3219 "); } #endif { std::stringstream ss; ss.write("\xd1", 1); assert(ss.str().length() == 1); + assert(ss.view().length() == 1); } return 0;