// -*- 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_FSTREAM
#define _LIBCPP_FSTREAM

/*
    fstream synopsis

template <class charT, class traits = char_traits<charT> >
class basic_filebuf
    : 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;

    // 27.9.1.2 Constructors/destructor:
    basic_filebuf();
    basic_filebuf(basic_filebuf&& rhs);
    virtual ~basic_filebuf();

    // 27.9.1.3 Assign/swap:
    basic_filebuf& operator=(basic_filebuf&& rhs);
    void swap(basic_filebuf& rhs);

    // 27.9.1.4 Members:
    bool is_open() const;
    basic_filebuf* open(const char* s, ios_base::openmode mode);
    basic_filebuf* open(const string& s, ios_base::openmode mode);
    basic_filebuf* open(const filesystem::path& p, ios_base::openmode mode); // C++17
    basic_filebuf* close();

protected:
    // 27.9.1.5 Overridden virtual functions:
    virtual streamsize showmanyc();
    virtual int_type underflow();
    virtual int_type uflow();
    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* s, streamsize n);
    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);
    virtual int sync();
    virtual void imbue(const locale& loc);
};

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

typedef basic_filebuf<char>    filebuf;
typedef basic_filebuf<wchar_t> wfilebuf;

template <class charT, class traits = char_traits<charT> >
class basic_ifstream
    : 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;
    using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26

    basic_ifstream();
    explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
    explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);
    template<class T>
    explicit basic_ifstream(const T& s, ios_base::openmode mode = ios_base::in); // Since C++17
    basic_ifstream(basic_ifstream&& rhs);

    basic_ifstream& operator=(basic_ifstream&& rhs);
    void swap(basic_ifstream& rhs);

    basic_filebuf<char_type, traits_type>* rdbuf() const;
    native_handle_type native_handle() const noexcept; // Since C++26
    bool is_open() const;
    void open(const char* s, ios_base::openmode mode = ios_base::in);
    void open(const string& s, ios_base::openmode mode = ios_base::in);
    void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++17

    void close();
};

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

typedef basic_ifstream<char>    ifstream;
typedef basic_ifstream<wchar_t> wifstream;

template <class charT, class traits = char_traits<charT> >
class basic_ofstream
    : 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;
    using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26

    basic_ofstream();
    explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
    explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);
    template<class T>
    explicit basic_ofstream(const T& s, ios_base::openmode mode = ios_base::out); // Since C++17
    basic_ofstream(basic_ofstream&& rhs);

    basic_ofstream& operator=(basic_ofstream&& rhs);
    void swap(basic_ofstream& rhs);

    basic_filebuf<char_type, traits_type>* rdbuf() const;
    native_handle_type native_handle() const noexcept; // Since C++26

    bool is_open() const;
    void open(const char* s, ios_base::openmode mode = ios_base::out);
    void open(const string& s, ios_base::openmode mode = ios_base::out);
    void open(const filesystem::path& p,
              ios_base::openmode mode = ios_base::out); // C++17

    void close();
};

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

typedef basic_ofstream<char>    ofstream;
typedef basic_ofstream<wchar_t> wofstream;

template <class charT, class traits=char_traits<charT> >
class basic_fstream
    : 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;
    using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26

    basic_fstream();
    explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
    explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
    template<class T>
    explicit basic_fstream(const T& s, ios_base::openmode mode = ios_base::in | ios_base::out); // Since C++17
    basic_fstream(basic_fstream&& rhs);

    basic_fstream& operator=(basic_fstream&& rhs);
    void swap(basic_fstream& rhs);

    basic_filebuf<char_type, traits_type>* rdbuf() const;
    native_handle_type native_handle() const noexcept; // Since C++26
    bool is_open() const;
    void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
    void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
    void open(const filesystem::path& s,
              ios_base::openmode mode = ios_base::in|ios_base::out); // C++17

    void close();
};

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

typedef basic_fstream<char>    fstream;
typedef basic_fstream<wchar_t> wfstream;

}  // std

*/

#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#  include <__cxx03/fstream>
#else
#  include <__config>

#  if _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION

#    include <__algorithm/max.h>
#    include <__assert>
#    include <__filesystem/path.h>
#    include <__fwd/fstream.h>
#    include <__locale>
#    include <__memory/addressof.h>
#    include <__memory/unique_ptr.h>
#    include <__ostream/basic_ostream.h>
#    include <__type_traits/enable_if.h>
#    include <__type_traits/is_same.h>
#    include <__utility/move.h>
#    include <__utility/swap.h>
#    include <__utility/unreachable.h>
#    include <cstdio>
#    include <istream>
#    include <streambuf>
#    include <typeinfo>
#    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
_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS

#    if _LIBCPP_STD_VER >= 23 && defined(_LIBCPP_WIN32API)
_LIBCPP_EXPORTED_FROM_ABI void* __filebuf_windows_native_handle(FILE* __file) noexcept;
#    endif

template <class _CharT, class _Traits>
class basic_filebuf : 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 typename traits_type::state_type state_type;
#    if _LIBCPP_STD_VER >= 26
#      if defined(_LIBCPP_WIN32API)
  using native_handle_type = void*; // HANDLE
#      elif __has_include(<unistd.h>)
  using native_handle_type = int; // POSIX file descriptor
#      else
#        error "Provide a native file handle!"
#      endif
#    endif

  // 27.9.1.2 Constructors/destructor:
  basic_filebuf();
  basic_filebuf(basic_filebuf&& __rhs);
  ~basic_filebuf() override;

  // 27.9.1.3 Assign/swap:
  _LIBCPP_HIDE_FROM_ABI basic_filebuf& operator=(basic_filebuf&& __rhs);
  void swap(basic_filebuf& __rhs);

  // 27.9.1.4 Members:
  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool is_open() const;
  basic_filebuf* open(const char* __s, ios_base::openmode __mode);
#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
  basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode);
#    endif
  _LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const string& __s, ios_base::openmode __mode);

#    if _LIBCPP_STD_VER >= 17
  _LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const filesystem::path& __p, ios_base::openmode __mode) {
    return open(__p.c_str(), __mode);
  }
#    endif
  _LIBCPP_HIDE_FROM_ABI basic_filebuf* __open(int __fd, ios_base::openmode __mode);
  basic_filebuf* close();
#    if _LIBCPP_STD_VER >= 26
  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
    _LIBCPP_ASSERT_UNCATEGORIZED(this->is_open(), "File must be opened");
