diff --git a/libcxx/docs/Status/Cxx20.rst b/libcxx/docs/Status/Cxx20.rst --- a/libcxx/docs/Status/Cxx20.rst +++ b/libcxx/docs/Status/Cxx20.rst @@ -49,7 +49,6 @@ .. [#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: Implemented all `stringbuf`/`istringstream`/`ostringstream` members and `view()` in `stringstream`. .. [#note-P0660] P0660: Section 32.3 Stop Tokens is complete. ``jthread`` hasn't been implemented yet. .. _issues-status-cxx20: 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","|In Progress| [#note-P0408]_","" +"`P0408R7 `__","LWG","Efficient Access to basic_stringbuf's Buffer","Cologne","|Complete|","17.0" "`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 @@ -221,9 +221,20 @@ explicit basic_stringstream(ios_base::openmode which = ios_base::out | ios_base::in); // before C++20 basic_stringstream() : basic_stringstream(ios_base::out | ios_base::in) {} // C++20 explicit basic_stringstream(ios_base::openmode which); // C++20 - - explicit basic_stringstream(const basic_string& str, - ios_base::openmode which = ios_base::out|ios_base::in); + explicit basic_stringstream(const basic_string& s, + ios_base::openmode which = ios_base::out | ios_base::in); + basic_stringstream(ios_base::openmode which, const allocator_type& a); // C++20 + explicit basic_stringstream(basic_string&& s, + ios_base::openmode which = ios_base::out | ios_base::in); // C++20 + template + basic_stringstream(const basic_string& s, const allocator_type& a) + : basic_stringstream(s, ios_base::out | ios_base::in, a) {} // C++20 + template + basic_stringstream(const basic_string& s, + ios_base::openmode which, const allocator_type& a); // C++20 + template + explicit basic_stringstream(const basic_string& s, + ios_base::openmode which = ios_base::out | ios_base::in); // C++20 basic_stringstream(basic_stringstream&& rhs); // [stringstream.assign] Assign and swap: @@ -232,9 +243,16 @@ // [stringstream.members] Member functions: basic_stringbuf* rdbuf() const; - basic_string str() const; - void str(const basic_string& str); - basic_string_view view() const noexcept; // C++20 + basic_string str() const; // before C++20 + basic_string str() const &; // C++20 + template + basic_string str(const SAlloc& sa) const; // C++20 + basic_string str() &&; // C++20 + basic_string_view view() const noexcept; // C++20 + void str(const basic_string& s); + template + void str(const basic_string& s); // C++20 + void str(basic_string&& s); // C++20 }; template @@ -1070,6 +1088,29 @@ , __sb_(__s, __wch) { } +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_HIDE_FROM_ABI basic_stringstream(ios_base::openmode __wch, const _Allocator& __a) + : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch, __a) {} + + _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(string_type&& __s, ios_base::openmode __wch = ios_base::out | ios_base::in) + : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch) {} + + template + _LIBCPP_HIDE_FROM_ABI basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a) + : basic_stringstream(__s, ios_base::out | ios_base::in, __a) {} + + template + _LIBCPP_HIDE_FROM_ABI basic_stringstream( + const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a) + : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch, __a) {} + + template + requires (!is_same_v<_SAlloc, allocator_type>) + _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, + ios_base::openmode __wch = ios_base::out | ios_base::in) + : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch) {} +#endif // _LIBCPP_STD_VER >= 20 + _LIBCPP_INLINE_VISIBILITY basic_stringstream(basic_stringstream&& __rhs) : basic_iostream<_CharT, _Traits>(_VSTD::move(__rhs)) @@ -1095,20 +1136,33 @@ basic_stringbuf* rdbuf() const { return const_cast*>(&__sb_); } - _LIBCPP_INLINE_VISIBILITY - string_type str() const { - return __sb_.str(); - } - _LIBCPP_INLINE_VISIBILITY - void str(const string_type& __s) { - __sb_.str(__s); + +#if _LIBCPP_STD_VER >= 20 + _LIBCPP_HIDE_FROM_ABI string_type str() const & { return __sb_.str(); } + + template + requires __is_allocator<_SAlloc>::value + _LIBCPP_HIDE_FROM_ABI basic_string str(const _SAlloc& __sa) const { + return __sb_.str(__sa); } + + _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); } + + _LIBCPP_HIDE_FROM_ABI basic_string_view view() const noexcept { return __sb_.view(); } +#else // _LIBCPP_STD_VER >= 20 + _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); } +#endif // _LIBCPP_STD_VER >= 20 + + _LIBCPP_HIDE_FROM_ABI 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(); + template + _LIBCPP_HIDE_FROM_ABI void str(const basic_string& __s) { + __sb_.str(__s); } -#endif + + _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); } +#endif // _LIBCPP_STD_VER >= 20 }; template diff --git a/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/mode.alloc.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/mode.alloc.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/mode.alloc.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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_stringstream(ios_base::openmode which, const Allocator& a); + +#include +#include + +#include "test_allocator.h" +#include "test_macros.h" + +template +static void test() { + const test_allocator a(2); + const std::basic_stringstream, test_allocator> ss(std::ios_base::in, a); + assert(ss.rdbuf()->get_allocator() == a); + assert(ss.view().empty()); +} + +int main(int, char**) { + test(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test(); +#endif + return 0; +} diff --git a/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/string-alloc.mode.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/string-alloc.mode.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/string-alloc.mode.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// explicit basic_stringstream(const basic_string& s, ios_base::openmode which = ios_base::out | ios_base::in) + +#include +#include + +#include "make_string.h" +#include "test_allocator.h" +#include "test_macros.h" + +#define STR(S) MAKE_STRING(CharT, S) +#define SV(S) MAKE_STRING_VIEW(CharT, S) + +template +static void test() { + { + const std::basic_string s(STR("testing")); + const std::basic_stringstream, test_allocator> ss(s); + assert(ss.view() == SV("testing")); + } + { + const std::basic_string s(STR("testing")); + const std::basic_stringstream, test_allocator> ss(s, std::ios_base::in); + assert(ss.view() == SV("testing")); + } +} + +int main(int, char**) { + test(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test(); +#endif + return 0; +} diff --git a/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/string.alloc.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/string.alloc.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/string.alloc.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// basic_stringstream(const basic_string& s, const Allocator& a) +// : basic_stringstream(s, ios_base::out | ios_base::in, a) {} + +#include +#include + +#include "make_string.h" +#include "test_allocator.h" +#include "test_macros.h" + +#define STR(S) MAKE_STRING(CharT, S) +#define SV(S) MAKE_STRING_VIEW(CharT, S) + +template +static void test() { + const std::basic_string s(STR("testing")); + const test_allocator a(2); + const std::basic_stringstream, test_allocator> ss(s, a); + assert(ss.rdbuf()->get_allocator() == a); + assert(ss.view() == SV("testing")); +} + +int main(int, char**) { + test(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test(); +#endif + return 0; +} diff --git a/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/string.mode.alloc.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/string.mode.alloc.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/string.mode.alloc.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_stringstream + +// template +// basic_stringstream(const basic_string& s, ios_base::openmode which, const Allocator& a) + +#include +#include + +#include "make_string.h" +#include "test_allocator.h" +#include "test_macros.h" + +#define STR(S) MAKE_STRING(CharT, S) +#define SV(S) MAKE_STRING_VIEW(CharT, S) + +template +static void test() { + const std::basic_string s(STR("testing")); + const test_allocator a(2); + const std::basic_stringstream, test_allocator> ss(s, std::ios_base::out, a); + assert(ss.rdbuf()->get_allocator() == a); + assert(ss.view() == SV("testing")); +} + +int main(int, char**) { + test(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test(); +#endif + return 0; +} diff --git a/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/string.move.mode.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/string.move.mode.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.cons/string.move.mode.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// explicit basic_stringstream(basic_string&& s, ios_base::openmode which = ios_base::out | ios_base::in); + +#include +#include + +#include "make_string.h" +#include "test_macros.h" + +#define STR(S) MAKE_STRING(CharT, S) + +template +static void test() { + { + std::basic_string s(STR("testing")); + const std::basic_stringstream ss(std::move(s)); + assert(ss.str() == STR("testing")); + } + { + std::basic_string s(STR("testing")); + const std::basic_stringstream ss(std::move(s), std::ios_base::out); + assert(ss.str() == STR("testing")); + } +} + +int main(int, char**) { + test(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test(); +#endif + return 0; +} diff --git a/libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/str.alloc.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/str.alloc.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/str.alloc.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_stringstream + +// template +// basic_string str(const SAlloc& sa) const; + +#include +#include + +#include "make_string.h" +#include "test_allocator.h" +#include "test_macros.h" + +#define STR(S) MAKE_STRING(CharT, S) +#define SV(S) MAKE_STRING_VIEW(CharT, S) + +template +static void test() { + const std::basic_stringstream ss(STR("testing")); + const test_allocator a(1); + const std::basic_string, test_allocator> s = ss.str(a); + assert(s == SV("testing")); + assert(s.get_allocator() == a); +} + +int main(int, char**) { + test(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test(); +#endif + return 0; +} diff --git a/libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/str.move.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/str.move.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/str.move.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_stringstream + +// basic_string str() &&; + +#include +#include + +#include "make_string.h" +#include "test_macros.h" + +#define STR(S) MAKE_STRING(CharT, S) + +template +static void test() { + { + std::basic_stringstream ss(STR("testing")); + std::basic_string s = std::move(ss).str(); + assert(s == STR("testing")); + assert(ss.view().empty()); + } +} + +int main(int, char**) { + test(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test(); +#endif + return 0; +} diff --git a/libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/str.string-alloc.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/str.string-alloc.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/str.string-alloc.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// void str(const basic_string& s); + +#include +#include + +#include "make_string.h" +#include "test_allocator.h" +#include "test_macros.h" + +#define STR(S) MAKE_STRING(CharT, S) + +template +static void test() { + { + const test_allocator a(6); + const std::basic_string, test_allocator> s(STR("testing"), a); + std::basic_stringstream ss; + ss.str(s); + assert(ss.str() == STR("testing")); + } +} + +int main(int, char**) { + test(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test(); +#endif + return 0; +} diff --git a/libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/str.string.move.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/str.string.move.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringstream/stringstream.members/str.string.move.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_stringstream + +// void str(basic_string&& s); + +#include +#include + +#include "make_string.h" +#include "test_macros.h" + +#define STR(S) MAKE_STRING(CharT, S) + +template +static void test() { + { + std::basic_stringstream ss; + std::basic_string s(STR("testing")); + ss.str(std::move(s)); + assert(ss.str() == STR("testing")); + } +} + +int main(int, char**) { + test(); +#ifndef TEST_HAS_NO_WIDE_CHARACTERS + test(); +#endif + return 0; +}