// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___CXX03_SSTREAM
#define _LIBCPP___CXX03_SSTREAM

// clang-format off

/*
    sstream synopsis [sstream.syn]

// Class template basic_stringbuf [stringbuf]
template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
class basic_stringbuf
    : public basic_streambuf<charT, traits>
{
public:
    typedef charT                          char_type;
    typedef traits                         traits_type;
    typedef typename traits_type::int_type int_type;
    typedef typename traits_type::pos_type pos_type;
    typedef typename traits_type::off_type off_type;
    typedef Allocator                      allocator_type;

    // [stringbuf.cons] constructors:
    explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out); // before C++20
    basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {}               // C++20
    explicit basic_stringbuf(ios_base::openmode which);                                // C++20
    explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& s,
                             ios_base::openmode which = ios_base::in | ios_base::out);
    explicit basic_stringbuf(const allocator_type& a)
        : basic_stringbuf(ios_base::in | ios_base::out, a) {}                          // C++20
    basic_stringbuf(ios_base::openmode which, const allocator_type& a);                // C++20
    explicit basic_stringbuf(basic_string<char_type, traits_type, allocator_type>&& s,
                             ios_base::openmode which = ios_base::in | ios_base::out); // C++20
    template <class SAlloc>
    basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
        : basic_stringbuf(s, ios_base::in | ios_base::out, a) {}                       // C++20
    template <class SAlloc>
    basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s,
                    ios_base::openmode which, const allocator_type& a);                // C++20
    template <class SAlloc>
    explicit basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s,
                             ios_base::openmode which = ios_base::in | ios_base::out); // C++20
    template<class T>
      explicit basic_stringbuf(const T& t,
                               ios_base::openmode which = ios_base::in | ios_base::out); // Since C++26
    template<class T>
      basic_stringbuf(const T& t, const Allocator& a);                                   // Since C++26
    template<class T>
      basic_stringbuf(const T& t, ios_base::openmode which, const Allocator& a);         // Since C++26
    basic_stringbuf(const basic_stringbuf&) = delete;
    basic_stringbuf(basic_stringbuf&& rhs);
    basic_stringbuf(basic_stringbuf&& rhs, const allocator_type& a);                   // C++20

    // [stringbuf.assign] Assign and swap:
    basic_stringbuf& operator=(const basic_stringbuf&) = delete;
    basic_stringbuf& operator=(basic_stringbuf&& rhs);
    void swap(basic_stringbuf& rhs) noexcept(see below);                               // conditionally noexcept since C++20

    // [stringbuf.members] Member functions:
    allocator_type get_allocator() const noexcept;                                     // C++20
    basic_string<char_type, traits_type, allocator_type> str() const;                  // before C++20
    basic_string<char_type, traits_type, allocator_type> str() const &;                // C++20
    template <class SAlloc>
    basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const;          // C++20
    basic_string<char_type, traits_type, allocator_type> str() &&;                     // C++20
    basic_string_view<char_type, traits_type> view() const noexcept;                   // C++20
    void str(const basic_string<char_type, traits_type, allocator_type>& s);
    template <class SAlloc>
    void str(const basic_string<char_type, traits_type, SAlloc>& s);                   // C++20
    void str(basic_string<char_type, traits_type, allocator_type>&& s);                // C++20
    template<class T>
      void str(const T& t);                                                            // Since C++26

protected:
    // [stringbuf.virtuals] Overridden virtual functions:
    virtual int_type underflow();
    virtual int_type pbackfail(int_type c = traits_type::eof());
    virtual int_type overflow (int_type c = traits_type::eof());
    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type*, streamsize);
    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
                             ios_base::openmode which = ios_base::in | ios_base::out);
    virtual pos_type seekpos(pos_type sp,
                             ios_base::openmode which = ios_base::in | ios_base::out);
};

// [stringbuf.assign] non member swap
template <class charT, class traits, class Allocator>
void swap(basic_stringbuf<charT, traits, Allocator>& x,
          basic_stringbuf<charT, traits, Allocator>& y); // conditionally noexcept since C++20

typedef basic_stringbuf<char>    stringbuf;
typedef basic_stringbuf<wchar_t> wstringbuf;

// Class template basic_istringstream [istringstream]
template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
class basic_istringstream
    : public basic_istream<charT, traits>
{
public:
    typedef charT                          char_type;
    typedef traits                         traits_type;
    typedef typename traits_type::int_type int_type;
    typedef typename traits_type::pos_type pos_type;
    typedef typename traits_type::off_type off_type;
    typedef Allocator                      allocator_type;

    // [istringstream.cons] Constructors:
    explicit basic_istringstream(ios_base::openmode which = ios_base::in);             // before C++20
    basic_istringstream() : basic_istringstream(ios_base::in) {}                       // C++20
    explicit basic_istringstream(ios_base::openmode which);                            // C++20
    explicit basic_istringstream(const basic_string<char_type, traits_type, allocator_type>& s,
                                 ios_base::openmode which = ios_base::in);
    basic_istringstream(ios_base::openmode which, const allocator_type& a);            // C++20
    explicit basic_istringstream(basic_string<char_type, traits_type, allocator_type>&& s,
                                 ios_base::openmode which = ios_base::in);             // C++20
    template <class SAlloc>
    basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
        : basic_istringstream(s, ios_base::in, a) {}                                   // C++20
    template <class SAlloc>
    basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s,
                        ios_base::openmode which, const allocator_type& a);            // C++20
    template <class SAlloc>
    explicit basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s,
                                 ios_base::openmode which = ios_base::in);             // C++20
    template<class T>
      explicit basic_istringstream(const T& t, ios_base::openmode which = ios_base::in); // Since C++26
    template<class T>
      basic_istringstream(const T& t, const Allocator& a);                               // Since C++26
    template<class T>
      basic_istringstream(const T& t, ios_base::openmode which, const Allocator& a);     // Since C++26
    basic_istringstream(const basic_istringstream&) = delete;
    basic_istringstream(basic_istringstream&& rhs);

    // [istringstream.assign] Assign and swap:
    basic_istringstream& operator=(const basic_istringstream&) = delete;
    basic_istringstream& operator=(basic_istringstream&& rhs);
    void swap(basic_istringstream& rhs);

    // [istringstream.members] Member functions:
    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
    basic_string<char_type, traits_type, allocator_type> str() const;                  // before C++20
    basic_string<char_type, traits_type, allocator_type> str() const &;                // C++20
    template <class SAlloc>
    basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const;          // C++20
    basic_string<char_type, traits_type, allocator_type> str() &&;                     // C++20
    basic_string_view<char_type, traits_type> view() const noexcept;                   // C++20
    void str(const basic_string<char_type, traits_type, allocator_type>& s);
    template <class SAlloc>
    void str(const basic_string<char_type, traits_type, SAlloc>& s);                   // C++20
    void str(basic_string<char_type, traits_type, allocator_type>&& s);                // C++20
    template<class T>
      void str(const T& t);                                                            // Since C++26
};

template <class charT, class traits, class Allocator>
void swap(basic_istringstream<charT, traits, Allocator>& x,
          basic_istringstream<charT, traits, Allocator>& y);

typedef basic_istringstream<char>    istringstream;
typedef basic_istringstream<wchar_t> wistringstream;

// Class template basic_ostringstream [ostringstream]
template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
class basic_ostringstream
    : public basic_ostream<charT, traits>
{
public:
    // types:
    typedef charT                          char_type;
    typedef traits                         traits_type;
    typedef typename traits_type::int_type int_type;
    typedef typename traits_type::pos_type pos_type;
    typedef typename traits_type::off_type off_type;
    typedef Allocator                      allocator_type;

    // [ostringstream.cons] Constructors:
    explicit basic_ostringstream(ios_base::openmode which = ios_base::out);            // before C++20
    basic_ostringstream() : basic_ostringstream(ios_base::out) {}                      // C++20
    explicit basic_ostringstream(ios_base::openmode which);                            // C++20
    explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type>& s,
                                 ios_base::openmode which = ios_base::out);
    basic_ostringstream(ios_base::openmode which, const allocator_type& a);            // C++20
    explicit basic_ostringstream(basic_string<char_type, traits_type, allocator_type>&& s,
                                 ios_base::openmode which = ios_base::out);            // C++20
    template <class SAlloc>
    basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
        : basic_ostringstream(s, ios_base::out, a) {}                                  // C++20
    template <class SAlloc>
    basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s,
                        ios_base::openmode which, const allocator_type& a);            // C++20
    template <class SAlloc>
    explicit basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s,
                                 ios_base::openmode which = ios_base::out);            // C++20
    template<class T>
      explicit basic_ostringstream(const T& t, ios_base::openmode which = ios_base::out); // Since C++26
    template<class T>
      basic_ostringstream(const T& t, const Allocator& a);                                // Since C++26
    template<class T>
      basic_ostringstream(const T& t, ios_base::openmode which, const Allocator& a);      // Since C++26
    basic_ostringstream(const basic_ostringstream&) = delete;
    basic_ostringstream(basic_ostringstream&& rhs);

    // [ostringstream.assign] Assign and swap:
    basic_ostringstream& operator=(const basic_ostringstream&) = delete;
    basic_ostringstream& operator=(basic_ostringstream&& rhs);
    void swap(basic_ostringstream& rhs);

    // [ostringstream.members] Member functions:
    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
    basic_string<char_type, traits_type, allocator_type> str() const;                  // before C++20
    basic_string<char_type, traits_type, allocator_type> str() const &;                // C++20
    template <class SAlloc>
    basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const;          // C++20
    basic_string<char_type, traits_type, allocator_type> str() &&;                     // C++20
    basic_string_view<char_type, traits_type> view() const noexcept;                   // C++20
    void str(const basic_string<char_type, traits_type, allocator_type>& s);
    template <class SAlloc>
    void str(const basic_string<char_type, traits_type, SAlloc>& s);                   // C++20
    void str(basic_string<char_type, traits_type, allocator_type>&& s);                // C++20
    template<class T>
      void str(const T& t);                                                            // Since C++26
};

template <class charT, class traits, class Allocator>
void swap(basic_ostringstream<charT, traits, Allocator>& x,
          basic_ostringstream<charT, traits, Allocator>& y);

typedef basic_ostringstream<char>    ostringstream;
typedef basic_ostringstream<wchar_t> wostringstream;

// Class template basic_stringstream [stringstream]
template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
class basic_stringstream
    : public basic_iostream<charT, traits>
{
public:
    // types:
    typedef charT                          char_type;
    typedef traits                         traits_type;
    typedef typename traits_type::int_type int_type;
    typedef typename traits_type::pos_type pos_type;
    typedef typename traits_type::off_type off_type;
    typedef Allocator                      allocator_type;

    // [stringstream.cons] constructors
    explicit basic_stringstream(ios_base::openmode which = ios_base::out | ios_base::in); // before C++20
    basic_stringstream() : basic_stringstream(ios_base::out | ios_base::in) {}            // C++20
    explicit basic_stringstream(ios_base::openmode which);                                // C++20
    explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type>& s,
                                ios_base::openmode which = ios_base::out | ios_base::in);
    basic_stringstream(ios_base::openmode which, const allocator_type& a);                // C++20
    explicit basic_stringstream(basic_string<char_type, traits_type, allocator_type>&& s,
                                ios_base::openmode which = ios_base::out | ios_base::in); // C++20
    template <class SAlloc>
    basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a)
        : basic_stringstream(s, ios_base::out | ios_base::in, a) {}                       // C++20
    template <class SAlloc>
    basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s,
                       ios_base::openmode which, const allocator_type& a);                // C++20
    template <class SAlloc>
    explicit basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s,
                                ios_base::openmode which = ios_base::out | ios_base::in); // C++20
    template<class T>
      explicit basic_stringstream(const T& t,
                                  ios_base::openmode which = ios_base::out | ios_base::in); // Since C++26
    template<class T>
      basic_stringstream(const T& t, const Allocator& a);                                   // Since C++26
    template<class T>
      basic_stringstream(const T& t, ios_base::openmode which, const Allocator& a);         // Since C++26
    basic_stringstream(const basic_stringstream&) = delete;
    basic_stringstream(basic_stringstream&& rhs);

    // [stringstream.assign] Assign and swap:
    basic_stringstream& operator=(const basic_stringstream&) = delete;
    basic_stringstream& operator=(basic_stringstream&& rhs);
    void swap(basic_stringstream& rhs);

    // [stringstream.members] Member functions:
    basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const;
    basic_string<char_type, traits_type, allocator_type> str() const;                     // before C++20
    basic_string<char_type, traits_type, allocator_type> str() const &;                   // C++20
    template <class SAlloc>
    basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const;             // C++20
    basic_string<char_type, traits_type, allocator_type> str() &&;                        // C++20
    basic_string_view<char_type, traits_type> view() const noexcept;                      // C++20
    void str(const basic_string<char_type, traits_type, allocator_type>& s);
    template <class SAlloc>
    void str(const basic_string<char_type, traits_type, SAlloc>& s);                      // C++20
    void str(basic_string<char_type, traits_type, allocator_type>&& s);                   // C++20
    template<class T>
      void str(const T& t);                                                               // Since C++26
};

template <class charT, class traits, class Allocator>
void swap(basic_stringstream<charT, traits, Allocator>& x,
          basic_stringstream<charT, traits, Allocator>& y);

typedef basic_stringstream<char>    stringstream;
typedef basic_stringstream<wchar_t> wstringstream;

}  // std

*/