#      if defined(_LIBCPP_WIN32API)
    return std::__filebuf_windows_native_handle(__file_);
#      elif __has_include(<unistd.h>)
    return fileno(__file_);
#      else
#        error "Provide a way to determine the file native handle!"
#      endif
  }
#    endif //  _LIBCPP_STD_VER >= 26

  _LIBCPP_HIDE_FROM_ABI inline static const char* __make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
  _LIBCPP_HIDE_FROM_ABI inline static const wchar_t* __make_mdwstring(ios_base::openmode __mode) _NOEXCEPT;
#    endif

protected:
  // 27.9.1.5 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;
  basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n) override;
  pos_type
  seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
  pos_type seekpos(pos_type __sp, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
  int sync() override;
  void imbue(const locale& __loc) override;

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL streamsize xsputn(const char_type* __str, streamsize __len) override {
    if (__always_noconv_ && __len >= (this->epptr() - this->pbase())) {
      if (traits_type::eq_int_type(overflow(), traits_type::eof()))
        return 0;

      return std::fwrite(__str, sizeof(char_type), __len, __file_);
    }
    return basic_streambuf<_CharT, _Traits>::xsputn(__str, __len);
  }

  _LIBCPP_HIDE_FROM_ABI_VIRTUAL streamsize xsgetn(char_type* __str, streamsize __len) override {
    if (__file_ && __always_noconv_) {
      char_type __1buf;
      __read_guard __guard(__1buf, *this);
      const streamsize __n = std::min(this->egptr() - this->gptr(), __len);
      if (__n != 0) {
        traits_type::copy(__str, this->gptr(), __n);
        this->__gbump_ptrdiff(__n);
      }
      const streamsize __remainder    = __len - __n;
      const streamsize __buffer_space = this->egptr() - this->eback();

      if (__remainder >= __buffer_space) {
        auto __res = std::fread(__str + __n, sizeof(char_type), __remainder, __file_) + __n;

        // Copy the buffer-sized tail into the buffer so that `unget`ting works correctly
        auto __buf_size = std::min<size_t>(__res, this->egptr() - this->eback());
        traits_type::copy(this->eback(), __str + __res - __buf_size, __buf_size);
        this->setg(this->eback(), this->eback() + __buf_size, this->eback() + __buf_size);

        return __res;
      } else if (__remainder > 0)
        return basic_streambuf<_CharT, _Traits>::xsgetn(__str + __n, __remainder) + __n;
      return __n;
    }
    return basic_streambuf<_CharT, _Traits>::xsgetn(__str, __len);
  }

private:
  char* __extbuf_;
  const char* __extbufnext_;
  const char* __extbufend_;
  char __extbuf_min_[8];
  size_t __ebs_;
  char_type* __intbuf_;
  size_t __ibs_;
  FILE* __file_;
  const codecvt<char_type, char, state_type>* __cv_;
  state_type __st_;
  state_type __st_last_;
  ios_base::openmode __om_;
  // There have been no file operations yet, which allows setting unbuffered
  // I/O mode.
  static const ios_base::openmode __no_io_operations = ios_base::trunc;
  // Unbuffered I/O mode has been requested.
  static const ios_base::openmode __use_unbuffered_io = ios_base::ate;
  // Used to track the currently used mode and track whether the output should
  // be unbuffered.
  // [filebuf.virtuals]/12
  //   If setbuf(0, 0) is called on a stream before any I/O has occurred on
  //   that stream, the stream becomes unbuffered. Otherwise the results are
  //   implementation-defined.
  // This allows calling setbuf(0, 0)
  // - before opening a file,
  // - after opening a file, before
  //   - a read
  //   - a write
  //   - a seek.
  // Note that opening a file with ios_base::ate does a seek operation.
  // Normally underflow, overflow, and sync change this flag to ios_base::in,
  // ios_base_out, or 0.
  //
  // The ios_base::trunc and ios_base::ate flags are not used in __cm_. They
  // are used to track the state of the unbuffered request. For readability
  // they have the aliases __no_io_operations and __use_unbuffered_io
  // respectively.
  //
  // The __no_io_operations and __use_unbuffered_io flags are used in the
  // following way:
  // - __no_io_operations is set upon construction to indicate the unbuffered
  //   state can be set.
  // - When requesting unbuffered output:
  //   - If the file is open it sets the mode.
  //   - Else places a request by adding the __use_unbuffered_io flag.
  // - When a file is opened it checks whether both __no_io_operations and
  //   __use_unbuffered_io are set. If so switches to unbuffered mode.
  // - All file I/O operations change the mode effectively clearing the
  //   __no_io_operations and __use_unbuffered_io flags.
  ios_base::openmode __cm_;
  bool __owns_eb_;
  bool __owns_ib_;
  bool __always_noconv_;

  bool __read_mode();

  struct [[__nodiscard__]] __read_guard {
    basic_filebuf& __self_;
    size_t __unget_size_;
    char_type& __1buf_;

    _LIBCPP_HIDE_FROM_ABI __read_guard(char_type& __1buf, basic_filebuf& __self) : __self_(__self), __1buf_(__1buf) {
      if (__self.__cm_ & ios_base::in) {
        __unget_size_ = std::min<size_t>((__self.egptr() - __self.eback()) / 2, 4);
      } else {
        __self.setp(nullptr, nullptr);
        if (__self.__always_noconv_) {
          __self.setg(reinterpret_cast<char_type*>(__self.__extbuf_),
                      reinterpret_cast<char_type*>(__self.__extbuf_) + __self.__ebs_,
                      reinterpret_cast<char_type*>(__self.__extbuf_) + __self.__ebs_);
        } else {
          __self.setg(__self.__intbuf_, __self.__intbuf_ + __self.__ibs_, __self.__intbuf_ + __self.__ibs_);
        }
        __self.__cm_  = ios_base::in;
        __unget_size_ = 0;
      }

      if (__self.gptr() == nullptr)
        __self.setg(std::addressof(__1buf_), std::addressof(__1buf_) + 1, std::addressof(__1buf_) + 1);
    }

    _LIBCPP_HIDE_FROM_ABI size_t __unget_size() { return __unget_size_; }

    _LIBCPP_HIDE_FROM_ABI ~__read_guard() {
      if (__self_.eback() == std::addressof(__1buf_))
        __self_.setg(nullptr, nullptr, nullptr);
    }
  };

  void __write_mode();

  _LIBCPP_HIDE_FROM_ABI static int __fseek(FILE* __file, pos_type __offset, int __whence);
  _LIBCPP_HIDE_FROM_ABI static pos_type __ftell(FILE* __file);

  _LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);

