Skip to content

Commit 61d2a9b

Browse files
committed
[libc++] Implement istringstream members of P0408R7 (Efficient Access to basic_stringbuf's Buffer)
Reviewed By: #libc, Mordante Differential Revision: https://reviews.llvm.org/D154454
1 parent 629460a commit 61d2a9b

File tree

11 files changed

+467
-19
lines changed

11 files changed

+467
-19
lines changed

libcxx/docs/Status/Cxx20.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ Paper Status
4949
.. [#note-P0883.1] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet.
5050
.. [#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.
5151
.. [#note-P2231] P2231: Optional is complete. The changes to variant haven't been implemented yet.
52-
.. [#note-P0408] P0408: All `stringbuf` members and `view()` in all classes implemented.
52+
.. [#note-P0408] P0408: All `stringbuf` and `istringstream` members plus `view()` in all classes implemented.
5353
.. [#note-P0660] P0660: Section 32.3 Stop Tokens is complete. ``jthread`` hasn't been implemented yet.
5454
5555
.. _issues-status-cxx20:

libcxx/include/sstream

Lines changed: 71 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,23 @@ public:
100100
typedef Allocator allocator_type;
101101
102102
// [istringstream.cons] Constructors:
103-
explicit basic_istringstream(ios_base::openmode which = ios_base::in); // before C++20
104-
basic_istringstream() : basic_istringstream(ios_base::in) {} // C++20
105-
explicit basic_istringstream(ios_base::openmode which); // C++20
106-
107-
explicit basic_istringstream(const basic_string<char_type, traits_type,allocator_type>& str,
103+
explicit basic_istringstream(ios_base::openmode which = ios_base::in); // before C++20
104+
basic_istringstream() : basic_istringstream(ios_base::in) {} // C++20
105+
explicit basic_istringstream(ios_base::openmode which); // C++20
106+
explicit basic_istringstream(const basic_string<char_type, traits_type, allocator_type>& s,
108107
ios_base::openmode which = ios_base::in);
108+
basic_istringstream(ios_base::openmode which, const allocator_type& a); // C++20
109+
explicit basic_istringstream(basic_string<char_type, traits_type, allocator_type>&& s,
110+
ios_base::openmode which = ios_base::in); // C++20
111+
template <class SAlloc>
112+
basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
113+
: basic_istringstream(s, ios_base::in, a) {} // C++20
114+
template <class SAlloc>
115+
basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s,
116+
ios_base::openmode which, const allocator_type& a); // C++20
117+
template <class SAlloc>
118+
explicit basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s,
119+
ios_base::openmode which = ios_base::in); // C++20
109120
basic_istringstream(basic_istringstream&& rhs);
110121
111122
// [istringstream.assign] Assign and swap:
@@ -114,9 +125,16 @@ public:
114125
115126
// [istringstream.members] Member functions:
116127
basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
117-
basic_string<char_type, traits_type, allocator_type> str() const;
128+
basic_string<char_type, traits_type, allocator_type> str() const; // before C++20
129+
basic_string<char_type, traits_type, allocator_type> str() const &; // C++20
130+
template <class SAlloc>
131+
basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const; // C++20
132+
basic_string<char_type, traits_type, allocator_type> str() &&; // C++20
133+
basic_string_view<char_type, traits_type> view() const noexcept; // C++20
118134
void str(const basic_string<char_type, traits_type, allocator_type>& s);
119-
basic_string_view<char_type, traits_type> view() const noexcept; // C++20
135+
template <class SAlloc>
136+
void str(const basic_string<char_type, traits_type, SAlloc>& s); // C++20
137+
void str(basic_string<char_type, traits_type, allocator_type>&& s); // C++20
120138
};
121139
122140
template <class charT, class traits, class Allocator>
@@ -790,6 +808,28 @@ public:
790808
, __sb_(__s, __wch | ios_base::in)
791809
{ }
792810

811+
#if _LIBCPP_STD_VER >= 20
812+
_LIBCPP_HIDE_FROM_ABI basic_istringstream(ios_base::openmode __wch, const _Allocator& __a)
813+
: basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::in, __a) {}
814+
815+
_LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(string_type&& __s, ios_base::openmode __wch = ios_base::in)
816+
: basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch | ios_base::in) {}
817+
818+
template <class _SAlloc>
819+
_LIBCPP_HIDE_FROM_ABI basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
820+
: basic_istringstream(__s, ios_base::in, __a) {}
821+
822+
template <class _SAlloc>
823+
_LIBCPP_HIDE_FROM_ABI basic_istringstream(
824+
const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
825+
: basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in, __a) {}
826+
827+
template <class _SAlloc>
828+
_LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
829+
ios_base::openmode __wch = ios_base::in)
830+
: basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in) {}
831+
#endif // _LIBCPP_STD_VER >= 20
832+
793833
_LIBCPP_INLINE_VISIBILITY
794834
basic_istringstream(basic_istringstream&& __rhs)
795835
: basic_istream<_CharT, _Traits>(_VSTD::move(__rhs))
@@ -815,20 +855,33 @@ public:
815855
basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
816856
return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
817857
}
818-
_LIBCPP_INLINE_VISIBILITY
819-
string_type str() const {
820-
return __sb_.str();
821-
}
822-
_LIBCPP_INLINE_VISIBILITY
823-
void str(const string_type& __s) {
824-
__sb_.str(__s);
858+
859+
#if _LIBCPP_STD_VER >= 20
860+
_LIBCPP_HIDE_FROM_ABI string_type str() const & { return __sb_.str(); }
861+
862+
template <class _SAlloc>
863+
requires __is_allocator<_SAlloc>::value
864+
_LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
865+
return __sb_.str(__sa);
825866
}
867+
868+
_LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); }
869+
870+
_LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
871+
#else // _LIBCPP_STD_VER >= 20
872+
_LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
873+
#endif // _LIBCPP_STD_VER >= 20
874+
875+
_LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
876+
826877
#if _LIBCPP_STD_VER >= 20
827-
_LIBCPP_HIDE_FROM_ABI
828-
basic_string_view<char_type, traits_type> view() const noexcept {
829-
return __sb_.view();
878+
template <class _SAlloc>
879+
_LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
880+
__sb_.str(__s);
830881
}
831-
#endif
882+
883+
_LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
884+
#endif // _LIBCPP_STD_VER >= 20
832885
};
833886

