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

    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);
    explicit basic_ifstream(const filesystem::path& p,
                            ios_base::openmode mode = ios_base::in); // 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;
    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;

    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);
    explicit basic_ofstream(const filesystem::path& p,
                            ios_base::openmode mode = ios_base::out); // 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;
    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;

    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);
    explicit basic_fstream(const filesystem::path& p,
                           ios_base::openmode mode = ios_base::in|ios_base::out); 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;
    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

*/

#include <__algorithm/max.h>
#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
#include <__locale>
#include <__utility/move.h>
#include <__utility/swap.h>
#include <__utility/unreachable.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <istream>
#include <ostream>
#include <version>

#if !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
#   include <filesystem>
#endif

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

_LIBCPP_PUSH_MACROS
#include <__undef_macros>

#if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION)
#  define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _CharT, class _Traits>
class _LIBCPP_TEMPLATE_VIS 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;

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

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

    // 27.9.1.4 Members:
    _LIBCPP_INLINE_VISIBILITY
    bool is_open() const;
    basic_filebuf* open(const char* __s, ios_base::openmode __mode);
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
    basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode);
#endif
    _LIBCPP_INLINE_VISIBILITY
    basic_filebuf* open(const string& __s, ios_base::openmode __mode);

#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
    basic_filebuf* open(const _VSTD_FS::path& __p, ios_base::openmode __mode) {
      return open(__p.c_str(), __mode);
    }
#endif
    _LIBCPP_INLINE_VISIBILITY
    basic_filebuf* __open(int __fd, ios_base::openmode __mode);
    basic_filebuf* close();

    _LIBCPP_INLINE_VISIBILITY
    inline static const char*
    __make_mdstring(ios_base::openmode __mode) _NOEXCEPT;

  protected:
    // 27.9.1.5 Overridden virtual functions:
    virtual int_type underflow();
    virtual int_type pbackfail(int_type __c = traits_type::eof());
    virtual int_type overflow (int_type __c = traits_type::eof());
    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n);
    virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
                             ios_base::openmode __wch = ios_base::in | ios_base::out);
    virtual pos_type seekpos(pos_type __sp,
                             ios_base::openmode __wch = ios_base::in | ios_base::out);
    virtual int sync();
    virtual void imbue(const locale& __loc);

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_;
  ios_base::openmode __cm_;
  bool __owns_eb_;
  bool __owns_ib_;
  bool __always_noconv_;

  bool __read_mode();
  void __write_mode();
};

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_(0),
      __owns_eb_(false),
      __owns_ib_(false),
      __always_noconv_(false)
{
    if (has_facet<codecvt<char_type, char, state_type> >(this->getloc()))
    {
        __cv_ = &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()
{
#ifndef _LIBCPP_NO_EXCEPTIONS
    try
    {
#endif // _LIBCPP_NO_EXCEPTIONS
        close();
#ifndef _LIBCPP_NO_EXCEPTIONS
    }
    catch (...)
    {
    }
#endif // _LIBCPP_NO_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;
    }
    _VSTD::swap(__ebs_, __rhs.__ebs_);
    _VSTD::swap(__intbuf_, __rhs.__intbuf_);
    _VSTD::swap(__ibs_, __rhs.__ibs_);
    _VSTD::swap(__file_, __rhs.__file_);
    _VSTD::swap(__cv_, __rhs.__cv_);
    _VSTD::swap(__st_, __rhs.__st_);
    _VSTD::swap(__st_last_, __rhs.__st_last_);
    _VSTD::swap(__om_, __rhs.__om_);
    _VSTD::swap(__cm_, __rhs.__cm_);
    _VSTD::swap(__owns_eb_, __rhs.__owns_eb_);
    _VSTD::swap(__owns_ib_, __rhs.__owns_ib_);
    _VSTD::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_INLINE_VISIBILITY
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;
  default:
    return nullptr;
  }
  __libcpp_unreachable();
}

template <class _CharT, class _Traits>
basic_filebuf<_CharT, _Traits>*
basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
{
    basic_filebuf<_CharT, _Traits>* __rt = nullptr;
    if (__file_ == nullptr)
    {
      if (const char* __mdstr = __make_mdstring(__mode)) {
        __rt = this;
        __file_ = fopen(__s, __mdstr);
        if (__file_) {
          __om_ = __mode;
          if (__mode & ios_base::ate) {
            if (fseek(__file_, 0, SEEK_END)) {
              fclose(__file_);
              __file_ = nullptr;
              __rt = nullptr;
            }
          }
        } else
          __rt = nullptr;
      }
    }
    return __rt;
}

template <class _CharT, class _Traits>
inline
basic_filebuf<_CharT, _Traits>*
basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
  if (__file_ == nullptr) {
    if (const char* __mdstr = __make_mdstring(__mode)) {
      __rt = this;
      __file_ = fdopen(__fd, __mdstr);
      if (__file_) {
        __om_ = __mode;
        if (__mode & ios_base::ate) {
          if (fseek(__file_, 0, SEEK_END)) {
            fclose(__file_);
            __file_ = nullptr;
            __rt = nullptr;
          }
        }
      } else
        __rt = nullptr;
    }
  }
  return __rt;
}

