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

#if _LIBCPP_HAS_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_LOCALIZATION

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

#endif // _LIBCPP_SSTREAM