public:
  // Update the buffer so that __file is considered to be the underlying file and is opened as __mode. This is used in
  // the open family of functions as well as various iostreams in sync_with_stdio(false) mode.
  _LIBCPP_HIDE_FROM_ABI basic_filebuf* __adopt_file(FILE* __file, ios_base::openmode __mode) {
    __file_ = __file;
    if (!__file_)
      return nullptr;

    __om_ = __mode;
    if (__cm_ == (__no_io_operations | __use_unbuffered_io)) {
      std::setbuf(__file_, nullptr);
      __cm_ = 0;
    }

    if (__mode & ios_base::ate) {
      __cm_ = 0;
      if (fseek(__file_, 0, SEEK_END)) {
        fclose(__file_);
        __file_ = nullptr;
        return nullptr;
      }
    }

    return this;
  }

private:
  // If the file is already open, switch to unbuffered mode. Otherwise, record
  // the request to use unbuffered mode so that we use that mode when we
  // eventually open the file.
  _LIBCPP_HIDE_FROM_ABI void __request_unbuffered_mode() {
    if (__file_) {
      std::setbuf(__file_, nullptr);
      __cm_ = 0;
    } else {
      __cm_ = __no_io_operations | __use_unbuffered_io;
    }
  }

  _LIBCPP_HIDE_FROM_ABI typename traits_type::int_type __overflow_failed() {
    if (this->pptr() == this->epptr() + 1) {
      this->pbump(-1); // lose the character we overflowed above -- we don't really have a
                       // choice since we couldn't commit the contents of the put area
    }
    return traits_type::eof();
  }
};

template <class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>::basic_filebuf()
    : __extbuf_(nullptr),
      __extbufnext_(nullptr),
      __extbufend_(nullptr),
      __ebs_(0),
      __intbuf_(nullptr),
      __ibs_(0),
      __file_(nullptr),
      __cv_(nullptr),
      __st_(),
      __st_last_(),
      __om_(0),
      __cm_(__no_io_operations),
      __owns_eb_(false),
      __owns_ib_(false),
      __always_noconv_(false) {
  if (std::has_facet<codecvt<char_type, char, state_type> >(this->getloc())) {
    __cv_            = std::addressof(std::use_facet<codecvt<char_type, char, state_type> >(this->getloc()));
    __always_noconv_ = __cv_->always_noconv();
  }
  setbuf(nullptr, 4096);
}

template <class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) : basic_streambuf<_CharT, _Traits>(__rhs) {
  if (__rhs.__extbuf_ == __rhs.__extbuf_min_) {
    __extbuf_     = __extbuf_min_;
    __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);
    __extbufend_  = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);
  } else {
    __extbuf_     = __rhs.__extbuf_;
    __extbufnext_ = __rhs.__extbufnext_;
    __extbufend_  = __rhs.__extbufend_;
  }
  __ebs_           = __rhs.__ebs_;
  __intbuf_        = __rhs.__intbuf_;
  __ibs_           = __rhs.__ibs_;
  __file_          = __rhs.__file_;
  __cv_            = __rhs.__cv_;
  __st_            = __rhs.__st_;
  __st_last_       = __rhs.__st_last_;
  __om_            = __rhs.__om_;
  __cm_            = __rhs.__cm_;
  __owns_eb_       = __rhs.__owns_eb_;
  __owns_ib_       = __rhs.__owns_ib_;
  __always_noconv_ = __rhs.__always_noconv_;
  if (__rhs.pbase()) {
    if (__rhs.pbase() == __rhs.__intbuf_)
      this->setp(__intbuf_, __intbuf_ + (__rhs.epptr() - __rhs.pbase()));
    else
      this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__rhs.epptr() - __rhs.pbase()));
    this->__pbump(__rhs.pptr() - __rhs.pbase());
  } else if (__rhs.eback()) {
    if (__rhs.eback() == __rhs.__intbuf_)
      this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()), __intbuf_ + (__rhs.egptr() - __rhs.eback()));
    else
      this->setg((char_type*)__extbuf_,
                 (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),
                 (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));
  }
  __rhs.__extbuf_     = nullptr;
  __rhs.__extbufnext_ = nullptr;
  __rhs.__extbufend_  = nullptr;
  __rhs.__ebs_        = 0;
  __rhs.__intbuf_     = 0;
  __rhs.__ibs_        = 0;
  __rhs.__file_       = nullptr;
  __rhs.__st_         = state_type();
  __rhs.__st_last_    = state_type();
  __rhs.__om_         = 0;
  __rhs.__cm_         = 0;
  __rhs.__owns_eb_    = false;
  __rhs.__owns_ib_    = false;
  __rhs.setg(0, 0, 0);
  __rhs.setp(0, 0);
}

template <class _CharT, class _Traits>
inline basic_filebuf<_CharT, _Traits>& basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) {
  close();
  swap(__rhs);
  return *this;
}

template <class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>::~basic_filebuf() {
#    if _LIBCPP_HAS_EXCEPTIONS
  try {
#    endif // _LIBCPP_HAS_EXCEPTIONS
    close();
#    if _LIBCPP_HAS_EXCEPTIONS
  } catch (...) {
  }
#    endif // _LIBCPP_HAS_EXCEPTIONS
  if (__owns_eb_)
    delete[] __extbuf_;
  if (__owns_ib_)
    delete[] __intbuf_;
}

