xref: /freebsd/contrib/llvm-project/libcxx/include/fstream (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
10b57cec5SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_FSTREAM
110b57cec5SDimitry Andric#define _LIBCPP_FSTREAM
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    fstream synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andrictemplate <class charT, class traits = char_traits<charT> >
170b57cec5SDimitry Andricclass basic_filebuf
180b57cec5SDimitry Andric    : public basic_streambuf<charT, traits>
190b57cec5SDimitry Andric{
200b57cec5SDimitry Andricpublic:
210b57cec5SDimitry Andric    typedef charT                          char_type;
220b57cec5SDimitry Andric    typedef traits                         traits_type;
230b57cec5SDimitry Andric    typedef typename traits_type::int_type int_type;
240b57cec5SDimitry Andric    typedef typename traits_type::pos_type pos_type;
250b57cec5SDimitry Andric    typedef typename traits_type::off_type off_type;
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric    // 27.9.1.2 Constructors/destructor:
280b57cec5SDimitry Andric    basic_filebuf();
290b57cec5SDimitry Andric    basic_filebuf(basic_filebuf&& rhs);
300b57cec5SDimitry Andric    virtual ~basic_filebuf();
310b57cec5SDimitry Andric
320b57cec5SDimitry Andric    // 27.9.1.3 Assign/swap:
330b57cec5SDimitry Andric    basic_filebuf& operator=(basic_filebuf&& rhs);
340b57cec5SDimitry Andric    void swap(basic_filebuf& rhs);
350b57cec5SDimitry Andric
360b57cec5SDimitry Andric    // 27.9.1.4 Members:
370b57cec5SDimitry Andric    bool is_open() const;
380b57cec5SDimitry Andric    basic_filebuf* open(const char* s, ios_base::openmode mode);
390b57cec5SDimitry Andric    basic_filebuf* open(const string& s, ios_base::openmode mode);
400b57cec5SDimitry Andric    basic_filebuf* open(const filesystem::path& p, ios_base::openmode mode); // C++17
410b57cec5SDimitry Andric    basic_filebuf* close();
420b57cec5SDimitry Andric
430b57cec5SDimitry Andricprotected:
440b57cec5SDimitry Andric    // 27.9.1.5 Overridden virtual functions:
450b57cec5SDimitry Andric    virtual streamsize showmanyc();
460b57cec5SDimitry Andric    virtual int_type underflow();
470b57cec5SDimitry Andric    virtual int_type uflow();
480b57cec5SDimitry Andric    virtual int_type pbackfail(int_type c = traits_type::eof());
490b57cec5SDimitry Andric    virtual int_type overflow (int_type c = traits_type::eof());
500b57cec5SDimitry Andric    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* s, streamsize n);
510b57cec5SDimitry Andric    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
520b57cec5SDimitry Andric                             ios_base::openmode which = ios_base::in | ios_base::out);
530b57cec5SDimitry Andric    virtual pos_type seekpos(pos_type sp,
540b57cec5SDimitry Andric                             ios_base::openmode which = ios_base::in | ios_base::out);
550b57cec5SDimitry Andric    virtual int sync();
560b57cec5SDimitry Andric    virtual void imbue(const locale& loc);
570b57cec5SDimitry Andric};
580b57cec5SDimitry Andric
590b57cec5SDimitry Andrictemplate <class charT, class traits>
600b57cec5SDimitry Andric  void
610b57cec5SDimitry Andric  swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y);
620b57cec5SDimitry Andric
630b57cec5SDimitry Andrictypedef basic_filebuf<char>    filebuf;
640b57cec5SDimitry Andrictypedef basic_filebuf<wchar_t> wfilebuf;
650b57cec5SDimitry Andric
660b57cec5SDimitry Andrictemplate <class charT, class traits = char_traits<charT> >
670b57cec5SDimitry Andricclass basic_ifstream
680b57cec5SDimitry Andric    : public basic_istream<charT,traits>
690b57cec5SDimitry Andric{
700b57cec5SDimitry Andricpublic:
710b57cec5SDimitry Andric    typedef charT                          char_type;
720b57cec5SDimitry Andric    typedef traits                         traits_type;
730b57cec5SDimitry Andric    typedef typename traits_type::int_type int_type;
740b57cec5SDimitry Andric    typedef typename traits_type::pos_type pos_type;
750b57cec5SDimitry Andric    typedef typename traits_type::off_type off_type;
760b57cec5SDimitry Andric
770b57cec5SDimitry Andric    basic_ifstream();
780b57cec5SDimitry Andric    explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
790b57cec5SDimitry Andric    explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);
800b57cec5SDimitry Andric    explicit basic_ifstream(const filesystem::path& p,
810b57cec5SDimitry Andric                            ios_base::openmode mode = ios_base::in); // C++17
820b57cec5SDimitry Andric    basic_ifstream(basic_ifstream&& rhs);
830b57cec5SDimitry Andric
840b57cec5SDimitry Andric    basic_ifstream& operator=(basic_ifstream&& rhs);
850b57cec5SDimitry Andric    void swap(basic_ifstream& rhs);
860b57cec5SDimitry Andric
870b57cec5SDimitry Andric    basic_filebuf<char_type, traits_type>* rdbuf() const;
880b57cec5SDimitry Andric    bool is_open() const;
890b57cec5SDimitry Andric    void open(const char* s, ios_base::openmode mode = ios_base::in);
900b57cec5SDimitry Andric    void open(const string& s, ios_base::openmode mode = ios_base::in);
910b57cec5SDimitry Andric    void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++17
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric    void close();
940b57cec5SDimitry Andric};
950b57cec5SDimitry Andric
960b57cec5SDimitry Andrictemplate <class charT, class traits>
970b57cec5SDimitry Andric  void
980b57cec5SDimitry Andric  swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y);
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andrictypedef basic_ifstream<char>    ifstream;
1010b57cec5SDimitry Andrictypedef basic_ifstream<wchar_t> wifstream;
1020b57cec5SDimitry Andric
1030b57cec5SDimitry Andrictemplate <class charT, class traits = char_traits<charT> >
1040b57cec5SDimitry Andricclass basic_ofstream
1050b57cec5SDimitry Andric    : public basic_ostream<charT,traits>
1060b57cec5SDimitry Andric{
1070b57cec5SDimitry Andricpublic:
1080b57cec5SDimitry Andric    typedef charT                          char_type;
1090b57cec5SDimitry Andric    typedef traits                         traits_type;
1100b57cec5SDimitry Andric    typedef typename traits_type::int_type int_type;
1110b57cec5SDimitry Andric    typedef typename traits_type::pos_type pos_type;
1120b57cec5SDimitry Andric    typedef typename traits_type::off_type off_type;
1130b57cec5SDimitry Andric
1140b57cec5SDimitry Andric    basic_ofstream();
1150b57cec5SDimitry Andric    explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
1160b57cec5SDimitry Andric    explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);
1170b57cec5SDimitry Andric    explicit basic_ofstream(const filesystem::path& p,
1180b57cec5SDimitry Andric                            ios_base::openmode mode = ios_base::out); // C++17
1190b57cec5SDimitry Andric    basic_ofstream(basic_ofstream&& rhs);
1200b57cec5SDimitry Andric
1210b57cec5SDimitry Andric    basic_ofstream& operator=(basic_ofstream&& rhs);
1220b57cec5SDimitry Andric    void swap(basic_ofstream& rhs);
1230b57cec5SDimitry Andric
1240b57cec5SDimitry Andric    basic_filebuf<char_type, traits_type>* rdbuf() const;
1250b57cec5SDimitry Andric    bool is_open() const;
1260b57cec5SDimitry Andric    void open(const char* s, ios_base::openmode mode = ios_base::out);
1270b57cec5SDimitry Andric    void open(const string& s, ios_base::openmode mode = ios_base::out);
1280b57cec5SDimitry Andric    void open(const filesystem::path& p,
1290b57cec5SDimitry Andric              ios_base::openmode mode = ios_base::out); // C++17
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric    void close();
1320b57cec5SDimitry Andric};
1330b57cec5SDimitry Andric
1340b57cec5SDimitry Andrictemplate <class charT, class traits>
1350b57cec5SDimitry Andric  void
1360b57cec5SDimitry Andric  swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y);
1370b57cec5SDimitry Andric
1380b57cec5SDimitry Andrictypedef basic_ofstream<char>    ofstream;
1390b57cec5SDimitry Andrictypedef basic_ofstream<wchar_t> wofstream;
1400b57cec5SDimitry Andric
1410b57cec5SDimitry Andrictemplate <class charT, class traits=char_traits<charT> >
1420b57cec5SDimitry Andricclass basic_fstream
1430b57cec5SDimitry Andric    : public basic_iostream<charT,traits>
1440b57cec5SDimitry Andric{
1450b57cec5SDimitry Andricpublic:
1460b57cec5SDimitry Andric    typedef charT                          char_type;
1470b57cec5SDimitry Andric    typedef traits                         traits_type;
1480b57cec5SDimitry Andric    typedef typename traits_type::int_type int_type;
1490b57cec5SDimitry Andric    typedef typename traits_type::pos_type pos_type;
1500b57cec5SDimitry Andric    typedef typename traits_type::off_type off_type;
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andric    basic_fstream();
1530b57cec5SDimitry Andric    explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
1540b57cec5SDimitry Andric    explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
1550b57cec5SDimitry Andric    explicit basic_fstream(const filesystem::path& p,
1560b57cec5SDimitry Andric                           ios_base::openmode mode = ios_base::in|ios_base::out); C++17
1570b57cec5SDimitry Andric    basic_fstream(basic_fstream&& rhs);
1580b57cec5SDimitry Andric
1590b57cec5SDimitry Andric    basic_fstream& operator=(basic_fstream&& rhs);
1600b57cec5SDimitry Andric    void swap(basic_fstream& rhs);
1610b57cec5SDimitry Andric
1620b57cec5SDimitry Andric    basic_filebuf<char_type, traits_type>* rdbuf() const;
1630b57cec5SDimitry Andric    bool is_open() const;
1640b57cec5SDimitry Andric    void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
1650b57cec5SDimitry Andric    void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
1660b57cec5SDimitry Andric    void open(const filesystem::path& s,
1670b57cec5SDimitry Andric              ios_base::openmode mode = ios_base::in|ios_base::out); // C++17
1680b57cec5SDimitry Andric
1690b57cec5SDimitry Andric    void close();
1700b57cec5SDimitry Andric};
1710b57cec5SDimitry Andric
1720b57cec5SDimitry Andrictemplate <class charT, class traits>
1730b57cec5SDimitry Andric  void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y);
1740b57cec5SDimitry Andric
1750b57cec5SDimitry Andrictypedef basic_fstream<char>    fstream;
1760b57cec5SDimitry Andrictypedef basic_fstream<wchar_t> wfstream;
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andric}  // std
1790b57cec5SDimitry Andric
1800b57cec5SDimitry Andric*/
1810b57cec5SDimitry Andric
18281ad6265SDimitry Andric#include <__algorithm/max.h>
18381ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler
184e8d8bef9SDimitry Andric#include <__availability>
185fe6060f1SDimitry Andric#include <__config>
18606c3fb27SDimitry Andric#include <__fwd/fstream.h>
1870b57cec5SDimitry Andric#include <__locale>
18881ad6265SDimitry Andric#include <__utility/move.h>
18981ad6265SDimitry Andric#include <__utility/swap.h>
19081ad6265SDimitry Andric#include <__utility/unreachable.h>
1910b57cec5SDimitry Andric#include <cstdio>
19206c3fb27SDimitry Andric#include <filesystem>
193fe6060f1SDimitry Andric#include <istream>
194fe6060f1SDimitry Andric#include <ostream>
195bdd1243dSDimitry Andric#include <typeinfo>
19604eeddc0SDimitry Andric#include <version>
197e8d8bef9SDimitry Andric
1980b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1990b57cec5SDimitry Andric#  pragma GCC system_header
2000b57cec5SDimitry Andric#endif
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS
2030b57cec5SDimitry Andric#include <__undef_macros>
2040b57cec5SDimitry Andric
205fe6060f1SDimitry Andric#if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION)
206fe6060f1SDimitry Andric#  define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
207fe6060f1SDimitry Andric#endif
2080b57cec5SDimitry Andric
20906c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_FILESYSTEM)
210bdd1243dSDimitry Andric
2110b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2120b57cec5SDimitry Andric
2130b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
214*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS basic_filebuf : public basic_streambuf<_CharT, _Traits> {
2150b57cec5SDimitry Andricpublic:
2160b57cec5SDimitry Andric  typedef _CharT char_type;
2170b57cec5SDimitry Andric  typedef _Traits traits_type;
2180b57cec5SDimitry Andric  typedef typename traits_type::int_type int_type;
2190b57cec5SDimitry Andric  typedef typename traits_type::pos_type pos_type;
2200b57cec5SDimitry Andric  typedef typename traits_type::off_type off_type;
2210b57cec5SDimitry Andric  typedef typename traits_type::state_type state_type;
2220b57cec5SDimitry Andric
2230b57cec5SDimitry Andric  // 27.9.1.2 Constructors/destructor:
2240b57cec5SDimitry Andric  basic_filebuf();
2250b57cec5SDimitry Andric  basic_filebuf(basic_filebuf&& __rhs);
226bdd1243dSDimitry Andric  ~basic_filebuf() override;
2270b57cec5SDimitry Andric
2280b57cec5SDimitry Andric  // 27.9.1.3 Assign/swap:
229*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_filebuf& operator=(basic_filebuf&& __rhs);
2300b57cec5SDimitry Andric  void swap(basic_filebuf& __rhs);
2310b57cec5SDimitry Andric
2320b57cec5SDimitry Andric  // 27.9.1.4 Members:
233*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
2340b57cec5SDimitry Andric  basic_filebuf* open(const char* __s, ios_base::openmode __mode);
2350b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
2360b57cec5SDimitry Andric  basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode);
2370b57cec5SDimitry Andric#  endif
238*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const string& __s, ios_base::openmode __mode);
2390b57cec5SDimitry Andric
24006c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
241*cb14a3feSDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI basic_filebuf*
242*cb14a3feSDimitry Andric  open(const filesystem::path& __p, ios_base::openmode __mode) {
2430b57cec5SDimitry Andric    return open(__p.c_str(), __mode);
2440b57cec5SDimitry Andric  }
2450b57cec5SDimitry Andric#  endif
246*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_filebuf* __open(int __fd, ios_base::openmode __mode);
2470b57cec5SDimitry Andric  basic_filebuf* close();
2480b57cec5SDimitry Andric
249*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI inline static const char* __make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
2500b57cec5SDimitry Andric
2510b57cec5SDimitry Andricprotected:
2520b57cec5SDimitry Andric  // 27.9.1.5 Overridden virtual functions:
253bdd1243dSDimitry Andric  int_type underflow() override;
254bdd1243dSDimitry Andric  int_type pbackfail(int_type __c = traits_type::eof()) override;
255bdd1243dSDimitry Andric  int_type overflow(int_type __c = traits_type::eof()) override;
256bdd1243dSDimitry Andric  basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n) override;
257*cb14a3feSDimitry Andric  pos_type
258*cb14a3feSDimitry Andric  seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
259*cb14a3feSDimitry Andric  pos_type seekpos(pos_type __sp, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
260bdd1243dSDimitry Andric  int sync() override;
261bdd1243dSDimitry Andric  void imbue(const locale& __loc) override;
2620b57cec5SDimitry Andric
2630b57cec5SDimitry Andricprivate:
2640b57cec5SDimitry Andric  char* __extbuf_;
2650b57cec5SDimitry Andric  const char* __extbufnext_;
2660b57cec5SDimitry Andric  const char* __extbufend_;
2670b57cec5SDimitry Andric  char __extbuf_min_[8];
2680b57cec5SDimitry Andric  size_t __ebs_;
2690b57cec5SDimitry Andric  char_type* __intbuf_;
2700b57cec5SDimitry Andric  size_t __ibs_;
2710b57cec5SDimitry Andric  FILE* __file_;
2720b57cec5SDimitry Andric  const codecvt<char_type, char, state_type>* __cv_;
2730b57cec5SDimitry Andric  state_type __st_;
2740b57cec5SDimitry Andric  state_type __st_last_;
2750b57cec5SDimitry Andric  ios_base::openmode __om_;
2760b57cec5SDimitry Andric  ios_base::openmode __cm_;
2770b57cec5SDimitry Andric  bool __owns_eb_;
2780b57cec5SDimitry Andric  bool __owns_ib_;
2790b57cec5SDimitry Andric  bool __always_noconv_;
2800b57cec5SDimitry Andric
2810b57cec5SDimitry Andric  bool __read_mode();
2820b57cec5SDimitry Andric  void __write_mode();
283*cb14a3feSDimitry Andric
284*cb14a3feSDimitry Andric  _LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
2850b57cec5SDimitry Andric};
2860b57cec5SDimitry Andric
2870b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
2880b57cec5SDimitry Andricbasic_filebuf<_CharT, _Traits>::basic_filebuf()
289e8d8bef9SDimitry Andric    : __extbuf_(nullptr),
290e8d8bef9SDimitry Andric      __extbufnext_(nullptr),
291e8d8bef9SDimitry Andric      __extbufend_(nullptr),
2920b57cec5SDimitry Andric      __ebs_(0),
293e8d8bef9SDimitry Andric      __intbuf_(nullptr),
2940b57cec5SDimitry Andric      __ibs_(0),
295e8d8bef9SDimitry Andric      __file_(nullptr),
2960b57cec5SDimitry Andric      __cv_(nullptr),
2970b57cec5SDimitry Andric      __st_(),
2980b57cec5SDimitry Andric      __st_last_(),
2990b57cec5SDimitry Andric      __om_(0),
3000b57cec5SDimitry Andric      __cm_(0),
3010b57cec5SDimitry Andric      __owns_eb_(false),
3020b57cec5SDimitry Andric      __owns_ib_(false),
303*cb14a3feSDimitry Andric      __always_noconv_(false) {
304*cb14a3feSDimitry Andric  if (std::has_facet<codecvt<char_type, char, state_type> >(this->getloc())) {
305bdd1243dSDimitry Andric    __cv_            = &std::use_facet<codecvt<char_type, char, state_type> >(this->getloc());
3060b57cec5SDimitry Andric    __always_noconv_ = __cv_->always_noconv();
3070b57cec5SDimitry Andric  }
308e8d8bef9SDimitry Andric  setbuf(nullptr, 4096);
3090b57cec5SDimitry Andric}
3100b57cec5SDimitry Andric
3110b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
312*cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) : basic_streambuf<_CharT, _Traits>(__rhs) {
313*cb14a3feSDimitry Andric  if (__rhs.__extbuf_ == __rhs.__extbuf_min_) {
3140b57cec5SDimitry Andric    __extbuf_     = __extbuf_min_;
3150b57cec5SDimitry Andric    __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);
3160b57cec5SDimitry Andric    __extbufend_  = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);
317*cb14a3feSDimitry Andric  } else {
3180b57cec5SDimitry Andric    __extbuf_     = __rhs.__extbuf_;
3190b57cec5SDimitry Andric    __extbufnext_ = __rhs.__extbufnext_;
3200b57cec5SDimitry Andric    __extbufend_  = __rhs.__extbufend_;
3210b57cec5SDimitry Andric  }
3220b57cec5SDimitry Andric  __ebs_           = __rhs.__ebs_;
3230b57cec5SDimitry Andric  __intbuf_        = __rhs.__intbuf_;
3240b57cec5SDimitry Andric  __ibs_           = __rhs.__ibs_;
3250b57cec5SDimitry Andric  __file_          = __rhs.__file_;
3260b57cec5SDimitry Andric  __cv_            = __rhs.__cv_;
3270b57cec5SDimitry Andric  __st_            = __rhs.__st_;
3280b57cec5SDimitry Andric  __st_last_       = __rhs.__st_last_;
3290b57cec5SDimitry Andric  __om_            = __rhs.__om_;
3300b57cec5SDimitry Andric  __cm_            = __rhs.__cm_;
3310b57cec5SDimitry Andric  __owns_eb_       = __rhs.__owns_eb_;
3320b57cec5SDimitry Andric  __owns_ib_       = __rhs.__owns_ib_;
3330b57cec5SDimitry Andric  __always_noconv_ = __rhs.__always_noconv_;
334*cb14a3feSDimitry Andric  if (__rhs.pbase()) {
3350b57cec5SDimitry Andric    if (__rhs.pbase() == __rhs.__intbuf_)
3360b57cec5SDimitry Andric      this->setp(__intbuf_, __intbuf_ + (__rhs.epptr() - __rhs.pbase()));
3370b57cec5SDimitry Andric    else
338*cb14a3feSDimitry Andric      this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__rhs.epptr() - __rhs.pbase()));
3390b57cec5SDimitry Andric    this->__pbump(__rhs.pptr() - __rhs.pbase());
340*cb14a3feSDimitry Andric  } else if (__rhs.eback()) {
3410b57cec5SDimitry Andric    if (__rhs.eback() == __rhs.__intbuf_)
342*cb14a3feSDimitry Andric      this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()), __intbuf_ + (__rhs.egptr() - __rhs.eback()));
3430b57cec5SDimitry Andric    else
3440b57cec5SDimitry Andric      this->setg((char_type*)__extbuf_,
3450b57cec5SDimitry Andric                 (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),
3460b57cec5SDimitry Andric                 (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));
3470b57cec5SDimitry Andric  }
348e8d8bef9SDimitry Andric  __rhs.__extbuf_     = nullptr;
349e8d8bef9SDimitry Andric  __rhs.__extbufnext_ = nullptr;
350e8d8bef9SDimitry Andric  __rhs.__extbufend_  = nullptr;
3510b57cec5SDimitry Andric  __rhs.__ebs_        = 0;
3520b57cec5SDimitry Andric  __rhs.__intbuf_     = 0;
3530b57cec5SDimitry Andric  __rhs.__ibs_        = 0;
354e8d8bef9SDimitry Andric  __rhs.__file_       = nullptr;
3550b57cec5SDimitry Andric  __rhs.__st_         = state_type();
3560b57cec5SDimitry Andric  __rhs.__st_last_    = state_type();
3570b57cec5SDimitry Andric  __rhs.__om_         = 0;
3580b57cec5SDimitry Andric  __rhs.__cm_         = 0;
3590b57cec5SDimitry Andric  __rhs.__owns_eb_    = false;
3600b57cec5SDimitry Andric  __rhs.__owns_ib_    = false;
3610b57cec5SDimitry Andric  __rhs.setg(0, 0, 0);
3620b57cec5SDimitry Andric  __rhs.setp(0, 0);
3630b57cec5SDimitry Andric}
3640b57cec5SDimitry Andric
3650b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
366*cb14a3feSDimitry Andricinline basic_filebuf<_CharT, _Traits>& basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) {
3670b57cec5SDimitry Andric  close();
3680b57cec5SDimitry Andric  swap(__rhs);
3690b57cec5SDimitry Andric  return *this;
3700b57cec5SDimitry Andric}
3710b57cec5SDimitry Andric
3720b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
373*cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>::~basic_filebuf() {
37406c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
375*cb14a3feSDimitry Andric  try {
37606c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
3770b57cec5SDimitry Andric    close();
37806c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
379*cb14a3feSDimitry Andric  } catch (...) {
3800b57cec5SDimitry Andric  }
38106c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
3820b57cec5SDimitry Andric  if (__owns_eb_)
3830b57cec5SDimitry Andric    delete[] __extbuf_;
3840b57cec5SDimitry Andric  if (__owns_ib_)
3850b57cec5SDimitry Andric    delete[] __intbuf_;
3860b57cec5SDimitry Andric}
3870b57cec5SDimitry Andric
3880b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
389*cb14a3feSDimitry Andricvoid basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) {
3900b57cec5SDimitry Andric  basic_streambuf<char_type, traits_type>::swap(__rhs);
391*cb14a3feSDimitry Andric  if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
39281ad6265SDimitry Andric    // Neither *this nor __rhs uses the small buffer, so we can simply swap the pointers.
39381ad6265SDimitry Andric    std::swap(__extbuf_, __rhs.__extbuf_);
39481ad6265SDimitry Andric    std::swap(__extbufnext_, __rhs.__extbufnext_);
39581ad6265SDimitry Andric    std::swap(__extbufend_, __rhs.__extbufend_);
396*cb14a3feSDimitry Andric  } else {
39781ad6265SDimitry Andric    ptrdiff_t __ln = __extbufnext_ ? __extbufnext_ - __extbuf_ : 0;
39881ad6265SDimitry Andric    ptrdiff_t __le = __extbufend_ ? __extbufend_ - __extbuf_ : 0;
39981ad6265SDimitry Andric    ptrdiff_t __rn = __rhs.__extbufnext_ ? __rhs.__extbufnext_ - __rhs.__extbuf_ : 0;
40081ad6265SDimitry Andric    ptrdiff_t __re = __rhs.__extbufend_ ? __rhs.__extbufend_ - __rhs.__extbuf_ : 0;
401*cb14a3feSDimitry Andric    if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
40281ad6265SDimitry Andric      // *this uses the small buffer, but __rhs doesn't.
4030b57cec5SDimitry Andric      __extbuf_       = __rhs.__extbuf_;
4040b57cec5SDimitry Andric      __rhs.__extbuf_ = __rhs.__extbuf_min_;
40581ad6265SDimitry Andric      std::memmove(__rhs.__extbuf_min_, __extbuf_min_, sizeof(__extbuf_min_));
406*cb14a3feSDimitry Andric    } else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_) {
40781ad6265SDimitry Andric      // *this doesn't use the small buffer, but __rhs does.
4080b57cec5SDimitry Andric      __rhs.__extbuf_ = __extbuf_;
4090b57cec5SDimitry Andric      __extbuf_       = __extbuf_min_;
41081ad6265SDimitry Andric      std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
411*cb14a3feSDimitry Andric    } else {
41281ad6265SDimitry Andric      // Both *this and __rhs use the small buffer.
41381ad6265SDimitry Andric      char __tmp[sizeof(__extbuf_min_)];
41481ad6265SDimitry Andric      std::memmove(__tmp, __extbuf_min_, sizeof(__extbuf_min_));
41581ad6265SDimitry Andric      std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
41681ad6265SDimitry Andric      std::memmove(__rhs.__extbuf_min_, __tmp, sizeof(__extbuf_min_));
4170b57cec5SDimitry Andric    }
4180b57cec5SDimitry Andric    __extbufnext_       = __extbuf_ + __rn;
4190b57cec5SDimitry Andric    __extbufend_        = __extbuf_ + __re;
4200b57cec5SDimitry Andric    __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;
4210b57cec5SDimitry Andric    __rhs.__extbufend_  = __rhs.__extbuf_ + __le;
4220b57cec5SDimitry Andric  }
4235f757f3fSDimitry Andric  std::swap(__ebs_, __rhs.__ebs_);
4245f757f3fSDimitry Andric  std::swap(__intbuf_, __rhs.__intbuf_);
4255f757f3fSDimitry Andric  std::swap(__ibs_, __rhs.__ibs_);
4265f757f3fSDimitry Andric  std::swap(__file_, __rhs.__file_);
4275f757f3fSDimitry Andric  std::swap(__cv_, __rhs.__cv_);
4285f757f3fSDimitry Andric  std::swap(__st_, __rhs.__st_);
4295f757f3fSDimitry Andric  std::swap(__st_last_, __rhs.__st_last_);
4305f757f3fSDimitry Andric  std::swap(__om_, __rhs.__om_);
4315f757f3fSDimitry Andric  std::swap(__cm_, __rhs.__cm_);
4325f757f3fSDimitry Andric  std::swap(__owns_eb_, __rhs.__owns_eb_);
4335f757f3fSDimitry Andric  std::swap(__owns_ib_, __rhs.__owns_ib_);
4345f757f3fSDimitry Andric  std::swap(__always_noconv_, __rhs.__always_noconv_);
435*cb14a3feSDimitry Andric  if (this->eback() == (char_type*)__rhs.__extbuf_min_) {
4360b57cec5SDimitry Andric    ptrdiff_t __n = this->gptr() - this->eback();
4370b57cec5SDimitry Andric    ptrdiff_t __e = this->egptr() - this->eback();
438*cb14a3feSDimitry Andric    this->setg((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __n, (char_type*)__extbuf_min_ + __e);
439*cb14a3feSDimitry Andric  } else if (this->pbase() == (char_type*)__rhs.__extbuf_min_) {
4400b57cec5SDimitry Andric    ptrdiff_t __n = this->pptr() - this->pbase();
4410b57cec5SDimitry Andric    ptrdiff_t __e = this->epptr() - this->pbase();
442*cb14a3feSDimitry Andric    this->setp((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __e);
4430b57cec5SDimitry Andric    this->__pbump(__n);
4440b57cec5SDimitry Andric  }
445*cb14a3feSDimitry Andric  if (__rhs.eback() == (char_type*)__extbuf_min_) {
4460b57cec5SDimitry Andric    ptrdiff_t __n = __rhs.gptr() - __rhs.eback();
4470b57cec5SDimitry Andric    ptrdiff_t __e = __rhs.egptr() - __rhs.eback();
448*cb14a3feSDimitry Andric    __rhs.setg(
449*cb14a3feSDimitry Andric        (char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __n, (char_type*)__rhs.__extbuf_min_ + __e);
450*cb14a3feSDimitry Andric  } else if (__rhs.pbase() == (char_type*)__extbuf_min_) {
4510b57cec5SDimitry Andric    ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();
4520b57cec5SDimitry Andric    ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();
453*cb14a3feSDimitry Andric    __rhs.setp((char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __e);
4540b57cec5SDimitry Andric    __rhs.__pbump(__n);
4550b57cec5SDimitry Andric  }
4560b57cec5SDimitry Andric}
4570b57cec5SDimitry Andric
4580b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
459*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) {
4600b57cec5SDimitry Andric  __x.swap(__y);
4610b57cec5SDimitry Andric}
4620b57cec5SDimitry Andric
4630b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
464*cb14a3feSDimitry Andricinline bool basic_filebuf<_CharT, _Traits>::is_open() const {
465e8d8bef9SDimitry Andric  return __file_ != nullptr;
4660b57cec5SDimitry Andric}
4670b57cec5SDimitry Andric
4680b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
469*cb14a3feSDimitry Andricconst char* basic_filebuf<_CharT, _Traits>::__make_mdstring(ios_base::openmode __mode) _NOEXCEPT {
4700b57cec5SDimitry Andric  switch (__mode & ~ios_base::ate) {
4710b57cec5SDimitry Andric  case ios_base::out:
4720b57cec5SDimitry Andric  case ios_base::out | ios_base::trunc:
473e40139ffSDimitry Andric    return "w" _LIBCPP_FOPEN_CLOEXEC_MODE;
4740b57cec5SDimitry Andric  case ios_base::out | ios_base::app:
4750b57cec5SDimitry Andric  case ios_base::app:
476e40139ffSDimitry Andric    return "a" _LIBCPP_FOPEN_CLOEXEC_MODE;
4770b57cec5SDimitry Andric  case ios_base::in:
478e40139ffSDimitry Andric    return "r" _LIBCPP_FOPEN_CLOEXEC_MODE;
4790b57cec5SDimitry Andric  case ios_base::in | ios_base::out:
480e40139ffSDimitry Andric    return "r+" _LIBCPP_FOPEN_CLOEXEC_MODE;
4810b57cec5SDimitry Andric  case ios_base::in | ios_base::out | ios_base::trunc:
482e40139ffSDimitry Andric    return "w+" _LIBCPP_FOPEN_CLOEXEC_MODE;
4830b57cec5SDimitry Andric  case ios_base::in | ios_base::out | ios_base::app:
4840b57cec5SDimitry Andric  case ios_base::in | ios_base::app:
485e40139ffSDimitry Andric    return "a+" _LIBCPP_FOPEN_CLOEXEC_MODE;
4860b57cec5SDimitry Andric  case ios_base::out | ios_base::binary:
4870b57cec5SDimitry Andric  case ios_base::out | ios_base::trunc | ios_base::binary:
488e40139ffSDimitry Andric    return "wb" _LIBCPP_FOPEN_CLOEXEC_MODE;
4890b57cec5SDimitry Andric  case ios_base::out | ios_base::app | ios_base::binary:
4900b57cec5SDimitry Andric  case ios_base::app | ios_base::binary:
491e40139ffSDimitry Andric    return "ab" _LIBCPP_FOPEN_CLOEXEC_MODE;
4920b57cec5SDimitry Andric  case ios_base::in | ios_base::binary:
493e40139ffSDimitry Andric    return "rb" _LIBCPP_FOPEN_CLOEXEC_MODE;
4940b57cec5SDimitry Andric  case ios_base::in | ios_base::out | ios_base::binary:
495e40139ffSDimitry Andric    return "r+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
4960b57cec5SDimitry Andric  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
497e40139ffSDimitry Andric    return "w+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
4980b57cec5SDimitry Andric  case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
4990b57cec5SDimitry Andric  case ios_base::in | ios_base::app | ios_base::binary:
500e40139ffSDimitry Andric    return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
5015f757f3fSDimitry Andric#  if _LIBCPP_STD_VER >= 23
5025f757f3fSDimitry Andric  case ios_base::out | ios_base::noreplace:
5035f757f3fSDimitry Andric  case ios_base::out | ios_base::trunc | ios_base::noreplace:
5045f757f3fSDimitry Andric    return "wx" _LIBCPP_FOPEN_CLOEXEC_MODE;
5055f757f3fSDimitry Andric  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
5065f757f3fSDimitry Andric    return "w+x" _LIBCPP_FOPEN_CLOEXEC_MODE;
5075f757f3fSDimitry Andric  case ios_base::out | ios_base::binary | ios_base::noreplace:
5085f757f3fSDimitry Andric  case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
5095f757f3fSDimitry Andric    return "wbx" _LIBCPP_FOPEN_CLOEXEC_MODE;
5105f757f3fSDimitry Andric  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
5115f757f3fSDimitry Andric    return "w+bx" _LIBCPP_FOPEN_CLOEXEC_MODE;
5125f757f3fSDimitry Andric#  endif // _LIBCPP_STD_VER >= 23
5130b57cec5SDimitry Andric  default:
5140b57cec5SDimitry Andric    return nullptr;
5150b57cec5SDimitry Andric  }
51681ad6265SDimitry Andric  __libcpp_unreachable();
5170b57cec5SDimitry Andric}
5180b57cec5SDimitry Andric
5190b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
520*cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
521e8d8bef9SDimitry Andric  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
522*cb14a3feSDimitry Andric  if (__file_ == nullptr) {
5230b57cec5SDimitry Andric    if (const char* __mdstr = __make_mdstring(__mode)) {
5240b57cec5SDimitry Andric      __rt    = this;
5250b57cec5SDimitry Andric      __file_ = fopen(__s, __mdstr);
5260b57cec5SDimitry Andric      if (__file_) {
5270b57cec5SDimitry Andric        __om_ = __mode;
5280b57cec5SDimitry Andric        if (__mode & ios_base::ate) {
5290b57cec5SDimitry Andric          if (fseek(__file_, 0, SEEK_END)) {
5300b57cec5SDimitry Andric            fclose(__file_);
531e8d8bef9SDimitry Andric            __file_ = nullptr;
532e8d8bef9SDimitry Andric            __rt    = nullptr;
5330b57cec5SDimitry Andric          }
5340b57cec5SDimitry Andric        }
5350b57cec5SDimitry Andric      } else
536e8d8bef9SDimitry Andric        __rt = nullptr;
5370b57cec5SDimitry Andric    }
5380b57cec5SDimitry Andric  }
5390b57cec5SDimitry Andric  return __rt;
5400b57cec5SDimitry Andric}
5410b57cec5SDimitry Andric
5420b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
543*cb14a3feSDimitry Andricinline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
544e8d8bef9SDimitry Andric  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
545e8d8bef9SDimitry Andric  if (__file_ == nullptr) {
5460b57cec5SDimitry Andric    if (const char* __mdstr = __make_mdstring(__mode)) {
5470b57cec5SDimitry Andric      __rt    = this;
5480b57cec5SDimitry Andric      __file_ = fdopen(__fd, __mdstr);
5490b57cec5SDimitry Andric      if (__file_) {
5500b57cec5SDimitry Andric        __om_ = __mode;
5510b57cec5SDimitry Andric        if (__mode & ios_base::ate) {
5520b57cec5SDimitry Andric          if (fseek(__file_, 0, SEEK_END)) {
5530b57cec5SDimitry Andric            fclose(__file_);
554e8d8bef9SDimitry Andric            __file_ = nullptr;
555e8d8bef9SDimitry Andric            __rt    = nullptr;
5560b57cec5SDimitry Andric          }
5570b57cec5SDimitry Andric        }
5580b57cec5SDimitry Andric      } else
559e8d8bef9SDimitry Andric        __rt = nullptr;
5600b57cec5SDimitry Andric    }
5610b57cec5SDimitry Andric  }
5620b57cec5SDimitry Andric  return __rt;
5630b57cec5SDimitry Andric}
5640b57cec5SDimitry Andric
5650b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
5660b57cec5SDimitry Andric// This is basically the same as the char* overload except that it uses _wfopen
5670b57cec5SDimitry Andric// and long mode strings.
5680b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
569*cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
570e8d8bef9SDimitry Andric  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
571*cb14a3feSDimitry Andric  if (__file_ == nullptr) {
5720b57cec5SDimitry Andric    __rt = this;
5730b57cec5SDimitry Andric    const wchar_t* __mdstr;
574*cb14a3feSDimitry Andric    switch (__mode & ~ios_base::ate) {
5750b57cec5SDimitry Andric    case ios_base::out:
5760b57cec5SDimitry Andric    case ios_base::out | ios_base::trunc:
5770b57cec5SDimitry Andric      __mdstr = L"w";
5780b57cec5SDimitry Andric      break;
5790b57cec5SDimitry Andric    case ios_base::out | ios_base::app:
5800b57cec5SDimitry Andric    case ios_base::app:
5810b57cec5SDimitry Andric      __mdstr = L"a";
5820b57cec5SDimitry Andric      break;
5830b57cec5SDimitry Andric    case ios_base::in:
5840b57cec5SDimitry Andric      __mdstr = L"r";
5850b57cec5SDimitry Andric      break;
5860b57cec5SDimitry Andric    case ios_base::in | ios_base::out:
5870b57cec5SDimitry Andric      __mdstr = L"r+";
5880b57cec5SDimitry Andric      break;
5890b57cec5SDimitry Andric    case ios_base::in | ios_base::out | ios_base::trunc:
5900b57cec5SDimitry Andric      __mdstr = L"w+";
5910b57cec5SDimitry Andric      break;
5920b57cec5SDimitry Andric    case ios_base::in | ios_base::out | ios_base::app:
5930b57cec5SDimitry Andric    case ios_base::in | ios_base::app:
5940b57cec5SDimitry Andric      __mdstr = L"a+";
5950b57cec5SDimitry Andric      break;
5960b57cec5SDimitry Andric    case ios_base::out | ios_base::binary:
5970b57cec5SDimitry Andric    case ios_base::out | ios_base::trunc | ios_base::binary:
5980b57cec5SDimitry Andric      __mdstr = L"wb";
5990b57cec5SDimitry Andric      break;
6000b57cec5SDimitry Andric    case ios_base::out | ios_base::app | ios_base::binary:
6010b57cec5SDimitry Andric    case ios_base::app | ios_base::binary:
6020b57cec5SDimitry Andric      __mdstr = L"ab";
6030b57cec5SDimitry Andric      break;
6040b57cec5SDimitry Andric    case ios_base::in | ios_base::binary:
6050b57cec5SDimitry Andric      __mdstr = L"rb";
6060b57cec5SDimitry Andric      break;
6070b57cec5SDimitry Andric    case ios_base::in | ios_base::out | ios_base::binary:
6080b57cec5SDimitry Andric      __mdstr = L"r+b";
6090b57cec5SDimitry Andric      break;
6100b57cec5SDimitry Andric    case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
6110b57cec5SDimitry Andric      __mdstr = L"w+b";
6120b57cec5SDimitry Andric      break;
6130b57cec5SDimitry Andric    case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
6140b57cec5SDimitry Andric    case ios_base::in | ios_base::app | ios_base::binary:
6150b57cec5SDimitry Andric      __mdstr = L"a+b";
6160b57cec5SDimitry Andric      break;
6175f757f3fSDimitry Andric#    if _LIBCPP_STD_VER >= 23
6185f757f3fSDimitry Andric    case ios_base::out | ios_base::noreplace:
6195f757f3fSDimitry Andric    case ios_base::out | ios_base::trunc | ios_base::noreplace:
6205f757f3fSDimitry Andric      __mdstr = L"wx";
6215f757f3fSDimitry Andric      break;
6225f757f3fSDimitry Andric    case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
6235f757f3fSDimitry Andric      __mdstr = L"w+x";
6245f757f3fSDimitry Andric      break;
6255f757f3fSDimitry Andric    case ios_base::out | ios_base::binary | ios_base::noreplace:
6265f757f3fSDimitry Andric    case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
6275f757f3fSDimitry Andric      __mdstr = L"wbx";
6285f757f3fSDimitry Andric      break;
6295f757f3fSDimitry Andric    case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
6305f757f3fSDimitry Andric      __mdstr = L"w+bx";
6315f757f3fSDimitry Andric      break;
6325f757f3fSDimitry Andric#    endif // _LIBCPP_STD_VER >= 23
6330b57cec5SDimitry Andric    default:
634e8d8bef9SDimitry Andric      __rt = nullptr;
6350b57cec5SDimitry Andric      break;
6360b57cec5SDimitry Andric    }
637*cb14a3feSDimitry Andric    if (__rt) {
6380b57cec5SDimitry Andric      __file_ = _wfopen(__s, __mdstr);
639*cb14a3feSDimitry Andric      if (__file_) {
6400b57cec5SDimitry Andric        __om_ = __mode;
641*cb14a3feSDimitry Andric        if (__mode & ios_base::ate) {
642*cb14a3feSDimitry Andric          if (fseek(__file_, 0, SEEK_END)) {
6430b57cec5SDimitry Andric            fclose(__file_);
644e8d8bef9SDimitry Andric            __file_ = nullptr;
645e8d8bef9SDimitry Andric            __rt    = nullptr;
6460b57cec5SDimitry Andric          }
6470b57cec5SDimitry Andric        }
648*cb14a3feSDimitry Andric      } else
649e8d8bef9SDimitry Andric        __rt = nullptr;
6500b57cec5SDimitry Andric    }
6510b57cec5SDimitry Andric  }
6520b57cec5SDimitry Andric  return __rt;
6530b57cec5SDimitry Andric}
6540b57cec5SDimitry Andric#  endif
6550b57cec5SDimitry Andric
6560b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
657*cb14a3feSDimitry Andricinline basic_filebuf<_CharT, _Traits>*
658*cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
6590b57cec5SDimitry Andric  return open(__s.c_str(), __mode);
6600b57cec5SDimitry Andric}
6610b57cec5SDimitry Andric
6620b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
663*cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::close() {
664e8d8bef9SDimitry Andric  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
665*cb14a3feSDimitry Andric  if (__file_) {
6660b57cec5SDimitry Andric    __rt = this;
6670b57cec5SDimitry Andric    unique_ptr<FILE, int (*)(FILE*)> __h(__file_, fclose);
6680b57cec5SDimitry Andric    if (sync())
669e8d8bef9SDimitry Andric      __rt = nullptr;
670e40139ffSDimitry Andric    if (fclose(__h.release()))
671e8d8bef9SDimitry Andric      __rt = nullptr;
672e8d8bef9SDimitry Andric    __file_ = nullptr;
6730b57cec5SDimitry Andric    setbuf(0, 0);
6740b57cec5SDimitry Andric  }
6750b57cec5SDimitry Andric  return __rt;
6760b57cec5SDimitry Andric}
6770b57cec5SDimitry Andric
6780b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
679*cb14a3feSDimitry Andrictypename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::underflow() {
680e8d8bef9SDimitry Andric  if (__file_ == nullptr)
6810b57cec5SDimitry Andric    return traits_type::eof();
6820b57cec5SDimitry Andric  bool __initial = __read_mode();
6830b57cec5SDimitry Andric  char_type __1buf;
684e8d8bef9SDimitry Andric  if (this->gptr() == nullptr)
6850b57cec5SDimitry Andric    this->setg(&__1buf, &__1buf + 1, &__1buf + 1);
686bdd1243dSDimitry Andric  const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
6870b57cec5SDimitry Andric  int_type __c            = traits_type::eof();
688*cb14a3feSDimitry Andric  if (this->gptr() == this->egptr()) {
6895f757f3fSDimitry Andric    std::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
690*cb14a3feSDimitry Andric    if (__always_noconv_) {
6910b57cec5SDimitry Andric      size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
692bdd1243dSDimitry Andric      __nmemb        = ::fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
693*cb14a3feSDimitry Andric      if (__nmemb != 0) {
694*cb14a3feSDimitry Andric        this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb);
6950b57cec5SDimitry Andric        __c = traits_type::to_int_type(*this->gptr());
6960b57cec5SDimitry Andric      }
697*cb14a3feSDimitry Andric    } else {
698bdd1243dSDimitry Andric      if (__extbufend_ != __extbufnext_) {
6995f757f3fSDimitry Andric        _LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr");
7005f757f3fSDimitry Andric        _LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr");
7015f757f3fSDimitry Andric        std::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
702bdd1243dSDimitry Andric      }
7030b57cec5SDimitry Andric      __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
7040b57cec5SDimitry Andric      __extbufend_  = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
705*cb14a3feSDimitry Andric      size_t __nmemb =
706*cb14a3feSDimitry Andric          std::min(static_cast<size_t>(__ibs_ - __unget_sz), static_cast<size_t>(__extbufend_ - __extbufnext_));
7070b57cec5SDimitry Andric      codecvt_base::result __r;
7080b57cec5SDimitry Andric      __st_last_  = __st_;
7090b57cec5SDimitry Andric      size_t __nr = fread((void*)const_cast<char*>(__extbufnext_), 1, __nmemb, __file_);
710*cb14a3feSDimitry Andric      if (__nr != 0) {
7110b57cec5SDimitry Andric        if (!__cv_)
7120b57cec5SDimitry Andric          __throw_bad_cast();
7130b57cec5SDimitry Andric
7140b57cec5SDimitry Andric        __extbufend_ = __extbufnext_ + __nr;
7150b57cec5SDimitry Andric        char_type* __inext;
716*cb14a3feSDimitry Andric        __r = __cv_->in(
717*cb14a3feSDimitry Andric            __st_, __extbuf_, __extbufend_, __extbufnext_, this->eback() + __unget_sz, this->eback() + __ibs_, __inext);
718*cb14a3feSDimitry Andric        if (__r == codecvt_base::noconv) {
719*cb14a3feSDimitry Andric          this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)const_cast<char*>(__extbufend_));
7200b57cec5SDimitry Andric          __c = traits_type::to_int_type(*this->gptr());
721*cb14a3feSDimitry Andric        } else if (__inext != this->eback() + __unget_sz) {
7220b57cec5SDimitry Andric          this->setg(this->eback(), this->eback() + __unget_sz, __inext);
7230b57cec5SDimitry Andric          __c = traits_type::to_int_type(*this->gptr());
7240b57cec5SDimitry Andric        }
7250b57cec5SDimitry Andric      }
7260b57cec5SDimitry Andric    }
727*cb14a3feSDimitry Andric  } else
7280b57cec5SDimitry Andric    __c = traits_type::to_int_type(*this->gptr());
7290b57cec5SDimitry Andric  if (this->eback() == &__1buf)
730e8d8bef9SDimitry Andric    this->setg(nullptr, nullptr, nullptr);
7310b57cec5SDimitry Andric  return __c;
7320b57cec5SDimitry Andric}
7330b57cec5SDimitry Andric
7340b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
735*cb14a3feSDimitry Andrictypename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) {
736*cb14a3feSDimitry Andric  if (__file_ && this->eback() < this->gptr()) {
737*cb14a3feSDimitry Andric    if (traits_type::eq_int_type(__c, traits_type::eof())) {
7380b57cec5SDimitry Andric      this->gbump(-1);
7390b57cec5SDimitry Andric      return traits_type::not_eof(__c);
7400b57cec5SDimitry Andric    }
741*cb14a3feSDimitry Andric    if ((__om_ & ios_base::out) || traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) {
7420b57cec5SDimitry Andric      this->gbump(-1);
7430b57cec5SDimitry Andric      *this->gptr() = traits_type::to_char_type(__c);
7440b57cec5SDimitry Andric      return __c;
7450b57cec5SDimitry Andric    }
7460b57cec5SDimitry Andric  }
7470b57cec5SDimitry Andric  return traits_type::eof();
7480b57cec5SDimitry Andric}
7490b57cec5SDimitry Andric
7500b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
751*cb14a3feSDimitry Andrictypename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {
752e8d8bef9SDimitry Andric  if (__file_ == nullptr)
7530b57cec5SDimitry Andric    return traits_type::eof();
7540b57cec5SDimitry Andric  __write_mode();
7550b57cec5SDimitry Andric  char_type __1buf;
7560b57cec5SDimitry Andric  char_type* __pb_save  = this->pbase();
7570b57cec5SDimitry Andric  char_type* __epb_save = this->epptr();
758*cb14a3feSDimitry Andric  if (!traits_type::eq_int_type(__c, traits_type::eof())) {
759e8d8bef9SDimitry Andric    if (this->pptr() == nullptr)
7600b57cec5SDimitry Andric      this->setp(&__1buf, &__1buf + 1);
7610b57cec5SDimitry Andric    *this->pptr() = traits_type::to_char_type(__c);
7620b57cec5SDimitry Andric    this->pbump(1);
7630b57cec5SDimitry Andric  }
764*cb14a3feSDimitry Andric  if (this->pptr() != this->pbase()) {
765*cb14a3feSDimitry Andric    if (__always_noconv_) {
7660b57cec5SDimitry Andric      size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
767bdd1243dSDimitry Andric      if (std::fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
7680b57cec5SDimitry Andric        return traits_type::eof();
769*cb14a3feSDimitry Andric    } else {
7700b57cec5SDimitry Andric      char* __extbe = __extbuf_;
7710b57cec5SDimitry Andric      codecvt_base::result __r;
772*cb14a3feSDimitry Andric      do {
7730b57cec5SDimitry Andric        if (!__cv_)
7740b57cec5SDimitry Andric          __throw_bad_cast();
7750b57cec5SDimitry Andric
7760b57cec5SDimitry Andric        const char_type* __e;
777*cb14a3feSDimitry Andric        __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, __extbuf_, __extbuf_ + __ebs_, __extbe);
7780b57cec5SDimitry Andric        if (__e == this->pbase())
7790b57cec5SDimitry Andric          return traits_type::eof();
780*cb14a3feSDimitry Andric        if (__r == codecvt_base::noconv) {
7810b57cec5SDimitry Andric          size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
782bdd1243dSDimitry Andric          if (std::fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
7830b57cec5SDimitry Andric            return traits_type::eof();
784*cb14a3feSDimitry Andric        } else if (__r == codecvt_base::ok || __r == codecvt_base::partial) {
7850b57cec5SDimitry Andric          size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
7860b57cec5SDimitry Andric          if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
7870b57cec5SDimitry Andric            return traits_type::eof();
788*cb14a3feSDimitry Andric          if (__r == codecvt_base::partial) {
7890b57cec5SDimitry Andric            this->setp(const_cast<char_type*>(__e), this->pptr());
7900b57cec5SDimitry Andric            this->__pbump(this->epptr() - this->pbase());
7910b57cec5SDimitry Andric          }
792*cb14a3feSDimitry Andric        } else
7930b57cec5SDimitry Andric          return traits_type::eof();
7940b57cec5SDimitry Andric      } while (__r == codecvt_base::partial);
7950b57cec5SDimitry Andric    }
7960b57cec5SDimitry Andric    this->setp(__pb_save, __epb_save);
7970b57cec5SDimitry Andric  }
7980b57cec5SDimitry Andric  return traits_type::not_eof(__c);
7990b57cec5SDimitry Andric}
8000b57cec5SDimitry Andric
8010b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
802*cb14a3feSDimitry Andricbasic_streambuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n) {
803e8d8bef9SDimitry Andric  this->setg(nullptr, nullptr, nullptr);
804e8d8bef9SDimitry Andric  this->setp(nullptr, nullptr);
8050b57cec5SDimitry Andric  if (__owns_eb_)
8060b57cec5SDimitry Andric    delete[] __extbuf_;
8070b57cec5SDimitry Andric  if (__owns_ib_)
8080b57cec5SDimitry Andric    delete[] __intbuf_;
8090b57cec5SDimitry Andric  __ebs_ = __n;
810*cb14a3feSDimitry Andric  if (__ebs_ > sizeof(__extbuf_min_)) {
811*cb14a3feSDimitry Andric    if (__always_noconv_ && __s) {
8120b57cec5SDimitry Andric      __extbuf_  = (char*)__s;
8130b57cec5SDimitry Andric      __owns_eb_ = false;
814*cb14a3feSDimitry Andric    } else {
8150b57cec5SDimitry Andric      __extbuf_  = new char[__ebs_];
8160b57cec5SDimitry Andric      __owns_eb_ = true;
8170b57cec5SDimitry Andric    }
818*cb14a3feSDimitry Andric  } else {
8190b57cec5SDimitry Andric    __extbuf_  = __extbuf_min_;
8200b57cec5SDimitry Andric    __ebs_     = sizeof(__extbuf_min_);
8210b57cec5SDimitry Andric    __owns_eb_ = false;
8220b57cec5SDimitry Andric  }
823*cb14a3feSDimitry Andric  if (!__always_noconv_) {
8240b57cec5SDimitry Andric    __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
825*cb14a3feSDimitry Andric    if (__s && __ibs_ > sizeof(__extbuf_min_)) {
8260b57cec5SDimitry Andric      __intbuf_  = __s;
8270b57cec5SDimitry Andric      __owns_ib_ = false;
828*cb14a3feSDimitry Andric    } else {
8290b57cec5SDimitry Andric      __intbuf_  = new char_type[__ibs_];
8300b57cec5SDimitry Andric      __owns_ib_ = true;
8310b57cec5SDimitry Andric    }
832*cb14a3feSDimitry Andric  } else {
8330b57cec5SDimitry Andric    __ibs_     = 0;
834e8d8bef9SDimitry Andric    __intbuf_  = nullptr;
8350b57cec5SDimitry Andric    __owns_ib_ = false;
8360b57cec5SDimitry Andric  }
8370b57cec5SDimitry Andric  return this;
8380b57cec5SDimitry Andric}
8390b57cec5SDimitry Andric
8400b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
8410b57cec5SDimitry Andrictypename basic_filebuf<_CharT, _Traits>::pos_type
842*cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) {
8430b57cec5SDimitry Andric  if (!__cv_)
8440b57cec5SDimitry Andric    __throw_bad_cast();
8450b57cec5SDimitry Andric
8460b57cec5SDimitry Andric  int __width = __cv_->encoding();
847e8d8bef9SDimitry Andric  if (__file_ == nullptr || (__width <= 0 && __off != 0) || sync())
8480b57cec5SDimitry Andric    return pos_type(off_type(-1));
8490b57cec5SDimitry Andric  // __width > 0 || __off == 0
8500b57cec5SDimitry Andric  int __whence;
851*cb14a3feSDimitry Andric  switch (__way) {
8520b57cec5SDimitry Andric  case ios_base::beg:
8530b57cec5SDimitry Andric    __whence = SEEK_SET;
8540b57cec5SDimitry Andric    break;
8550b57cec5SDimitry Andric  case ios_base::cur:
8560b57cec5SDimitry Andric    __whence = SEEK_CUR;
8570b57cec5SDimitry Andric    break;
8580b57cec5SDimitry Andric  case ios_base::end:
8590b57cec5SDimitry Andric    __whence = SEEK_END;
8600b57cec5SDimitry Andric    break;
8610b57cec5SDimitry Andric  default:
8620b57cec5SDimitry Andric    return pos_type(off_type(-1));
8630b57cec5SDimitry Andric  }
8640b57cec5SDimitry Andric#  if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
8650b57cec5SDimitry Andric  if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
8660b57cec5SDimitry Andric    return pos_type(off_type(-1));
8670b57cec5SDimitry Andric  pos_type __r = ftell(__file_);
8680b57cec5SDimitry Andric#  else
869bdd1243dSDimitry Andric  if (::fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
8700b57cec5SDimitry Andric    return pos_type(off_type(-1));
8710b57cec5SDimitry Andric  pos_type __r = ftello(__file_);
8720b57cec5SDimitry Andric#  endif
8730b57cec5SDimitry Andric  __r.state(__st_);
8740b57cec5SDimitry Andric  return __r;
8750b57cec5SDimitry Andric}
8760b57cec5SDimitry Andric
8770b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
8780b57cec5SDimitry Andrictypename basic_filebuf<_CharT, _Traits>::pos_type
879*cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) {
880e8d8bef9SDimitry Andric  if (__file_ == nullptr || sync())
8810b57cec5SDimitry Andric    return pos_type(off_type(-1));
8820b57cec5SDimitry Andric#  if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
8830b57cec5SDimitry Andric  if (fseek(__file_, __sp, SEEK_SET))
8840b57cec5SDimitry Andric    return pos_type(off_type(-1));
8850b57cec5SDimitry Andric#  else
886bdd1243dSDimitry Andric  if (::fseeko(__file_, __sp, SEEK_SET))
8870b57cec5SDimitry Andric    return pos_type(off_type(-1));
8880b57cec5SDimitry Andric#  endif
8890b57cec5SDimitry Andric  __st_ = __sp.state();
8900b57cec5SDimitry Andric  return __sp;
8910b57cec5SDimitry Andric}
8920b57cec5SDimitry Andric
8930b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
894*cb14a3feSDimitry Andricint basic_filebuf<_CharT, _Traits>::sync() {
895e8d8bef9SDimitry Andric  if (__file_ == nullptr)
8960b57cec5SDimitry Andric    return 0;
8970b57cec5SDimitry Andric  if (!__cv_)
8980b57cec5SDimitry Andric    __throw_bad_cast();
8990b57cec5SDimitry Andric
900*cb14a3feSDimitry Andric  if (__cm_ & ios_base::out) {
9010b57cec5SDimitry Andric    if (this->pptr() != this->pbase())
9020b57cec5SDimitry Andric      if (overflow() == traits_type::eof())
9030b57cec5SDimitry Andric        return -1;
9040b57cec5SDimitry Andric    codecvt_base::result __r;
905*cb14a3feSDimitry Andric    do {
9060b57cec5SDimitry Andric      char* __extbe;
9070b57cec5SDimitry Andric      __r            = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
9080b57cec5SDimitry Andric      size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
9090b57cec5SDimitry Andric      if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
9100b57cec5SDimitry Andric        return -1;
9110b57cec5SDimitry Andric    } while (__r == codecvt_base::partial);
9120b57cec5SDimitry Andric    if (__r == codecvt_base::error)
9130b57cec5SDimitry Andric      return -1;
9140b57cec5SDimitry Andric    if (fflush(__file_))
9150b57cec5SDimitry Andric      return -1;
916*cb14a3feSDimitry Andric  } else if (__cm_ & ios_base::in) {
9170b57cec5SDimitry Andric    off_type __c;
9180b57cec5SDimitry Andric    state_type __state = __st_last_;
9190b57cec5SDimitry Andric    bool __update_st   = false;
9200b57cec5SDimitry Andric    if (__always_noconv_)
9210b57cec5SDimitry Andric      __c = this->egptr() - this->gptr();
922*cb14a3feSDimitry Andric    else {
9230b57cec5SDimitry Andric      int __width = __cv_->encoding();
9240b57cec5SDimitry Andric      __c         = __extbufend_ - __extbufnext_;
9250b57cec5SDimitry Andric      if (__width > 0)
9260b57cec5SDimitry Andric        __c += __width * (this->egptr() - this->gptr());
927*cb14a3feSDimitry Andric      else {
928*cb14a3feSDimitry Andric        if (this->gptr() != this->egptr()) {
929*cb14a3feSDimitry Andric          const int __off = __cv_->length(__state, __extbuf_, __extbufnext_, this->gptr() - this->eback());
9300b57cec5SDimitry Andric          __c += __extbufnext_ - __extbuf_ - __off;
9310b57cec5SDimitry Andric          __update_st = true;
9320b57cec5SDimitry Andric        }
9330b57cec5SDimitry Andric      }
9340b57cec5SDimitry Andric    }
9350b57cec5SDimitry Andric#  if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
9360b57cec5SDimitry Andric    if (fseek(__file_, -__c, SEEK_CUR))
9370b57cec5SDimitry Andric      return -1;
9380b57cec5SDimitry Andric#  else
939bdd1243dSDimitry Andric    if (::fseeko(__file_, -__c, SEEK_CUR))
9400b57cec5SDimitry Andric      return -1;
9410b57cec5SDimitry Andric#  endif
9420b57cec5SDimitry Andric    if (__update_st)
9430b57cec5SDimitry Andric      __st_ = __state;
9440b57cec5SDimitry Andric    __extbufnext_ = __extbufend_ = __extbuf_;
945e8d8bef9SDimitry Andric    this->setg(nullptr, nullptr, nullptr);
9460b57cec5SDimitry Andric    __cm_ = 0;
9470b57cec5SDimitry Andric  }
9480b57cec5SDimitry Andric  return 0;
9490b57cec5SDimitry Andric}
9500b57cec5SDimitry Andric
9510b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
952*cb14a3feSDimitry Andricvoid basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) {
9530b57cec5SDimitry Andric  sync();
954bdd1243dSDimitry Andric  __cv_            = &std::use_facet<codecvt<char_type, char, state_type> >(__loc);
9550b57cec5SDimitry Andric  bool __old_anc   = __always_noconv_;
9560b57cec5SDimitry Andric  __always_noconv_ = __cv_->always_noconv();
957*cb14a3feSDimitry Andric  if (__old_anc != __always_noconv_) {
958e8d8bef9SDimitry Andric    this->setg(nullptr, nullptr, nullptr);
959e8d8bef9SDimitry Andric    this->setp(nullptr, nullptr);
9600b57cec5SDimitry Andric    // invariant, char_type is char, else we couldn't get here
9610b57cec5SDimitry Andric    if (__always_noconv_) // need to dump __intbuf_
9620b57cec5SDimitry Andric    {
9630b57cec5SDimitry Andric      if (__owns_eb_)
9640b57cec5SDimitry Andric        delete[] __extbuf_;
9650b57cec5SDimitry Andric      __owns_eb_ = __owns_ib_;
9660b57cec5SDimitry Andric      __ebs_     = __ibs_;
9670b57cec5SDimitry Andric      __extbuf_  = (char*)__intbuf_;
9680b57cec5SDimitry Andric      __ibs_     = 0;
969e8d8bef9SDimitry Andric      __intbuf_  = nullptr;
9700b57cec5SDimitry Andric      __owns_ib_ = false;
971*cb14a3feSDimitry Andric    } else // need to obtain an __intbuf_.
9720b57cec5SDimitry Andric    {      // If __extbuf_ is user-supplied, use it, else new __intbuf_
973*cb14a3feSDimitry Andric      if (!__owns_eb_ && __extbuf_ != __extbuf_min_) {
9740b57cec5SDimitry Andric        __ibs_     = __ebs_;
9750b57cec5SDimitry Andric        __intbuf_  = (char_type*)__extbuf_;
9760b57cec5SDimitry Andric        __owns_ib_ = false;
9770b57cec5SDimitry Andric        __extbuf_  = new char[__ebs_];
9780b57cec5SDimitry Andric        __owns_eb_ = true;
979*cb14a3feSDimitry Andric      } else {
9800b57cec5SDimitry Andric        __ibs_     = __ebs_;
9810b57cec5SDimitry Andric        __intbuf_  = new char_type[__ibs_];
9820b57cec5SDimitry Andric        __owns_ib_ = true;
9830b57cec5SDimitry Andric      }
9840b57cec5SDimitry Andric    }
9850b57cec5SDimitry Andric  }
9860b57cec5SDimitry Andric}
9870b57cec5SDimitry Andric
9880b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
989*cb14a3feSDimitry Andricbool basic_filebuf<_CharT, _Traits>::__read_mode() {
990*cb14a3feSDimitry Andric  if (!(__cm_ & ios_base::in)) {
991e8d8bef9SDimitry Andric    this->setp(nullptr, nullptr);
9920b57cec5SDimitry Andric    if (__always_noconv_)
993*cb14a3feSDimitry Andric      this->setg((char_type*)__extbuf_, (char_type*)__extbuf_ + __ebs_, (char_type*)__extbuf_ + __ebs_);
9940b57cec5SDimitry Andric    else
9950b57cec5SDimitry Andric      this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
9960b57cec5SDimitry Andric    __cm_ = ios_base::in;
9970b57cec5SDimitry Andric    return true;
9980b57cec5SDimitry Andric  }
9990b57cec5SDimitry Andric  return false;
10000b57cec5SDimitry Andric}
10010b57cec5SDimitry Andric
10020b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1003*cb14a3feSDimitry Andricvoid basic_filebuf<_CharT, _Traits>::__write_mode() {
1004*cb14a3feSDimitry Andric  if (!(__cm_ & ios_base::out)) {
1005e8d8bef9SDimitry Andric    this->setg(nullptr, nullptr, nullptr);
1006*cb14a3feSDimitry Andric    if (__ebs_ > sizeof(__extbuf_min_)) {
10070b57cec5SDimitry Andric      if (__always_noconv_)
1008*cb14a3feSDimitry Andric        this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__ebs_ - 1));
10090b57cec5SDimitry Andric      else
10100b57cec5SDimitry Andric        this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
1011*cb14a3feSDimitry Andric    } else
1012e8d8bef9SDimitry Andric      this->setp(nullptr, nullptr);
10130b57cec5SDimitry Andric    __cm_ = ios_base::out;
10140b57cec5SDimitry Andric  }
10150b57cec5SDimitry Andric}
10160b57cec5SDimitry Andric
10170b57cec5SDimitry Andric// basic_ifstream
10180b57cec5SDimitry Andric
10190b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1020*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS basic_ifstream : public basic_istream<_CharT, _Traits> {
10210b57cec5SDimitry Andricpublic:
10220b57cec5SDimitry Andric  typedef _CharT char_type;
10230b57cec5SDimitry Andric  typedef _Traits traits_type;
10240b57cec5SDimitry Andric  typedef typename traits_type::int_type int_type;
10250b57cec5SDimitry Andric  typedef typename traits_type::pos_type pos_type;
10260b57cec5SDimitry Andric  typedef typename traits_type::off_type off_type;
10270b57cec5SDimitry Andric
1028*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_ifstream();
1029*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
10300b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1031*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
10320b57cec5SDimitry Andric#  endif
1033*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
103406c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
1035*cb14a3feSDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(
1036*cb14a3feSDimitry Andric      const filesystem::path& __p, ios_base::openmode __mode = ios_base::in)
10370b57cec5SDimitry Andric      : basic_ifstream(__p.c_str(), __mode) {}
10380b57cec5SDimitry Andric#  endif // _LIBCPP_STD_VER >= 17
1039*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_ifstream(basic_ifstream&& __rhs);
1040*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_ifstream& operator=(basic_ifstream&& __rhs);
1041*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs);
10420b57cec5SDimitry Andric
1043*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
1044*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
10450b57cec5SDimitry Andric  void open(const char* __s, ios_base::openmode __mode = ios_base::in);
10460b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
10470b57cec5SDimitry Andric  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
10480b57cec5SDimitry Andric#  endif
10490b57cec5SDimitry Andric  void open(const string& __s, ios_base::openmode __mode = ios_base::in);
105006c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
1051*cb14a3feSDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1052*cb14a3feSDimitry Andric  open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) {
10530b57cec5SDimitry Andric    return open(__p.c_str(), __mode);
10540b57cec5SDimitry Andric  }
10550b57cec5SDimitry Andric#  endif // _LIBCPP_STD_VER >= 17
10560b57cec5SDimitry Andric
1057*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
1058*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void close();
10590b57cec5SDimitry Andric
10600b57cec5SDimitry Andricprivate:
10610b57cec5SDimitry Andric  basic_filebuf<char_type, traits_type> __sb_;
10620b57cec5SDimitry Andric};
10630b57cec5SDimitry Andric
10640b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1065*cb14a3feSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream() : basic_istream<char_type, traits_type>(&__sb_) {}
10660b57cec5SDimitry Andric
10670b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1068*cb14a3feSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
1069*cb14a3feSDimitry Andric    : basic_istream<char_type, traits_type>(&__sb_) {
1070e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
10710b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
10720b57cec5SDimitry Andric}
10730b57cec5SDimitry Andric
10740b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
10750b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1076*cb14a3feSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode)
1077*cb14a3feSDimitry Andric    : basic_istream<char_type, traits_type>(&__sb_) {
1078e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
10790b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
10800b57cec5SDimitry Andric}
10810b57cec5SDimitry Andric#  endif
10820b57cec5SDimitry Andric
10830b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1084*cb14a3feSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)
1085*cb14a3feSDimitry Andric    : basic_istream<char_type, traits_type>(&__sb_) {
1086e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
10870b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
10880b57cec5SDimitry Andric}
10890b57cec5SDimitry Andric
10900b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1091*cb14a3feSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
1092*cb14a3feSDimitry Andric    : basic_istream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
10930b57cec5SDimitry Andric  this->set_rdbuf(&__sb_);
10940b57cec5SDimitry Andric}
10950b57cec5SDimitry Andric
10960b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1097*cb14a3feSDimitry Andricinline basic_ifstream<_CharT, _Traits>& basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) {
10985f757f3fSDimitry Andric  basic_istream<char_type, traits_type>::operator=(std::move(__rhs));
10995f757f3fSDimitry Andric  __sb_ = std::move(__rhs.__sb_);
11000b57cec5SDimitry Andric  return *this;
11010b57cec5SDimitry Andric}
11020b57cec5SDimitry Andric
11030b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1104*cb14a3feSDimitry Andricinline void basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) {
11050b57cec5SDimitry Andric  basic_istream<char_type, traits_type>::swap(__rhs);
11060b57cec5SDimitry Andric  __sb_.swap(__rhs.__sb_);
11070b57cec5SDimitry Andric}
11080b57cec5SDimitry Andric
11090b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1110*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) {
11110b57cec5SDimitry Andric  __x.swap(__y);
11120b57cec5SDimitry Andric}
11130b57cec5SDimitry Andric
11140b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1115*cb14a3feSDimitry Andricinline basic_filebuf<_CharT, _Traits>* basic_ifstream<_CharT, _Traits>::rdbuf() const {
11160b57cec5SDimitry Andric  return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
11170b57cec5SDimitry Andric}
11180b57cec5SDimitry Andric
11190b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1120*cb14a3feSDimitry Andricinline bool basic_ifstream<_CharT, _Traits>::is_open() const {
11210b57cec5SDimitry Andric  return __sb_.is_open();
11220b57cec5SDimitry Andric}
11230b57cec5SDimitry Andric
11240b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1125*cb14a3feSDimitry Andricvoid basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
11260b57cec5SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::in))
11270b57cec5SDimitry Andric    this->clear();
11280b57cec5SDimitry Andric  else
11290b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
11300b57cec5SDimitry Andric}
11310b57cec5SDimitry Andric
11320b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
11330b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1134*cb14a3feSDimitry Andricvoid basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
11350b57cec5SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::in))
11360b57cec5SDimitry Andric    this->clear();
11370b57cec5SDimitry Andric  else
11380b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
11390b57cec5SDimitry Andric}
11400b57cec5SDimitry Andric#  endif
11410b57cec5SDimitry Andric
11420b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1143*cb14a3feSDimitry Andricvoid basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
11440b57cec5SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::in))
11450b57cec5SDimitry Andric    this->clear();
11460b57cec5SDimitry Andric  else
11470b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
11480b57cec5SDimitry Andric}
11490b57cec5SDimitry Andric
11500b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1151*cb14a3feSDimitry Andricinline void basic_ifstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
11520b57cec5SDimitry Andric  if (__sb_.__open(__fd, __mode | ios_base::in))
11530b57cec5SDimitry Andric    this->clear();
11540b57cec5SDimitry Andric  else
11550b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
11560b57cec5SDimitry Andric}
11570b57cec5SDimitry Andric
11580b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1159*cb14a3feSDimitry Andricinline void basic_ifstream<_CharT, _Traits>::close() {
11600b57cec5SDimitry Andric  if (__sb_.close() == 0)
11610b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
11620b57cec5SDimitry Andric}
11630b57cec5SDimitry Andric
11640b57cec5SDimitry Andric// basic_ofstream
11650b57cec5SDimitry Andric
11660b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1167*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS basic_ofstream : public basic_ostream<_CharT, _Traits> {
11680b57cec5SDimitry Andricpublic:
11690b57cec5SDimitry Andric  typedef _CharT char_type;
11700b57cec5SDimitry Andric  typedef _Traits traits_type;
11710b57cec5SDimitry Andric  typedef typename traits_type::int_type int_type;
11720b57cec5SDimitry Andric  typedef typename traits_type::pos_type pos_type;
11730b57cec5SDimitry Andric  typedef typename traits_type::off_type off_type;
11740b57cec5SDimitry Andric
1175*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_ofstream();
1176*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
11770b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1178*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
11790b57cec5SDimitry Andric#  endif
1180*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
11810b57cec5SDimitry Andric
118206c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
1183*cb14a3feSDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(
1184*cb14a3feSDimitry Andric      const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
11850b57cec5SDimitry Andric      : basic_ofstream(__p.c_str(), __mode) {}
11860b57cec5SDimitry Andric#  endif // _LIBCPP_STD_VER >= 17
11870b57cec5SDimitry Andric
1188*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_ofstream(basic_ofstream&& __rhs);
1189*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_ofstream& operator=(basic_ofstream&& __rhs);
1190*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream& __rhs);
11910b57cec5SDimitry Andric
1192*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
1193*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
11940b57cec5SDimitry Andric  void open(const char* __s, ios_base::openmode __mode = ios_base::out);
11950b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
11960b57cec5SDimitry Andric  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
11970b57cec5SDimitry Andric#  endif
11980b57cec5SDimitry Andric  void open(const string& __s, ios_base::openmode __mode = ios_base::out);
11990b57cec5SDimitry Andric
120006c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
1201*cb14a3feSDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1202*cb14a3feSDimitry Andric  open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) {
1203*cb14a3feSDimitry Andric    return open(__p.c_str(), __mode);
1204*cb14a3feSDimitry Andric  }
12050b57cec5SDimitry Andric#  endif // _LIBCPP_STD_VER >= 17
12060b57cec5SDimitry Andric
1207*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
1208*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void close();
12090b57cec5SDimitry Andric
12100b57cec5SDimitry Andricprivate:
12110b57cec5SDimitry Andric  basic_filebuf<char_type, traits_type> __sb_;
12120b57cec5SDimitry Andric};
12130b57cec5SDimitry Andric
12140b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1215*cb14a3feSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream() : basic_ostream<char_type, traits_type>(&__sb_) {}
12160b57cec5SDimitry Andric
12170b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1218*cb14a3feSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
1219*cb14a3feSDimitry Andric    : basic_ostream<char_type, traits_type>(&__sb_) {
1220e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
12210b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
12220b57cec5SDimitry Andric}
12230b57cec5SDimitry Andric
12240b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
12250b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1226*cb14a3feSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode)
1227*cb14a3feSDimitry Andric    : basic_ostream<char_type, traits_type>(&__sb_) {
1228e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
12290b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
12300b57cec5SDimitry Andric}
12310b57cec5SDimitry Andric#  endif
12320b57cec5SDimitry Andric
12330b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1234*cb14a3feSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)
1235*cb14a3feSDimitry Andric    : basic_ostream<char_type, traits_type>(&__sb_) {
1236e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
12370b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
12380b57cec5SDimitry Andric}
12390b57cec5SDimitry Andric
12400b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1241*cb14a3feSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
1242*cb14a3feSDimitry Andric    : basic_ostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
12430b57cec5SDimitry Andric  this->set_rdbuf(&__sb_);
12440b57cec5SDimitry Andric}
12450b57cec5SDimitry Andric
12460b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1247*cb14a3feSDimitry Andricinline basic_ofstream<_CharT, _Traits>& basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) {
12485f757f3fSDimitry Andric  basic_ostream<char_type, traits_type>::operator=(std::move(__rhs));
12495f757f3fSDimitry Andric  __sb_ = std::move(__rhs.__sb_);
12500b57cec5SDimitry Andric  return *this;
12510b57cec5SDimitry Andric}
12520b57cec5SDimitry Andric
12530b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1254*cb14a3feSDimitry Andricinline void basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) {
12550b57cec5SDimitry Andric  basic_ostream<char_type, traits_type>::swap(__rhs);
12560b57cec5SDimitry Andric  __sb_.swap(__rhs.__sb_);
12570b57cec5SDimitry Andric}
12580b57cec5SDimitry Andric
12590b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1260*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) {
12610b57cec5SDimitry Andric  __x.swap(__y);
12620b57cec5SDimitry Andric}
12630b57cec5SDimitry Andric
12640b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1265*cb14a3feSDimitry Andricinline basic_filebuf<_CharT, _Traits>* basic_ofstream<_CharT, _Traits>::rdbuf() const {
12660b57cec5SDimitry Andric  return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
12670b57cec5SDimitry Andric}
12680b57cec5SDimitry Andric
12690b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1270*cb14a3feSDimitry Andricinline bool basic_ofstream<_CharT, _Traits>::is_open() const {
12710b57cec5SDimitry Andric  return __sb_.is_open();
12720b57cec5SDimitry Andric}
12730b57cec5SDimitry Andric
12740b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1275*cb14a3feSDimitry Andricvoid basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
12760b57cec5SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::out))
12770b57cec5SDimitry Andric    this->clear();
12780b57cec5SDimitry Andric  else
12790b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
12800b57cec5SDimitry Andric}
12810b57cec5SDimitry Andric
12820b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
12830b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1284*cb14a3feSDimitry Andricvoid basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
12850b57cec5SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::out))
12860b57cec5SDimitry Andric    this->clear();
12870b57cec5SDimitry Andric  else
12880b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
12890b57cec5SDimitry Andric}
12900b57cec5SDimitry Andric#  endif
12910b57cec5SDimitry Andric
12920b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1293*cb14a3feSDimitry Andricvoid basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
12940b57cec5SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::out))
12950b57cec5SDimitry Andric    this->clear();
12960b57cec5SDimitry Andric  else
12970b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
12980b57cec5SDimitry Andric}
12990b57cec5SDimitry Andric
13000b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1301*cb14a3feSDimitry Andricinline void basic_ofstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
13020b57cec5SDimitry Andric  if (__sb_.__open(__fd, __mode | ios_base::out))
13030b57cec5SDimitry Andric    this->clear();
13040b57cec5SDimitry Andric  else
13050b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
13060b57cec5SDimitry Andric}
13070b57cec5SDimitry Andric
13080b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1309*cb14a3feSDimitry Andricinline void basic_ofstream<_CharT, _Traits>::close() {
1310e8d8bef9SDimitry Andric  if (__sb_.close() == nullptr)
13110b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
13120b57cec5SDimitry Andric}
13130b57cec5SDimitry Andric
13140b57cec5SDimitry Andric// basic_fstream
13150b57cec5SDimitry Andric
13160b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1317*cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS basic_fstream : public basic_iostream<_CharT, _Traits> {
13180b57cec5SDimitry Andricpublic:
13190b57cec5SDimitry Andric  typedef _CharT char_type;
13200b57cec5SDimitry Andric  typedef _Traits traits_type;
13210b57cec5SDimitry Andric  typedef typename traits_type::int_type int_type;
13220b57cec5SDimitry Andric  typedef typename traits_type::pos_type pos_type;
13230b57cec5SDimitry Andric  typedef typename traits_type::off_type off_type;
13240b57cec5SDimitry Andric
1325*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_fstream();
1326*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const char* __s,
1327*cb14a3feSDimitry Andric                                               ios_base::openmode __mode = ios_base::in | ios_base::out);
13280b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1329*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const wchar_t* __s,
1330*cb14a3feSDimitry Andric                                               ios_base::openmode __mode = ios_base::in | ios_base::out);
13310b57cec5SDimitry Andric#  endif
1332*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const string& __s,
1333*cb14a3feSDimitry Andric                                               ios_base::openmode __mode = ios_base::in | ios_base::out);
13340b57cec5SDimitry Andric
133506c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
1336*cb14a3feSDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(
1337*cb14a3feSDimitry Andric      const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
13380b57cec5SDimitry Andric      : basic_fstream(__p.c_str(), __mode) {}
13390b57cec5SDimitry Andric#  endif // _LIBCPP_STD_VER >= 17
13400b57cec5SDimitry Andric
1341*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_fstream(basic_fstream&& __rhs);
13420b57cec5SDimitry Andric
1343*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_fstream& operator=(basic_fstream&& __rhs);
1344fe6060f1SDimitry Andric
1345*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream& __rhs);
13460b57cec5SDimitry Andric
1347*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
1348*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
134906c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
13500b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
13510b57cec5SDimitry Andric  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
13520b57cec5SDimitry Andric#  endif
135306c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
13540b57cec5SDimitry Andric
135506c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
1356*cb14a3feSDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1357*cb14a3feSDimitry Andric  open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) {
1358*cb14a3feSDimitry Andric    return open(__p.c_str(), __mode);
1359*cb14a3feSDimitry Andric  }
13600b57cec5SDimitry Andric#  endif // _LIBCPP_STD_VER >= 17
13610b57cec5SDimitry Andric
1362*cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void close();
13630b57cec5SDimitry Andric
13640b57cec5SDimitry Andricprivate:
13650b57cec5SDimitry Andric  basic_filebuf<char_type, traits_type> __sb_;
13660b57cec5SDimitry Andric};
13670b57cec5SDimitry Andric
13680b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1369*cb14a3feSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream() : basic_iostream<char_type, traits_type>(&__sb_) {}
13700b57cec5SDimitry Andric
13710b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1372*cb14a3feSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
1373*cb14a3feSDimitry Andric    : basic_iostream<char_type, traits_type>(&__sb_) {
1374e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode) == nullptr)
13750b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
13760b57cec5SDimitry Andric}
13770b57cec5SDimitry Andric
13780b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
13790b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1380*cb14a3feSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode)
1381*cb14a3feSDimitry Andric    : basic_iostream<char_type, traits_type>(&__sb_) {
1382e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode) == nullptr)
13830b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
13840b57cec5SDimitry Andric}
13850b57cec5SDimitry Andric#  endif
13860b57cec5SDimitry Andric
13870b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1388*cb14a3feSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)
1389*cb14a3feSDimitry Andric    : basic_iostream<char_type, traits_type>(&__sb_) {
1390e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode) == nullptr)
13910b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
13920b57cec5SDimitry Andric}
13930b57cec5SDimitry Andric
13940b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1395*cb14a3feSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
1396*cb14a3feSDimitry Andric    : basic_iostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
13970b57cec5SDimitry Andric  this->set_rdbuf(&__sb_);
13980b57cec5SDimitry Andric}
13990b57cec5SDimitry Andric
14000b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1401*cb14a3feSDimitry Andricinline basic_fstream<_CharT, _Traits>& basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) {
14025f757f3fSDimitry Andric  basic_iostream<char_type, traits_type>::operator=(std::move(__rhs));
14035f757f3fSDimitry Andric  __sb_ = std::move(__rhs.__sb_);
14040b57cec5SDimitry Andric  return *this;
14050b57cec5SDimitry Andric}
14060b57cec5SDimitry Andric
14070b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1408*cb14a3feSDimitry Andricinline void basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) {
14090b57cec5SDimitry Andric  basic_iostream<char_type, traits_type>::swap(__rhs);
14100b57cec5SDimitry Andric  __sb_.swap(__rhs.__sb_);
14110b57cec5SDimitry Andric}
14120b57cec5SDimitry Andric
14130b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1414*cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) {
14150b57cec5SDimitry Andric  __x.swap(__y);
14160b57cec5SDimitry Andric}
14170b57cec5SDimitry Andric
14180b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1419*cb14a3feSDimitry Andricinline basic_filebuf<_CharT, _Traits>* basic_fstream<_CharT, _Traits>::rdbuf() const {
14200b57cec5SDimitry Andric  return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
14210b57cec5SDimitry Andric}
14220b57cec5SDimitry Andric
14230b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1424*cb14a3feSDimitry Andricinline bool basic_fstream<_CharT, _Traits>::is_open() const {
14250b57cec5SDimitry Andric  return __sb_.is_open();
14260b57cec5SDimitry Andric}
14270b57cec5SDimitry Andric
14280b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1429*cb14a3feSDimitry Andricvoid basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
14300b57cec5SDimitry Andric  if (__sb_.open(__s, __mode))
14310b57cec5SDimitry Andric    this->clear();
14320b57cec5SDimitry Andric  else
14330b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
14340b57cec5SDimitry Andric}
14350b57cec5SDimitry Andric
14360b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
14370b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1438*cb14a3feSDimitry Andricvoid basic_fstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
14390b57cec5SDimitry Andric  if (__sb_.open(__s, __mode))
14400b57cec5SDimitry Andric    this->clear();
14410b57cec5SDimitry Andric  else
14420b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
14430b57cec5SDimitry Andric}
14440b57cec5SDimitry Andric#  endif
14450b57cec5SDimitry Andric
14460b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1447*cb14a3feSDimitry Andricvoid basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
14480b57cec5SDimitry Andric  if (__sb_.open(__s, __mode))
14490b57cec5SDimitry Andric    this->clear();
14500b57cec5SDimitry Andric  else
14510b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
14520b57cec5SDimitry Andric}
14530b57cec5SDimitry Andric
14540b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1455*cb14a3feSDimitry Andricinline void basic_fstream<_CharT, _Traits>::close() {
1456e8d8bef9SDimitry Andric  if (__sb_.close() == nullptr)
14570b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
14580b57cec5SDimitry Andric}
14590b57cec5SDimitry Andric
14605f757f3fSDimitry Andric#  if _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
146181ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ifstream<char>;
146281ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ofstream<char>;
146381ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>;
1464e8d8bef9SDimitry Andric#  endif
1465e8d8bef9SDimitry Andric
14660b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
14670b57cec5SDimitry Andric
146806c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_FILESYSTEM
1469bdd1243dSDimitry Andric
14700b57cec5SDimitry Andric_LIBCPP_POP_MACROS
14710b57cec5SDimitry Andric
1472bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1473bdd1243dSDimitry Andric#  include <atomic>
1474bdd1243dSDimitry Andric#  include <concepts>
147506c3fb27SDimitry Andric#  include <cstdlib>
1476bdd1243dSDimitry Andric#  include <iosfwd>
1477bdd1243dSDimitry Andric#  include <limits>
14785f757f3fSDimitry Andric#  include <mutex>
1479bdd1243dSDimitry Andric#  include <new>
1480bdd1243dSDimitry Andric#  include <stdexcept>
1481bdd1243dSDimitry Andric#  include <type_traits>
1482bdd1243dSDimitry Andric#endif
1483bdd1243dSDimitry Andric
14840b57cec5SDimitry Andric#endif // _LIBCPP_FSTREAM
1485