// clang-format on

#include <__cxx03/__config>
#include <__cxx03/__fwd/sstream.h>
#include <__cxx03/__ostream/basic_ostream.h>
#include <__cxx03/__type_traits/is_convertible.h>
#include <__cxx03/__utility/swap.h>
#include <__cxx03/istream>
#include <__cxx03/string>
#include <__cxx03/string_view>
#include <__cxx03/version>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__cxx03/__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

// Class template basic_stringbuf [stringbuf]

template <class _CharT, class _Traits, class _Allocator>
class _LIBCPP_TEMPLATE_VIS basic_stringbuf : public basic_streambuf<_CharT, _Traits> {
public:
  typedef _CharT char_type;
  typedef _Traits traits_type;
  typedef typename traits_type::int_type int_type;
  typedef typename traits_type::pos_type pos_type;
  typedef typename traits_type::off_type off_type;
  typedef _Allocator allocator_type;

  typedef basic_string<char_type, traits_type, allocator_type> string_type;

private:
  string_type __str_;
  mutable char_type* __hm_;
  ios_base::openmode __mode_;
  _LIBCPP_HIDE_FROM_ABI void __init_buf_ptrs();
  _LIBCPP_HIDE_FROM_ABI void __move_init(basic_stringbuf&& __rhs);

public:
  // [stringbuf.cons] constructors:
  _LIBCPP_HIDE_FROM_ABI basic_stringbuf() : __hm_(nullptr), __mode_(ios_base::in | ios_base::out) {
    // it is implementation-defined whether we initialize eback() & friends to nullptr, and libc++ doesn't
    __init_buf_ptrs();
  }

