diff options
author | Piotr Fusik <fox@scene.pl> | 2023-05-16 12:00:58 -0700 |
---|---|---|
committer | Nikolas Klauser <n_klauser@apple.com> | 2023-05-16 12:02:35 -0700 |
commit | 49007a020c14a48062fac34c5c83c907d6ae1c31 (patch) | |
tree | f25a25954a7cccb8c52a38c75178243769b1120f /libcxx | |
parent | 9d202bfed1f9a1ebac5f6a2f9725af2be252cd58 (diff) | |
download | llvm-49007a020c14a48062fac34c5c83c907d6ae1c31.tar.gz |
[libc++] Add C++20 stringstream::view()
Reviewed By: #libc, philnik, Mordante
Spies: Mordante, philnik, libcxx-commits
Differential Revision: https://reviews.llvm.org/D148641
Diffstat (limited to 'libcxx')
7 files changed, 287 insertions, 1 deletions
diff --git a/libcxx/docs/Status/Cxx20.rst b/libcxx/docs/Status/Cxx20.rst index 11cd7c40bf51..e0ffdc6585d0 100644 --- a/libcxx/docs/Status/Cxx20.rst +++ b/libcxx/docs/Status/Cxx20.rst @@ -49,6 +49,7 @@ Paper Status .. [#note-P0883.1] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet. .. [#note-P0883.2] P0883: ``ATOMIC_FLAG_INIT`` was marked deprecated in version 14.0, but was undeprecated with the implementation of LWG3659 in version 15.0. .. [#note-P2231] P2231: Optional is complete. The changes to variant haven't been implemented yet. + .. [#note-P0408] P0408: Only `view()` members implemented. .. _issues-status-cxx20: diff --git a/libcxx/docs/Status/Cxx20Papers.csv b/libcxx/docs/Status/Cxx20Papers.csv index 6b01966b6989..62951f56da83 100644 --- a/libcxx/docs/Status/Cxx20Papers.csv +++ b/libcxx/docs/Status/Cxx20Papers.csv @@ -99,7 +99,7 @@ "`P1464R1 <https://wg21.link/P1464R1>`__","LWG","Mandating the Standard Library: Clause 22 - Iterators library","Kona","|Complete|","9.0" "","","","","","","" "`P0325R4 <https://wg21.link/P0325R4>`__","LWG","to_array from LFTS with updates","Cologne","|Complete|","10.0" -"`P0408R7 <https://wg21.link/P0408R7>`__","LWG","Efficient Access to basic_stringbuf's Buffer","Cologne","","" +"`P0408R7 <https://wg21.link/P0408R7>`__","LWG","Efficient Access to basic_stringbuf's Buffer","Cologne","|In Progress| [#note-P0408]_","" "`P0466R5 <https://wg21.link/P0466R5>`__","LWG","Layout-compatibility and Pointer-interconvertibility Traits","Cologne","","" "`P0553R4 <https://wg21.link/P0553R4>`__","LWG","Bit operations","Cologne","|Complete|","9.0" "`P0631R8 <https://wg21.link/P0631R8>`__","LWG","Math Constants","Cologne","|Complete|","11.0" diff --git a/libcxx/include/sstream b/libcxx/include/sstream index 6af2cb8fa87f..6dd581e30cb4 100644 --- a/libcxx/include/sstream +++ b/libcxx/include/sstream @@ -41,6 +41,7 @@ public: // [stringbuf.members] Member functions: basic_string<char_type, traits_type, allocator_type> str() const; void str(const basic_string<char_type, traits_type, allocator_type>& s); + basic_string_view<char_type, traits_type> view() const noexcept; // C++20 protected: // [stringbuf.virtuals] Overridden virtual functions: @@ -92,6 +93,7 @@ public: basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const; basic_string<char_type, traits_type, allocator_type> str() const; void str(const basic_string<char_type, traits_type, allocator_type>& s); + basic_string_view<char_type, traits_type> view() const noexcept; // C++20 }; template <class charT, class traits, class Allocator> @@ -132,6 +134,7 @@ public: basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const; basic_string<char_type, traits_type, allocator_type> str() const; void str(const basic_string<char_type, traits_type, allocator_type>& s); + basic_string_view<char_type, traits_type> view() const noexcept; // C++20 }; template <class charT, class traits, class Allocator> @@ -172,6 +175,7 @@ public: basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const; basic_string<char_type, traits_type, allocator_type> str() const; void str(const basic_string<char_type, traits_type, allocator_type>& str); + basic_string_view<char_type, traits_type> view() const noexcept; // C++20 }; template <class charT, class traits, class Allocator> @@ -253,6 +257,10 @@ public: // [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<char_type, traits_type> view() const noexcept; +#endif protected: // [stringbuf.virtuals] Overridden virtual functions: @@ -447,6 +455,9 @@ template <class _CharT, class _Traits, class _Allocator> 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()) @@ -456,6 +467,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::str() const 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 <class _CharT, class _Traits, class _Allocator> @@ -491,6 +503,20 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s) } } +#if _LIBCPP_STD_VER >= 20 +template <class _CharT, class _Traits, class _Allocator> +_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 <class _CharT, class _Traits, class _Allocator> typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type basic_stringbuf<_CharT, _Traits, _Allocator>::underflow() @@ -694,6 +720,12 @@ public: void str(const string_type& __s) { __sb_.str(__s); } +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_HIDE_FROM_ABI + basic_string_view<char_type, traits_type> view() const noexcept { + return __sb_.view(); + } +#endif }; template <class _CharT, class _Traits, class _Allocator> @@ -775,6 +807,12 @@ public: void str(const string_type& __s) { __sb_.str(__s); } +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_HIDE_FROM_ABI + basic_string_view<char_type, traits_type> view() const noexcept { + return __sb_.view(); + } +#endif }; template <class _CharT, class _Traits, class _Allocator> @@ -855,6 +893,12 @@ public: void str(const string_type& __s) { __sb_.str(__s); } +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_HIDE_FROM_ABI + basic_string_view<char_type, traits_type> view() const noexcept { + return __sb_.view(); + } +#endif }; template <class _CharT, class _Traits, class _Allocator> 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 index 000000000000..cdf7facd6de5 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/istringstream/istringstream.members/view.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <sstream> + +// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > +// class basic_istringstream + +// basic_string_view<charT, traits> view() const noexcept; + +#include <sstream> +#include <cassert> +#include <type_traits> + +#include "make_string.h" +#include "test_macros.h" + +#define STR(S) MAKE_STRING(CharT, S) +#define SV(S) MAKE_STRING_VIEW(CharT, S) + +template <class CharT> +struct my_char_traits : public std::char_traits<CharT> {}; + +template <class CharT> +static void test() { + std::basic_istringstream<CharT> ss(STR(" 123 456")); + static_assert(noexcept(ss.view())); + assert(ss.view() == SV(" 123 456")); + ss.str(STR(" 789")); + ss.clear(); + assert(ss.view() == SV(" 789")); + + const std::basic_istringstream<CharT> css(STR("abc")); + static_assert(noexcept(css.view())); + assert(css.view() == SV("abc")); + + std::basic_istringstream<CharT, my_char_traits<CharT>> tss; + static_assert(std::is_same_v<decltype(tss.view()), std::basic_string_view<CharT, my_char_traits<CharT>>>); +} + +int main(int, char**) { + test<char>(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test<wchar_t>(); +#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 index 000000000000..1dc691d0d11d --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.members/view.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <sstream> + +// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > +// class basic_ostringstream + +// basic_string_view<charT, traits> view() const noexcept; + +#include <sstream> +#include <cassert> +#include <type_traits> + +#include "make_string.h" +#include "test_macros.h" + +#define STR(S) MAKE_STRING(CharT, S) +#define SV(S) MAKE_STRING_VIEW(CharT, S) + +template <class CharT> +struct my_char_traits : public std::char_traits<CharT> {}; + +template <class CharT> +static void test() { + std::basic_ostringstream<CharT> ss(STR(" 123 456")); + static_assert(noexcept(ss.view())); + assert(ss.view() == SV(" 123 456")); + int i = 0; + ss << i; + assert(ss.view() == SV("0123 456")); + ss << 456; + assert(ss.view() == SV("0456 456")); + ss.str(STR(" 789")); + assert(ss.view() == SV(" 789")); + ss << SV("abc"); + assert(ss.view() == SV("abc9")); + + const std::basic_ostringstream<CharT> css(STR("abc")); + static_assert(noexcept(css.view())); + assert(css.view() == SV("abc")); + + std::basic_ostringstream<CharT, my_char_traits<CharT>> tss; + static_assert(std::is_same_v<decltype(tss.view()), std::basic_string_view<CharT, my_char_traits<CharT>>>); +} + +int main(int, char**) { + test<char>(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test<wchar_t>(); +#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 index 000000000000..4aa2e4ab2351 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.members/view.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <sstream> + +// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > +// class basic_stringbuf + +// basic_string_view<charT, traits> view() const noexcept; + +#include <sstream> +#include <cassert> +#include <type_traits> + +#include "make_string.h" +#include "test_macros.h" + +#define STR(S) MAKE_STRING(CharT, S) +#define SV(S) MAKE_STRING_VIEW(CharT, S) + +template <class CharT> +struct my_char_traits : public std::char_traits<CharT> {}; + +template <class CharT> +static void test() { + std::basic_stringbuf<CharT> buf(STR("testing")); + static_assert(noexcept(buf.view())); + assert(buf.view() == SV("testing")); + buf.str(STR("another test")); + assert(buf.view() == SV("another test")); + + std::basic_stringbuf<CharT> robuf(STR("foo"), std::ios_base::in); + assert(robuf.view() == SV("foo")); + + std::basic_stringbuf<CharT> nbuf(STR("not used"), 0); + assert(nbuf.view() == std::basic_string_view<CharT>()); + + const std::basic_stringbuf<CharT> cbuf(STR("abc")); + static_assert(noexcept(cbuf.view())); + assert(cbuf.view() == SV("abc")); + + std::basic_stringbuf<CharT, my_char_traits<CharT>> tbuf; + static_assert(std::is_same_v<decltype(tbuf.view()), std::basic_string_view<CharT, my_char_traits<CharT>>>); +} + +int main(int, char**) { + test<char>(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test<wchar_t>(); +#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 index 000000000000..f8f8a6567d7d --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringstream.members/view.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// <sstream> + +// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> > +// class basic_stringstream + +// basic_string_view<charT, traits> view() const noexcept; + +#include <sstream> +#include <cassert> +#include <type_traits> + +#include "make_string.h" +#include "test_macros.h" + +#define STR(S) MAKE_STRING(CharT, S) +#define SV(S) MAKE_STRING_VIEW(CharT, S) + +template <class CharT> +struct my_char_traits : public std::char_traits<CharT> {}; + +template <class CharT> +static void test() { + std::basic_stringstream<CharT> ss(STR(" 123 456 ")); + static_assert(noexcept(ss.view())); + assert(ss.view() == SV(" 123 456 ")); + int i = 0; + ss >> i; + assert(i == 123); + ss >> i; + assert(i == 456); + ss << i << ' ' << 123; + assert(ss.view() == SV("456 1236 ")); + ss.str(STR("5466 89 ")); + ss >> i; + assert(i == 5466); + ss >> i; + assert(i == 89); + ss << i << ' ' << 321; + assert(ss.view() == SV("89 3219 ")); + + const std::basic_stringstream<CharT> css(STR("abc")); + static_assert(noexcept(css.view())); + assert(css.view() == SV("abc")); + + std::basic_stringstream<CharT, my_char_traits<CharT>> tss; + static_assert(std::is_same_v<decltype(tss.view()), std::basic_string_view<CharT, my_char_traits<CharT>>>); +} + +int main(int, char**) { + test<char>(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test<wchar_t>(); +#endif + std::stringstream ss; + ss.write("\xd1", 1); + assert(ss.view().length() == 1); + return 0; +} |