template <class _CharT, class _Traits>
void basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) {
  basic_streambuf<char_type, traits_type>::swap(__rhs);
  if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
    // Neither *this nor __rhs uses the small buffer, so we can simply swap the pointers.
    std::swap(__extbuf_, __rhs.__extbuf_);
    std::swap(__extbufnext_, __rhs.__extbufnext_);
    std::swap(__extbufend_, __rhs.__extbufend_);
  } else {
    ptrdiff_t __ln = __extbufnext_ ? __extbufnext_ - __extbuf_ : 0;
    ptrdiff_t __le = __extbufend_ ? __extbufend_ - __extbuf_ : 0;
    ptrdiff_t __rn = __rhs.__extbufnext_ ? __rhs.__extbufnext_ - __rhs.__extbuf_ : 0;
    ptrdiff_t __re = __rhs.__extbufend_ ? __rhs.__extbufend_ - __rhs.__extbuf_ : 0;
    if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
      // *this uses the small buffer, but __rhs doesn't.
      __extbuf_       = __rhs.__extbuf_;
      __rhs.__extbuf_ = __rhs.__extbuf_min_;
      std::memmove(__rhs.__extbuf_min_, __extbuf_min_, sizeof(__extbuf_min_));
    } else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_) {
      // *this doesn't use the small buffer, but __rhs does.
      __rhs.__extbuf_ = __extbuf_;
      __extbuf_       = __extbuf_min_;
      std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
    } else {
      // Both *this and __rhs use the small buffer.
      char __tmp[sizeof(__extbuf_min_)];
      std::memmove(__tmp, __extbuf_min_, sizeof(__extbuf_min_));
      std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
      std::memmove(__rhs.__extbuf_min_, __tmp, sizeof(__extbuf_min_));
    }
    __extbufnext_       = __extbuf_ + __rn;
    __extbufend_        = __extbuf_ + __re;
    __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;
    __rhs.__extbufend_  = __rhs.__extbuf_ + __le;
  }
  std::swap(__ebs_, __rhs.__ebs_);
  std::swap(__intbuf_, __rhs.__intbuf_);
  std::swap(__ibs_, __rhs.__ibs_);
  std::swap(__file_, __rhs.__file_);
  std::swap(__cv_, __rhs.__cv_);
  std::swap(__st_, __rhs.__st_);
  std::swap(__st_last_, __rhs.__st_last_);
  std::swap(__om_, __rhs.__om_);
  std::swap(__cm_, __rhs.__cm_);
  std::swap(__owns_eb_, __rhs.__owns_eb_);
  std::swap(__owns_ib_, __rhs.__owns_ib_);
  std::swap(__always_noconv_, __rhs.__always_noconv_);
  if (this->eback() == (char_type*)__rhs.__extbuf_min_) {
    ptrdiff_t __n = this->gptr() - this->eback();
    ptrdiff_t __e = this->egptr() - this->eback();
    this->setg((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __n, (char_type*)__extbuf_min_ + __e);
  } else if (this->pbase() == (char_type*)__rhs.__extbuf_min_) {
    ptrdiff_t __n = this->pptr() - this->pbase();
    ptrdiff_t __e = this->epptr() - this->pbase();
    this->setp((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __e);
    this->__pbump(__n);
  }
  if (__rhs.eback() == (char_type*)__extbuf_min_) {
    ptrdiff_t __n = __rhs.gptr() - __rhs.eback();
    ptrdiff_t __e = __rhs.egptr() - __rhs.eback();
    __rhs.setg(
        (char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __n, (char_type*)__rhs.__extbuf_min_ + __e);
  } else if (__rhs.pbase() == (char_type*)__extbuf_min_) {
    ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();
    ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();
    __rhs.setp((char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __e);
    __rhs.__pbump(__n);
  }
}

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

template <class _CharT, class _Traits>
inline bool basic_filebuf<_CharT, _Traits>::is_open() const {
  return __file_ != nullptr;
}

// Configures the fopen close-on-exec mode character, if any. This string will
// be appended to any mode string used by fstream for fopen/fdopen.
//
// Not all platforms support this, but it helps avoid fd-leaks on platforms that
// do.
#    if defined(__BIONIC__)
#      define _LIBCPP_FOPEN_CLOEXEC_MODE "e"
#    else
#      define _LIBCPP_FOPEN_CLOEXEC_MODE
#    endif

template <class _CharT, class _Traits>
const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(ios_base::openmode __mode) _NOEXCEPT {
  switch (__mode & ~ios_base::ate) {
  case ios_base::out:
  case ios_base::out | ios_base::trunc:
    return "w" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::out | ios_base::app:
  case ios_base::app:
    return "a" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::in:
    return "r" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::in | ios_base::out:
    return "r+" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::in | ios_base::out | ios_base::trunc:
    return "w+" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::in | ios_base::out | ios_base::app:
  case ios_base::in | ios_base::app:
    return "a+" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::out | ios_base::binary:
  case ios_base::out | ios_base::trunc | ios_base::binary:
    return "wb" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::out | ios_base::app | ios_base::binary:
  case ios_base::app | ios_base::binary:
    return "ab" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::in | ios_base::binary:
    return "rb" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::in | ios_base::out | ios_base::binary:
    return "r+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
    return "w+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
  case ios_base::in | ios_base::app | ios_base::binary:
    return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
#    if _LIBCPP_STD_VER >= 23
  case ios_base::out | ios_base::noreplace:
  case ios_base::out | ios_base::trunc | ios_base::noreplace:
    return "wx" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
    return "w+x" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::out | ios_base::binary | ios_base::noreplace:
  case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
    return "wbx" _LIBCPP_FOPEN_CLOEXEC_MODE;
  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
    return "w+bx" _LIBCPP_FOPEN_CLOEXEC_MODE;
#    endif // _LIBCPP_STD_VER >= 23
  default:
    return nullptr;
  }
  __libcpp_unreachable();
}

#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
template <class _CharT, class _Traits>
const wchar_t* basic_filebuf<_CharT, _Traits>::__make_mdwstring(ios_base::openmode __mode) _NOEXCEPT {
  switch (__mode & ~ios_base::ate) {
  case ios_base::out:
  case ios_base::out | ios_base::trunc:
    return L"w";
  case ios_base::out | ios_base::app:
  case ios_base::app:
    return L"a";
  case ios_base::in:
    return L"r";
  case ios_base::in | ios_base::out:
    return L"r+";
  case ios_base::in | ios_base::out | ios_base::trunc:
    return L"w+";
  case ios_base::in | ios_base::out | ios_base::app:
  case ios_base::in | ios_base::app:
    return L"a+";
  case ios_base::out | ios_base::binary:
  case ios_base::out | ios_base::trunc | ios_base::binary:
    return L"wb";
  case ios_base::out | ios_base::app | ios_base::binary:
  case ios_base::app | ios_base::binary:
    return L"ab";
  case ios_base::in | ios_base::binary:
    return L"rb";
  case ios_base::in | ios_base::out | ios_base::binary:
    return L"r+b";
  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
    return L"w+b";
  case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
  case ios_base::in | ios_base::app | ios_base::binary:
    return L"a+b";
#      if _LIBCPP_STD_VER >= 23
  case ios_base::out | ios_base::noreplace:
  case ios_base::out | ios_base::trunc | ios_base::noreplace:
    return L"wx";
  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
    return L"w+x";
  case ios_base::out | ios_base::binary | ios_base::noreplace:
  case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
    return L"wbx";
  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
    return L"w+bx";
#      endif // _LIBCPP_STD_VER >= 23
  default:
    return nullptr;
  }
  __libcpp_unreachable();
}
#    endif

template <class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
  if (__file_)
    return nullptr;
  const char* __mdstr = __make_mdstring(__mode);
  if (!__mdstr)
    return nullptr;

  return __adopt_file(std::fopen(__s, __mdstr), __mode);
}

template <class _CharT, class _Traits>
inline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
  if (__file_)
    return nullptr;
  const char* __mdstr = __make_mdstring(__mode);
  if (!__mdstr)
    return nullptr;

  return __adopt_file(fdopen(__fd, __mdstr), __mode);
}

#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
// This is basically the same as the char* overload except that it uses _wfopen
// and long mode strings.
template <class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
  if (__file_)
    return nullptr;
  const wchar_t* __mdstr = __make_mdwstring(__mode);
  if (!__mdstr)
    return nullptr;

  return __adopt_file(_wfopen(__s, __mdstr), __mode);
}
#    endif

