2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_SSTREAM
11 #define _LIBCPP_SSTREAM
14 sstream synopsis [sstream.syn]
16 // Class template basic_stringbuf [stringbuf]
17 template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
19 : public basic_streambuf<charT, traits>
22 typedef charT char_type;
23 typedef traits traits_type;
24 typedef typename traits_type::int_type int_type;
25 typedef typename traits_type::pos_type pos_type;
26 typedef typename traits_type::off_type off_type;
27 typedef Allocator allocator_type;
29 // [stringbuf.cons] constructors:
30 explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out); // before C++20
31 basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {} // C++20
32 explicit basic_stringbuf(ios_base::openmode which); // C++20
33 explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& s,
34 ios_base::openmode which = ios_base::in | ios_base::out);
35 explicit basic_stringbuf(const allocator_type& a)
36 : basic_stringbuf(ios_base::in | ios_base::out, a) {} // C++20
37 basic_stringbuf(ios_base::openmode which, const allocator_type& a); // C++20
38 explicit basic_stringbuf(basic_string<char_type, traits_type, allocator_type>&& s,
39 ios_base::openmode which = ios_base::in | ios_base::out); // C++20
40 template <class SAlloc>
41 basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
42 : basic_stringbuf(s, ios_base::in | ios_base::out, a) {} // C++20
43 template <class SAlloc>
44 basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s,
45 ios_base::openmode which, const allocator_type& a); // C++20
46 template <class SAlloc>
47 explicit basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s,
48 ios_base::openmode which = ios_base::in | ios_base::out); // C++20
49 basic_stringbuf(basic_stringbuf&& rhs);
50 basic_stringbuf(basic_stringbuf&& rhs, const allocator_type& a); // C++20
52 // [stringbuf.assign] Assign and swap:
53 basic_stringbuf& operator=(basic_stringbuf&& rhs);
54 void swap(basic_stringbuf& rhs) noexcept(see below); // conditionally noexcept since C++20
56 // [stringbuf.members] Member functions:
57 allocator_type get_allocator() const noexcept; // C++20
58 basic_string<char_type, traits_type, allocator_type> str() const; // before C++20
59 basic_string<char_type, traits_type, allocator_type> str() const &; // C++20
60 template <class SAlloc>
61 basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const; // C++20
62 basic_string<char_type, traits_type, allocator_type> str() &&; // C++20
63 basic_string_view<char_type, traits_type> view() const noexcept; // C++20
64 void str(const basic_string<char_type, traits_type, allocator_type>& s);
65 template <class SAlloc>
66 void str(const basic_string<char_type, traits_type, SAlloc>& s); // C++20
67 void str(basic_string<char_type, traits_type, allocator_type>&& s); // C++20
70 // [stringbuf.virtuals] Overridden virtual functions:
71 virtual int_type underflow();
72 virtual int_type pbackfail(int_type c = traits_type::eof());
73 virtual int_type overflow (int_type c = traits_type::eof());
74 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type*, streamsize);
75 virtual pos_type seekoff(off_type off, ios_base::seekdir way,
76 ios_base::openmode which = ios_base::in | ios_base::out);
77 virtual pos_type seekpos(pos_type sp,
78 ios_base::openmode which = ios_base::in | ios_base::out);
81 // [stringbuf.assign] non member swap
82 template <class charT, class traits, class Allocator>
83 void swap(basic_stringbuf<charT, traits, Allocator>& x,
84 basic_stringbuf<charT, traits, Allocator>& y); // conditionally noexcept since C++20
86 typedef basic_stringbuf<char> stringbuf;
87 typedef basic_stringbuf<wchar_t> wstringbuf;
89 // Class template basic_istringstream [istringstream]
90 template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
91 class basic_istringstream
92 : public basic_istream<charT, traits>
95 typedef charT char_type;
96 typedef traits traits_type;
97 typedef typename traits_type::int_type int_type;
98 typedef typename traits_type::pos_type pos_type;
99 typedef typename traits_type::off_type off_type;
100 typedef Allocator allocator_type;
102 // [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 explicit basic_istringstream(const basic_string<char_type, traits_type, allocator_type>& s,
107 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
120 basic_istringstream(basic_istringstream&& rhs);
122 // [istringstream.assign] Assign and swap:
123 basic_istringstream& operator=(basic_istringstream&& rhs);
124 void swap(basic_istringstream& rhs);
126 // [istringstream.members] Member functions:
127 basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() 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
134 void str(const basic_string<char_type, traits_type, allocator_type>& s);
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
140 template <class charT, class traits, class Allocator>
141 void swap(basic_istringstream<charT, traits, Allocator>& x,
142 basic_istringstream<charT, traits, Allocator>& y);
144 typedef basic_istringstream<char> istringstream;
145 typedef basic_istringstream<wchar_t> wistringstream;
147 // Class template basic_ostringstream [ostringstream]
148 template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
149 class basic_ostringstream
150 : public basic_ostream<charT, traits>
154 typedef charT char_type;
155 typedef traits traits_type;
156 typedef typename traits_type::int_type int_type;
157 typedef typename traits_type::pos_type pos_type;
158 typedef typename traits_type::off_type off_type;
159 typedef Allocator allocator_type;
161 // [ostringstream.cons] Constructors:
162 explicit basic_ostringstream(ios_base::openmode which = ios_base::out); // before C++20
163 basic_ostringstream() : basic_ostringstream(ios_base::out) {} // C++20
164 explicit basic_ostringstream(ios_base::openmode which); // C++20
165 explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type>& s,
166 ios_base::openmode which = ios_base::out);
167 basic_ostringstream(ios_base::openmode which, const allocator_type& a); // C++20
168 explicit basic_ostringstream(basic_string<char_type, traits_type, allocator_type>&& s,
169 ios_base::openmode which = ios_base::out); // C++20
170 template <class SAlloc>
171 basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
172 : basic_ostringstream(s, ios_base::out, a) {} // C++20
173 template <class SAlloc>
174 basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s,
175 ios_base::openmode which, const allocator_type& a); // C++20
176 template <class SAlloc>
177 explicit basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s,
178 ios_base::openmode which = ios_base::out); // C++20
179 basic_ostringstream(basic_ostringstream&& rhs);
181 // [ostringstream.assign] Assign and swap:
182 basic_ostringstream& operator=(basic_ostringstream&& rhs);
183 void swap(basic_ostringstream& rhs);
185 // [ostringstream.members] Member functions:
186 basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
187 basic_string<char_type, traits_type, allocator_type> str() const; // before C++20
188 basic_string<char_type, traits_type, allocator_type> str() const &; // C++20
189 template <class SAlloc>
190 basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const; // C++20
191 basic_string<char_type, traits_type, allocator_type> str() &&; // C++20
192 basic_string_view<char_type, traits_type> view() const noexcept; // C++20
193 void str(const basic_string<char_type, traits_type, allocator_type>& s);
194 template <class SAlloc>
195 void str(const basic_string<char_type, traits_type, SAlloc>& s); // C++20
196 void str(basic_string<char_type, traits_type, allocator_type>&& s); // C++20
199 template <class charT, class traits, class Allocator>
200 void swap(basic_ostringstream<charT, traits, Allocator>& x,
201 basic_ostringstream<charT, traits, Allocator>& y);
203 typedef basic_ostringstream<char> ostringstream;
204 typedef basic_ostringstream<wchar_t> wostringstream;
206 // Class template basic_stringstream [stringstream]
207 template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
208 class basic_stringstream
209 : public basic_iostream<charT, traits>
213 typedef charT char_type;
214 typedef traits traits_type;
215 typedef typename traits_type::int_type int_type;
216 typedef typename traits_type::pos_type pos_type;
217 typedef typename traits_type::off_type off_type;
218 typedef Allocator allocator_type;
220 // [stringstream.cons] constructors
221 explicit basic_stringstream(ios_base::openmode which = ios_base::out | ios_base::in); // before C++20
222 basic_stringstream() : basic_stringstream(ios_base::out | ios_base::in) {} // C++20
223 explicit basic_stringstream(ios_base::openmode which); // C++20
224 explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type>& s,
225 ios_base::openmode which = ios_base::out | ios_base::in);
226 basic_stringstream(ios_base::openmode which, const allocator_type& a); // C++20
227 explicit basic_stringstream(basic_string<char_type, traits_type, allocator_type>&& s,
228 ios_base::openmode which = ios_base::out | ios_base::in); // C++20
229 template <class SAlloc>
230 basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
231 : basic_stringstream(s, ios_base::out | ios_base::in, a) {} // C++20
232 template <class SAlloc>
233 basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s,
234 ios_base::openmode which, const allocator_type& a); // C++20
235 template <class SAlloc>
236 explicit basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s,
237 ios_base::openmode which = ios_base::out | ios_base::in); // C++20
238 basic_stringstream(basic_stringstream&& rhs);
240 // [stringstream.assign] Assign and swap:
241 basic_stringstream& operator=(basic_stringstream&& rhs);
242 void swap(basic_stringstream& rhs);
244 // [stringstream.members] Member functions:
245 basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
246 basic_string<char_type, traits_type, allocator_type> str() const; // before C++20
247 basic_string<char_type, traits_type, allocator_type> str() const &; // C++20
248 template <class SAlloc>
249 basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const; // C++20
250 basic_string<char_type, traits_type, allocator_type> str() &&; // C++20
251 basic_string_view<char_type, traits_type> view() const noexcept; // C++20
252 void str(const basic_string<char_type, traits_type, allocator_type>& s);
253 template <class SAlloc>
254 void str(const basic_string<char_type, traits_type, SAlloc>& s); // C++20
255 void str(basic_string<char_type, traits_type, allocator_type>&& s); // C++20
258 template <class charT, class traits, class Allocator>
259 void swap(basic_stringstream<charT, traits, Allocator>& x,
260 basic_stringstream<charT, traits, Allocator>& y);
262 typedef basic_stringstream<char> stringstream;
263 typedef basic_stringstream<wchar_t> wstringstream;
269 #include <__assert> // all public C++ headers provide the assertion handler
270 #include <__availability>
272 #include <__fwd/sstream.h>
273 #include <__utility/swap.h>
279 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
280 # pragma GCC system_header
284 #include <__undef_macros>
287 // TODO(LLVM-19): Remove this once we drop support for Clang 16,
288 // which had this bug: https://github.com/llvm/llvm-project/issues/40363
290 #define _LIBCPP_HIDE_FROM_ABI_SSTREAM _LIBCPP_ALWAYS_INLINE
292 #define _LIBCPP_HIDE_FROM_ABI_SSTREAM _LIBCPP_HIDE_FROM_ABI
295 _LIBCPP_BEGIN_NAMESPACE_STD
297 // Class template basic_stringbuf [stringbuf]
299 template <class _CharT, class _Traits, class _Allocator>
300 class _LIBCPP_TEMPLATE_VIS basic_stringbuf
301 : public basic_streambuf<_CharT, _Traits>
304 typedef _CharT char_type;
305 typedef _Traits traits_type;
306 typedef typename traits_type::int_type int_type;
307 typedef typename traits_type::pos_type pos_type;
308 typedef typename traits_type::off_type off_type;
309 typedef _Allocator allocator_type;
311 typedef basic_string<char_type, traits_type, allocator_type> string_type;
316 mutable char_type* __hm_;
317 ios_base::openmode __mode_;
318 _LIBCPP_HIDE_FROM_ABI void __init_buf_ptrs();
319 _LIBCPP_HIDE_FROM_ABI void __move_init(basic_stringbuf&& __rhs);
322 // [stringbuf.cons] constructors:
323 _LIBCPP_INLINE_VISIBILITY
325 : __hm_(nullptr), __mode_(ios_base::in | ios_base::out) {}
327 _LIBCPP_INLINE_VISIBILITY
328 explicit basic_stringbuf(ios_base::openmode __wch)
329 : __hm_(nullptr), __mode_(__wch) {}
331 _LIBCPP_INLINE_VISIBILITY
332 explicit basic_stringbuf(const string_type& __s,
333 ios_base::openmode __wch = ios_base::in | ios_base::out)
334 : __str_(__s.get_allocator()), __hm_(nullptr), __mode_(__wch)
339 #if _LIBCPP_STD_VER >= 20
340 _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const allocator_type& __a)
341 : basic_stringbuf(ios_base::in | ios_base::out, __a) {}
343 _LIBCPP_HIDE_FROM_ABI basic_stringbuf(ios_base::openmode __wch, const allocator_type& __a)
344 : __str_(__a), __hm_(nullptr), __mode_(__wch) {}
346 _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(string_type&& __s,
347 ios_base::openmode __wch = ios_base::in | ios_base::out)
348 : __str_(std::move(__s)), __hm_(nullptr), __mode_(__wch) {
352 template <class _SAlloc>
353 _LIBCPP_HIDE_FROM_ABI
354 basic_stringbuf(const basic_string<char_type, traits_type, _SAlloc>& __s, const allocator_type& __a)
355 : basic_stringbuf(__s, ios_base::in | ios_base::out, __a) {}
357 template <class _SAlloc>
358 _LIBCPP_HIDE_FROM_ABI basic_stringbuf(
359 const basic_string<char_type, traits_type, _SAlloc>& __s, ios_base::openmode __wch, const allocator_type& __a)
360 : __str_(__s, __a), __hm_(nullptr), __mode_(__wch) {
364 template <class _SAlloc>
365 requires (!is_same_v<_SAlloc, allocator_type>)
366 _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const basic_string<char_type, traits_type, _SAlloc>& __s,
367 ios_base::openmode __wch = ios_base::in | ios_base::out)
368 : __str_(__s), __hm_(nullptr), __mode_(__wch) {
371 #endif // _LIBCPP_STD_VER >= 20
373 basic_stringbuf(basic_stringbuf&& __rhs) : __mode_(__rhs.__mode_) { __move_init(std::move(__rhs)); }
375 #if _LIBCPP_STD_VER >= 20
376 _LIBCPP_HIDE_FROM_ABI basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a)
377 : basic_stringbuf(__rhs.__mode_, __a) {
378 __move_init(std::move(__rhs));
382 // [stringbuf.assign] Assign and swap:
383 basic_stringbuf& operator=(basic_stringbuf&& __rhs);
384 void swap(basic_stringbuf& __rhs)
385 #if _LIBCPP_STD_VER >= 20
386 noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
387 allocator_traits<allocator_type>::is_always_equal::value)
391 // [stringbuf.members] Member functions:
393 #if _LIBCPP_STD_VER >= 20
394 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
397 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
398 string_type str() const;
400 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return str(__str_.get_allocator()); }
402 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && {
403 const basic_string_view<_CharT, _Traits> __view = view();
404 typename string_type::size_type __pos = __view.empty() ? 0 : __view.data() - __str_.data();
405 // In C++23, this is just string_type(std::move(__str_), __pos, __view.size(), __str_.get_allocator());
406 // But we need something that works in C++20 also.
407 string_type __result(__str_.get_allocator());
408 __result.__move_assign(std::move(__str_), __pos, __view.size());
413 #endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
415 #if _LIBCPP_STD_VER >= 20
416 template <class _SAlloc>
417 requires __is_allocator<_SAlloc>::value
418 _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
419 return basic_string<_CharT, _Traits, _SAlloc>(view(), __sa);
422 _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept;
423 #endif // _LIBCPP_STD_VER >= 20
425 void str(const string_type& __s) {
430 #if _LIBCPP_STD_VER >= 20
431 template <class _SAlloc>
432 requires (!is_same_v<_SAlloc, allocator_type>)
433 _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
438 _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) {
439 __str_ = std::move(__s);
442 #endif // _LIBCPP_STD_VER >= 20
445 // [stringbuf.virtuals] Overridden virtual functions:
446 int_type underflow() override;
447 int_type pbackfail(int_type __c = traits_type::eof()) override;
448 int_type overflow (int_type __c = traits_type::eof()) override;
449 pos_type seekoff(off_type __off, ios_base::seekdir __way,
450 ios_base::openmode __wch = ios_base::in | ios_base::out) override;
451 _LIBCPP_HIDE_FROM_ABI_VIRTUAL
452 pos_type seekpos(pos_type __sp,
453 ios_base::openmode __wch = ios_base::in | ios_base::out) override {
454 return seekoff(__sp, ios_base::beg, __wch);
458 template <class _CharT, class _Traits, class _Allocator>
459 _LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__move_init(basic_stringbuf&& __rhs) {
460 char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
461 ptrdiff_t __binp = -1;
462 ptrdiff_t __ninp = -1;
463 ptrdiff_t __einp = -1;
464 if (__rhs.eback() != nullptr)
466 __binp = __rhs.eback() - __p;
467 __ninp = __rhs.gptr() - __p;
468 __einp = __rhs.egptr() - __p;
470 ptrdiff_t __bout = -1;
471 ptrdiff_t __nout = -1;
472 ptrdiff_t __eout = -1;
473 if (__rhs.pbase() != nullptr)
475 __bout = __rhs.pbase() - __p;
476 __nout = __rhs.pptr() - __p;
477 __eout = __rhs.epptr() - __p;
479 ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
480 __str_ = _VSTD::move(__rhs.__str_);
481 __p = const_cast<char_type*>(__str_.data());
483 this->setg(__p + __binp, __p + __ninp, __p + __einp);
486 this->setp(__p + __bout, __p + __eout);
487 this->__pbump(__nout);
489 __hm_ = __hm == -1 ? nullptr : __p + __hm;
490 __p = const_cast<char_type*>(__rhs.__str_.data());
491 __rhs.setg(__p, __p, __p);
492 __rhs.setp(__p, __p);
494 this->pubimbue(__rhs.getloc());
497 template <class _CharT, class _Traits, class _Allocator>
498 basic_stringbuf<_CharT, _Traits, _Allocator>&
499 basic_stringbuf<_CharT, _Traits, _Allocator>::operator=(basic_stringbuf&& __rhs)
501 char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
502 ptrdiff_t __binp = -1;
503 ptrdiff_t __ninp = -1;
504 ptrdiff_t __einp = -1;
505 if (__rhs.eback() != nullptr)
507 __binp = __rhs.eback() - __p;
508 __ninp = __rhs.gptr() - __p;
509 __einp = __rhs.egptr() - __p;
511 ptrdiff_t __bout = -1;
512 ptrdiff_t __nout = -1;
513 ptrdiff_t __eout = -1;
514 if (__rhs.pbase() != nullptr)
516 __bout = __rhs.pbase() - __p;
517 __nout = __rhs.pptr() - __p;
518 __eout = __rhs.epptr() - __p;
520 ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
521 __str_ = _VSTD::move(__rhs.__str_);
522 __p = const_cast<char_type*>(__str_.data());
524 this->setg(__p + __binp, __p + __ninp, __p + __einp);
526 this->setg(nullptr, nullptr, nullptr);
529 this->setp(__p + __bout, __p + __eout);
530 this->__pbump(__nout);
533 this->setp(nullptr, nullptr);
535 __hm_ = __hm == -1 ? nullptr : __p + __hm;
536 __mode_ = __rhs.__mode_;
537 __p = const_cast<char_type*>(__rhs.__str_.data());
538 __rhs.setg(__p, __p, __p);
539 __rhs.setp(__p, __p);
541 this->pubimbue(__rhs.getloc());
545 template <class _CharT, class _Traits, class _Allocator>
547 basic_stringbuf<_CharT, _Traits, _Allocator>::swap(basic_stringbuf& __rhs)
548 #if _LIBCPP_STD_VER >= 20
549 noexcept(allocator_traits<_Allocator>::propagate_on_container_swap::value ||
550 allocator_traits<_Allocator>::is_always_equal::value)
553 char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
554 ptrdiff_t __rbinp = -1;
555 ptrdiff_t __rninp = -1;
556 ptrdiff_t __reinp = -1;
557 if (__rhs.eback() != nullptr)
559 __rbinp = __rhs.eback() - __p;
560 __rninp = __rhs.gptr() - __p;
561 __reinp = __rhs.egptr() - __p;
563 ptrdiff_t __rbout = -1;
564 ptrdiff_t __rnout = -1;
565 ptrdiff_t __reout = -1;
566 if (__rhs.pbase() != nullptr)
568 __rbout = __rhs.pbase() - __p;
569 __rnout = __rhs.pptr() - __p;
570 __reout = __rhs.epptr() - __p;
572 ptrdiff_t __rhm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
573 __p = const_cast<char_type*>(__str_.data());
574 ptrdiff_t __lbinp = -1;
575 ptrdiff_t __lninp = -1;
576 ptrdiff_t __leinp = -1;
577 if (this->eback() != nullptr)
579 __lbinp = this->eback() - __p;
580 __lninp = this->gptr() - __p;
581 __leinp = this->egptr() - __p;
583 ptrdiff_t __lbout = -1;
584 ptrdiff_t __lnout = -1;
585 ptrdiff_t __leout = -1;
586 if (this->pbase() != nullptr)
588 __lbout = this->pbase() - __p;
589 __lnout = this->pptr() - __p;
590 __leout = this->epptr() - __p;
592 ptrdiff_t __lhm = __hm_ == nullptr ? -1 : __hm_ - __p;
593 _VSTD::swap(__mode_, __rhs.__mode_);
594 __str_.swap(__rhs.__str_);
595 __p = const_cast<char_type*>(__str_.data());
597 this->setg(__p + __rbinp, __p + __rninp, __p + __reinp);
599 this->setg(nullptr, nullptr, nullptr);
602 this->setp(__p + __rbout, __p + __reout);
603 this->__pbump(__rnout);
606 this->setp(nullptr, nullptr);
607 __hm_ = __rhm == -1 ? nullptr : __p + __rhm;
608 __p = const_cast<char_type*>(__rhs.__str_.data());
610 __rhs.setg(__p + __lbinp, __p + __lninp, __p + __leinp);
612 __rhs.setg(nullptr, nullptr, nullptr);
615 __rhs.setp(__p + __lbout, __p + __leout);
616 __rhs.__pbump(__lnout);
619 __rhs.setp(nullptr, nullptr);
620 __rhs.__hm_ = __lhm == -1 ? nullptr : __p + __lhm;
621 locale __tl = __rhs.getloc();
622 __rhs.pubimbue(this->getloc());
623 this->pubimbue(__tl);
626 template <class _CharT, class _Traits, class _Allocator>
627 inline _LIBCPP_INLINE_VISIBILITY
629 swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
630 basic_stringbuf<_CharT, _Traits, _Allocator>& __y)
631 #if _LIBCPP_STD_VER >= 20
632 noexcept(noexcept(__x.swap(__y)))
638 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
639 template <class _CharT, class _Traits, class _Allocator>
640 basic_string<_CharT, _Traits, _Allocator>
641 basic_stringbuf<_CharT, _Traits, _Allocator>::str() const {
642 if (__mode_ & ios_base::out) {
643 if (__hm_ < this->pptr())
644 __hm_ = this->pptr();
645 return string_type(this->pbase(), __hm_, __str_.get_allocator());
646 } else if (__mode_ & ios_base::in)
647 return string_type(this->eback(), this->egptr(), __str_.get_allocator());
648 return string_type(__str_.get_allocator());
650 #endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
652 template <class _CharT, class _Traits, class _Allocator>
653 _LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__init_buf_ptrs() {
655 char_type* __data = const_cast<char_type*>(__str_.data());
656 typename string_type::size_type __sz = __str_.size();
657 if (__mode_ & ios_base::in) {
658 __hm_ = __data + __sz;
659 this->setg(__data, __data, __hm_);
661 if (__mode_ & ios_base::out) {
662 __hm_ = __data + __sz;
663 __str_.resize(__str_.capacity());
664 this->setp(__data, __data + __str_.size());
665 if (__mode_ & (ios_base::app | ios_base::ate)) {
666 while (__sz > INT_MAX) {
667 this->pbump(INT_MAX);
676 #if _LIBCPP_STD_VER >= 20
677 template <class _CharT, class _Traits, class _Allocator>
678 _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT, _Traits>
679 basic_stringbuf<_CharT, _Traits, _Allocator>::view() const noexcept {
680 if (__mode_ & ios_base::out) {
681 if (__hm_ < this->pptr())
682 __hm_ = this->pptr();
683 return basic_string_view<_CharT, _Traits>(this->pbase(), __hm_);
684 } else if (__mode_ & ios_base::in)
685 return basic_string_view<_CharT, _Traits>(this->eback(), this->egptr());
686 return basic_string_view<_CharT, _Traits>();
688 #endif // _LIBCPP_STD_VER >= 20
690 template <class _CharT, class _Traits, class _Allocator>
691 typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
692 basic_stringbuf<_CharT, _Traits, _Allocator>::underflow()
694 if (__hm_ < this->pptr())
695 __hm_ = this->pptr();
696 if (__mode_ & ios_base::in)
698 if (this->egptr() < __hm_)
699 this->setg(this->eback(), this->gptr(), __hm_);
700 if (this->gptr() < this->egptr())
701 return traits_type::to_int_type(*this->gptr());
703 return traits_type::eof();
706 template <class _CharT, class _Traits, class _Allocator>
707 typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
708 basic_stringbuf<_CharT, _Traits, _Allocator>::pbackfail(int_type __c)
710 if (__hm_ < this->pptr())
711 __hm_ = this->pptr();
712 if (this->eback() < this->gptr())
714 if (traits_type::eq_int_type(__c, traits_type::eof()))
716 this->setg(this->eback(), this->gptr()-1, __hm_);
717 return traits_type::not_eof(__c);
719 if ((__mode_ & ios_base::out) ||
720 traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
722 this->setg(this->eback(), this->gptr()-1, __hm_);
723 *this->gptr() = traits_type::to_char_type(__c);
727 return traits_type::eof();
730 template <class _CharT, class _Traits, class _Allocator>
731 typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
732 basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c)
734 if (!traits_type::eq_int_type(__c, traits_type::eof()))
736 ptrdiff_t __ninp = this->gptr() - this->eback();
737 if (this->pptr() == this->epptr())
739 if (!(__mode_ & ios_base::out))
740 return traits_type::eof();
741 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
744 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
745 ptrdiff_t __nout = this->pptr() - this->pbase();
746 ptrdiff_t __hm = __hm_ - this->pbase();
747 __str_.push_back(char_type());
748 __str_.resize(__str_.capacity());
749 char_type* __p = const_cast<char_type*>(__str_.data());
750 this->setp(__p, __p + __str_.size());
751 this->__pbump(__nout);
752 __hm_ = this->pbase() + __hm;
753 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
757 return traits_type::eof();
759 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
761 __hm_ = _VSTD::max(this->pptr() + 1, __hm_);
762 if (__mode_ & ios_base::in)
764 char_type* __p = const_cast<char_type*>(__str_.data());
765 this->setg(__p, __p + __ninp, __hm_);
767 return this->sputc(traits_type::to_char_type(__c));
769 return traits_type::not_eof(__c);
772 template <class _CharT, class _Traits, class _Allocator>
773 typename basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type
774 basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off,
775 ios_base::seekdir __way,
776 ios_base::openmode __wch)
778 if (__hm_ < this->pptr())
779 __hm_ = this->pptr();
780 if ((__wch & (ios_base::in | ios_base::out)) == 0)
782 if ((__wch & (ios_base::in | ios_base::out)) == (ios_base::in | ios_base::out)
783 && __way == ios_base::cur)
785 const ptrdiff_t __hm = __hm_ == nullptr ? 0 : __hm_ - __str_.data();
793 if (__wch & ios_base::in)
794 __noff = this->gptr() - this->eback();
796 __noff = this->pptr() - this->pbase();
805 if (__noff < 0 || __hm < __noff)
809 if ((__wch & ios_base::in) && this->gptr() == nullptr)
811 if ((__wch & ios_base::out) && this->pptr() == nullptr)
814 if (__wch & ios_base::in)
815 this->setg(this->eback(), this->eback() + __noff, __hm_);
816 if (__wch & ios_base::out)
818 this->setp(this->pbase(), this->epptr());
819 this->__pbump(__noff);
821 return pos_type(__noff);
824 // Class template basic_istringstream [istringstream]
826 template <class _CharT, class _Traits, class _Allocator>
827 class _LIBCPP_TEMPLATE_VIS basic_istringstream
828 : public basic_istream<_CharT, _Traits>
831 typedef _CharT char_type;
832 typedef _Traits traits_type;
833 typedef typename traits_type::int_type int_type;
834 typedef typename traits_type::pos_type pos_type;
835 typedef typename traits_type::off_type off_type;
836 typedef _Allocator allocator_type;
838 typedef basic_string<char_type, traits_type, allocator_type> string_type;
841 basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
844 // [istringstream.cons] Constructors:
845 _LIBCPP_INLINE_VISIBILITY
846 basic_istringstream()
847 : basic_istream<_CharT, _Traits>(&__sb_), __sb_(ios_base::in) {}
849 _LIBCPP_INLINE_VISIBILITY
850 explicit basic_istringstream(ios_base::openmode __wch)
851 : basic_istream<_CharT, _Traits>(&__sb_), __sb_(__wch | ios_base::in) {}
853 _LIBCPP_INLINE_VISIBILITY
854 explicit basic_istringstream(const string_type& __s,
855 ios_base::openmode __wch = ios_base::in)
856 : basic_istream<_CharT, _Traits>(&__sb_)
857 , __sb_(__s, __wch | ios_base::in)
860 #if _LIBCPP_STD_VER >= 20
861 _LIBCPP_HIDE_FROM_ABI basic_istringstream(ios_base::openmode __wch, const _Allocator& __a)
862 : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::in, __a) {}
864 _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(string_type&& __s, ios_base::openmode __wch = ios_base::in)
865 : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch | ios_base::in) {}
867 template <class _SAlloc>
868 _LIBCPP_HIDE_FROM_ABI basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
869 : basic_istringstream(__s, ios_base::in, __a) {}
871 template <class _SAlloc>
872 _LIBCPP_HIDE_FROM_ABI basic_istringstream(
873 const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
874 : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in, __a) {}
876 template <class _SAlloc>
877 _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
878 ios_base::openmode __wch = ios_base::in)
879 : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in) {}
880 #endif // _LIBCPP_STD_VER >= 20
882 _LIBCPP_INLINE_VISIBILITY
883 basic_istringstream(basic_istringstream&& __rhs)
884 : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs))
885 , __sb_(_VSTD::move(__rhs.__sb_))
887 basic_istream<_CharT, _Traits>::set_rdbuf(&__sb_);
890 // [istringstream.assign] Assign and swap:
891 basic_istringstream& operator=(basic_istringstream&& __rhs) {
892 basic_istream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
893 __sb_ = _VSTD::move(__rhs.__sb_);
896 _LIBCPP_INLINE_VISIBILITY
897 void swap(basic_istringstream& __rhs) {
898 basic_istream<char_type, traits_type>::swap(__rhs);
899 __sb_.swap(__rhs.__sb_);
902 // [istringstream.members] Member functions:
903 _LIBCPP_INLINE_VISIBILITY
904 basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
905 return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
908 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
909 _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
911 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return __sb_.str(); }
913 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && { return std::move(__sb_).str(); }
916 #if _LIBCPP_STD_VER >= 20
917 template <class _SAlloc>
918 requires __is_allocator<_SAlloc>::value
919 _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
920 return __sb_.str(__sa);
923 _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
924 #endif // _LIBCPP_STD_VER >= 20
926 _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
928 #if _LIBCPP_STD_VER >= 20
929 template <class _SAlloc>
930 _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
934 _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
935 #endif // _LIBCPP_STD_VER >= 20
938 template <class _CharT, class _Traits, class _Allocator>
939 inline _LIBCPP_INLINE_VISIBILITY
941 swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x,
942 basic_istringstream<_CharT, _Traits, _Allocator>& __y)
947 // Class template basic_ostringstream [ostringstream]
949 template <class _CharT, class _Traits, class _Allocator>
950 class _LIBCPP_TEMPLATE_VIS basic_ostringstream
951 : public basic_ostream<_CharT, _Traits>
954 typedef _CharT char_type;
955 typedef _Traits traits_type;
956 typedef typename traits_type::int_type int_type;
957 typedef typename traits_type::pos_type pos_type;
958 typedef typename traits_type::off_type off_type;
959 typedef _Allocator allocator_type;
961 typedef basic_string<char_type, traits_type, allocator_type> string_type;
964 basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
967 // [ostringstream.cons] Constructors:
968 _LIBCPP_INLINE_VISIBILITY
969 basic_ostringstream()
970 : basic_ostream<_CharT, _Traits>(&__sb_), __sb_(ios_base::out) {}
972 _LIBCPP_INLINE_VISIBILITY
973 explicit basic_ostringstream(ios_base::openmode __wch)
974 : basic_ostream<_CharT, _Traits>(&__sb_), __sb_(__wch | ios_base::out) {}
976 _LIBCPP_INLINE_VISIBILITY
977 explicit basic_ostringstream(const string_type& __s,
978 ios_base::openmode __wch = ios_base::out)
979 : basic_ostream<_CharT, _Traits>(&__sb_)
980 , __sb_(__s, __wch | ios_base::out)
983 #if _LIBCPP_STD_VER >= 20
984 _LIBCPP_HIDE_FROM_ABI basic_ostringstream(ios_base::openmode __wch, const _Allocator& __a)
985 : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::out, __a) {}
987 _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(string_type&& __s, ios_base::openmode __wch = ios_base::out)
988 : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch | ios_base::out) {}
990 template <class _SAlloc>
991 _LIBCPP_HIDE_FROM_ABI basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
992 : basic_ostringstream(__s, ios_base::out, __a) {}
994 template <class _SAlloc>
995 _LIBCPP_HIDE_FROM_ABI basic_ostringstream(
996 const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
997 : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::out, __a) {}
999 template <class _SAlloc>
1000 requires (!is_same_v<_SAlloc, allocator_type>)
1001 _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
1002 ios_base::openmode __wch = ios_base::out)
1003 : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::out) {}
1004 #endif // _LIBCPP_STD_VER >= 20
1006 _LIBCPP_INLINE_VISIBILITY
1007 basic_ostringstream(basic_ostringstream&& __rhs)
1008 : basic_ostream<_CharT, _Traits>(_VSTD::move(__rhs))
1009 , __sb_(_VSTD::move(__rhs.__sb_))
1011 basic_ostream<_CharT, _Traits>::set_rdbuf(&__sb_);
1014 // [ostringstream.assign] Assign and swap:
1015 basic_ostringstream& operator=(basic_ostringstream&& __rhs) {
1016 basic_ostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
1017 __sb_ = _VSTD::move(__rhs.__sb_);
1021 _LIBCPP_INLINE_VISIBILITY
1022 void swap(basic_ostringstream& __rhs) {
1023 basic_ostream<char_type, traits_type>::swap(__rhs);
1024 __sb_.swap(__rhs.__sb_);
1027 // [ostringstream.members] Member functions:
1028 _LIBCPP_INLINE_VISIBILITY
1029 basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
1030 return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
1033 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
1034 _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
1036 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return __sb_.str(); }
1038 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && { return std::move(__sb_).str(); }
1041 #if _LIBCPP_STD_VER >= 20
1042 template <class _SAlloc>
1043 requires __is_allocator<_SAlloc>::value
1044 _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
1045 return __sb_.str(__sa);
1048 _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
1049 #endif // _LIBCPP_STD_VER >= 20
1051 _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
1053 #if _LIBCPP_STD_VER >= 20
1054 template <class _SAlloc>
1055 _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
1059 _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
1060 #endif // _LIBCPP_STD_VER >= 20
1063 template <class _CharT, class _Traits, class _Allocator>
1064 inline _LIBCPP_INLINE_VISIBILITY
1066 swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x,
1067 basic_ostringstream<_CharT, _Traits, _Allocator>& __y)
1072 // Class template basic_stringstream [stringstream]
1074 template <class _CharT, class _Traits, class _Allocator>
1075 class _LIBCPP_TEMPLATE_VIS basic_stringstream
1076 : public basic_iostream<_CharT, _Traits>
1079 typedef _CharT char_type;
1080 typedef _Traits traits_type;
1081 typedef typename traits_type::int_type int_type;
1082 typedef typename traits_type::pos_type pos_type;
1083 typedef typename traits_type::off_type off_type;
1084 typedef _Allocator allocator_type;
1086 typedef basic_string<char_type, traits_type, allocator_type> string_type;
1089 basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
1092 // [stringstream.cons] constructors
1093 _LIBCPP_INLINE_VISIBILITY
1094 basic_stringstream()
1095 : basic_iostream<_CharT, _Traits>(&__sb_), __sb_(ios_base::in | ios_base::out) {}
1097 _LIBCPP_INLINE_VISIBILITY
1098 explicit basic_stringstream(ios_base::openmode __wch)
1099 : basic_iostream<_CharT, _Traits>(&__sb_), __sb_(__wch) {}
1101 _LIBCPP_INLINE_VISIBILITY
1102 explicit basic_stringstream(const string_type& __s,
1103 ios_base::openmode __wch = ios_base::in | ios_base::out)
1104 : basic_iostream<_CharT, _Traits>(&__sb_)
1108 #if _LIBCPP_STD_VER >= 20
1109 _LIBCPP_HIDE_FROM_ABI basic_stringstream(ios_base::openmode __wch, const _Allocator& __a)
1110 : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch, __a) {}
1112 _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(string_type&& __s, ios_base::openmode __wch = ios_base::out | ios_base::in)
1113 : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch) {}
1115 template <class _SAlloc>
1116 _LIBCPP_HIDE_FROM_ABI basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
1117 : basic_stringstream(__s, ios_base::out | ios_base::in, __a) {}
1119 template <class _SAlloc>
1120 _LIBCPP_HIDE_FROM_ABI basic_stringstream(
1121 const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
1122 : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch, __a) {}
1124 template <class _SAlloc>
1125 requires (!is_same_v<_SAlloc, allocator_type>)
1126 _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
1127 ios_base::openmode __wch = ios_base::out | ios_base::in)
1128 : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch) {}
1129 #endif // _LIBCPP_STD_VER >= 20
1131 _LIBCPP_INLINE_VISIBILITY
1132 basic_stringstream(basic_stringstream&& __rhs)
1133 : basic_iostream<_CharT, _Traits>(_VSTD::move(__rhs))
1134 , __sb_(_VSTD::move(__rhs.__sb_))
1136 basic_istream<_CharT, _Traits>::set_rdbuf(&__sb_);
1139 // [stringstream.assign] Assign and swap:
1140 basic_stringstream& operator=(basic_stringstream&& __rhs) {
1141 basic_iostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
1142 __sb_ = _VSTD::move(__rhs.__sb_);
1145 _LIBCPP_INLINE_VISIBILITY
1146 void swap(basic_stringstream& __rhs) {
1147 basic_iostream<char_type, traits_type>::swap(__rhs);
1148 __sb_.swap(__rhs.__sb_);
1151 // [stringstream.members] Member functions:
1152 _LIBCPP_INLINE_VISIBILITY
1153 basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
1154 return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
1157 #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
1158 _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
1160 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return __sb_.str(); }
1162 _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && { return std::move(__sb_).str(); }
1165 #if _LIBCPP_STD_VER >= 20
1166 template <class _SAlloc>
1167 requires __is_allocator<_SAlloc>::value
1168 _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
1169 return __sb_.str(__sa);
1172 _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
1173 #endif // _LIBCPP_STD_VER >= 20
1175 _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
1177 #if _LIBCPP_STD_VER >= 20
1178 template <class _SAlloc>
1179 _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
1183 _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
1184 #endif // _LIBCPP_STD_VER >= 20
1187 template <class _CharT, class _Traits, class _Allocator>
1188 inline _LIBCPP_INLINE_VISIBILITY
1190 swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x,
1191 basic_stringstream<_CharT, _Traits, _Allocator>& __y)
1196 #ifndef _LIBCPP_AVAILABILITY_HAS_NO_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
1197 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringbuf<char>;
1198 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringstream<char>;
1199 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostringstream<char>;
1200 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istringstream<char>;
1203 _LIBCPP_END_NAMESPACE_STD
1207 #if _LIBCPP_STD_VER <= 20 && !defined(_LIPCPP_REMOVE_TRANSITIVE_INCLUDES)
1208 # include <type_traits>
1211 #endif // _LIBCPP_SSTREAM