// -*- 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
    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 <__config>

#ifndef _LIBCPP_HAS_NO_LOCALIZATION

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

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

_LIBCPP_PUSH_MACROS
#  include <__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);
  }

#  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) {
    __init_buf_ptrs();
  }

  _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

#  if _LIBCPP_STD_VER >= 26

  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const _Tp& __t,
                                                 ios_base::openmode __which = ios_base::in | ios_base::out)
      : basic_stringbuf(__t, __which, _Allocator()) {}

  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI basic_stringbuf(const _Tp& __t, const _Allocator& __a)
      : basic_stringbuf(__t, ios_base::in | ios_base::out, __a) {}

  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI basic_stringbuf(const _Tp& __t, ios_base::openmode __which, const _Allocator& __a)
      : __hm_(nullptr), __mode_(__which) {
    basic_string_view<_CharT, _Traits> __sv = __t;
    __str_                                  = string_type(__sv, __a);
    __init_buf_ptrs();
  }

#  endif //  _LIBCPP_STD_VER >= 26

  basic_stringbuf(const basic_stringbuf&) = delete;
  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=(const basic_stringbuf&) = delete;
  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 string_type str() const& { return str(__str_.get_allocator()); }

  _LIBCPP_HIDE_FROM_ABI 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

#  if _LIBCPP_STD_VER >= 26

  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI void str(const _Tp& __t) {
    basic_string_view<_CharT, _Traits> __sv = __t;
    __str_                                  = __sv;
    __init_buf_ptrs();
  }

#  endif //  _LIBCPP_STD_VER >= 26

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();
#  if _LIBCPP_HAS_EXCEPTIONS
      try {
#  endif // _LIBCPP_HAS_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;
#  if _LIBCPP_HAS_EXCEPTIONS
      } catch (...) {
        return traits_type::eof();
      }
#  endif // _LIBCPP_HAS_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) {}

#  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

#  if _LIBCPP_STD_VER >= 26

  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(const _Tp& __t, ios_base::openmode __which = ios_base::in)
      : basic_istringstream(__t, __which, _Allocator()) {}

  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI basic_istringstream(const _Tp& __t, const _Allocator& __a)
      : basic_istringstream(__t, ios_base::in, __a) {}

  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI basic_istringstream(const _Tp& __t, ios_base::openmode __which, const _Allocator& __a)
      : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__t, __which | ios_base::in, __a) {}

#  endif //  _LIBCPP_STD_VER >= 26

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

#  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 string_type str() const& { return __sb_.str(); }

  _LIBCPP_HIDE_FROM_ABI 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

#  if _LIBCPP_STD_VER >= 26
  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI void str(const _Tp& __t) {
    rdbuf()->str(__t);
  }
#  endif //  _LIBCPP_STD_VER >= 26
};

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

#  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

#  if _LIBCPP_STD_VER >= 26

  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(const _Tp& __t, ios_base::openmode __which = ios_base::out)
      : basic_ostringstream(__t, __which | ios_base::out, _Allocator()) {}

  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI basic_ostringstream(const _Tp& __t, const _Allocator& __a)
      : basic_ostringstream(__t, ios_base::out, __a) {}

  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI basic_ostringstream(const _Tp& __t, ios_base::openmode __which, const _Allocator& __a)
      : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__t, __which | ios_base::out, __a) {}

#  endif //  _LIBCPP_STD_VER >= 26

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

#  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 string_type str() const& { return __sb_.str(); }

  _LIBCPP_HIDE_FROM_ABI 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

#  if _LIBCPP_STD_VER >= 26
  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI void str(const _Tp& __t) {
    rdbuf()->str(__t);
  }
#  endif //  _LIBCPP_STD_VER >= 26
};

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

#  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

#  if _LIBCPP_STD_VER >= 26

  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(const _Tp& __t,
                                                    ios_base::openmode __which = ios_base::out | ios_base::in)
      : basic_stringstream(__t, __which, _Allocator()) {}

  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI basic_stringstream(const _Tp& __t, const _Allocator& __a)
      : basic_stringstream(__t, ios_base::out | ios_base::in, __a) {}

  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI basic_stringstream(const _Tp& __t, ios_base::openmode __which, const _Allocator& __a)
      : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__t, __which, __a) {}

#  endif //  _LIBCPP_STD_VER >= 26

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

#  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 string_type str() const& { return __sb_.str(); }

  _LIBCPP_HIDE_FROM_ABI 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

#  if _LIBCPP_STD_VER >= 26
  template <class _Tp>
    requires is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>
  _LIBCPP_HIDE_FROM_ABI void str(const _Tp& __t) {
    rdbuf()->str(__t);
  }
#  endif //  _LIBCPP_STD_VER >= 26
};

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

#endif // !_LIBCPP_HAS_NO_LOCALIZATION

#if _LIBCPP_STD_VER <= 20 && !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES)
#  include <ostream>
#  include <type_traits>
#endif

#endif // _LIBCPP_SSTREAM