template <class _CharT, class _Traits>
inline basic_filebuf<_CharT, _Traits>*
basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
  return open(__s.c_str(), __mode);
}

template <class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::close() {
  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
  if (__file_) {
    __rt = this;
    unique_ptr<FILE, int (*)(FILE*)> __h(__file_, fclose);
    if (sync())
      __rt = nullptr;
    if (fclose(__h.release()))
      __rt = nullptr;
    __file_ = nullptr;
    // Reset the get and the put areas without getting rid of the underlying buffers,
    // which might have been configured by the user. Make sure to keep the buffers
    // since the user may re-open the stream.
    this->setg(nullptr, nullptr, nullptr);
    this->setp(nullptr, nullptr);
    __cm_ = __no_io_operations;
  }
  return __rt;
}

template <class _CharT, class _Traits>
typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::underflow() {
  if (__file_ == nullptr)
    return traits_type::eof();

  char_type __1buf;
  __read_guard __guard(__1buf, *this);

  const size_t __unget_sz = __guard.__unget_size();
  int_type __c            = traits_type::eof();
  if (this->gptr() == this->egptr()) {
    std::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
    if (__always_noconv_) {
      size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
      __nmemb        = std::fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
      if (__nmemb != 0) {
        this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb);
        __c = traits_type::to_int_type(*this->gptr());
      }
    } else {
      if (__extbufend_ != __extbufnext_) {
        _LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr");
        _LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr");
        std::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
      }
      __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
      __extbufend_  = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
      size_t __nmemb =
          std::min(static_cast<size_t>(__ibs_ - __unget_sz), static_cast<size_t>(__extbufend_ - __extbufnext_));
      codecvt_base::result __r;
      __st_last_  = __st_;
      size_t __nr = std::fread((void*)const_cast<char*>(__extbufnext_), 1, __nmemb, __file_);
      if (__nr != 0) {
        if (!__cv_)
          std::__throw_bad_cast();

        __extbufend_ = __extbufnext_ + __nr;
        char_type* __inext;
        __r = __cv_->in(
            __st_, __extbuf_, __extbufend_, __extbufnext_, this->eback() + __unget_sz, this->eback() + __ibs_, __inext);
        if (__r == codecvt_base::noconv) {
          this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)const_cast<char*>(__extbufend_));
          __c = traits_type::to_int_type(*this->gptr());
        } else if (__inext != this->eback() + __unget_sz) {
          this->setg(this->eback(), this->eback() + __unget_sz, __inext);
          __c = traits_type::to_int_type(*this->gptr());
        }
      }
    }
  } else
    __c = traits_type::to_int_type(*this->gptr());
  return __c;
}

template <class _CharT, class _Traits>
typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) {
  if (__file_ && this->eback() < this->gptr()) {
    if (traits_type::eq_int_type(__c, traits_type::eof())) {
      this->gbump(-1);
      return traits_type::not_eof(__c);
    }
    if ((__om_ & ios_base::out) || traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) {
      this->gbump(-1);
      *this->gptr() = traits_type::to_char_type(__c);
      return __c;
    }
  }
  return traits_type::eof();
}

template <class _CharT, class _Traits>
typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {
  if (__file_ == nullptr)
    return traits_type::eof();
  __write_mode();
  char_type __1buf;
  char_type* __pb_save  = this->pbase();
  char_type* __epb_save = this->epptr();
  if (!traits_type::eq_int_type(__c, traits_type::eof())) {
    if (this->pptr() == nullptr)
      this->setp(std::addressof(__1buf), std::addressof(__1buf) + 1);
    *this->pptr() = traits_type::to_char_type(__c);
    this->pbump(1);
  }

  // There is nothing to write, early return
  if (this->pptr() == this->pbase()) {
    return traits_type::not_eof(__c);
  }

  if (__always_noconv_) {
    size_t __n = static_cast<size_t>(this->pptr() - this->pbase());
    if (std::fwrite(this->pbase(), sizeof(char_type), __n, __file_) != __n) {
      return __overflow_failed();
    }
  } else {
    if (!__cv_)
      std::__throw_bad_cast();

    // See [filebuf.virtuals]
    char_type* __b = this->pbase();
    char_type* __p = this->pptr();
    const char_type* __end;
    char* __extbuf_end = __extbuf_;
    do {
      codecvt_base::result __r = __cv_->out(__st_, __b, __p, __end, __extbuf_, __extbuf_ + __ebs_, __extbuf_end);
      if (__end == __b) {
        return __overflow_failed();
      }

      // No conversion needed: output characters directly to the file, done.
      if (__r == codecvt_base::noconv) {
        size_t __n = static_cast<size_t>(__p - __b);
        if (std::fwrite(__b, 1, __n, __file_) != __n) {
          return __overflow_failed();
        }
        break;

        // Conversion successful: output the converted characters to the file, done.
      } else if (__r == codecvt_base::ok) {
        size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);
        if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) {
          return __overflow_failed();
        }
        break;

        // Conversion partially successful: output converted characters to the file and repeat with the
        // remaining characters.
      } else if (__r == codecvt_base::partial) {
        size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);
        if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) {
          return __overflow_failed();
        }
        __b = const_cast<char_type*>(__end);
        continue;

      } else {
        return __overflow_failed();
      }
    } while (true);
  }
  this->setp(__pb_save, __epb_save);
  return traits_type::not_eof(__c);
}