  _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(ios_base::openmode __wch) : __hm_(nullptr), __mode_(__wch) {
    // it is implementation-defined whether we initialize eback() & friends to nullptr, and libc++ doesn't
    __init_buf_ptrs();
  }

  _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const string_type& __s,
                                                 ios_base::openmode __wch = ios_base::in | ios_base::out)
      : __str_(__s.get_allocator()), __hm_(nullptr), __mode_(__wch) {
    str(__s);
  }

  basic_stringbuf(const basic_stringbuf&) = delete;
  basic_stringbuf(basic_stringbuf&& __rhs) : __mode_(__rhs.__mode_) { __move_init(std::move(__rhs)); }

  // [stringbuf.assign] Assign and swap:
  basic_stringbuf& operator=(const basic_stringbuf&) = delete;
  basic_stringbuf& operator=(basic_stringbuf&& __rhs);
  void swap(basic_stringbuf& __rhs);

  // [stringbuf.members] Member functions:

  string_type str() const;

  void str(const string_type& __s) {
    __str_ = __s;
    __init_buf_ptrs();
  }

protected:
  // [stringbuf.virtuals] Overridden virtual functions:
  int_type underflow() override;
  int_type pbackfail(int_type __c = traits_type::eof()) override;
  int_type overflow(int_type __c = traits_type::eof()) override;
  pos_type
  seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
  _LIBCPP_HIDE_FROM_ABI_VIRTUAL
  pos_type seekpos(pos_type __sp, ios_base::openmode __wch = ios_base::in | ios_base::out) override {
    return seekoff(__sp, ios_base::beg, __wch);
  }
};

