xref: /freebsd/contrib/llvm-project/libcxx/include/sstream (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
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
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_SSTREAM
11#define _LIBCPP_SSTREAM
12
13// clang-format off
14
15/*
16    sstream synopsis [sstream.syn]
17
18// Class template basic_stringbuf [stringbuf]
19template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
20class basic_stringbuf
21    : public basic_streambuf<charT, traits>
22{
23public:
24    typedef charT                          char_type;
25    typedef traits                         traits_type;
26    typedef typename traits_type::int_type int_type;
27    typedef typename traits_type::pos_type pos_type;
28    typedef typename traits_type::off_type off_type;
29    typedef Allocator                      allocator_type;
30
31    // [stringbuf.cons] constructors:
32    explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out); // before C++20
33    basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {}               // C++20
34    explicit basic_stringbuf(ios_base::openmode which);                                // C++20
35    explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& s,
36                             ios_base::openmode which = ios_base::in | ios_base::out);
37    explicit basic_stringbuf(const allocator_type& a)
38        : basic_stringbuf(ios_base::in | ios_base::out, a) {}                          // C++20
39    basic_stringbuf(ios_base::openmode which, const allocator_type& a);                // C++20
40    explicit basic_stringbuf(basic_string<char_type, traits_type, allocator_type>&& s,
41                             ios_base::openmode which = ios_base::in | ios_base::out); // C++20
42    template <class SAlloc>
43    basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
44        : basic_stringbuf(s, ios_base::in | ios_base::out, a) {}                       // C++20
45    template <class SAlloc>
46    basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s,
47                    ios_base::openmode which, const allocator_type& a);                // C++20
48    template <class SAlloc>
49    explicit basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s,
50                             ios_base::openmode which = ios_base::in | ios_base::out); // C++20
51    basic_stringbuf(basic_stringbuf&& rhs);
52    basic_stringbuf(basic_stringbuf&& rhs, const allocator_type& a);                   // C++20
53
54    // [stringbuf.assign] Assign and swap:
55    basic_stringbuf& operator=(basic_stringbuf&& rhs);
56    void swap(basic_stringbuf& rhs) noexcept(see below);                               // conditionally noexcept since C++20
57
58    // [stringbuf.members] Member functions:
59    allocator_type get_allocator() const noexcept;                                     // C++20
60    basic_string<char_type, traits_type, allocator_type> str() const;                  // before C++20
61    basic_string<char_type, traits_type, allocator_type> str() const &;                // C++20
62    template <class SAlloc>
63    basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const;          // C++20
64    basic_string<char_type, traits_type, allocator_type> str() &&;                     // C++20
65    basic_string_view<char_type, traits_type> view() const noexcept;                   // C++20
66    void str(const basic_string<char_type, traits_type, allocator_type>& s);
67    template <class SAlloc>
68    void str(const basic_string<char_type, traits_type, SAlloc>& s);                   // C++20
69    void str(basic_string<char_type, traits_type, allocator_type>&& s);                // C++20
70
71protected:
72    // [stringbuf.virtuals] Overridden virtual functions:
73    virtual int_type underflow();
74    virtual int_type pbackfail(int_type c = traits_type::eof());
75    virtual int_type overflow (int_type c = traits_type::eof());
76    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type*, streamsize);
77    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
78                             ios_base::openmode which = ios_base::in | ios_base::out);
79    virtual pos_type seekpos(pos_type sp,
80                             ios_base::openmode which = ios_base::in | ios_base::out);
81};
82
83// [stringbuf.assign] non member swap
84template <class charT, class traits, class Allocator>
85void swap(basic_stringbuf<charT, traits, Allocator>& x,
86          basic_stringbuf<charT, traits, Allocator>& y); // conditionally noexcept since C++20
87
88typedef basic_stringbuf<char>    stringbuf;
89typedef basic_stringbuf<wchar_t> wstringbuf;
90
91// Class template basic_istringstream [istringstream]
92template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
93class basic_istringstream
94    : public basic_istream<charT, traits>
95{
96public:
97    typedef charT                          char_type;
98    typedef traits                         traits_type;
99    typedef typename traits_type::int_type int_type;
100    typedef typename traits_type::pos_type pos_type;
101    typedef typename traits_type::off_type off_type;
102    typedef Allocator                      allocator_type;
103
104    // [istringstream.cons] Constructors:
105    explicit basic_istringstream(ios_base::openmode which = ios_base::in);             // before C++20
106    basic_istringstream() : basic_istringstream(ios_base::in) {}                       // C++20
107    explicit basic_istringstream(ios_base::openmode which);                            // C++20
108    explicit basic_istringstream(const basic_string<char_type, traits_type, allocator_type>& s,
109                                 ios_base::openmode which = ios_base::in);
110    basic_istringstream(ios_base::openmode which, const allocator_type& a);            // C++20
111    explicit basic_istringstream(basic_string<char_type, traits_type, allocator_type>&& s,
112                                 ios_base::openmode which = ios_base::in);             // C++20
113    template <class SAlloc>
114    basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
115        : basic_istringstream(s, ios_base::in, a) {}                                   // C++20
116    template <class SAlloc>
117    basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s,
118                        ios_base::openmode which, const allocator_type& a);            // C++20
119    template <class SAlloc>
120    explicit basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s,
121                                 ios_base::openmode which = ios_base::in);             // C++20
122    basic_istringstream(basic_istringstream&& rhs);
123
124    // [istringstream.assign] Assign and swap:
125    basic_istringstream& operator=(basic_istringstream&& rhs);
126    void swap(basic_istringstream& rhs);
127
128    // [istringstream.members] Member functions:
129    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
130    basic_string<char_type, traits_type, allocator_type> str() const;                  // before C++20
131    basic_string<char_type, traits_type, allocator_type> str() const &;                // C++20
132    template <class SAlloc>
133    basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const;          // C++20
134    basic_string<char_type, traits_type, allocator_type> str() &&;                     // C++20
135    basic_string_view<char_type, traits_type> view() const noexcept;                   // C++20
136    void str(const basic_string<char_type, traits_type, allocator_type>& s);
137    template <class SAlloc>
138    void str(const basic_string<char_type, traits_type, SAlloc>& s);                   // C++20
139    void str(basic_string<char_type, traits_type, allocator_type>&& s);                // C++20
140};
141
142template <class charT, class traits, class Allocator>
143void swap(basic_istringstream<charT, traits, Allocator>& x,
144          basic_istringstream<charT, traits, Allocator>& y);
145
146typedef basic_istringstream<char>    istringstream;
147typedef basic_istringstream<wchar_t> wistringstream;
148
149// Class template basic_ostringstream [ostringstream]
150template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
151class basic_ostringstream
152    : public basic_ostream<charT, traits>
153{
154public:
155    // types:
156    typedef charT                          char_type;
157    typedef traits                         traits_type;
158    typedef typename traits_type::int_type int_type;
159    typedef typename traits_type::pos_type pos_type;
160    typedef typename traits_type::off_type off_type;
161    typedef Allocator                      allocator_type;
162
163    // [ostringstream.cons] Constructors:
164    explicit basic_ostringstream(ios_base::openmode which = ios_base::out);            // before C++20
165    basic_ostringstream() : basic_ostringstream(ios_base::out) {}                      // C++20
166    explicit basic_ostringstream(ios_base::openmode which);                            // C++20
167    explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type>& s,
168                                 ios_base::openmode which = ios_base::out);
169    basic_ostringstream(ios_base::openmode which, const allocator_type& a);            // C++20
170    explicit basic_ostringstream(basic_string<char_type, traits_type, allocator_type>&& s,
171                                 ios_base::openmode which = ios_base::out);            // C++20
172    template <class SAlloc>
173    basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
174        : basic_ostringstream(s, ios_base::out, a) {}                                  // C++20
175    template <class SAlloc>
176    basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s,
177                        ios_base::openmode which, const allocator_type& a);            // C++20
178    template <class SAlloc>
179    explicit basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s,
180                                 ios_base::openmode which = ios_base::out);            // C++20
181    basic_ostringstream(basic_ostringstream&& rhs);
182
183    // [ostringstream.assign] Assign and swap:
184    basic_ostringstream& operator=(basic_ostringstream&& rhs);
185    void swap(basic_ostringstream& rhs);
186
187    // [ostringstream.members] Member functions:
188    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
189    basic_string<char_type, traits_type, allocator_type> str() const;                  // before C++20
190    basic_string<char_type, traits_type, allocator_type> str() const &;                // C++20
191    template <class SAlloc>
192    basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const;          // C++20
193    basic_string<char_type, traits_type, allocator_type> str() &&;                     // C++20
194    basic_string_view<char_type, traits_type> view() const noexcept;                   // C++20
195    void str(const basic_string<char_type, traits_type, allocator_type>& s);
196    template <class SAlloc>
197    void str(const basic_string<char_type, traits_type, SAlloc>& s);                   // C++20
198    void str(basic_string<char_type, traits_type, allocator_type>&& s);                // C++20
199};
200
201template <class charT, class traits, class Allocator>
202void swap(basic_ostringstream<charT, traits, Allocator>& x,
203          basic_ostringstream<charT, traits, Allocator>& y);
204
205typedef basic_ostringstream<char>    ostringstream;
206typedef basic_ostringstream<wchar_t> wostringstream;
207
208// Class template basic_stringstream [stringstream]
209template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
210class basic_stringstream
211    : public basic_iostream<charT, traits>
212{
213public:
214    // types:
215    typedef charT                          char_type;
216    typedef traits                         traits_type;
217    typedef typename traits_type::int_type int_type;
218    typedef typename traits_type::pos_type pos_type;
219    typedef typename traits_type::off_type off_type;
220    typedef Allocator                      allocator_type;
221
222    // [stringstream.cons] constructors
223    explicit basic_stringstream(ios_base::openmode which = ios_base::out | ios_base::in); // before C++20
224    basic_stringstream() : basic_stringstream(ios_base::out | ios_base::in) {}            // C++20
225    explicit basic_stringstream(ios_base::openmode which);                                // C++20
226    explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type>& s,
227                                ios_base::openmode which = ios_base::out | ios_base::in);
228    basic_stringstream(ios_base::openmode which, const allocator_type& a);                // C++20
229    explicit basic_stringstream(basic_string<char_type, traits_type, allocator_type>&& s,
230                                ios_base::openmode which = ios_base::out | ios_base::in); // C++20
231    template <class SAlloc>
232    basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
233        : basic_stringstream(s, ios_base::out | ios_base::in, a) {}                       // C++20
234    template <class SAlloc>
235    basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s,
236                       ios_base::openmode which, const allocator_type& a);                // C++20
237    template <class SAlloc>
238    explicit basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s,
239                                ios_base::openmode which = ios_base::out | ios_base::in); // C++20
240    basic_stringstream(basic_stringstream&& rhs);
241
242    // [stringstream.assign] Assign and swap:
243    basic_stringstream& operator=(basic_stringstream&& rhs);
244    void swap(basic_stringstream& rhs);
245
246    // [stringstream.members] Member functions:
247    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
248    basic_string<char_type, traits_type, allocator_type> str() const;                     // before C++20
249    basic_string<char_type, traits_type, allocator_type> str() const &;                   // C++20
250    template <class SAlloc>
251    basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const;             // C++20
252    basic_string<char_type, traits_type, allocator_type> str() &&;                        // C++20
253    basic_string_view<char_type, traits_type> view() const noexcept;                      // C++20
254    void str(const basic_string<char_type, traits_type, allocator_type>& s);
255    template <class SAlloc>
256    void str(const basic_string<char_type, traits_type, SAlloc>& s);                      // C++20
257    void str(basic_string<char_type, traits_type, allocator_type>&& s);                   // C++20
258};
259
260template <class charT, class traits, class Allocator>
261void swap(basic_stringstream<charT, traits, Allocator>& x,
262          basic_stringstream<charT, traits, Allocator>& y);
263
264typedef basic_stringstream<char>    stringstream;
265typedef basic_stringstream<wchar_t> wstringstream;
266
267}  // std
268
269*/
270
271// clang-format on
272
273#include <__assert> // all public C++ headers provide the assertion handler
274#include <__availability>
275#include <__config>
276#include <__fwd/sstream.h>
277#include <__utility/swap.h>
278#include <istream>
279#include <ostream>
280#include <string>
281#include <version>
282
283#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
284#  pragma GCC system_header
285#endif
286
287_LIBCPP_PUSH_MACROS
288#include <__undef_macros>
289
290
291// TODO(LLVM-19): Remove this once we drop support for Clang 16,
292// which had this bug: https://github.com/llvm/llvm-project/issues/40363
293#ifdef _WIN32
294#define _LIBCPP_HIDE_FROM_ABI_SSTREAM _LIBCPP_ALWAYS_INLINE
295#else
296#define _LIBCPP_HIDE_FROM_ABI_SSTREAM _LIBCPP_HIDE_FROM_ABI
297#endif
298
299_LIBCPP_BEGIN_NAMESPACE_STD
300
301// Class template basic_stringbuf [stringbuf]
302
303template <class _CharT, class _Traits, class _Allocator>
304class _LIBCPP_TEMPLATE_VIS basic_stringbuf
305    : public basic_streambuf<_CharT, _Traits>
306{
307public:
308    typedef _CharT                         char_type;
309    typedef _Traits                        traits_type;
310    typedef typename traits_type::int_type int_type;
311    typedef typename traits_type::pos_type pos_type;
312    typedef typename traits_type::off_type off_type;
313    typedef _Allocator                     allocator_type;
314
315    typedef basic_string<char_type, traits_type, allocator_type> string_type;
316
317private:
318
319    string_type __str_;
320    mutable char_type* __hm_;
321    ios_base::openmode __mode_;
322    _LIBCPP_HIDE_FROM_ABI void __init_buf_ptrs();
323    _LIBCPP_HIDE_FROM_ABI void __move_init(basic_stringbuf&& __rhs);
324
325public:
326    // [stringbuf.cons] constructors:
327    _LIBCPP_HIDE_FROM_ABI
328    basic_stringbuf()
329        : __hm_(nullptr), __mode_(ios_base::in | ios_base::out) {}
330
331    _LIBCPP_HIDE_FROM_ABI
332    explicit basic_stringbuf(ios_base::openmode __wch)
333        : __hm_(nullptr), __mode_(__wch) {}
334
335    _LIBCPP_HIDE_FROM_ABI
336    explicit basic_stringbuf(const string_type& __s,
337                             ios_base::openmode __wch = ios_base::in | ios_base::out)
338        : __str_(__s.get_allocator()), __hm_(nullptr), __mode_(__wch)
339    {
340        str(__s);
341    }
342
343#if _LIBCPP_STD_VER >= 20
344    _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const allocator_type& __a)
345        : basic_stringbuf(ios_base::in | ios_base::out, __a) {}
346
347    _LIBCPP_HIDE_FROM_ABI basic_stringbuf(ios_base::openmode __wch, const allocator_type& __a)
348        : __str_(__a), __hm_(nullptr), __mode_(__wch) {}
349
350    _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(string_type&& __s,
351                                                   ios_base::openmode __wch = ios_base::in | ios_base::out)
352        : __str_(std::move(__s)), __hm_(nullptr), __mode_(__wch) {
353        __init_buf_ptrs();
354    }
355
356    template <class _SAlloc>
357    _LIBCPP_HIDE_FROM_ABI
358    basic_stringbuf(const basic_string<char_type, traits_type, _SAlloc>& __s, const allocator_type& __a)
359        : basic_stringbuf(__s, ios_base::in | ios_base::out, __a) {}
360
361    template <class _SAlloc>
362    _LIBCPP_HIDE_FROM_ABI basic_stringbuf(
363        const basic_string<char_type, traits_type, _SAlloc>& __s, ios_base::openmode __wch, const allocator_type& __a)
364        : __str_(__s, __a), __hm_(nullptr), __mode_(__wch) {
365        __init_buf_ptrs();
366    }
367
368    template <class _SAlloc>
369      requires (!is_same_v<_SAlloc, allocator_type>)
370    _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const basic_string<char_type, traits_type, _SAlloc>& __s,
371                                                   ios_base::openmode __wch = ios_base::in | ios_base::out)
372        : __str_(__s), __hm_(nullptr), __mode_(__wch) {
373        __init_buf_ptrs();
374    }
375#endif // _LIBCPP_STD_VER >= 20
376
377    basic_stringbuf(basic_stringbuf&& __rhs) : __mode_(__rhs.__mode_) { __move_init(std::move(__rhs)); }
378
379#if _LIBCPP_STD_VER >= 20
380    _LIBCPP_HIDE_FROM_ABI basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a)
381        : basic_stringbuf(__rhs.__mode_, __a) {
382        __move_init(std::move(__rhs));
383    }
384#endif
385
386    // [stringbuf.assign] Assign and swap:
387    basic_stringbuf& operator=(basic_stringbuf&& __rhs);
388    void swap(basic_stringbuf& __rhs)
389#if _LIBCPP_STD_VER >= 20
390        noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
391                 allocator_traits<allocator_type>::is_always_equal::value)
392#endif
393        ;
394
395    // [stringbuf.members] Member functions:
396
397#if _LIBCPP_STD_VER >= 20
398    _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
399#endif
400
401#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
402    string_type str() const;
403#else
404    _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return str(__str_.get_allocator()); }
405
406    _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && {
407        const basic_string_view<_CharT, _Traits> __view = view();
408        typename string_type::size_type __pos = __view.empty() ? 0 : __view.data() - __str_.data();
409        // In C++23, this is just string_type(std::move(__str_), __pos, __view.size(), __str_.get_allocator());
410        // But we need something that works in C++20 also.
411        string_type __result(__str_.get_allocator());
412        __result.__move_assign(std::move(__str_), __pos, __view.size());
413        __str_.clear();
414        __init_buf_ptrs();
415        return __result;
416    }
417#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
418
419#if _LIBCPP_STD_VER >= 20
420    template <class _SAlloc>
421      requires __is_allocator<_SAlloc>::value
422    _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
423        return basic_string<_CharT, _Traits, _SAlloc>(view(), __sa);
424    }
425
426    _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept;
427#endif // _LIBCPP_STD_VER >= 20
428
429    void str(const string_type& __s) {
430        __str_ = __s;
431        __init_buf_ptrs();
432    }
433
434#if _LIBCPP_STD_VER >= 20
435    template <class _SAlloc>
436      requires (!is_same_v<_SAlloc, allocator_type>)
437    _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
438        __str_ = __s;
439        __init_buf_ptrs();
440    }
441
442    _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) {
443        __str_ = std::move(__s);
444        __init_buf_ptrs();
445    }
446#endif // _LIBCPP_STD_VER >= 20
447
448protected:
449    // [stringbuf.virtuals] Overridden virtual functions:
450    int_type underflow() override;
451    int_type pbackfail(int_type __c = traits_type::eof()) override;
452    int_type overflow (int_type __c = traits_type::eof()) override;
453    pos_type seekoff(off_type __off, ios_base::seekdir __way,
454                     ios_base::openmode __wch = ios_base::in | ios_base::out) override;
455    _LIBCPP_HIDE_FROM_ABI_VIRTUAL
456    pos_type seekpos(pos_type __sp,
457                     ios_base::openmode __wch = ios_base::in | ios_base::out) override {
458        return seekoff(__sp, ios_base::beg, __wch);
459    }
460};
461
462template <class _CharT, class _Traits, class _Allocator>
463_LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__move_init(basic_stringbuf&& __rhs) {
464    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
465    ptrdiff_t __binp = -1;
466    ptrdiff_t __ninp = -1;
467    ptrdiff_t __einp = -1;
468    if (__rhs.eback() != nullptr)
469    {
470        __binp = __rhs.eback() - __p;
471        __ninp = __rhs.gptr() - __p;
472        __einp = __rhs.egptr() - __p;
473    }
474    ptrdiff_t __bout = -1;
475    ptrdiff_t __nout = -1;
476    ptrdiff_t __eout = -1;
477    if (__rhs.pbase() != nullptr)
478    {
479        __bout = __rhs.pbase() - __p;
480        __nout = __rhs.pptr() - __p;
481        __eout = __rhs.epptr() - __p;
482    }
483    ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
484    __str_ = std::move(__rhs.__str_);
485    __p = const_cast<char_type*>(__str_.data());
486    if (__binp != -1)
487        this->setg(__p + __binp, __p + __ninp, __p + __einp);
488    if (__bout != -1)
489    {
490        this->setp(__p + __bout, __p + __eout);
491        this->__pbump(__nout);
492    }
493    __hm_ = __hm == -1 ? nullptr : __p + __hm;
494    __p = const_cast<char_type*>(__rhs.__str_.data());
495    __rhs.setg(__p, __p, __p);
496    __rhs.setp(__p, __p);
497    __rhs.__hm_ = __p;
498    this->pubimbue(__rhs.getloc());
499}
500
501template <class _CharT, class _Traits, class _Allocator>
502basic_stringbuf<_CharT, _Traits, _Allocator>&
503basic_stringbuf<_CharT, _Traits, _Allocator>::operator=(basic_stringbuf&& __rhs)
504{
505    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
506    ptrdiff_t __binp = -1;
507    ptrdiff_t __ninp = -1;
508    ptrdiff_t __einp = -1;
509    if (__rhs.eback() != nullptr)
510    {
511        __binp = __rhs.eback() - __p;
512        __ninp = __rhs.gptr() - __p;
513        __einp = __rhs.egptr() - __p;
514    }
515    ptrdiff_t __bout = -1;
516    ptrdiff_t __nout = -1;
517    ptrdiff_t __eout = -1;
518    if (__rhs.pbase() != nullptr)
519    {
520        __bout = __rhs.pbase() - __p;
521        __nout = __rhs.pptr() - __p;
522        __eout = __rhs.epptr() - __p;
523    }
524    ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
525    __str_ = std::move(__rhs.__str_);
526    __p = const_cast<char_type*>(__str_.data());
527    if (__binp != -1)
528        this->setg(__p + __binp, __p + __ninp, __p + __einp);
529    else
530        this->setg(nullptr, nullptr, nullptr);
531    if (__bout != -1)
532    {
533        this->setp(__p + __bout, __p + __eout);
534        this->__pbump(__nout);
535    }
536    else
537        this->setp(nullptr, nullptr);
538
539    __hm_ = __hm == -1 ? nullptr : __p + __hm;
540    __mode_ = __rhs.__mode_;
541    __p = const_cast<char_type*>(__rhs.__str_.data());
542    __rhs.setg(__p, __p, __p);
543    __rhs.setp(__p, __p);
544    __rhs.__hm_ = __p;
545    this->pubimbue(__rhs.getloc());
546    return *this;
547}
548
549template <class _CharT, class _Traits, class _Allocator>
550void
551basic_stringbuf<_CharT, _Traits, _Allocator>::swap(basic_stringbuf& __rhs)
552#if _LIBCPP_STD_VER >= 20
553    noexcept(allocator_traits<_Allocator>::propagate_on_container_swap::value ||
554             allocator_traits<_Allocator>::is_always_equal::value)
555#endif
556{
557    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
558    ptrdiff_t __rbinp = -1;
559    ptrdiff_t __rninp = -1;
560    ptrdiff_t __reinp = -1;
561    if (__rhs.eback() != nullptr)
562    {
563        __rbinp = __rhs.eback() - __p;
564        __rninp = __rhs.gptr() - __p;
565        __reinp = __rhs.egptr() - __p;
566    }
567    ptrdiff_t __rbout = -1;
568    ptrdiff_t __rnout = -1;
569    ptrdiff_t __reout = -1;
570    if (__rhs.pbase() != nullptr)
571    {
572        __rbout = __rhs.pbase() - __p;
573        __rnout = __rhs.pptr() - __p;
574        __reout = __rhs.epptr() - __p;
575    }
576    ptrdiff_t __rhm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
577    __p = const_cast<char_type*>(__str_.data());
578    ptrdiff_t __lbinp = -1;
579    ptrdiff_t __lninp = -1;
580    ptrdiff_t __leinp = -1;
581    if (this->eback() != nullptr)
582    {
583        __lbinp = this->eback() - __p;
584        __lninp = this->gptr() - __p;
585        __leinp = this->egptr() - __p;
586    }
587    ptrdiff_t __lbout = -1;
588    ptrdiff_t __lnout = -1;
589    ptrdiff_t __leout = -1;
590    if (this->pbase() != nullptr)
591    {
592        __lbout = this->pbase() - __p;
593        __lnout = this->pptr() - __p;
594        __leout = this->epptr() - __p;
595    }
596    ptrdiff_t __lhm = __hm_ == nullptr ? -1 : __hm_ - __p;
597    std::swap(__mode_, __rhs.__mode_);
598    __str_.swap(__rhs.__str_);
599    __p = const_cast<char_type*>(__str_.data());
600    if (__rbinp != -1)
601        this->setg(__p + __rbinp, __p + __rninp, __p + __reinp);
602    else
603        this->setg(nullptr, nullptr, nullptr);
604    if (__rbout != -1)
605    {
606        this->setp(__p + __rbout, __p + __reout);
607        this->__pbump(__rnout);
608    }
609    else
610        this->setp(nullptr, nullptr);
611    __hm_ = __rhm == -1 ? nullptr : __p + __rhm;
612    __p = const_cast<char_type*>(__rhs.__str_.data());
613    if (__lbinp != -1)
614        __rhs.setg(__p + __lbinp, __p + __lninp, __p + __leinp);
615    else
616        __rhs.setg(nullptr, nullptr, nullptr);
617    if (__lbout != -1)
618    {
619        __rhs.setp(__p + __lbout, __p + __leout);
620        __rhs.__pbump(__lnout);
621    }
622    else
623        __rhs.setp(nullptr, nullptr);
624    __rhs.__hm_ = __lhm == -1 ? nullptr : __p + __lhm;
625    locale __tl = __rhs.getloc();
626    __rhs.pubimbue(this->getloc());
627    this->pubimbue(__tl);
628}
629
630template <class _CharT, class _Traits, class _Allocator>
631inline _LIBCPP_HIDE_FROM_ABI
632void
633swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
634     basic_stringbuf<_CharT, _Traits, _Allocator>& __y)
635#if _LIBCPP_STD_VER >= 20
636    noexcept(noexcept(__x.swap(__y)))
637#endif
638{
639    __x.swap(__y);
640}
641
642#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
643template <class _CharT, class _Traits, class _Allocator>
644basic_string<_CharT, _Traits, _Allocator>
645basic_stringbuf<_CharT, _Traits, _Allocator>::str() const {
646    if (__mode_ & ios_base::out) {
647        if (__hm_ < this->pptr())
648            __hm_ = this->pptr();
649        return string_type(this->pbase(), __hm_, __str_.get_allocator());
650    } else if (__mode_ & ios_base::in)
651        return string_type(this->eback(), this->egptr(), __str_.get_allocator());
652    return string_type(__str_.get_allocator());
653}
654#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
655
656template <class _CharT, class _Traits, class _Allocator>
657_LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__init_buf_ptrs() {
658    __hm_ = nullptr;
659    char_type* __data = const_cast<char_type*>(__str_.data());
660    typename string_type::size_type __sz = __str_.size();
661    if (__mode_ & ios_base::in) {
662        __hm_ = __data + __sz;
663        this->setg(__data, __data, __hm_);
664    }
665    if (__mode_ & ios_base::out) {
666        __hm_ = __data + __sz;
667        __str_.resize(__str_.capacity());
668        this->setp(__data, __data + __str_.size());
669        if (__mode_ & (ios_base::app | ios_base::ate)) {
670            while (__sz > INT_MAX) {
671                this->pbump(INT_MAX);
672                __sz -= INT_MAX;
673            }
674            if (__sz > 0)
675                this->pbump(__sz);
676        }
677    }
678}
679
680#if _LIBCPP_STD_VER >= 20
681template <class _CharT, class _Traits, class _Allocator>
682_LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT, _Traits>
683basic_stringbuf<_CharT, _Traits, _Allocator>::view() const noexcept {
684    if (__mode_ & ios_base::out) {
685        if (__hm_ < this->pptr())
686            __hm_ = this->pptr();
687        return basic_string_view<_CharT, _Traits>(this->pbase(), __hm_);
688    } else if (__mode_ & ios_base::in)
689        return basic_string_view<_CharT, _Traits>(this->eback(), this->egptr());
690    return basic_string_view<_CharT, _Traits>();
691}
692#endif // _LIBCPP_STD_VER >= 20
693
694template <class _CharT, class _Traits, class _Allocator>
695typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
696basic_stringbuf<_CharT, _Traits, _Allocator>::underflow()
697{
698    if (__hm_ < this->pptr())
699        __hm_ = this->pptr();
700    if (__mode_ & ios_base::in)
701    {
702        if (this->egptr() < __hm_)
703            this->setg(this->eback(), this->gptr(), __hm_);
704        if (this->gptr() < this->egptr())
705            return traits_type::to_int_type(*this->gptr());
706    }
707    return traits_type::eof();
708}
709
710template <class _CharT, class _Traits, class _Allocator>
711typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
712basic_stringbuf<_CharT, _Traits, _Allocator>::pbackfail(int_type __c)
713{
714    if (__hm_ < this->pptr())
715        __hm_ = this->pptr();
716    if (this->eback() < this->gptr())
717    {
718        if (traits_type::eq_int_type(__c, traits_type::eof()))
719        {
720            this->setg(this->eback(), this->gptr()-1, __hm_);
721            return traits_type::not_eof(__c);
722        }
723        if ((__mode_ & ios_base::out) ||
724            traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
725        {
726            this->setg(this->eback(), this->gptr()-1, __hm_);
727            *this->gptr() = traits_type::to_char_type(__c);
728            return __c;
729        }
730    }
731    return traits_type::eof();
732}
733
734template <class _CharT, class _Traits, class _Allocator>
735typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
736basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c)
737{
738    if (!traits_type::eq_int_type(__c, traits_type::eof()))
739    {
740        ptrdiff_t __ninp = this->gptr() - this->eback();
741        if (this->pptr() == this->epptr())
742        {
743            if (!(__mode_ & ios_base::out))
744                return traits_type::eof();
745#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
746            try
747            {
748#endif // _LIBCPP_HAS_NO_EXCEPTIONS
749                ptrdiff_t __nout = this->pptr() - this->pbase();
750                ptrdiff_t __hm = __hm_ - this->pbase();
751                __str_.push_back(char_type());
752                __str_.resize(__str_.capacity());
753                char_type* __p = const_cast<char_type*>(__str_.data());
754                this->setp(__p, __p + __str_.size());
755                this->__pbump(__nout);
756                __hm_ = this->pbase() + __hm;
757#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
758            }
759            catch (...)
760            {
761                return traits_type::eof();
762            }
763#endif // _LIBCPP_HAS_NO_EXCEPTIONS
764        }
765        __hm_ = std::max(this->pptr() + 1, __hm_);
766        if (__mode_ & ios_base::in)
767        {
768            char_type* __p = const_cast<char_type*>(__str_.data());
769            this->setg(__p, __p + __ninp, __hm_);
770        }
771        return this->sputc(traits_type::to_char_type(__c));
772    }
773    return traits_type::not_eof(__c);
774}
775
776template <class _CharT, class _Traits, class _Allocator>
777typename basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type
778basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off,
779                                                      ios_base::seekdir __way,
780                                                      ios_base::openmode __wch)
781{
782    if (__hm_ < this->pptr())
783        __hm_ = this->pptr();
784    if ((__wch & (ios_base::in | ios_base::out)) == 0)
785        return pos_type(-1);
786    if ((__wch & (ios_base::in | ios_base::out)) == (ios_base::in | ios_base::out)
787        && __way == ios_base::cur)
788        return pos_type(-1);
789    const ptrdiff_t __hm = __hm_ == nullptr ? 0 : __hm_ - __str_.data();
790    off_type __noff;
791    switch (__way)
792    {
793    case ios_base::beg:
794        __noff = 0;
795        break;
796    case ios_base::cur:
797        if (__wch & ios_base::in)
798            __noff = this->gptr() - this->eback();
799        else
800            __noff = this->pptr() - this->pbase();
801        break;
802    case ios_base::end:
803        __noff = __hm;
804        break;
805    default:
806        return pos_type(-1);
807    }
808    __noff += __off;
809    if (__noff < 0 || __hm < __noff)
810        return pos_type(-1);
811    if (__noff != 0)
812    {
813        if ((__wch & ios_base::in) && this->gptr() == nullptr)
814            return pos_type(-1);
815        if ((__wch & ios_base::out) && this->pptr() == nullptr)
816            return pos_type(-1);
817    }
818    if (__wch & ios_base::in)
819        this->setg(this->eback(), this->eback() + __noff, __hm_);
820    if (__wch & ios_base::out)
821    {
822        this->setp(this->pbase(), this->epptr());
823        this->__pbump(__noff);
824    }
825    return pos_type(__noff);
826}
827
828// Class template basic_istringstream [istringstream]
829
830template <class _CharT, class _Traits, class _Allocator>
831class _LIBCPP_TEMPLATE_VIS basic_istringstream
832    : public basic_istream<_CharT, _Traits>
833{
834public:
835    typedef _CharT                         char_type;
836    typedef _Traits                        traits_type;
837    typedef typename traits_type::int_type int_type;
838    typedef typename traits_type::pos_type pos_type;
839    typedef typename traits_type::off_type off_type;
840    typedef _Allocator                     allocator_type;
841
842    typedef basic_string<char_type, traits_type, allocator_type> string_type;
843
844private:
845    basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
846
847public:
848    // [istringstream.cons] Constructors:
849    _LIBCPP_HIDE_FROM_ABI
850    basic_istringstream()
851        : basic_istream<_CharT, _Traits>(&__sb_), __sb_(ios_base::in) {}
852
853    _LIBCPP_HIDE_FROM_ABI
854    explicit basic_istringstream(ios_base::openmode __wch)
855        : basic_istream<_CharT, _Traits>(&__sb_), __sb_(__wch | ios_base::in) {}
856
857    _LIBCPP_HIDE_FROM_ABI
858    explicit basic_istringstream(const string_type& __s,
859                                 ios_base::openmode __wch = ios_base::in)
860        : basic_istream<_CharT, _Traits>(&__sb_)
861        , __sb_(__s, __wch | ios_base::in)
862    { }
863
864#if _LIBCPP_STD_VER >= 20
865    _LIBCPP_HIDE_FROM_ABI basic_istringstream(ios_base::openmode __wch, const _Allocator& __a)
866        : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::in, __a) {}
867
868    _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(string_type&& __s, ios_base::openmode __wch = ios_base::in)
869        : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch | ios_base::in) {}
870
871    template <class _SAlloc>
872    _LIBCPP_HIDE_FROM_ABI basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
873        : basic_istringstream(__s, ios_base::in, __a) {}
874
875    template <class _SAlloc>
876    _LIBCPP_HIDE_FROM_ABI basic_istringstream(
877        const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
878        : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in, __a) {}
879
880    template <class _SAlloc>
881    _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
882                                                       ios_base::openmode __wch = ios_base::in)
883        : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in) {}
884#endif // _LIBCPP_STD_VER >= 20
885
886    _LIBCPP_HIDE_FROM_ABI
887    basic_istringstream(basic_istringstream&& __rhs)
888        : basic_istream<_CharT, _Traits>(std::move(__rhs))
889        , __sb_(std::move(__rhs.__sb_))
890    {
891        basic_istream<_CharT, _Traits>::set_rdbuf(&__sb_);
892    }
893
894    // [istringstream.assign] Assign and swap:
895    basic_istringstream& operator=(basic_istringstream&& __rhs) {
896        basic_istream<char_type, traits_type>::operator=(std::move(__rhs));
897        __sb_ = std::move(__rhs.__sb_);
898        return *this;
899    }
900    _LIBCPP_HIDE_FROM_ABI
901    void swap(basic_istringstream& __rhs) {
902        basic_istream<char_type, traits_type>::swap(__rhs);
903        __sb_.swap(__rhs.__sb_);
904    }
905
906    // [istringstream.members] Member functions:
907    _LIBCPP_HIDE_FROM_ABI
908    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
909        return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
910    }
911
912#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
913    _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
914#else
915    _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return __sb_.str(); }
916
917    _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && { return std::move(__sb_).str(); }
918#endif
919
920#if _LIBCPP_STD_VER >= 20
921    template <class _SAlloc>
922      requires __is_allocator<_SAlloc>::value
923    _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
924        return __sb_.str(__sa);
925    }
926
927    _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
928#endif // _LIBCPP_STD_VER >= 20
929
930    _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
931
932#if _LIBCPP_STD_VER >= 20
933    template <class _SAlloc>
934    _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
935        __sb_.str(__s);
936    }
937
938    _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
939#endif // _LIBCPP_STD_VER >= 20
940};
941
942template <class _CharT, class _Traits, class _Allocator>
943inline _LIBCPP_HIDE_FROM_ABI
944void
945swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x,
946     basic_istringstream<_CharT, _Traits, _Allocator>& __y)
947{
948    __x.swap(__y);
949}
950
951// Class template basic_ostringstream [ostringstream]
952
953template <class _CharT, class _Traits, class _Allocator>
954class _LIBCPP_TEMPLATE_VIS basic_ostringstream
955    : public basic_ostream<_CharT, _Traits>
956{
957public:
958    typedef _CharT                         char_type;
959    typedef _Traits                        traits_type;
960    typedef typename traits_type::int_type int_type;
961    typedef typename traits_type::pos_type pos_type;
962    typedef typename traits_type::off_type off_type;
963    typedef _Allocator                     allocator_type;
964
965    typedef basic_string<char_type, traits_type, allocator_type> string_type;
966
967private:
968    basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
969
970public:
971    // [ostringstream.cons] Constructors:
972    _LIBCPP_HIDE_FROM_ABI
973    basic_ostringstream()
974        : basic_ostream<_CharT, _Traits>(&__sb_), __sb_(ios_base::out) {}
975
976    _LIBCPP_HIDE_FROM_ABI
977    explicit basic_ostringstream(ios_base::openmode __wch)
978        : basic_ostream<_CharT, _Traits>(&__sb_), __sb_(__wch | ios_base::out) {}
979
980    _LIBCPP_HIDE_FROM_ABI
981    explicit basic_ostringstream(const string_type& __s,
982                                 ios_base::openmode __wch = ios_base::out)
983        : basic_ostream<_CharT, _Traits>(&__sb_)
984        , __sb_(__s, __wch | ios_base::out)
985    { }
986
987#if _LIBCPP_STD_VER >= 20
988    _LIBCPP_HIDE_FROM_ABI basic_ostringstream(ios_base::openmode __wch, const _Allocator& __a)
989        : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::out, __a) {}
990
991    _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(string_type&& __s, ios_base::openmode __wch = ios_base::out)
992        : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch | ios_base::out) {}
993
994    template <class _SAlloc>
995    _LIBCPP_HIDE_FROM_ABI basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
996        : basic_ostringstream(__s, ios_base::out, __a) {}
997
998    template <class _SAlloc>
999    _LIBCPP_HIDE_FROM_ABI basic_ostringstream(
1000        const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
1001        : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::out, __a) {}
1002
1003    template <class _SAlloc>
1004      requires (!is_same_v<_SAlloc, allocator_type>)
1005    _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
1006                                                       ios_base::openmode __wch = ios_base::out)
1007        : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::out) {}
1008#endif // _LIBCPP_STD_VER >= 20
1009
1010    _LIBCPP_HIDE_FROM_ABI
1011    basic_ostringstream(basic_ostringstream&& __rhs)
1012        : basic_ostream<_CharT, _Traits>(std::move(__rhs))
1013        , __sb_(std::move(__rhs.__sb_))
1014    {
1015        basic_ostream<_CharT, _Traits>::set_rdbuf(&__sb_);
1016    }
1017
1018    // [ostringstream.assign] Assign and swap:
1019    basic_ostringstream& operator=(basic_ostringstream&& __rhs) {
1020        basic_ostream<char_type, traits_type>::operator=(std::move(__rhs));
1021        __sb_ = std::move(__rhs.__sb_);
1022        return *this;
1023    }
1024
1025    _LIBCPP_HIDE_FROM_ABI
1026    void swap(basic_ostringstream& __rhs) {
1027        basic_ostream<char_type, traits_type>::swap(__rhs);
1028        __sb_.swap(__rhs.__sb_);
1029    }
1030
1031    // [ostringstream.members] Member functions:
1032    _LIBCPP_HIDE_FROM_ABI
1033    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
1034        return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
1035    }
1036
1037#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
1038    _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
1039#else
1040    _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return __sb_.str(); }
1041
1042    _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && { return std::move(__sb_).str(); }
1043#endif
1044
1045#if _LIBCPP_STD_VER >= 20
1046    template <class _SAlloc>
1047      requires __is_allocator<_SAlloc>::value
1048    _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
1049        return __sb_.str(__sa);
1050    }
1051
1052    _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
1053#endif // _LIBCPP_STD_VER >= 20
1054
1055    _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
1056
1057#if _LIBCPP_STD_VER >= 20
1058    template <class _SAlloc>
1059    _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
1060        __sb_.str(__s);
1061    }
1062
1063    _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
1064#endif // _LIBCPP_STD_VER >= 20
1065};
1066
1067template <class _CharT, class _Traits, class _Allocator>
1068inline _LIBCPP_HIDE_FROM_ABI
1069void
1070swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x,
1071     basic_ostringstream<_CharT, _Traits, _Allocator>& __y)
1072{
1073    __x.swap(__y);
1074}
1075
1076// Class template basic_stringstream [stringstream]
1077
1078template <class _CharT, class _Traits, class _Allocator>
1079class _LIBCPP_TEMPLATE_VIS basic_stringstream
1080    : public basic_iostream<_CharT, _Traits>
1081{
1082public:
1083    typedef _CharT                         char_type;
1084    typedef _Traits                        traits_type;
1085    typedef typename traits_type::int_type int_type;
1086    typedef typename traits_type::pos_type pos_type;
1087    typedef typename traits_type::off_type off_type;
1088    typedef _Allocator                     allocator_type;
1089
1090    typedef basic_string<char_type, traits_type, allocator_type> string_type;
1091
1092private:
1093    basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
1094
1095public:
1096    // [stringstream.cons] constructors
1097    _LIBCPP_HIDE_FROM_ABI
1098    basic_stringstream()
1099        : basic_iostream<_CharT, _Traits>(&__sb_), __sb_(ios_base::in | ios_base::out) {}
1100
1101    _LIBCPP_HIDE_FROM_ABI
1102    explicit basic_stringstream(ios_base::openmode __wch)
1103        : basic_iostream<_CharT, _Traits>(&__sb_), __sb_(__wch) {}
1104
1105    _LIBCPP_HIDE_FROM_ABI
1106    explicit basic_stringstream(const string_type& __s,
1107                                ios_base::openmode __wch = ios_base::in | ios_base::out)
1108        : basic_iostream<_CharT, _Traits>(&__sb_)
1109        , __sb_(__s, __wch)
1110    { }
1111
1112#if _LIBCPP_STD_VER >= 20
1113    _LIBCPP_HIDE_FROM_ABI basic_stringstream(ios_base::openmode __wch, const _Allocator& __a)
1114        : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch, __a) {}
1115
1116    _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(string_type&& __s, ios_base::openmode __wch = ios_base::out | ios_base::in)
1117        : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch) {}
1118
1119    template <class _SAlloc>
1120    _LIBCPP_HIDE_FROM_ABI basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
1121        : basic_stringstream(__s, ios_base::out | ios_base::in, __a) {}
1122
1123    template <class _SAlloc>
1124    _LIBCPP_HIDE_FROM_ABI basic_stringstream(
1125        const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
1126        : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch, __a) {}
1127
1128    template <class _SAlloc>
1129      requires (!is_same_v<_SAlloc, allocator_type>)
1130    _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
1131                                                      ios_base::openmode __wch = ios_base::out | ios_base::in)
1132        : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch) {}
1133#endif // _LIBCPP_STD_VER >= 20
1134
1135    _LIBCPP_HIDE_FROM_ABI
1136    basic_stringstream(basic_stringstream&& __rhs)
1137        : basic_iostream<_CharT, _Traits>(std::move(__rhs))
1138        , __sb_(std::move(__rhs.__sb_))
1139    {
1140        basic_istream<_CharT, _Traits>::set_rdbuf(&__sb_);
1141    }
1142
1143    // [stringstream.assign] Assign and swap:
1144    basic_stringstream& operator=(basic_stringstream&& __rhs) {
1145        basic_iostream<char_type, traits_type>::operator=(std::move(__rhs));
1146        __sb_ = std::move(__rhs.__sb_);
1147        return *this;
1148    }
1149    _LIBCPP_HIDE_FROM_ABI
1150    void swap(basic_stringstream& __rhs) {
1151        basic_iostream<char_type, traits_type>::swap(__rhs);
1152        __sb_.swap(__rhs.__sb_);
1153    }
1154
1155    // [stringstream.members] Member functions:
1156    _LIBCPP_HIDE_FROM_ABI
1157    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
1158        return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
1159    }
1160
1161#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
1162    _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
1163#else
1164    _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return __sb_.str(); }
1165
1166    _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && { return std::move(__sb_).str(); }
1167#endif
1168
1169#if _LIBCPP_STD_VER >= 20
1170    template <class _SAlloc>
1171      requires __is_allocator<_SAlloc>::value
1172    _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
1173        return __sb_.str(__sa);
1174    }
1175
1176    _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
1177#endif // _LIBCPP_STD_VER >= 20
1178
1179    _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
1180
1181#if _LIBCPP_STD_VER >= 20
1182    template <class _SAlloc>
1183    _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
1184        __sb_.str(__s);
1185    }
1186
1187    _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
1188#endif // _LIBCPP_STD_VER >= 20
1189};
1190
1191template <class _CharT, class _Traits, class _Allocator>
1192inline _LIBCPP_HIDE_FROM_ABI
1193void
1194swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x,
1195     basic_stringstream<_CharT, _Traits, _Allocator>& __y)
1196{
1197    __x.swap(__y);
1198}
1199
1200#if _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
1201extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringbuf<char>;
1202extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringstream<char>;
1203extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostringstream<char>;
1204extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istringstream<char>;
1205#endif
1206
1207_LIBCPP_END_NAMESPACE_STD
1208
1209_LIBCPP_POP_MACROS
1210
1211#if _LIBCPP_STD_VER <= 20 && !defined(_LIPCPP_REMOVE_TRANSITIVE_INCLUDES)
1212#  include <type_traits>
1213#endif
1214
1215#endif // _LIBCPP_SSTREAM
1216