template <class _CharT, class _Traits>
basic_streambuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n) {
  this->setg(nullptr, nullptr, nullptr);
  this->setp(nullptr, nullptr);
  // Calling setbuf(nullptr, 0) before any i/o operation switches the stream to unbuffered mode
  if (__cm_ == __no_io_operations && __s == nullptr && __n == 0)
    __request_unbuffered_mode();
  if (__owns_eb_)
    delete[] __extbuf_;
  if (__owns_ib_)
    delete[] __intbuf_;
  __ebs_ = __n;
  if (__ebs_ > sizeof(__extbuf_min_)) {
    if (__always_noconv_ && __s) {
      __extbuf_  = (char*)__s;
      __owns_eb_ = false;
    } else {
      __extbuf_  = new char[__ebs_];
      __owns_eb_ = true;
    }
  } else {
    __extbuf_  = __extbuf_min_;
    __ebs_     = sizeof(__extbuf_min_);
    __owns_eb_ = false;
  }
  if (!__always_noconv_) {
    __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
    if (__s && __ibs_ > sizeof(__extbuf_min_)) {
      __intbuf_  = __s;
      __owns_ib_ = false;
    } else {
      __intbuf_  = new char_type[__ibs_];
      __owns_ib_ = true;
    }
  } else {
    __ibs_     = 0;
    __intbuf_  = nullptr;
    __owns_ib_ = false;
  }
  return this;
}

template <class _CharT, class _Traits>
typename basic_filebuf<_CharT, _Traits>::pos_type
basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) {
  if (!__cv_)
    std::__throw_bad_cast();

  int __width = __cv_->encoding();
  if (__file_ == nullptr || (__width <= 0 && __off != 0) || sync())
    return pos_type(off_type(-1));
  // __width > 0 || __off == 0
  int __whence;
  switch (__way) {
  case ios_base::beg:
    __whence = SEEK_SET;
    break;
  case ios_base::cur:
    __whence = SEEK_CUR;
    break;
  case ios_base::end:
    __whence = SEEK_END;
    break;
  default:
    return pos_type(off_type(-1));
  }
  if (__fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
    return pos_type(off_type(-1));
  pos_type __r = __ftell(__file_);
  __r.state(__st_);
  return __r;
}

template <class _CharT, class _Traits>
int basic_filebuf<_CharT, _Traits>::__fseek(FILE* __file, pos_type __offset, int __whence) {
#    if defined(_LIBCPP_MSVCRT_LIKE)
  return _fseeki64(__file, __offset, __whence);
#    elif _LIBCPP_LIBC_NEWLIB
  return fseek(__file, __offset, __whence);
#    else
  return ::fseeko(__file, __offset, __whence);
#    endif
}

template <class _CharT, class _Traits>
typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>::__ftell(FILE* __file) {
#    if defined(_LIBCPP_MSVCRT_LIKE)
  return _ftelli64(__file);
#    elif _LIBCPP_LIBC_NEWLIB
  return ftell(__file);
#    else
  return ftello(__file);
#    endif
}

template <class _CharT, class _Traits>
typename basic_filebuf<_CharT, _Traits>::pos_type
basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) {
  if (__file_ == nullptr || sync())
    return pos_type(off_type(-1));
  if (__fseek(__file_, __sp, SEEK_SET))
    return pos_type(off_type(-1));
  __st_ = __sp.state();
  return __sp;
}

template <class _CharT, class _Traits>
int basic_filebuf<_CharT, _Traits>::sync() {
  if (__file_ == nullptr)
    return 0;
  if (!__cv_)
    std::__throw_bad_cast();

  if (__cm_ & ios_base::out) {
    if (this->pptr() != this->pbase())
      if (overflow() == traits_type::eof())
        return -1;
    codecvt_base::result __r;
    do {
      char* __extbe;
      __r            = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
      size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
      if (std::fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
        return -1;
    } while (__r == codecvt_base::partial);
    if (__r == codecvt_base::error)
      return -1;
    if (std::fflush(__file_))
      return -1;
  } else if (__cm_ & ios_base::in) {
    off_type __c;
    state_type __state = __st_last_;
    bool __update_st   = false;
    if (__always_noconv_)
      __c = this->egptr() - this->gptr();
    else {
      int __width = __cv_->encoding();
      __c         = __extbufend_ - __extbufnext_;
      if (__width > 0)
        __c += __width * (this->egptr() - this->gptr());
      else {
        if (this->gptr() != this->egptr()) {
          const int __off = __cv_->length(__state, __extbuf_, __extbufnext_, this->gptr() - this->eback());
          __c += __extbufnext_ - __extbuf_ - __off;
          __update_st = true;
        }
      }
    }
    if (__fseek(__file_, -__c, SEEK_CUR))
      return -1;
    if (__update_st)
      __st_ = __state;
    __extbufnext_ = __extbufend_ = __extbuf_;
    this->setg(nullptr, nullptr, nullptr);
    __cm_ = 0;
  }
  return 0;
}

template <class _CharT, class _Traits>
void basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) {
  sync();
  __cv_            = std::addressof(std::use_facet<codecvt<char_type, char, state_type> >(__loc));
  bool __old_anc   = __always_noconv_;
  __always_noconv_ = __cv_->always_noconv();
  if (__old_anc != __always_noconv_) {
    this->setg(nullptr, nullptr, nullptr);
    this->setp(nullptr, nullptr);
    // invariant, char_type is char, else we couldn't get here
    if (__always_noconv_) // need to dump __intbuf_
    {
      if (__owns_eb_)
        delete[] __extbuf_;
      __owns_eb_ = __owns_ib_;
      __ebs_     = __ibs_;
      __extbuf_  = (char*)__intbuf_;
      __ibs_     = 0;
      __intbuf_  = nullptr;
      __owns_ib_ = false;
    } else // need to obtain an __intbuf_.
    {      // If __extbuf_ is user-supplied, use it, else new __intbuf_
      if (!__owns_eb_ && __extbuf_ != __extbuf_min_) {
        __ibs_     = __ebs_;
        __intbuf_  = (char_type*)__extbuf_;
        __owns_ib_ = false;
        __extbuf_  = new char[__ebs_];
        __owns_eb_ = true;
      } else {
        __ibs_     = __ebs_;
        __intbuf_  = new char_type[__ibs_];
        __owns_ib_ = true;
      }
    }
  }
}

