// -*- 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_SSTREAM
#define _LIBCPP_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
    basic_stringbuf(basic_stringbuf&& rhs);
    basic_stringbuf(basic_stringbuf&& rhs, const allocator_type& a);                   // C++20

    // [stringbuf.assign] Assign and swap:
    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

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
    basic_istringstream(basic_istringstream&& rhs);

    // [istringstream.assign] Assign and swap:
    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 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
    basic_ostringstream(basic_ostringstream&& rhs);

    // [ostringstream.assign] Assign and swap:
    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 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
    basic_stringstream(basic_stringstream&& rhs);

    // [stringstream.assign] Assign and swap:
    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 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 <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
#include <__fwd/sstream.h>
#include <__utility/swap.h>
#include <istream>
#include <ostream>
#include <string>
#include <version>

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

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

// TODO(LLVM-19): Remove this once we drop support for Clang 16,
// which had this bug: https://github.com/llvm/llvm-project/issues/40363
#ifdef _WIN32
#  define _LIBCPP_HIDE_FROM_ABI_SSTREAM _LIBCPP_ALWAYS_INLINE
#else
#  define _LIBCPP_HIDE_FROM_ABI_SSTREAM _LIBCPP_HIDE_FROM_ABI
#endif

_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) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(ios_base::openmode __wch) : __hm_(nullptr), __mode_(__wch) {}

  _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);
  }

#if _LIBCPP_STD_VER >= 20
  _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const allocator_type& __a)
      : basic_stringbuf(ios_base::in | ios_base::out, __a) {}

  _LIBCPP_HIDE_FROM_ABI basic_stringbuf(ios_base::openmode __wch, const allocator_type& __a)
      : __str_(__a), __hm_(nullptr), __mode_(__wch) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(string_type&& __s,
                                                 ios_base::openmode __wch = ios_base::in | ios_base::out)
      : __str_(std::move(__s)), __hm_(nullptr), __mode_(__wch) {
    __init_buf_ptrs();
  }

  template <class _SAlloc>
  _LIBCPP_HIDE_FROM_ABI
  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) {}

  template <class _SAlloc>
  _LIBCPP_HIDE_FROM_ABI basic_stringbuf(
      const basic_string<char_type, traits_type, _SAlloc>& __s, ios_base::openmode __wch, const allocator_type& __a)
      : __str_(__s, __a), __hm_(nullptr), __mode_(__wch) {
    __init_buf_ptrs();
  }

  template <class _SAlloc>
    requires(!is_same_v<_SAlloc, allocator_type>)
  _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const basic_string<char_type, traits_type, _SAlloc>& __s,
                                                 ios_base::openmode __wch = ios_base::in | ios_base::out)
      : __str_(__s), __hm_(nullptr), __mode_(__wch) {
    __init_buf_ptrs();
  }
#endif // _LIBCPP_STD_VER >= 20

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

#if _LIBCPP_STD_VER >= 20
  _LIBCPP_HIDE_FROM_ABI basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a)
      : basic_stringbuf(__rhs.__mode_, __a) {
    __move_init(std::move(__rhs));
  }
#endif

  // [stringbuf.assign] Assign and swap:
  basic_stringbuf& operator=(basic_stringbuf&& __rhs);
  void swap(basic_stringbuf& __rhs)
#if _LIBCPP_STD_VER >= 20
      noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
               allocator_traits<allocator_type>::is_always_equal::value)
#endif
          ;

  // [stringbuf.members] Member functions:

#if _LIBCPP_STD_VER >= 20
  _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); }
#endif

#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
  string_type str() const;
#else
  _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const& { return str(__str_.get_allocator()); }

  _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && {
    const basic_string_view<_CharT, _Traits> __view = view();
    typename string_type::size_type __pos           = __view.empty() ? 0 : __view.data() - __str_.data();
    // In C++23, this is just string_type(std::move(__str_), __pos, __view.size(), __str_.get_allocator());
    // But we need something that works in C++20 also.
    string_type __result(std::move(__str_), __str_.get_allocator());
    __result.resize(__pos + __view.size());
    __result.erase(0, __pos);
    __init_buf_ptrs();
    return __result;
  }
#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)

#if _LIBCPP_STD_VER >= 20
  template <class _SAlloc>
    requires __is_allocator<_SAlloc>::value
  _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
    return basic_string<_CharT, _Traits, _SAlloc>(view(), __sa);
  }

  _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept;
#endif // _LIBCPP_STD_VER >= 20

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

#if _LIBCPP_STD_VER >= 20
  template <class _SAlloc>
    requires(!is_same_v<_SAlloc, allocator_type>)
  _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
    __str_ = __s;
    __init_buf_ptrs();
  }

  _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) {
    __str_ = std::move(__s);
    __init_buf_ptrs();
  }
#endif // _LIBCPP_STD_VER >= 20

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)
#if _LIBCPP_STD_VER >= 20
    noexcept(allocator_traits<_Allocator>::propagate_on_container_swap::value ||
             allocator_traits<_Allocator>::is_always_equal::value)
#endif
{
  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)
#if _LIBCPP_STD_VER >= 20
    noexcept(noexcept(__x.swap(__y)))
#endif
{
  __x.swap(__y);
}

#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
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());
}
#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)

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);
    }
  }
}