template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__move_init(basic_stringbuf&& __rhs) {
  char_type* __p   = const_cast<char_type*>(__rhs.__str_.data());
  ptrdiff_t __binp = -1;
  ptrdiff_t __ninp = -1;
  ptrdiff_t __einp = -1;
  if (__rhs.eback() != nullptr) {
    __binp = __rhs.eback() - __p;
    __ninp = __rhs.gptr() - __p;
    __einp = __rhs.egptr() - __p;
  }
  ptrdiff_t __bout = -1;
  ptrdiff_t __nout = -1;
  ptrdiff_t __eout = -1;
  if (__rhs.pbase() != nullptr) {
    __bout = __rhs.pbase() - __p;
    __nout = __rhs.pptr() - __p;
    __eout = __rhs.epptr() - __p;
  }
  ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
  __str_         = std::move(__rhs.__str_);
  __p            = const_cast<char_type*>(__str_.data());
  if (__binp != -1)
    this->setg(__p + __binp, __p + __ninp, __p + __einp);
  if (__bout != -1) {
    this->setp(__p + __bout, __p + __eout);
    this->__pbump(__nout);
  }
  __hm_ = __hm == -1 ? nullptr : __p + __hm;
  __p   = const_cast<char_type*>(__rhs.__str_.data());
  __rhs.setg(__p, __p, __p);
  __rhs.setp(__p, __p);
  __rhs.__hm_ = __p;
  this->pubimbue(__rhs.getloc());
}

