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

#    if _LIBCPP_STD_VER >= 26 && 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:
  _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_AVAILABILITY_FILESYSTEM_LIBRARY _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
  _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;

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

  // There are multiple (__)open function, they use different C-API open
  // function. After that call these functions behave the same. This function
  // does that part and determines the final return value.
  _LIBCPP_HIDE_FROM_ABI basic_filebuf* __do_open(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;
  }

  // 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(char_type* __s, streamsize __n) {
    if (__cm_ == __no_io_operations && __s == nullptr && __n == 0) {
      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;
}

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 __do_open(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 __do_open(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 __do_open(_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;
    setbuf(0, 0);
  }
  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();
  bool __initial = __read_mode();
  char_type __1buf;
  if (this->gptr() == nullptr)
    this->setg(std::addressof(__1buf), std::addressof(__1buf) + 1, std::addressof(__1buf) + 1);
  const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
  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());
  if (this->eback() == std::addressof(__1buf))
    this->setg(nullptr, nullptr, nullptr);
  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);
  __request_unbuffered_mode(__s, __n);
  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 defined(_NEWLIB_VERSION)
  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 defined(_NEWLIB_VERSION)
  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>
bool basic_filebuf<_CharT, _Traits>::__read_mode() {
  if (!(__cm_ & ios_base::in)) {
    this->setp(nullptr, nullptr);
    if (__always_noconv_)
      this->setg((char_type*)__extbuf_, (char_type*)__extbuf_ + __ebs_, (char_type*)__extbuf_ + __ebs_);
    else
      this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
    __cm_ = ios_base::in;
    return true;
  }
  return false;
}

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

  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
#    if _LIBCPP_STD_VER >= 26
  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
#    endif
  _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_AVAILABILITY_FILESYSTEM_LIBRARY _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_AVAILABILITY_FILESYSTEM_LIBRARY
      _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);

  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
#    if _LIBCPP_STD_VER >= 26
  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
#    endif
  _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_AVAILABILITY_FILESYSTEM_LIBRARY _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();
  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const char* __s,
                                               ios_base::openmode __mode = ios_base::in | ios_base::out);
#    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);
#    endif
  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const string& __s,
                                               ios_base::openmode __mode = ios_base::in | ios_base::out);

#    if _LIBCPP_STD_VER >= 17
  template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _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);

  _LIBCPP_HIDE_FROM_ABI basic_fstream& operator=(basic_fstream&& __rhs);

  _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream& __rhs);

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

#    if _LIBCPP_STD_VER >= 17
  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _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();

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

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

template <class _CharT, class _Traits>
inline basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
    : 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
template <class _CharT, class _Traits>
inline basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode)
    : basic_iostream<char_type, traits_type>(std::addressof(__sb_)) {
  if (__sb_.open(__s, __mode) == nullptr)
    this->setstate(ios_base::failbit);
}
#    endif

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

// extension
template <class _CharT, class _Traits>
inline basic_fstream<_CharT, _Traits>::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_));
}

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

template <class _CharT, class _Traits>
inline void basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) {
  basic_iostream<char_type, traits_type>::swap(__rhs);
  __sb_.swap(__rhs.__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);
}

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

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

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

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

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

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

#    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_NAMESPACE_STD

_LIBCPP_POP_MACROS

#  endif // _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION

#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _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_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 23
#    include <filesystem>
#  endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)

#endif // _LIBCPP_FSTREAM