#if _LIBCPP_STD_VER >= 20
template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT, _Traits>
basic_stringbuf<_CharT, _Traits, _Allocator>::view() const noexcept {
  if (__mode_ & ios_base::out) {
    if (__hm_ < this->pptr())
      __hm_ = this->pptr();
    return basic_string_view<_CharT, _Traits>(this->pbase(), __hm_);
  } else if (__mode_ & ios_base::in)
    return basic_string_view<_CharT, _Traits>(this->eback(), this->egptr());
  return basic_string_view<_CharT, _Traits>();
}
#endif // _LIBCPP_STD_VER >= 20

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>(&__sb_), __sb_(ios_base::in) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(ios_base::openmode __wch)
      : basic_istream<_CharT, _Traits>(&__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>(&__sb_), __sb_(__s, __wch | ios_base::in) {}

#if _LIBCPP_STD_VER >= 20
  _LIBCPP_HIDE_FROM_ABI basic_istringstream(ios_base::openmode __wch, const _Allocator& __a)
      : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::in, __a) {}

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

  template <class _SAlloc>
  _LIBCPP_HIDE_FROM_ABI basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
      : basic_istringstream(__s, ios_base::in, __a) {}

  template <class _SAlloc>
  _LIBCPP_HIDE_FROM_ABI basic_istringstream(
      const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
      : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in, __a) {}

  template <class _SAlloc>
  _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
                                                     ios_base::openmode __wch = ios_base::in)
      : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in) {}
#endif // _LIBCPP_STD_VER >= 20

  _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(&__sb_);
  }

  // [istringstream.assign] Assign and swap:
  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>*>(&__sb_);
  }

#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
  _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
#else
  _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const& { return __sb_.str(); }

  _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && { return std::move(__sb_).str(); }
#endif

#if _LIBCPP_STD_VER >= 20
  template <class _SAlloc>
    requires __is_allocator<_SAlloc>::value
  _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
    return __sb_.str(__sa);
  }

  _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
#endif // _LIBCPP_STD_VER >= 20

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

#if _LIBCPP_STD_VER >= 20
  template <class _SAlloc>
  _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
    __sb_.str(__s);
  }

  _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
#endif // _LIBCPP_STD_VER >= 20
};

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>(&__sb_), __sb_(ios_base::out) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(ios_base::openmode __wch)
      : basic_ostream<_CharT, _Traits>(&__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>(&__sb_), __sb_(__s, __wch | ios_base::out) {}

#if _LIBCPP_STD_VER >= 20
  _LIBCPP_HIDE_FROM_ABI basic_ostringstream(ios_base::openmode __wch, const _Allocator& __a)
      : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::out, __a) {}

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

  template <class _SAlloc>
  _LIBCPP_HIDE_FROM_ABI basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
      : basic_ostringstream(__s, ios_base::out, __a) {}

  template <class _SAlloc>
  _LIBCPP_HIDE_FROM_ABI basic_ostringstream(
      const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
      : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::out, __a) {}

  template <class _SAlloc>
    requires(!is_same_v<_SAlloc, allocator_type>)
  _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
                                                     ios_base::openmode __wch = ios_base::out)
      : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::out) {}
#endif // _LIBCPP_STD_VER >= 20

  _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(&__sb_);
  }

  // [ostringstream.assign] Assign and swap:
  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>*>(&__sb_);
  }

#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
  _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
#else
  _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const& { return __sb_.str(); }

  _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && { return std::move(__sb_).str(); }
#endif

#if _LIBCPP_STD_VER >= 20
  template <class _SAlloc>
    requires __is_allocator<_SAlloc>::value
  _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
    return __sb_.str(__sa);
  }

  _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
#endif // _LIBCPP_STD_VER >= 20

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

#if _LIBCPP_STD_VER >= 20
  template <class _SAlloc>
  _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
    __sb_.str(__s);
  }

  _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
#endif // _LIBCPP_STD_VER >= 20
};

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>(&__sb_), __sb_(ios_base::in | ios_base::out) {}

  _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(ios_base::openmode __wch)
      : basic_iostream<_CharT, _Traits>(&__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>(&__sb_), __sb_(__s, __wch) {}

#if _LIBCPP_STD_VER >= 20
  _LIBCPP_HIDE_FROM_ABI basic_stringstream(ios_base::openmode __wch, const _Allocator& __a)
      : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch, __a) {}

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

  template <class _SAlloc>
  _LIBCPP_HIDE_FROM_ABI basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a)
      : basic_stringstream(__s, ios_base::out | ios_base::in, __a) {}

  template <class _SAlloc>
  _LIBCPP_HIDE_FROM_ABI
  basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a)
      : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch, __a) {}

  template <class _SAlloc>
    requires(!is_same_v<_SAlloc, allocator_type>)
  _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s,
                                                    ios_base::openmode __wch = ios_base::out | ios_base::in)
      : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch) {}
#endif // _LIBCPP_STD_VER >= 20

  _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(&__sb_);
  }

  // [stringstream.assign] Assign and swap:
  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>*>(&__sb_);
  }

#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY)
  _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); }
#else
  _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const& { return __sb_.str(); }

  _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && { return std::move(__sb_).str(); }
#endif

#if _LIBCPP_STD_VER >= 20
  template <class _SAlloc>
    requires __is_allocator<_SAlloc>::value
  _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const {
    return __sb_.str(__sa);
  }

  _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); }
#endif // _LIBCPP_STD_VER >= 20

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

#if _LIBCPP_STD_VER >= 20
  template <class _SAlloc>
  _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) {
    __sb_.str(__s);
  }

  _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); }
#endif // _LIBCPP_STD_VER >= 20
};

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 _LIBCPP_STD_VER <= 20 && !defined(_LIPCPP_REMOVE_TRANSITIVE_INCLUDES)
#  include <type_traits>
#endif

#endif // _LIBCPP_SSTREAM
