diff --git a/libcxx/docs/Status/Cxx20Papers.csv b/libcxx/docs/Status/Cxx20Papers.csv --- a/libcxx/docs/Status/Cxx20Papers.csv +++ b/libcxx/docs/Status/Cxx20Papers.csv @@ -99,7 +99,7 @@ "`P1464R1 `__","LWG","Mandating the Standard Library: Clause 22 - Iterators library","Kona","|Complete|","9.0" "","","","","","","" "`P0325R4 `__","LWG","to_array from LFTS with updates","Cologne","|Complete|","10.0" -"`P0408R7 `__","LWG","Efficient Access to basic_stringbuf's Buffer","Cologne","","" +"`P0408R7 `__","LWG","Efficient Access to basic_stringbuf's Buffer","Cologne","|In Progress|","" "`P0466R5 `__","LWG","Layout-compatibility and Pointer-interconvertibility Traits","Cologne","","" "`P0553R4 `__","LWG","Bit operations","Cologne","|Complete|","9.0" "`P0631R8 `__","LWG","Math Constants","Cologne","|Complete|","11.0" 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,10 @@ // [stringbuf.members] Member functions: string_type str() const; void str(const string_type& __s); +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_HIDE_FROM_ABI + basic_string_view view() const noexcept; +#endif protected: // [stringbuf.virtuals] Overridden virtual functions: @@ -446,6 +454,9 @@ basic_string<_CharT, _Traits, _Allocator> basic_stringbuf<_CharT, _Traits, _Allocator>::str() const { +#if _LIBCPP_STD_VER >= 20 + return string_type(view(), __str_.get_allocator()); +#else // _LIBCPP_STD_VER >= 20 if (__mode_ & ios_base::out) { if (__hm_ < this->pptr()) @@ -455,6 +466,7 @@ else if (__mode_ & ios_base::in) return string_type(this->eback(), this->egptr(), __str_.get_allocator()); return string_type(__str_.get_allocator()); +#endif // _LIBCPP_STD_VER >= 20 } template @@ -490,6 +502,24 @@ } } +#if _LIBCPP_STD_VER >= 20 +template +_LIBCPP_HIDE_FROM_ABI +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_); + } + else if (__mode_ & ios_base::in) + return basic_string_view<_CharT, _Traits>(this->eback(), this->egptr()); + return basic_string_view<_CharT, _Traits>(); +} +#endif // _LIBCPP_STD_VER >= 20 + template typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type basic_stringbuf<_CharT, _Traits, _Allocator>::underflow() @@ -693,6 +723,12 @@ void str(const string_type& __s) { __sb_.str(__s); } +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_HIDE_FROM_ABI + basic_string_view view() const noexcept { + return __sb_.view(); + } +#endif }; template @@ -774,6 +810,12 @@ void str(const string_type& __s) { __sb_.str(__s); } +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_HIDE_FROM_ABI + basic_string_view view() const noexcept { + return __sb_.view(); + } +#endif }; template @@ -854,6 +896,12 @@ void str(const string_type& __s) { __sb_.str(__s); } +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_HIDE_FROM_ABI + basic_string_view view() const noexcept { + return __sb_.view(); + } +#endif }; template diff --git a/libcxx/test/std/input.output/string.streams/istringstream/istringstream.members/view.pass.cpp b/libcxx/test/std/input.output/string.streams/istringstream/istringstream.members/view.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/istringstream/istringstream.members/view.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// + +// template , class Allocator = allocator > +// class basic_istringstream + +// basic_string_view view() const noexcept; + +#include +#include + +#include "test_macros.h" + +static std::string_view get_view(const std::istringstream& ss) noexcept { return ss.view(); } + +int main(int, char**) { + { + std::istringstream ss(" 123 456"); + assert(ss.view() == " 123 456"); + ss.str(" 789"); + ss.clear(); + assert(get_view(ss) == " 789"); + } +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + { + std::wistringstream ss(L" 123 456"); + assert(ss.view() == L" 123 456"); + ss.str(L" 789"); + ss.clear(); + assert(ss.view() == L" 789"); + } +#endif + + return 0; +} diff --git a/libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.members/view.pass.cpp b/libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.members/view.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.members/view.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// + +// template , class Allocator = allocator > +// class basic_ostringstream + +// basic_string_view view() const noexcept; + +#include +#include + +#include "test_macros.h" + +static std::string_view get_view(const std::ostringstream& ss) noexcept { return ss.view(); } + +int main(int, char**) { + { + std::ostringstream ss(" 123 456"); + assert(ss.view() == " 123 456"); + int i = 0; + ss << i; + assert(ss.view() == "0123 456"); + ss << 456; + assert(ss.view() == "0456 456"); + ss.str(" 789"); + assert(ss.view() == " 789"); + ss << "abc"; + assert(get_view(ss) == "abc9"); + } +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + { + std::wostringstream ss(L" 123 456"); + assert(ss.view() == L" 123 456"); + int i = 0; + ss << i; + assert(ss.view() == L"0123 456"); + ss << 456; + assert(ss.view() == L"0456 456"); + ss.str(L" 789"); + assert(ss.view() == L" 789"); + ss << L"abc"; + assert(ss.view() == L"abc9"); + } +#endif + + return 0; +} diff --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/view.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/view.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/view.pass.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// + +// template , class Allocator = allocator > +// class basic_stringbuf + +// basic_string_view view() const noexcept; + +#include +#include + +#include "test_macros.h" + +static std::string_view get_view(const std::stringbuf& buf) noexcept { return buf.view(); } + +int main(int, char**) { + { + std::stringbuf buf("testing"); + assert(buf.view() == "testing"); + buf.str("another test"); + assert(get_view(buf) == "another test"); + } +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + { + std::wstringbuf buf(L"testing"); + assert(buf.view() == L"testing"); + buf.str(L"another test"); + assert(buf.view() == L"another test"); + } +#endif + + return 0; +} diff --git a/libcxx/test/std/input.output/string.streams/stringstream.members/view.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream.members/view.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringstream.members/view.pass.cpp @@ -0,0 +1,71 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// + +// template , class Allocator = allocator > +// class basic_stringstream + +// basic_string_view view() const noexcept; + +#include +#include + +#include "test_macros.h" + +static std::string_view get_view(const std::stringstream& ss) noexcept { return ss.view(); } + +int main(int, char**) { + { + std::stringstream ss(" 123 456 "); + assert(ss.view() == " 123 456 "); + int i = 0; + ss >> i; + assert(i == 123); + ss >> i; + assert(i == 456); + ss << i << ' ' << 123; + assert(ss.view() == "456 1236 "); + ss.str("5466 89 "); + ss >> i; + assert(i == 5466); + ss >> i; + assert(i == 89); + ss << i << ' ' << 321; + assert(get_view(ss) == "89 3219 "); + } +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + { + std::wstringstream ss(L" 123 456 "); + assert(ss.str() == L" 123 456 "); + int i = 0; + ss >> i; + assert(i == 123); + ss >> i; + assert(i == 456); + ss << i << ' ' << 123; + assert(ss.view() == L"456 1236 "); + ss.str(L"5466 89 "); + ss >> i; + assert(i == 5466); + ss >> i; + assert(i == 89); + ss << i << ' ' << 321; + assert(ss.view() == L"89 3219 "); + } +#endif + { + std::stringstream ss; + ss.write("\xd1", 1); + assert(ss.view().length() == 1); + } + + return 0; +}