template <class _CharT, class _Traits, class _Allocator>
basic_stringbuf<_CharT, _Traits, _Allocator>&
basic_stringbuf<_CharT, _Traits, _Allocator>::operator=(basic_stringbuf&& __rhs) {
  char_type* __p   = const_cast<char_type*>(__rhs.__str_.data());
  ptrdiff_t __binp = -1;
  ptrdiff_t __ninp = -1;
  ptrdiff_t __einp = -1;
  if (__rhs.eback() != nullptr) {
    __binp = __rhs.eback() - __p;
    __ninp = __rhs.gptr() - __p;
    __einp = __rhs.egptr() - __p;
  }
  ptrdiff_t __bout = -1;
  ptrdiff_t __nout = -1;
  ptrdiff_t __eout = -1;
  if (__rhs.pbase() != nullptr) {
    __bout = __rhs.pbase() - __p;
    __nout = __rhs.pptr() - __p;
    __eout = __rhs.epptr() - __p;
  }
  ptrdiff_t __hm = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
  __str_         = std::move(__rhs.__str_);
  __p            = const_cast<char_type*>(__str_.data());
  if (__binp != -1)
    this->setg(__p + __binp, __p + __ninp, __p + __einp);
  else
    this->setg(nullptr, nullptr, nullptr);
  if (__bout != -1) {
    this->setp(__p + __bout, __p + __eout);
    this->__pbump(__nout);
  } else
    this->setp(nullptr, nullptr);

  __hm_   = __hm == -1 ? nullptr : __p + __hm;
  __mode_ = __rhs.__mode_;
  __p     = const_cast<char_type*>(__rhs.__str_.data());
  __rhs.setg(__p, __p, __p);
  __rhs.setp(__p, __p);
  __rhs.__hm_ = __p;
  this->pubimbue(__rhs.getloc());
  return *this;
}

template <class _CharT, class _Traits, class _Allocator>
void basic_stringbuf<_CharT, _Traits, _Allocator>::swap(basic_stringbuf& __rhs) {
  char_type* __p    = const_cast<char_type*>(__rhs.__str_.data());
  ptrdiff_t __rbinp = -1;
  ptrdiff_t __rninp = -1;
  ptrdiff_t __reinp = -1;
  if (__rhs.eback() != nullptr) {
    __rbinp = __rhs.eback() - __p;
    __rninp = __rhs.gptr() - __p;
    __reinp = __rhs.egptr() - __p;
  }
  ptrdiff_t __rbout = -1;
  ptrdiff_t __rnout = -1;
  ptrdiff_t __reout = -1;
  if (__rhs.pbase() != nullptr) {
    __rbout = __rhs.pbase() - __p;
    __rnout = __rhs.pptr() - __p;
    __reout = __rhs.epptr() - __p;
  }
  ptrdiff_t __rhm   = __rhs.__hm_ == nullptr ? -1 : __rhs.__hm_ - __p;
  __p               = const_cast<char_type*>(__str_.data());
  ptrdiff_t __lbinp = -1;
  ptrdiff_t __lninp = -1;
  ptrdiff_t __leinp = -1;
  if (this->eback() != nullptr) {
    __lbinp = this->eback() - __p;
    __lninp = this->gptr() - __p;
    __leinp = this->egptr() - __p;
  }
  ptrdiff_t __lbout = -1;
  ptrdiff_t __lnout = -1;
  ptrdiff_t __leout = -1;
  if (this->pbase() != nullptr) {
    __lbout = this->pbase() - __p;
    __lnout = this->pptr() - __p;
    __leout = this->epptr() - __p;
  }
  ptrdiff_t __lhm = __hm_ == nullptr ? -1 : __hm_ - __p;
  std::swap(__mode_, __rhs.__mode_);
  __str_.swap(__rhs.__str_);
  __p = const_cast<char_type*>(__str_.data());
  if (__rbinp != -1)
    this->setg(__p + __rbinp, __p + __rninp, __p + __reinp);
  else
    this->setg(nullptr, nullptr, nullptr);
  if (__rbout != -1) {
    this->setp(__p + __rbout, __p + __reout);
    this->__pbump(__rnout);
  } else
    this->setp(nullptr, nullptr);
  __hm_ = __rhm == -1 ? nullptr : __p + __rhm;
  __p   = const_cast<char_type*>(__rhs.__str_.data());
  if (__lbinp != -1)
    __rhs.setg(__p + __lbinp, __p + __lninp, __p + __leinp);
  else
    __rhs.setg(nullptr, nullptr, nullptr);
  if (__lbout != -1) {
    __rhs.setp(__p + __lbout, __p + __leout);
    __rhs.__pbump(__lnout);
  } else
    __rhs.setp(nullptr, nullptr);
  __rhs.__hm_ = __lhm == -1 ? nullptr : __p + __lhm;
  locale __tl = __rhs.getloc();
  __rhs.pubimbue(this->getloc());
  this->pubimbue(__tl);
}