#ifdef _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)
{
    basic_filebuf<_CharT, _Traits>* __rt = nullptr;
    if (__file_ == nullptr)
    {
        __rt = this;
        const wchar_t* __mdstr;
        switch (__mode & ~ios_base::ate)
        {
        case ios_base::out:
        case ios_base::out | ios_base::trunc:
            __mdstr = L"w";
            break;
        case ios_base::out | ios_base::app:
        case ios_base::app:
            __mdstr = L"a";
            break;
        case ios_base::in:
            __mdstr = L"r";
            break;
        case ios_base::in | ios_base::out:
            __mdstr = L"r+";
            break;
        case ios_base::in | ios_base::out | ios_base::trunc:
            __mdstr = L"w+";
            break;
        case ios_base::in | ios_base::out | ios_base::app:
        case ios_base::in | ios_base::app:
            __mdstr = L"a+";
            break;
        case ios_base::out | ios_base::binary:
        case ios_base::out | ios_base::trunc | ios_base::binary:
            __mdstr = L"wb";
            break;
        case ios_base::out | ios_base::app | ios_base::binary:
        case ios_base::app | ios_base::binary:
            __mdstr = L"ab";
            break;
        case ios_base::in | ios_base::binary:
            __mdstr = L"rb";
            break;
        case ios_base::in | ios_base::out | ios_base::binary:
            __mdstr = L"r+b";
            break;
        case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
            __mdstr = L"w+b";
            break;
        case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
        case ios_base::in | ios_base::app | ios_base::binary:
            __mdstr = L"a+b";
            break;
        default:
            __rt = nullptr;
            break;
        }
        if (__rt)
        {
            __file_ = _wfopen(__s, __mdstr);
            if (__file_)
            {
                __om_ = __mode;
                if (__mode & ios_base::ate)
                {
                    if (fseek(__file_, 0, SEEK_END))
                    {
                        fclose(__file_);
                        __file_ = nullptr;
                        __rt = nullptr;
                    }
                }
            }
            else
                __rt = nullptr;
        }
    }
    return __rt;
}
#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(&__1buf, &__1buf+1, &__1buf+1);
    const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
    int_type __c = traits_type::eof();
    if (this->gptr() == this->egptr())
    {
        _VSTD::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 = 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
        {
            _LIBCPP_ASSERT ( !(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" );
            if (__extbufend_ != __extbufnext_)
                _VSTD::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
            __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
            __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
            size_t __nmemb = _VSTD::min(static_cast<size_t>(__ibs_ - __unget_sz),
                                 static_cast<size_t>(__extbufend_ - __extbufnext_));
            codecvt_base::result __r;
            __st_last_ = __st_;
            size_t __nr = fread((void*) const_cast<char *>(__extbufnext_), 1, __nmemb, __file_);
            if (__nr != 0)
            {
                if (!__cv_)
                    __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() == &__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(&__1buf, &__1buf+1);
        *this->pptr() = traits_type::to_char_type(__c);
        this->pbump(1);
    }
    if (this->pptr() != this->pbase())
    {
        if (__always_noconv_)
        {
            size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
            if (fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
                return traits_type::eof();
        }
        else
        {
            char* __extbe = __extbuf_;
            codecvt_base::result __r;
            do
            {
                if (!__cv_)
                    __throw_bad_cast();

                const char_type* __e;
                __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
                                        __extbuf_, __extbuf_ + __ebs_, __extbe);
                if (__e == this->pbase())
                    return traits_type::eof();
                if (__r == codecvt_base::noconv)
                {
                    size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
                    if (fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
                        return traits_type::eof();
                }
                else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
                {
                    size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
                    if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
                        return traits_type::eof();
                    if (__r == codecvt_base::partial)
                    {
                        this->setp(const_cast<char_type*>(__e), this->pptr());
                        this->__pbump(this->epptr() - this->pbase());
                    }
                }
                else
                    return traits_type::eof();
            } while (__r == codecvt_base::partial);
        }
        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);
    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_)
        __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 defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
    if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
        return pos_type(off_type(-1));
    pos_type __r = ftell(__file_);
#else
    if (fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
        return pos_type(off_type(-1));
    pos_type __r = ftello(__file_);
#endif
    __r.state(__st_);
    return __r;
}

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 defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
    if (fseek(__file_, __sp, SEEK_SET))
        return pos_type(off_type(-1));
#else
    if (fseeko(__file_, __sp, SEEK_SET))
        return pos_type(off_type(-1));
#endif
    __st_ = __sp.state();
    return __sp;
}

template <class _CharT, class _Traits>
int
basic_filebuf<_CharT, _Traits>::sync()
{
    if (__file_ == nullptr)
        return 0;
    if (!__cv_)
        __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 (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
                return -1;
        } while (__r == codecvt_base::partial);
        if (__r == codecvt_base::error)
            return -1;
        if (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 defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
        if (fseek(__file_, -__c, SEEK_CUR))
            return -1;
#else
        if (fseeko(__file_, -__c, SEEK_CUR))
            return -1;
#endif
        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_ = &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 _LIBCPP_TEMPLATE_VIS 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;

    _LIBCPP_INLINE_VISIBILITY
    basic_ifstream();
    _LIBCPP_INLINE_VISIBILITY
    explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
    _LIBCPP_INLINE_VISIBILITY
    explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
#endif
    _LIBCPP_INLINE_VISIBILITY
    explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
    explicit basic_ifstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in)
      : basic_ifstream(__p.c_str(), __mode) {}
#endif // _LIBCPP_STD_VER >= 17
    _LIBCPP_INLINE_VISIBILITY
    basic_ifstream(basic_ifstream&& __rhs);
    _LIBCPP_INLINE_VISIBILITY
    basic_ifstream& operator=(basic_ifstream&& __rhs);
    _LIBCPP_INLINE_VISIBILITY
    void swap(basic_ifstream& __rhs);

    _LIBCPP_INLINE_VISIBILITY
    basic_filebuf<char_type, traits_type>* rdbuf() const;
    _LIBCPP_INLINE_VISIBILITY
    bool is_open() const;
    void open(const char* __s, ios_base::openmode __mode = ios_base::in);
#ifdef _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 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
    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_INLINE_VISIBILITY
    void __open(int __fd, ios_base::openmode __mode);
    _LIBCPP_INLINE_VISIBILITY
    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>(&__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>(&__sb_)
{
    if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
        this->setstate(ios_base::failbit);
}

#ifdef _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>(&__sb_)
{
    if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
        this->setstate(ios_base::failbit);
}
#endif

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>(&__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>(_VSTD::move(__rhs)),
      __sb_(_VSTD::move(__rhs.__sb_))
{
    this->set_rdbuf(&__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=(_VSTD::move(__rhs));
    __sb_ = _VSTD::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_INLINE_VISIBILITY
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>*>(&__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);
}

#ifdef _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 _LIBCPP_TEMPLATE_VIS 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;

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

#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
    explicit basic_ofstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
      : basic_ofstream(__p.c_str(), __mode) {}
#endif // _LIBCPP_STD_VER >= 17

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

    _LIBCPP_INLINE_VISIBILITY
    basic_filebuf<char_type, traits_type>* rdbuf() const;
    _LIBCPP_INLINE_VISIBILITY
    bool is_open() const;
    void open(const char* __s, ios_base::openmode __mode = ios_base::out);
#ifdef _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 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
    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_INLINE_VISIBILITY
    void __open(int __fd, ios_base::openmode __mode);
    _LIBCPP_INLINE_VISIBILITY
    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>(&__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>(&__sb_)
{
    if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
        this->setstate(ios_base::failbit);
}

#ifdef _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>(&__sb_)
{
    if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
        this->setstate(ios_base::failbit);
}
#endif

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>(&__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>(_VSTD::move(__rhs)),
      __sb_(_VSTD::move(__rhs.__sb_))
{
    this->set_rdbuf(&__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=(_VSTD::move(__rhs));
    __sb_ = _VSTD::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_INLINE_VISIBILITY
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>*>(&__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);
}

#ifdef _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 _LIBCPP_TEMPLATE_VIS 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;

    _LIBCPP_INLINE_VISIBILITY
    basic_fstream();
    _LIBCPP_INLINE_VISIBILITY
    explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
    _LIBCPP_INLINE_VISIBILITY
    explicit basic_fstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
#endif
    _LIBCPP_INLINE_VISIBILITY
    explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);

#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
    explicit basic_fstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
      : basic_fstream(__p.c_str(), __mode) {}
#endif // _LIBCPP_STD_VER >= 17

    _LIBCPP_INLINE_VISIBILITY
    basic_fstream(basic_fstream&& __rhs);

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

    _LIBCPP_INLINE_VISIBILITY
    void swap(basic_fstream& __rhs);

    _LIBCPP_INLINE_VISIBILITY
    basic_filebuf<char_type, traits_type>* rdbuf() const;
    _LIBCPP_INLINE_VISIBILITY
    bool is_open() const;
    void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
#ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
    void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
#endif
    void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);

#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY)
    _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY
    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_INLINE_VISIBILITY
    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>(&__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>(&__sb_)
{
    if (__sb_.open(__s, __mode) == nullptr)
        this->setstate(ios_base::failbit);
}

#ifdef _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>(&__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>(&__sb_)
{
    if (__sb_.open(__s, __mode) == nullptr)
        this->setstate(ios_base::failbit);
}

template <class _CharT, class _Traits>
inline
basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
    : basic_iostream<char_type, traits_type>(_VSTD::move(__rhs)),
      __sb_(_VSTD::move(__rhs.__sb_))
{
    this->set_rdbuf(&__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=(_VSTD::move(__rhs));
    __sb_ = _VSTD::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_INLINE_VISIBILITY
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>*>(&__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);
}

#ifdef _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 defined(_LIBCPP_ABI_ENABLE_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_FSTREAM