template <class _CharT, class _Traits>
void basic_filebuf<_CharT, _Traits>::__write_mode() {
  if (!(__cm_ & ios_base::out)) {
    this->setg(nullptr, nullptr, nullptr);
    if (__ebs_ > sizeof(__extbuf_min_)) {
      if (__always_noconv_)
        this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__ebs_ - 1));
      else
        this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
    } else
      this->setp(nullptr, nullptr);
    __cm_ = ios_base::out;
  }
}

// basic_ifstream

template <class _CharT, class _Traits>
class basic_ifstream : 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;
#    if _LIBCPP_STD_VER >= 26
  using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
#    endif

  _LIBCPP_HIDE_FROM_ABI basic_ifstream();
  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
#    endif
  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
#    if _LIBCPP_STD_VER >= 17
  template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const _Tp& __p, ios_base::openmode __mode = ios_base::in)
      : basic_ifstream(__p.c_str(), __mode) {}
#    endif // _LIBCPP_STD_VER >= 17
  _LIBCPP_HIDE_FROM_ABI basic_ifstream(basic_ifstream&& __rhs);
  _LIBCPP_HIDE_FROM_ABI basic_ifstream& operator=(basic_ifstream&& __rhs);
  _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs);

  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
#    if _LIBCPP_STD_VER >= 26
  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
    return rdbuf()->native_handle();
  }
#    endif
  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool is_open() const;
  void open(const char* __s, ios_base::openmode __mode = ios_base::in);
#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
#    endif
  void open(const string& __s, ios_base::openmode __mode = ios_base::in);
#    if _LIBCPP_STD_VER >= 17
  _LIBCPP_HIDE_FROM_ABI void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) {
    return open(__p.c_str(), __mode);
  }
#    endif // _LIBCPP_STD_VER >= 17

  _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
  _LIBCPP_HIDE_FROM_ABI void close();

private:
  basic_filebuf<char_type, traits_type> __sb_;
};

template <class _CharT, class _Traits>
inline basic_ifstream<_CharT, _Traits>::basic_ifstream()
    : basic_istream<char_type, traits_type>(std::addressof(__sb_)) {}

template <class _CharT, class _Traits>
inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
    : basic_istream<char_type, traits_type>(std::addressof(__sb_)) {
  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
    this->setstate(ios_base::failbit);
}

#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
template <class _CharT, class _Traits>
inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode)
    : basic_istream<char_type, traits_type>(std::addressof(__sb_)) {
  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
    this->setstate(ios_base::failbit);
}
#    endif

// extension
template <class _CharT, class _Traits>
inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)
    : basic_istream<char_type, traits_type>(std::addressof(__sb_)) {
  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
    this->setstate(ios_base::failbit);
}

template <class _CharT, class _Traits>
inline basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
    : basic_istream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
  this->set_rdbuf(std::addressof(__sb_));
}

template <class _CharT, class _Traits>
inline basic_ifstream<_CharT, _Traits>& basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) {
  basic_istream<char_type, traits_type>::operator=(std::move(__rhs));
  __sb_ = std::move(__rhs.__sb_);
  return *this;
}

template <class _CharT, class _Traits>
inline void basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) {
  basic_istream<char_type, traits_type>::swap(__rhs);
  __sb_.swap(__rhs.__sb_);
}

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

template <class _CharT, class _Traits>
inline basic_filebuf<_CharT, _Traits>* basic_ifstream<_CharT, _Traits>::rdbuf() const {
  return const_cast<basic_filebuf<char_type, traits_type>*>(std::addressof(__sb_));
}

template <class _CharT, class _Traits>
inline bool basic_ifstream<_CharT, _Traits>::is_open() const {
  return __sb_.is_open();
}

template <class _CharT, class _Traits>
void basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
  if (__sb_.open(__s, __mode | ios_base::in))
    this->clear();
  else
    this->setstate(ios_base::failbit);
}

#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
template <class _CharT, class _Traits>
void basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
  if (__sb_.open(__s, __mode | ios_base::in))
    this->clear();
  else
    this->setstate(ios_base::failbit);
}
#    endif

template <class _CharT, class _Traits>
void basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
  if (__sb_.open(__s, __mode | ios_base::in))
    this->clear();
  else
    this->setstate(ios_base::failbit);
}

template <class _CharT, class _Traits>
inline void basic_ifstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
  if (__sb_.__open(__fd, __mode | ios_base::in))
    this->clear();
  else
    this->setstate(ios_base::failbit);
}

template <class _CharT, class _Traits>
inline void basic_ifstream<_CharT, _Traits>::close() {
  if (__sb_.close() == 0)
    this->setstate(ios_base::failbit);
}

// basic_ofstream

template <class _CharT, class _Traits>
class basic_ofstream : 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;
#    if _LIBCPP_STD_VER >= 26
  using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
#    endif

  _LIBCPP_HIDE_FROM_ABI basic_ofstream();
  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
#    endif
  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);

#    if _LIBCPP_STD_VER >= 17
  template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const _Tp& __p, ios_base::openmode __mode = ios_base::out)
      : basic_ofstream(__p.c_str(), __mode) {}
#    endif // _LIBCPP_STD_VER >= 17

  _LIBCPP_HIDE_FROM_ABI basic_ofstream(basic_ofstream&& __rhs);
  _LIBCPP_HIDE_FROM_ABI basic_ofstream& operator=(basic_ofstream&& __rhs);
  _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream& __rhs);

  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
#    if _LIBCPP_STD_VER >= 26
  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
    return rdbuf()->native_handle();
  }
#    endif
  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool is_open() const;
  void open(const char* __s, ios_base::openmode __mode = ios_base::out);
#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
#    endif
  void open(const string& __s, ios_base::openmode __mode = ios_base::out);

#    if _LIBCPP_STD_VER >= 17
  _LIBCPP_HIDE_FROM_ABI void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) {
    return open(__p.c_str(), __mode);
  }
#    endif // _LIBCPP_STD_VER >= 17

  _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
  _LIBCPP_HIDE_FROM_ABI void close();

private:
  basic_filebuf<char_type, traits_type> __sb_;
};

template <class _CharT, class _Traits>
inline basic_ofstream<_CharT, _Traits>::basic_ofstream()
    : basic_ostream<char_type, traits_type>(std::addressof(__sb_)) {}