template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI void
swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x, basic_stringbuf<_CharT, _Traits, _Allocator>& __y) {
  __x.swap(__y);
}

template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator> basic_stringbuf<_CharT, _Traits, _Allocator>::str() const {
  if (__mode_ & ios_base::out) {
    if (__hm_ < this->pptr())
      __hm_ = this->pptr();
    return string_type(this->pbase(), __hm_, __str_.get_allocator());
  } else if (__mode_ & ios_base::in)
    return string_type(this->eback(), this->egptr(), __str_.get_allocator());
  return string_type(__str_.get_allocator());
}

template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__init_buf_ptrs() {
  __hm_                                = nullptr;
  char_type* __data                    = const_cast<char_type*>(__str_.data());
  typename string_type::size_type __sz = __str_.size();
  if (__mode_ & ios_base::in) {
    __hm_ = __data + __sz;
    this->setg(__data, __data, __hm_);
  }
  if (__mode_ & ios_base::out) {
    __hm_ = __data + __sz;
    __str_.resize(__str_.capacity());
    this->setp(__data, __data + __str_.size());
    if (__mode_ & (ios_base::app | ios_base::ate)) {
      while (__sz > INT_MAX) {
        this->pbump(INT_MAX);
        __sz -= INT_MAX;
      }
      if (__sz > 0)
        this->pbump(__sz);
    }
  }
}

template <class _CharT, class _Traits, class _Allocator>
typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
basic_stringbuf<_CharT, _Traits, _Allocator>::underflow() {
  if (__hm_ < this->pptr())
    __hm_ = this->pptr();
  if (__mode_ & ios_base::in) {
    if (this->egptr() < __hm_)
      this->setg(this->eback(), this->gptr(), __hm_);
    if (this->gptr() < this->egptr())
      return traits_type::to_int_type(*this->gptr());
  }
  return traits_type::eof();
}

template <class _CharT, class _Traits, class _Allocator>
typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
basic_stringbuf<_CharT, _Traits, _Allocator>::pbackfail(int_type __c) {
  if (__hm_ < this->pptr())
    __hm_ = this->pptr();
  if (this->eback() < this->gptr()) {
    if (traits_type::eq_int_type(__c, traits_type::eof())) {
      this->setg(this->eback(), this->gptr() - 1, __hm_);
      return traits_type::not_eof(__c);
    }
    if ((__mode_ & ios_base::out) || traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) {
      this->setg(this->eback(), this->gptr() - 1, __hm_);
      *this->gptr() = traits_type::to_char_type(__c);
      return __c;
    }
  }
  return traits_type::eof();
}