834887
template <class _CharT, class _Traits, class _Allocator>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17
10+
11+
// <sstream>
12+
13+
// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
14+
// class basic_istringstream
15+
16+
// basic_istringstream(ios_base::openmode which, const Allocator& a);
17+
18+
#include <sstream>
19+
#include <cassert>
20+
21+
#include "test_allocator.h"
22+
#include "test_macros.h"
23+
24+
template <class CharT>
25+
static void test() {
26+
const test_allocator<CharT> a(2);
27+
const std::basic_istringstream<CharT, std::char_traits<CharT>, test_allocator<CharT>> ss(std::ios_base::binary, a);
28+
assert(ss.rdbuf()->get_allocator() == a);
29+
assert(ss.view().empty());
30+
}
31+
32+
int main(int, char**) {
33+
test<char>();
34+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
35+
test<wchar_t>();
36+
#endif
37+
return 0;
38+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17
10+
11+
// <sstream>
12+
13+
// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
14+
// class basic_istringstream
15+
16+
// template <class SAlloc>
17+
// explicit basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s, ios_base::openmode which = ios_base::in)
18+
19+
#include <sstream>
20+
#include <cassert>
21+
22+
#include "make_string.h"
23+
#include "test_allocator.h"
24+
#include "test_macros.h"
25+
26+
#define STR(S) MAKE_STRING(CharT, S)
27+
#define SV(S) MAKE_STRING_VIEW(CharT, S)
28+
29+
template <class CharT>
30+
static void test() {
31+
{
32+
const std::basic_string<CharT> s(STR("testing"));
33+
const std::basic_istringstream<CharT, std::char_traits<CharT>, test_allocator<CharT>> ss(s);
34+
assert(ss.view() == SV("testing"));
35+
}
36+
{
37+
const std::basic_string<CharT> s(STR("testing"));
38+
const std::basic_istringstream<CharT, std::char_traits<CharT>, test_allocator<CharT>> ss(s, std::ios_base::binary);
39+
assert(ss.view() == SV("testing"));
40+
}
41+
}
42+
43+
int main(int, char**) {
44+
test<char>();
45+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
46+
test<wchar_t>();
47+
#endif
48+
return 0;
49+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17
10+
11+
// <sstream>
12+
13+
// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
14+
// class basic_istringstream
15+
16+
// template <class SAlloc>
17+
// basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s, const Allocator& a)
18+
// : basic_istringstream(s, ios_base::in, a) {}
19+
20+
#include <sstream>
21+
#include <cassert>
22+
23+
#include "make_string.h"
24+
#include "test_allocator.h"
25+
#include "test_macros.h"
26+
27+
#define STR(S) MAKE_STRING(CharT, S)
28+
#define SV(S) MAKE_STRING_VIEW(CharT, S)
29+
30+
template <class CharT>
31+
static void test() {
32+
const std::basic_string<CharT> s(STR("testing"));
33+
const test_allocator<CharT> a(2);
34+
const std::basic_istringstream<CharT, std::char_traits<CharT>, test_allocator<CharT>> ss(s, a);
35+
assert(ss.rdbuf()->get_allocator() == a);
36+
assert(ss.view() == SV("testing"));
37+
}
38+
39+
int main(int, char**) {
40+
test<char>();
41+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
42+
test<wchar_t>();
43+
#endif
44+
return 0;
45+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17
10+
11+
// <sstream>
12+
13+
// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
14+
// class basic_istringstream
15+
16+
// template <class SAlloc>
17+
// basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s, ios_base::openmode which, const Allocator& a)
18+
19+
#include <sstream>
20+
#include <cassert>
21+
22+
#include "make_string.h"
23+
#include "test_allocator.h"
24+
#include "test_macros.h"
25+
26+
#define STR(S) MAKE_STRING(CharT, S)
27+
#define SV(S) MAKE_STRING_VIEW(CharT, S)
28+
29+
template <class CharT>
30+
static void test() {
31+
const std::basic_string<CharT> s(STR("testing"));
32+
const test_allocator<CharT> a(2);
33+
const std::basic_istringstream<CharT, std::char_traits<CharT>, test_allocator<CharT>> ss(s, std::ios_base::binary, a);
34+
assert(ss.rdbuf()->get_allocator() == a);
35+
assert(ss.view() == SV("testing"));
36+
}
37+
38+
int main(int, char**) {
39+
test<char>();
40+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
41+
test<wchar_t>();
42+
#endif
43+
return 0;
44+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17
10+
11+
// <sstream>
12+
13+
// template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
14+
// class basic_istringstream
15+
16+
// explicit basic_istringstream(basic_string<char_type, traits_type, allocator_type>&& s, ios_base::openmode which = ios_base::in);
17+
18+
#include <sstream>
19+
#include <cassert>
20+
21+
#include "make_string.h"
22+
#include "test_macros.h"
23+
24+
#define STR(S) MAKE_STRING(CharT, S)
25+
26+
template <class CharT>
27+
static void test() {
28+
{
29+
std::basic_string<CharT> s(STR("testing"));
30+
const std::basic_istringstream<CharT> ss(std::move(s));
31+
assert(ss.str() == STR("testing"));
32+
}
33+
{
34+
std::basic_string<CharT> s(STR("testing"));
35+
const std::basic_istringstream<CharT> ss(std::move(s), std::ios_base::binary);
36+
assert(ss.str() == STR("testing"));
37+
}
38+
}
39+
40+
int main(int, char**) {
41+
test<char>();
42+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
43+
test<wchar_t>();
44+
#endif
45+
return 0;
46+
}

0 commit comments

Comments
 (0)