// -*- 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_dir/codecvt.h>
#    include <__locale_dir/locale.h>
#    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

#    if defined(_AIX)
// On AIX, fopen64/fseeko64/ftello64 are not guaranteed to always be declared, so we declare them
// here. We use `__asm__` to avoid colliding with the declaration in the header in any way.
extern "C" FILE* __libcpp_fopen64(const char*, const char*) __asm__("fopen64");
extern "C" long long __libcpp_ftello64(FILE*) __asm__("ftello64");
extern "C" int __libcpp_fseeko64(FILE*, long long, int) __asm__("fseeko64");
#    endif

_LIBCPP_PUSH_MACROS
#    include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS

#    if _LIBCPP_STD_VER >= 23 && defined(_WIN32)
_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(_WIN32)
  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(_WIN32)
    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_HIDE_FROM_ABI static FILE* __fopen(const char* __name, const char* __mode);

  _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>
FILE* basic_filebuf<_CharT, _Traits>::__fopen(const char* __name, const char* __mode) {
#    if defined(_AIX)
  return ::__libcpp_fopen64(__name, __mode);
#    elif defined(__GLIBC__)
  return ::fopen64(__name, __mode);
#    else
  return std::fopen(__name, __mode);
#    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(__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) {
#    ifdef _WIN32
  return _fseeki64(__file, __offset, __whence);
#    elif _LIBCPP_LIBC_NEWLIB
  return fseek(__file, __offset, __whence);
#    elif defined(_AIX)
  return ::__libcpp_fseeko64(__file, __offset, __whence);
#    elif defined(__GLIBC__)
  return ::fseeko64(__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) {
#    ifdef _WIN32
  return _ftelli64(__file);
#    elif _LIBCPP_LIBC_NEWLIB
  return ftell(__file);
#    elif defined(_AIX)
  return ::__libcpp_ftello64(__file);
#    elif defined(__GLIBC__)
  return ::ftello64(__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

#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)

#endif // _LIBCPP_FSTREAM
