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/*
14    sstream synopsis
15
16template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
17class basic_stringbuf
18    : public basic_streambuf<charT, traits>
19{
20public:
21    typedef charT                          char_type;
22    typedef traits                         traits_type;
23    typedef typename traits_type::int_type int_type;
24    typedef typename traits_type::pos_type pos_type;
25    typedef typename traits_type::off_type off_type;
26    typedef Allocator                      allocator_type;
27
28    // 27.8.1.1 [stringbuf.cons], constructors:
29    explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out); // before C++20
30    basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {}               // C++20
31    explicit basic_stringbuf(ios_base::openmode which);                                // C++20
32    explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& str,
33                             ios_base::openmode which = ios_base::in | ios_base::out);
34    basic_stringbuf(basic_stringbuf&& rhs);
35
36    // 27.8.1.2 Assign and swap:
37    basic_stringbuf& operator=(basic_stringbuf&& rhs);
38    void swap(basic_stringbuf& rhs);
39
40    // 27.8.1.3 Get and set:
41    basic_string<char_type, traits_type, allocator_type> str() const;
42    void str(const basic_string<char_type, traits_type, allocator_type>& s);
43
44protected:
45    // 27.8.1.4 Overridden virtual functions:
46    virtual int_type underflow();
47    virtual int_type pbackfail(int_type c = traits_type::eof());
48    virtual int_type overflow (int_type c = traits_type::eof());
49    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type*, streamsize);
50    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
51                             ios_base::openmode which = ios_base::in | ios_base::out);
52    virtual pos_type seekpos(pos_type sp,
53                             ios_base::openmode which = ios_base::in | ios_base::out);
54};
55
56template <class charT, class traits, class Allocator>
57  void swap(basic_stringbuf<charT, traits, Allocator>& x,
58            basic_stringbuf<charT, traits, Allocator>& y);
59
60typedef basic_stringbuf<char>    stringbuf;
61typedef basic_stringbuf<wchar_t> wstringbuf;
62
63template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
64class basic_istringstream
65    : public basic_istream<charT, traits>
66{
67public:
68    typedef charT                          char_type;
69    typedef traits                         traits_type;
70    typedef typename traits_type::int_type int_type;
71    typedef typename traits_type::pos_type pos_type;
72    typedef typename traits_type::off_type off_type;
73    typedef Allocator                      allocator_type;
74
75    // 27.8.2.1 Constructors:
76    explicit basic_istringstream(ios_base::openmode which = ios_base::in); // before C++20
77    basic_istringstream() : basic_istringstream(ios_base::in) {}           // C++20
78    explicit basic_istringstream(ios_base::openmode which);                // C++20
79
80    explicit basic_istringstream(const basic_string<char_type, traits_type,allocator_type>& str,
81                                 ios_base::openmode which = ios_base::in);
82    basic_istringstream(basic_istringstream&& rhs);
83
84    // 27.8.2.2 Assign and swap:
85    basic_istringstream& operator=(basic_istringstream&& rhs);
86    void swap(basic_istringstream& rhs);
87
88    // 27.8.2.3 Members:
89    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
90    basic_string<char_type, traits_type, allocator_type> str() const;
91    void str(const basic_string<char_type, traits_type, allocator_type>& s);
92};
93
94template <class charT, class traits, class Allocator>
95  void swap(basic_istringstream<charT, traits, Allocator>& x,
96            basic_istringstream<charT, traits, Allocator>& y);
97
98typedef basic_istringstream<char>    istringstream;
99typedef basic_istringstream<wchar_t> wistringstream;
100
101template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
102class basic_ostringstream
103    : public basic_ostream<charT, traits>
104{
105public:
106    // types:
107    typedef charT                          char_type;
108    typedef traits                         traits_type;
109    typedef typename traits_type::int_type int_type;
110    typedef typename traits_type::pos_type pos_type;
111    typedef typename traits_type::off_type off_type;
112    typedef Allocator                      allocator_type;
113
114    // 27.8.3.1 Constructors/destructor:
115    explicit basic_ostringstream(ios_base::openmode which = ios_base::out); // before C++20
116    basic_ostringstream() : basic_ostringstream(ios_base::out) {}           // C++20
117    explicit basic_ostringstream(ios_base::openmode which);                 // C++20
118
119    explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type>& str,
120                                 ios_base::openmode which = ios_base::out);
121    basic_ostringstream(basic_ostringstream&& rhs);
122
123    // 27.8.3.2 Assign/swap:
124    basic_ostringstream& operator=(basic_ostringstream&& rhs);
125    void swap(basic_ostringstream& rhs);
126
127    // 27.8.3.3 Members:
128    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
129    basic_string<char_type, traits_type, allocator_type> str() const;
130    void str(const basic_string<char_type, traits_type, allocator_type>& s);
131};
132
133template <class charT, class traits, class Allocator>
134  void swap(basic_ostringstream<charT, traits, Allocator>& x,
135            basic_ostringstream<charT, traits, Allocator>& y);
136
137typedef basic_ostringstream<char>    ostringstream;
138typedef basic_ostringstream<wchar_t> wostringstream;
139
140template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
141class basic_stringstream
142    : public basic_iostream<charT, traits>
143{
144public:
145    // types:
146    typedef charT                          char_type;
147    typedef traits                         traits_type;
148    typedef typename traits_type::int_type int_type;
149    typedef typename traits_type::pos_type pos_type;
150    typedef typename traits_type::off_type off_type;
151    typedef Allocator                      allocator_type;
152
153    // constructors/destructor
154    explicit basic_stringstream(ios_base::openmode which = ios_base::out | ios_base::in); // before C++20
155    basic_stringstream() : basic_stringstream(ios_base::out | ios_base::in) {}            // C++20
156    explicit basic_stringstream(ios_base::openmode which);                                // C++20
157
158    explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type>& str,
159                                ios_base::openmode which = ios_base::out|ios_base::in);
160    basic_stringstream(basic_stringstream&& rhs);
161
162    // 27.8.5.1 Assign/swap:
163    basic_stringstream& operator=(basic_stringstream&& rhs);
164    void swap(basic_stringstream& rhs);
165
166    // Members:
167    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
168    basic_string<char_type, traits_type, allocator_type> str() const;
169    void str(const basic_string<char_type, traits_type, allocator_type>& str);
170};
171
172template <class charT, class traits, class Allocator>
173  void swap(basic_stringstream<charT, traits, Allocator>& x,
174            basic_stringstream<charT, traits, Allocator>& y);
175
176typedef basic_stringstream<char>    stringstream;
177typedef basic_stringstream<wchar_t> wstringstream;
178
179}  // std
180
181*/
182
183#include <__config>
184#include <__utility/swap.h>
185#include <istream>
186#include <ostream>
187#include <string>
188#include <version>
189
190#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
191#  pragma GCC system_header
192#endif
193
194_LIBCPP_PUSH_MACROS
195#include <__undef_macros>
196
197
198_LIBCPP_BEGIN_NAMESPACE_STD
199
200// basic_stringbuf
201
202template <class _CharT, class _Traits, class _Allocator>
203class _LIBCPP_TEMPLATE_VIS basic_stringbuf
204    : public basic_streambuf<_CharT, _Traits>
205{
206public:
207    typedef _CharT                         char_type;
208    typedef _Traits                        traits_type;
209    typedef typename traits_type::int_type int_type;
210    typedef typename traits_type::pos_type pos_type;
211    typedef typename traits_type::off_type off_type;
212    typedef _Allocator                     allocator_type;
213
214    typedef basic_string<char_type, traits_type, allocator_type> string_type;
215
216private:
217
218    string_type __str_;
219    mutable char_type* __hm_;
220    ios_base::openmode __mode_;
221
222public:
223    // 30.8.2.1 [stringbuf.cons], constructors
224    _LIBCPP_INLINE_VISIBILITY
225    basic_stringbuf()
226        : __hm_(nullptr), __mode_(ios_base::in | ios_base::out) {}
227
228    _LIBCPP_INLINE_VISIBILITY
229    explicit basic_stringbuf(ios_base::openmode __wch)
230        : __hm_(nullptr), __mode_(__wch) {}
231
232    _LIBCPP_INLINE_VISIBILITY
233    explicit basic_stringbuf(const string_type& __s,
234                             ios_base::openmode __wch = ios_base::in | ios_base::out)
235        : __str_(__s.get_allocator()), __hm_(nullptr), __mode_(__wch)
236    {
237        str(__s);
238    }
239
240    basic_stringbuf(basic_stringbuf&& __rhs);
241
242    // 27.8.1.2 Assign and swap:
243    basic_stringbuf& operator=(basic_stringbuf&& __rhs);
244    void swap(basic_stringbuf& __rhs);
245
246    // 27.8.1.3 Get and set:
247    string_type str() const;
248    void str(const string_type& __s);
249
250protected:
251    // 27.8.1.4 Overridden virtual functions:
252    virtual int_type underflow();
253    virtual int_type pbackfail(int_type __c = traits_type::eof());
254    virtual int_type overflow (int_type __c = traits_type::eof());
255    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
256                             ios_base::openmode __wch = ios_base::in | ios_base::out);
257    _LIBCPP_INLINE_VISIBILITY
258    virtual pos_type seekpos(pos_type __sp,
259                             ios_base::openmode __wch = ios_base::in | ios_base::out) {
260        return seekoff(__sp, ios_base::beg, __wch);
261    }
262};
263
264template <class _CharT, class _Traits, class _Allocator>
265basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(basic_stringbuf&& __rhs)
266    : __mode_(__rhs.__mode_)
267{
268    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
269    ptrdiff_t __binp = -1;
270    ptrdiff_t __ninp = -1;
271    ptrdiff_t __einp = -1;
272    if (__rhs.eback() != nullptr)
273    {
274        __binp = __rhs.eback() - __p;
275        __ninp = __rhs.gptr() - __p;
276        __einp = __rhs.egptr() - __p;
277    }
278    ptrdiff_t __bout = -1;
279    ptrdiff_t __nout = -1;
280    ptrdiff_t __eout = -1;
281    if (__rhs.pbase() != nullptr)
282    {
283        __bout = __rhs.pbase() - __p;
284        __nout = __rhs.pptr() - __p;
285        __eout = __rhs.epptr() - __p;
286    }
287    ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
288    __str_ = _VSTD::move(__rhs.__str_);
289    __p = const_cast<char_type*>(__str_.data());
290    if (__binp != -1)
291        this->setg(__p + __binp, __p + __ninp, __p + __einp);
292    if (__bout != -1)
293    {
294        this->setp(__p + __bout, __p + __eout);
295        this->__pbump(__nout);
296    }
297    __hm_ = __hm == -1 ? nullptr : __p + __hm;
298    __p = const_cast<char_type*>(__rhs.__str_.data());
299    __rhs.setg(__p, __p, __p);
300    __rhs.setp(__p, __p);
301    __rhs.__hm_ = __p;
302    this->pubimbue(__rhs.getloc());
303}
304
305template <class _CharT, class _Traits, class _Allocator>
306basic_stringbuf<_CharT, _Traits, _Allocator>&
307basic_stringbuf<_CharT, _Traits, _Allocator>::operator=(basic_stringbuf&& __rhs)
308{
309    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
310    ptrdiff_t __binp = -1;
311    ptrdiff_t __ninp = -1;
312    ptrdiff_t __einp = -1;
313    if (__rhs.eback() != nullptr)
314    {
315        __binp = __rhs.eback() - __p;
316        __ninp = __rhs.gptr() - __p;
317        __einp = __rhs.egptr() - __p;
318    }
319    ptrdiff_t __bout = -1;
320    ptrdiff_t __nout = -1;
321    ptrdiff_t __eout = -1;
322    if (__rhs.pbase() != nullptr)
323    {
324        __bout = __rhs.pbase() - __p;
325        __nout = __rhs.pptr() - __p;
326        __eout = __rhs.epptr() - __p;
327    }
328    ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
329    __str_ = _VSTD::move(__rhs.__str_);
330    __p = const_cast<char_type*>(__str_.data());
331    if (__binp != -1)
332        this->setg(__p + __binp, __p + __ninp, __p + __einp);
333    else
334        this->setg(nullptr, nullptr, nullptr);
335    if (__bout != -1)
336    {
337        this->setp(__p + __bout, __p + __eout);
338        this->__pbump(__nout);
339    }
340    else
341        this->setp(nullptr, nullptr);
342
343    __hm_ = __hm == -1 ? nullptr : __p + __hm;
344    __mode_ = __rhs.__mode_;
345    __p = const_cast<char_type*>(__rhs.__str_.data());
346    __rhs.setg(__p, __p, __p);
347    __rhs.setp(__p, __p);
348    __rhs.__hm_ = __p;
349    this->pubimbue(__rhs.getloc());
350    return *this;
351}
352
353template <class _CharT, class _Traits, class _Allocator>
354void
355basic_stringbuf<_CharT, _Traits, _Allocator>::swap(basic_stringbuf& __rhs)
356{
357    char_type* __p = const_cast<char_type*>(__rhs.__str_.data());
358    ptrdiff_t __rbinp = -1;
359    ptrdiff_t __rninp = -1;
360    ptrdiff_t __reinp = -1;
361    if (__rhs.eback() != nullptr)
362    {
363        __rbinp = __rhs.eback() - __p;
364        __rninp = __rhs.gptr() - __p;
365        __reinp = __rhs.egptr() - __p;
366    }
367    ptrdiff_t __rbout = -1;
368    ptrdiff_t __rnout = -1;
369    ptrdiff_t __reout = -1;
370    if (__rhs.pbase() != nullptr)
371    {
372        __rbout = __rhs.pbase() - __p;
373        __rnout = __rhs.pptr() - __p;
374        __reout = __rhs.epptr() - __p;
375    }
376    ptrdiff_t __rhm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
377    __p = const_cast<char_type*>(__str_.data());
378    ptrdiff_t __lbinp = -1;
379    ptrdiff_t __lninp = -1;
380    ptrdiff_t __leinp = -1;
381    if (this->eback() != nullptr)
382    {
383        __lbinp = this->eback() - __p;
384        __lninp = this->gptr() - __p;
385        __leinp = this->egptr() - __p;
386    }
387    ptrdiff_t __lbout = -1;
388    ptrdiff_t __lnout = -1;
389    ptrdiff_t __leout = -1;
390    if (this->pbase() != nullptr)
391    {
392        __lbout = this->pbase() - __p;
393        __lnout = this->pptr() - __p;
394        __leout = this->epptr() - __p;
395    }
396    ptrdiff_t __lhm = __hm_ == nullptr ? -1 : __hm_ - __p;
397    _VSTD::swap(__mode_, __rhs.__mode_);
398    __str_.swap(__rhs.__str_);
399    __p = const_cast<char_type*>(__str_.data());
400    if (__rbinp != -1)
401        this->setg(__p + __rbinp, __p + __rninp, __p + __reinp);
402    else
403        this->setg(nullptr, nullptr, nullptr);
404    if (__rbout != -1)
405    {
406        this->setp(__p + __rbout, __p + __reout);
407        this->__pbump(__rnout);
408    }
409    else
410        this->setp(nullptr, nullptr);
411    __hm_ = __rhm == -1 ? nullptr : __p + __rhm;
412    __p = const_cast<char_type*>(__rhs.__str_.data());
413    if (__lbinp != -1)
414        __rhs.setg(__p + __lbinp, __p + __lninp, __p + __leinp);
415    else
416        __rhs.setg(nullptr, nullptr, nullptr);
417    if (__lbout != -1)
418    {
419        __rhs.setp(__p + __lbout, __p + __leout);
420        __rhs.__pbump(__lnout);
421    }
422    else
423        __rhs.setp(nullptr, nullptr);
424    __rhs.__hm_ = __lhm == -1 ? nullptr : __p + __lhm;
425    locale __tl = __rhs.getloc();
426    __rhs.pubimbue(this->getloc());
427    this->pubimbue(__tl);
428}
429
430template <class _CharT, class _Traits, class _Allocator>
431inline _LIBCPP_INLINE_VISIBILITY
432void
433swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
434     basic_stringbuf<_CharT, _Traits, _Allocator>& __y)
435{
436    __x.swap(__y);
437}
438
439template <class _CharT, class _Traits, class _Allocator>
440basic_string<_CharT, _Traits, _Allocator>
441basic_stringbuf<_CharT, _Traits, _Allocator>::str() const
442{
443    if (__mode_ & ios_base::out)
444    {
445        if (__hm_ < this->pptr())
446            __hm_ = this->pptr();
447        return string_type(this->pbase(), __hm_, __str_.get_allocator());
448    }
449    else if (__mode_ & ios_base::in)
450        return string_type(this->eback(), this->egptr(), __str_.get_allocator());
451    return string_type(__str_.get_allocator());
452}
453
454template <class _CharT, class _Traits, class _Allocator>
455void
456basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s)
457{
458    __str_ = __s;
459    __hm_ = nullptr;
460    if (__mode_ & ios_base::in)
461    {
462        __hm_ = const_cast<char_type*>(__str_.data()) + __str_.size();
463        this->setg(const_cast<char_type*>(__str_.data()),
464                   const_cast<char_type*>(__str_.data()),
465                   __hm_);
466    }
467    if (__mode_ & ios_base::out)
468    {
469        typename string_type::size_type __sz = __str_.size();
470        __hm_ = const_cast<char_type*>(__str_.data()) + __sz;
471        __str_.resize(__str_.capacity());
472        this->setp(const_cast<char_type*>(__str_.data()),
473                   const_cast<char_type*>(__str_.data()) + __str_.size());
474        if (__mode_ & (ios_base::app | ios_base::ate))
475        {
476            while (__sz > INT_MAX)
477            {
478                this->pbump(INT_MAX);
479                __sz -= INT_MAX;
480            }
481            if (__sz > 0)
482                this->pbump(__sz);
483        }
484    }
485}
486
487template <class _CharT, class _Traits, class _Allocator>
488typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
489basic_stringbuf<_CharT, _Traits, _Allocator>::underflow()
490{
491    if (__hm_ < this->pptr())
492        __hm_ = this->pptr();
493    if (__mode_ & ios_base::in)
494    {
495        if (this->egptr() < __hm_)
496            this->setg(this->eback(), this->gptr(), __hm_);
497        if (this->gptr() < this->egptr())
498            return traits_type::to_int_type(*this->gptr());
499    }
500    return traits_type::eof();
501}
502
503template <class _CharT, class _Traits, class _Allocator>
504typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
505basic_stringbuf<_CharT, _Traits, _Allocator>::pbackfail(int_type __c)
506{
507    if (__hm_ < this->pptr())
508        __hm_ = this->pptr();
509    if (this->eback() < this->gptr())
510    {
511        if (traits_type::eq_int_type(__c, traits_type::eof()))
512        {
513            this->setg(this->eback(), this->gptr()-1, __hm_);
514            return traits_type::not_eof(__c);
515        }
516        if ((__mode_ & ios_base::out) ||
517            traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
518        {
519            this->setg(this->eback(), this->gptr()-1, __hm_);
520            *this->gptr() = traits_type::to_char_type(__c);
521            return __c;
522        }
523    }
524    return traits_type::eof();
525}
526
527template <class _CharT, class _Traits, class _Allocator>
528typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
529basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c)
530{
531    if (!traits_type::eq_int_type(__c, traits_type::eof()))
532    {
533        ptrdiff_t __ninp = this->gptr()  - this->eback();
534        if (this->pptr() == this->epptr())
535        {
536            if (!(__mode_ & ios_base::out))
537                return traits_type::eof();
538#ifndef _LIBCPP_NO_EXCEPTIONS
539            try
540            {
541#endif // _LIBCPP_NO_EXCEPTIONS
542                ptrdiff_t __nout = this->pptr()  - this->pbase();
543                ptrdiff_t __hm = __hm_ - this->pbase();
544                __str_.push_back(char_type());
545                __str_.resize(__str_.capacity());
546                char_type* __p = const_cast<char_type*>(__str_.data());
547                this->setp(__p, __p + __str_.size());
548                this->__pbump(__nout);
549                __hm_ = this->pbase() + __hm;
550#ifndef _LIBCPP_NO_EXCEPTIONS
551            }
552            catch (...)
553            {
554                return traits_type::eof();
555            }
556#endif // _LIBCPP_NO_EXCEPTIONS
557        }
558        __hm_ = _VSTD::max(this->pptr() + 1, __hm_);
559        if (__mode_ & ios_base::in)
560        {
561            char_type* __p = const_cast<char_type*>(__str_.data());
562            this->setg(__p, __p + __ninp, __hm_);
563        }
564        return this->sputc(traits_type::to_char_type(__c));
565    }
566    return traits_type::not_eof(__c);
567}
568
569template <class _CharT, class _Traits, class _Allocator>
570typename basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type
571basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off,
572                                                      ios_base::seekdir __way,
573                                                      ios_base::openmode __wch)
574{
575    if (__hm_ < this->pptr())
576        __hm_ = this->pptr();
577    if ((__wch & (ios_base::in | ios_base::out)) == 0)
578        return pos_type(-1);
579    if ((__wch & (ios_base::in | ios_base::out)) == (ios_base::in | ios_base::out)
580        && __way == ios_base::cur)
581        return pos_type(-1);
582    const ptrdiff_t __hm = __hm_ == nullptr ? 0 : __hm_ - __str_.data();
583    off_type __noff;
584    switch (__way)
585    {
586    case ios_base::beg:
587        __noff = 0;
588        break;
589    case ios_base::cur:
590        if (__wch & ios_base::in)
591            __noff = this->gptr() - this->eback();
592        else
593            __noff = this->pptr() - this->pbase();
594        break;
595    case ios_base::end:
596        __noff = __hm;
597        break;
598    default:
599        return pos_type(-1);
600    }
601    __noff += __off;
602    if (__noff < 0 || __hm < __noff)
603        return pos_type(-1);
604    if (__noff != 0)
605    {
606        if ((__wch & ios_base::in) && this->gptr() == nullptr)
607            return pos_type(-1);
608        if ((__wch & ios_base::out) && this->pptr() == nullptr)
609            return pos_type(-1);
610    }
611    if (__wch & ios_base::in)
612        this->setg(this->eback(), this->eback() + __noff, __hm_);
613    if (__wch & ios_base::out)
614    {
615        this->setp(this->pbase(), this->epptr());
616        this->pbump(__noff);
617    }
618    return pos_type(__noff);
619}
620
621// basic_istringstream
622
623template <class _CharT, class _Traits, class _Allocator>
624class _LIBCPP_TEMPLATE_VIS basic_istringstream
625    : public basic_istream<_CharT, _Traits>
626{
627public:
628    typedef _CharT                         char_type;
629    typedef _Traits                        traits_type;
630    typedef typename traits_type::int_type int_type;
631    typedef typename traits_type::pos_type pos_type;
632    typedef typename traits_type::off_type off_type;
633    typedef _Allocator                     allocator_type;
634
635    typedef basic_string<char_type, traits_type, allocator_type> string_type;
636
637private:
638    basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
639
640public:
641    // 30.8.3.1 [istringstream.cons], constructors
642    _LIBCPP_INLINE_VISIBILITY
643    basic_istringstream()
644        : basic_istream<_CharT, _Traits>(&__sb_), __sb_(ios_base::in) {}
645
646    _LIBCPP_INLINE_VISIBILITY
647    explicit basic_istringstream(ios_base::openmode __wch)
648        : basic_istream<_CharT, _Traits>(&__sb_), __sb_(__wch | ios_base::in) {}
649
650    _LIBCPP_INLINE_VISIBILITY
651    explicit basic_istringstream(const string_type& __s,
652                                 ios_base::openmode __wch = ios_base::in)
653        : basic_istream<_CharT, _Traits>(&__sb_)
654        , __sb_(__s, __wch | ios_base::in)
655    { }
656
657    _LIBCPP_INLINE_VISIBILITY
658    basic_istringstream(basic_istringstream&& __rhs)
659        : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs))
660        , __sb_(_VSTD::move(__rhs.__sb_))
661    {
662        basic_istream<_CharT, _Traits>::set_rdbuf(&__sb_);
663    }
664
665    // 27.8.2.2 Assign and swap:
666    basic_istringstream& operator=(basic_istringstream&& __rhs) {
667        basic_istream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
668        __sb_ = _VSTD::move(__rhs.__sb_);
669        return *this;
670    }
671    _LIBCPP_INLINE_VISIBILITY
672    void swap(basic_istringstream& __rhs) {
673        basic_istream<char_type, traits_type>::swap(__rhs);
674        __sb_.swap(__rhs.__sb_);
675    }
676
677    // 27.8.2.3 Members:
678    _LIBCPP_INLINE_VISIBILITY
679    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
680        return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
681    }
682    _LIBCPP_INLINE_VISIBILITY
683    string_type str() const {
684        return __sb_.str();
685    }
686    _LIBCPP_INLINE_VISIBILITY
687    void str(const string_type& __s) {
688        __sb_.str(__s);
689    }
690};
691
692template <class _CharT, class _Traits, class _Allocator>
693inline _LIBCPP_INLINE_VISIBILITY
694void
695swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x,
696     basic_istringstream<_CharT, _Traits, _Allocator>& __y)
697{
698    __x.swap(__y);
699}
700
701// basic_ostringstream
702
703template <class _CharT, class _Traits, class _Allocator>
704class _LIBCPP_TEMPLATE_VIS basic_ostringstream
705    : public basic_ostream<_CharT, _Traits>
706{
707public:
708    typedef _CharT                         char_type;
709    typedef _Traits                        traits_type;
710    typedef typename traits_type::int_type int_type;
711    typedef typename traits_type::pos_type pos_type;
712    typedef typename traits_type::off_type off_type;
713    typedef _Allocator                     allocator_type;
714
715    typedef basic_string<char_type, traits_type, allocator_type> string_type;
716
717private:
718    basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
719
720public:
721    // 30.8.4.1 [ostringstream.cons], constructors
722    _LIBCPP_INLINE_VISIBILITY
723    basic_ostringstream()
724        : basic_ostream<_CharT, _Traits>(&__sb_), __sb_(ios_base::out) {}
725
726    _LIBCPP_INLINE_VISIBILITY
727    explicit basic_ostringstream(ios_base::openmode __wch)
728        : basic_ostream<_CharT, _Traits>(&__sb_), __sb_(__wch | ios_base::out) {}
729
730    _LIBCPP_INLINE_VISIBILITY
731    explicit basic_ostringstream(const string_type& __s,
732                                 ios_base::openmode __wch = ios_base::out)
733        : basic_ostream<_CharT, _Traits>(&__sb_)
734        , __sb_(__s, __wch | ios_base::out)
735    { }
736
737    _LIBCPP_INLINE_VISIBILITY
738    basic_ostringstream(basic_ostringstream&& __rhs)
739        : basic_ostream<_CharT, _Traits>(_VSTD::move(__rhs))
740        , __sb_(_VSTD::move(__rhs.__sb_))
741    {
742        basic_ostream<_CharT, _Traits>::set_rdbuf(&__sb_);
743    }
744
745    // 27.8.2.2 Assign and swap:
746    basic_ostringstream& operator=(basic_ostringstream&& __rhs) {
747        basic_ostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
748        __sb_ = _VSTD::move(__rhs.__sb_);
749        return *this;
750    }
751
752    _LIBCPP_INLINE_VISIBILITY
753    void swap(basic_ostringstream& __rhs) {
754        basic_ostream<char_type, traits_type>::swap(__rhs);
755        __sb_.swap(__rhs.__sb_);
756    }
757
758    // 27.8.2.3 Members:
759    _LIBCPP_INLINE_VISIBILITY
760    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
761        return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
762    }
763    _LIBCPP_INLINE_VISIBILITY
764    string_type str() const {
765        return __sb_.str();
766    }
767    _LIBCPP_INLINE_VISIBILITY
768    void str(const string_type& __s) {
769        __sb_.str(__s);
770    }
771};
772
773template <class _CharT, class _Traits, class _Allocator>
774inline _LIBCPP_INLINE_VISIBILITY
775void
776swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x,
777     basic_ostringstream<_CharT, _Traits, _Allocator>& __y)
778{
779    __x.swap(__y);
780}
781
782// basic_stringstream
783
784template <class _CharT, class _Traits, class _Allocator>
785class _LIBCPP_TEMPLATE_VIS basic_stringstream
786    : public basic_iostream<_CharT, _Traits>
787{
788public:
789    typedef _CharT                         char_type;
790    typedef _Traits                        traits_type;
791    typedef typename traits_type::int_type int_type;
792    typedef typename traits_type::pos_type pos_type;
793    typedef typename traits_type::off_type off_type;
794    typedef _Allocator                     allocator_type;
795
796    typedef basic_string<char_type, traits_type, allocator_type> string_type;
797
798private:
799    basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
800
801public:
802    // 30.8.5.1 [stringstream.cons], constructors
803    _LIBCPP_INLINE_VISIBILITY
804    basic_stringstream()
805        : basic_iostream<_CharT, _Traits>(&__sb_), __sb_(ios_base::in | ios_base::out) {}
806
807    _LIBCPP_INLINE_VISIBILITY
808    explicit basic_stringstream(ios_base::openmode __wch)
809        : basic_iostream<_CharT, _Traits>(&__sb_), __sb_(__wch) {}
810
811    _LIBCPP_INLINE_VISIBILITY
812    explicit basic_stringstream(const string_type& __s,
813                                ios_base::openmode __wch = ios_base::in | ios_base::out)
814        : basic_iostream<_CharT, _Traits>(&__sb_)
815        , __sb_(__s, __wch)
816    { }
817
818    _LIBCPP_INLINE_VISIBILITY
819    basic_stringstream(basic_stringstream&& __rhs)
820        : basic_iostream<_CharT, _Traits>(_VSTD::move(__rhs))
821        , __sb_(_VSTD::move(__rhs.__sb_))
822    {
823        basic_istream<_CharT, _Traits>::set_rdbuf(&__sb_);
824    }
825
826    // 27.8.2.2 Assign and swap:
827    basic_stringstream& operator=(basic_stringstream&& __rhs) {
828        basic_iostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
829        __sb_ = _VSTD::move(__rhs.__sb_);
830        return *this;
831    }
832    _LIBCPP_INLINE_VISIBILITY
833    void swap(basic_stringstream& __rhs) {
834        basic_iostream<char_type, traits_type>::swap(__rhs);
835        __sb_.swap(__rhs.__sb_);
836    }
837
838    // 27.8.2.3 Members:
839    _LIBCPP_INLINE_VISIBILITY
840    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
841        return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_);
842    }
843    _LIBCPP_INLINE_VISIBILITY
844    string_type str() const {
845        return __sb_.str();
846    }
847    _LIBCPP_INLINE_VISIBILITY
848    void str(const string_type& __s) {
849        __sb_.str(__s);
850    }
851};
852
853template <class _CharT, class _Traits, class _Allocator>
854inline _LIBCPP_INLINE_VISIBILITY
855void
856swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x,
857     basic_stringstream<_CharT, _Traits, _Allocator>& __y)
858{
859    __x.swap(__y);
860}
861
862#if defined(_LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1)
863_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringbuf<char>)
864_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringstream<char>)
865_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostringstream<char>)
866_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istringstream<char>)
867#endif
868
869_LIBCPP_END_NAMESPACE_STD
870
871_LIBCPP_POP_MACROS
872
873#endif // _LIBCPP_SSTREAM
874