template <class _CharT, class _Traits>
inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
    : basic_ostream<char_type, traits_type>(std::addressof(__sb_)) {
  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
    this->setstate(ios_base::failbit);
}

#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
template <class _CharT, class _Traits>
inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode)
    : basic_ostream<char_type, traits_type>(std::addressof(__sb_)) {
  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
    this->setstate(ios_base::failbit);
}
#    endif

// extension
template <class _CharT, class _Traits>
inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)
    : basic_ostream<char_type, traits_type>(std::addressof(__sb_)) {
  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
    this->setstate(ios_base::failbit);
}

template <class _CharT, class _Traits>
inline basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
    : basic_ostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
  this->set_rdbuf(std::addressof(__sb_));
}

template <class _CharT, class _Traits>
inline basic_ofstream<_CharT, _Traits>& basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) {
  basic_ostream<char_type, traits_type>::operator=(std::move(__rhs));
  __sb_ = std::move(__rhs.__sb_);
  return *this;
}

template <class _CharT, class _Traits>
inline void basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) {
  basic_ostream<char_type, traits_type>::swap(__rhs);
  __sb_.swap(__rhs.__sb_);
}

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

template <class _CharT, class _Traits>
inline basic_filebuf<_CharT, _Traits>* basic_ofstream<_CharT, _Traits>::rdbuf() const {
  return const_cast<basic_filebuf<char_type, traits_type>*>(std::addressof(__sb_));
}

template <class _CharT, class _Traits>
inline bool basic_ofstream<_CharT, _Traits>::is_open() const {
  return __sb_.is_open();
}

template <class _CharT, class _Traits>
void basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
  if (__sb_.open(__s, __mode | ios_base::out))
    this->clear();
  else
    this->setstate(ios_base::failbit);
}

#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
template <class _CharT, class _Traits>
void basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
  if (__sb_.open(__s, __mode | ios_base::out))
    this->clear();
  else
    this->setstate(ios_base::failbit);
}
#    endif

template <class _CharT, class _Traits>
void basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
  if (__sb_.open(__s, __mode | ios_base::out))
    this->clear();
  else
    this->setstate(ios_base::failbit);
}

template <class _CharT, class _Traits>
inline void basic_ofstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
  if (__sb_.__open(__fd, __mode | ios_base::out))
    this->clear();
  else
    this->setstate(ios_base::failbit);
}

template <class _CharT, class _Traits>
inline void basic_ofstream<_CharT, _Traits>::close() {
  if (__sb_.close() == nullptr)
    this->setstate(ios_base::failbit);
}

// basic_fstream

template <class _CharT, class _Traits>
class basic_fstream : 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;
#    if _LIBCPP_STD_VER >= 26
  using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
#    endif

  _LIBCPP_HIDE_FROM_ABI basic_fstream() : basic_iostream<char_type, traits_type>(std::addressof(__sb_)) {}
  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const char* __s,
                                               ios_base::openmode __mode = ios_base::in | ios_base::out)
      : basic_iostream<char_type, traits_type>(std::addressof(__sb_)) {
    if (__sb_.open(__s, __mode) == nullptr)
      this->setstate(ios_base::failbit);
  }
#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const wchar_t* __s,
                                               ios_base::openmode __mode = ios_base::in | ios_base::out)
      : basic_iostream<char_type, traits_type>(std::addressof(__sb_)) {
    if (__sb_.open(__s, __mode) == nullptr)
      this->setstate(ios_base::failbit);
  }
#    endif

  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const string& __s,
                                               ios_base::openmode __mode = ios_base::in | ios_base::out)
      : basic_iostream<char_type, traits_type>(std::addressof(__sb_)) {
    if (__sb_.open(__s, __mode) == nullptr)
      this->setstate(ios_base::failbit);
  }

#    if _LIBCPP_STD_VER >= 17
  template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const _Tp& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
      : basic_fstream(__p.c_str(), __mode) {}
#    endif // _LIBCPP_STD_VER >= 17

  _LIBCPP_HIDE_FROM_ABI basic_fstream(basic_fstream&& __rhs)
      : basic_iostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
    this->set_rdbuf(std::addressof(__sb_));
  }

  _LIBCPP_HIDE_FROM_ABI basic_fstream& operator=(basic_fstream&& __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_fstream& __rhs) {
    basic_iostream<char_type, traits_type>::swap(__rhs);
    __sb_.swap(__rhs.__sb_);
  }

  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const {
    return const_cast<basic_filebuf<char_type, traits_type>*>(std::addressof(__sb_));
  }

#    if _LIBCPP_STD_VER >= 26
  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
    return rdbuf()->native_handle();
  }
#    endif

  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool is_open() const { return __sb_.is_open(); }

  _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out) {
    if (__sb_.open(__s, __mode))
      this->clear();
    else
      this->setstate(ios_base::failbit);
  }

#    if _LIBCPP_HAS_OPEN_WITH_WCHAR
  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out) {
    if (__sb_.open(__s, __mode))
      this->clear();
    else
      this->setstate(ios_base::failbit);
  }
#    endif
  _LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out) {
    if (__sb_.open(__s, __mode))
      this->clear();
    else
      this->setstate(ios_base::failbit);
  }

#    if _LIBCPP_STD_VER >= 17
  _LIBCPP_HIDE_FROM_ABI void
  open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) {
    return open(__p.c_str(), __mode);
  }
#    endif // _LIBCPP_STD_VER >= 17

  _LIBCPP_HIDE_FROM_ABI void close() {
    if (__sb_.close() == nullptr)
      this->setstate(ios_base::failbit);
  }

private:
  basic_filebuf<char_type, traits_type> __sb_;
};

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

#    if _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ifstream<char>;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ofstream<char>;
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>;
#    endif

_LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#  endif // _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION

#  if defined(_LIBCPP_KEEP_TRANSITIVE_INCLUDES_LLVM23) && _LIBCPP_STD_VER <= 20
#    include <atomic>
#    include <concepts>
#    include <cstdlib>
#    include <iosfwd>
#    include <limits>
#    include <mutex>
#    include <new>
#    include <stdexcept>
#    include <type_traits>
#  endif

#  if defined(_LIBCPP_KEEP_TRANSITIVE_INCLUDES_LLVM23) && _LIBCPP_STD_VER <= 23
#    include <filesystem>
#  endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)

#endif // _LIBCPP_FSTREAM