template <class _CharT, class _Traits, class _Allocator>
typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type
basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c) {
  if (!traits_type::eq_int_type(__c, traits_type::eof())) {
    ptrdiff_t __ninp = this->gptr() - this->eback();
    if (this->pptr() == this->epptr()) {
      if (!(__mode_ & ios_base::out))
        return traits_type::eof();
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
      try {
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
        ptrdiff_t __nout = this->pptr() - this->pbase();
        ptrdiff_t __hm   = __hm_ - this->pbase();
        __str_.push_back(char_type());
        __str_.resize(__str_.capacity());
        char_type* __p = const_cast<char_type*>(__str_.data());
        this->setp(__p, __p + __str_.size());
        this->__pbump(__nout);
        __hm_ = this->pbase() + __hm;
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
      } catch (...) {
        return traits_type::eof();
      }
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
    }
    __hm_ = std::max(this->pptr() + 1, __hm_);
    if (__mode_ & ios_base::in) {
      char_type* __p = const_cast<char_type*>(__str_.data());
      this->setg(__p, __p + __ninp, __hm_);
    }
    return this->sputc(traits_type::to_char_type(__c));
  }
  return traits_type::not_eof(__c);
}

template <class _CharT, class _Traits, class _Allocator>
typename basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(
    off_type __off, ios_base::seekdir __way, ios_base::openmode __wch) {
  if (__hm_ < this->pptr())
    __hm_ = this->pptr();
  if ((__wch & (ios_base::in | ios_base::out)) == 0)
    return pos_type(-1);
  if ((__wch & (ios_base::in | ios_base::out)) == (ios_base::in | ios_base::out) && __way == ios_base::cur)
    return pos_type(-1);
  const ptrdiff_t __hm = __hm_ == nullptr ? 0 : __hm_ - __str_.data();
  off_type __noff;
  switch (__way) {
  case ios_base::beg:
    __noff = 0;
    break;
  case ios_base::cur:
    if (__wch & ios_base::in)
      __noff = this->gptr() - this->eback();
    else
      __noff = this->pptr() - this->pbase();
    break;
  case ios_base::end:
    __noff = __hm;
    break;
  default:
    return pos_type(-1);
  }
  __noff += __off;
  if (__noff < 0 || __hm < __noff)
    return pos_type(-1);
  if (__noff != 0) {
    if ((__wch & ios_base::in) && this->gptr() == nullptr)
      return pos_type(-1);
    if ((__wch & ios_base::out) && this->pptr() == nullptr)
      return pos_type(-1);
  }
  if (__wch & ios_base::in)
    this->setg(this->eback(), this->eback() + __noff, __hm_);
  if (__wch & ios_base::out) {
    this->setp(this->pbase(), this->epptr());
    this->__pbump(__noff);
  }
  return pos_type(__noff);
}

// Class template basic_istringstream [istringstream]

template <class _CharT, class _Traits, class _Allocator>
class _LIBCPP_TEMPLATE_VIS basic_istringstream : public basic_istream<_CharT, _Traits> {
public:
  typedef _CharT char_type;
  typedef _Traits traits_type;
  typedef typename traits_type::int_type int_type;
  typedef typename traits_type::pos_type pos_type;
  typedef typename traits_type::off_type off_type;
  typedef _Allocator allocator_type;

  typedef basic_string<char_type, traits_type, allocator_type> string_type;

private:
  basic_stringbuf<char_type, traits_type, allocator_type> __sb_;

public:
  // [istringstream.cons] Constructors:
  _LIBCPP_HIDE_FROM_ABI basic_istringstream()
      : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(ios_base::in) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(ios_base::openmode __wch)
      : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::in) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(const string_type& __s, ios_base::openmode __wch = ios_base::in)
      : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in) {}

  basic_istringstream(const basic_istringstream&) = delete;
  _LIBCPP_HIDE_FROM_ABI basic_istringstream(basic_istringstream&& __rhs)
      : basic_istream<_CharT, _Traits>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
    basic_istream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
  }

  // [istringstream.assign] Assign and swap:
  basic_istringstream& operator=(const basic_istringstream&) = delete;
  basic_istringstream& operator=(basic_istringstream&& __rhs) {
    basic_istream<char_type, traits_type>::operator=(std::move(__rhs));
    __sb_ = std::move(__rhs.__sb_);
    return *this;
  }
  _LIBCPP_HIDE_FROM_ABI void swap(basic_istringstream& __rhs) {
    basic_istream<char_type, traits_type>::swap(__rhs);
    __sb_.swap(__rhs.__sb_);
  }

  // [istringstream.members] Member functions:
  _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
    return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(std::addressof(__sb_));
  }

  _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }

  _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
};

template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI void
swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x, basic_istringstream<_CharT, _Traits, _Allocator>& __y) {
  __x.swap(__y);
}

// Class template basic_ostringstream [ostringstream]

template <class _CharT, class _Traits, class _Allocator>
class _LIBCPP_TEMPLATE_VIS basic_ostringstream : public basic_ostream<_CharT, _Traits> {
public:
  typedef _CharT char_type;
  typedef _Traits traits_type;
  typedef typename traits_type::int_type int_type;
  typedef typename traits_type::pos_type pos_type;
  typedef typename traits_type::off_type off_type;
  typedef _Allocator allocator_type;

  typedef basic_string<char_type, traits_type, allocator_type> string_type;

private:
  basic_stringbuf<char_type, traits_type, allocator_type> __sb_;

public:
  // [ostringstream.cons] Constructors:
  _LIBCPP_HIDE_FROM_ABI basic_ostringstream()
      : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(ios_base::out) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(ios_base::openmode __wch)
      : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::out) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(const string_type& __s, ios_base::openmode __wch = ios_base::out)
      : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::out) {}

  basic_ostringstream(const basic_ostringstream&) = delete;
  _LIBCPP_HIDE_FROM_ABI basic_ostringstream(basic_ostringstream&& __rhs)
      : basic_ostream<_CharT, _Traits>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
    basic_ostream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
  }

  // [ostringstream.assign] Assign and swap:
  basic_ostringstream& operator=(const basic_ostringstream&) = delete;
  basic_ostringstream& operator=(basic_ostringstream&& __rhs) {
    basic_ostream<char_type, traits_type>::operator=(std::move(__rhs));
    __sb_ = std::move(__rhs.__sb_);
    return *this;
  }

  _LIBCPP_HIDE_FROM_ABI void swap(basic_ostringstream& __rhs) {
    basic_ostream<char_type, traits_type>::swap(__rhs);
    __sb_.swap(__rhs.__sb_);
  }

  // [ostringstream.members] Member functions:
  _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
    return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(std::addressof(__sb_));
  }

  _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
  _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
};

template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI void
swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x, basic_ostringstream<_CharT, _Traits, _Allocator>& __y) {
  __x.swap(__y);
}

// Class template basic_stringstream [stringstream]

template <class _CharT, class _Traits, class _Allocator>
class _LIBCPP_TEMPLATE_VIS basic_stringstream : public basic_iostream<_CharT, _Traits> {
public:
  typedef _CharT char_type;
  typedef _Traits traits_type;
  typedef typename traits_type::int_type int_type;
  typedef typename traits_type::pos_type pos_type;
  typedef typename traits_type::off_type off_type;
  typedef _Allocator allocator_type;

  typedef basic_string<char_type, traits_type, allocator_type> string_type;

private:
  basic_stringbuf<char_type, traits_type, allocator_type> __sb_;

public:
  // [stringstream.cons] constructors
  _LIBCPP_HIDE_FROM_ABI basic_stringstream()
      : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(ios_base::in | ios_base::out) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(ios_base::openmode __wch)
      : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(const string_type& __s,
                                                    ios_base::openmode __wch = ios_base::in | ios_base::out)
      : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch) {}

  basic_stringstream(const basic_stringstream&) = delete;
  _LIBCPP_HIDE_FROM_ABI basic_stringstream(basic_stringstream&& __rhs)
      : basic_iostream<_CharT, _Traits>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
    basic_istream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
  }

  // [stringstream.assign] Assign and swap:
  basic_stringstream& operator=(const basic_stringstream&) = delete;
  basic_stringstream& operator=(basic_stringstream&& __rhs) {
    basic_iostream<char_type, traits_type>::operator=(std::move(__rhs));
    __sb_ = std::move(__rhs.__sb_);
    return *this;
  }
  _LIBCPP_HIDE_FROM_ABI void swap(basic_stringstream& __rhs) {
    basic_iostream<char_type, traits_type>::swap(__rhs);
    __sb_.swap(__rhs.__sb_);
  }

  // [stringstream.members] Member functions:
  _LIBCPP_HIDE_FROM_ABI basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const {
    return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(std::addressof(__sb_));
  }

  _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }

  _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); }
};

template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI void
swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x, basic_stringstream<_CharT, _Traits, _Allocator>& __y) {
  __x.swap(__y);
}

#if _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringbuf<char>;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringstream<char>;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostringstream<char>;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istringstream<char>;
#endif

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES)
#  include <__cxx03/ostream>
#  include <__cxx03/type_traits>
#endif

#endif // _LIBCPP___CXX03_SSTREAM
