xref: /freebsd/contrib/llvm-project/libcxx/include/fstream (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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;
761db9f3b2SDimitry Andric    using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
770b57cec5SDimitry Andric
780b57cec5SDimitry Andric    basic_ifstream();
790b57cec5SDimitry Andric    explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
800b57cec5SDimitry Andric    explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);
81*0fca6ea1SDimitry Andric    template<class T>
82*0fca6ea1SDimitry Andric    explicit basic_ifstream(const T& s, ios_base::openmode mode = ios_base::in); // Since C++17
830b57cec5SDimitry Andric    basic_ifstream(basic_ifstream&& rhs);
840b57cec5SDimitry Andric
850b57cec5SDimitry Andric    basic_ifstream& operator=(basic_ifstream&& rhs);
860b57cec5SDimitry Andric    void swap(basic_ifstream& rhs);
870b57cec5SDimitry Andric
880b57cec5SDimitry Andric    basic_filebuf<char_type, traits_type>* rdbuf() const;
891db9f3b2SDimitry Andric    native_handle_type native_handle() const noexcept; // Since C++26
900b57cec5SDimitry Andric    bool is_open() const;
910b57cec5SDimitry Andric    void open(const char* s, ios_base::openmode mode = ios_base::in);
920b57cec5SDimitry Andric    void open(const string& s, ios_base::openmode mode = ios_base::in);
930b57cec5SDimitry Andric    void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++17
940b57cec5SDimitry Andric
950b57cec5SDimitry Andric    void close();
960b57cec5SDimitry Andric};
970b57cec5SDimitry Andric
980b57cec5SDimitry Andrictemplate <class charT, class traits>
990b57cec5SDimitry Andric  void
1000b57cec5SDimitry Andric  swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y);
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andrictypedef basic_ifstream<char>    ifstream;
1030b57cec5SDimitry Andrictypedef basic_ifstream<wchar_t> wifstream;
1040b57cec5SDimitry Andric
1050b57cec5SDimitry Andrictemplate <class charT, class traits = char_traits<charT> >
1060b57cec5SDimitry Andricclass basic_ofstream
1070b57cec5SDimitry Andric    : public basic_ostream<charT,traits>
1080b57cec5SDimitry Andric{
1090b57cec5SDimitry Andricpublic:
1100b57cec5SDimitry Andric    typedef charT                          char_type;
1110b57cec5SDimitry Andric    typedef traits                         traits_type;
1120b57cec5SDimitry Andric    typedef typename traits_type::int_type int_type;
1130b57cec5SDimitry Andric    typedef typename traits_type::pos_type pos_type;
1140b57cec5SDimitry Andric    typedef typename traits_type::off_type off_type;
1151db9f3b2SDimitry Andric    using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric    basic_ofstream();
1180b57cec5SDimitry Andric    explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
1190b57cec5SDimitry Andric    explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);
120*0fca6ea1SDimitry Andric    template<class T>
121*0fca6ea1SDimitry Andric    explicit basic_ofstream(const T& s, ios_base::openmode mode = ios_base::out); // Since C++17
1220b57cec5SDimitry Andric    basic_ofstream(basic_ofstream&& rhs);
1230b57cec5SDimitry Andric
1240b57cec5SDimitry Andric    basic_ofstream& operator=(basic_ofstream&& rhs);
1250b57cec5SDimitry Andric    void swap(basic_ofstream& rhs);
1260b57cec5SDimitry Andric
1270b57cec5SDimitry Andric    basic_filebuf<char_type, traits_type>* rdbuf() const;
1281db9f3b2SDimitry Andric    native_handle_type native_handle() const noexcept; // Since C++26
1291db9f3b2SDimitry Andric
1300b57cec5SDimitry Andric    bool is_open() const;
1310b57cec5SDimitry Andric    void open(const char* s, ios_base::openmode mode = ios_base::out);
1320b57cec5SDimitry Andric    void open(const string& s, ios_base::openmode mode = ios_base::out);
1330b57cec5SDimitry Andric    void open(const filesystem::path& p,
1340b57cec5SDimitry Andric              ios_base::openmode mode = ios_base::out); // C++17
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andric    void close();
1370b57cec5SDimitry Andric};
1380b57cec5SDimitry Andric
1390b57cec5SDimitry Andrictemplate <class charT, class traits>
1400b57cec5SDimitry Andric  void
1410b57cec5SDimitry Andric  swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y);
1420b57cec5SDimitry Andric
1430b57cec5SDimitry Andrictypedef basic_ofstream<char>    ofstream;
1440b57cec5SDimitry Andrictypedef basic_ofstream<wchar_t> wofstream;
1450b57cec5SDimitry Andric
1460b57cec5SDimitry Andrictemplate <class charT, class traits=char_traits<charT> >
1470b57cec5SDimitry Andricclass basic_fstream
1480b57cec5SDimitry Andric    : public basic_iostream<charT,traits>
1490b57cec5SDimitry Andric{
1500b57cec5SDimitry Andricpublic:
1510b57cec5SDimitry Andric    typedef charT                          char_type;
1520b57cec5SDimitry Andric    typedef traits                         traits_type;
1530b57cec5SDimitry Andric    typedef typename traits_type::int_type int_type;
1540b57cec5SDimitry Andric    typedef typename traits_type::pos_type pos_type;
1550b57cec5SDimitry Andric    typedef typename traits_type::off_type off_type;
1561db9f3b2SDimitry Andric    using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
1570b57cec5SDimitry Andric
1580b57cec5SDimitry Andric    basic_fstream();
1590b57cec5SDimitry Andric    explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
1600b57cec5SDimitry Andric    explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
161*0fca6ea1SDimitry Andric    template<class T>
162*0fca6ea1SDimitry Andric    explicit basic_fstream(const T& s, ios_base::openmode mode = ios_base::in | ios_base::out); // Since C++17
1630b57cec5SDimitry Andric    basic_fstream(basic_fstream&& rhs);
1640b57cec5SDimitry Andric
1650b57cec5SDimitry Andric    basic_fstream& operator=(basic_fstream&& rhs);
1660b57cec5SDimitry Andric    void swap(basic_fstream& rhs);
1670b57cec5SDimitry Andric
1680b57cec5SDimitry Andric    basic_filebuf<char_type, traits_type>* rdbuf() const;
1691db9f3b2SDimitry Andric    native_handle_type native_handle() const noexcept; // Since C++26
1700b57cec5SDimitry Andric    bool is_open() const;
1710b57cec5SDimitry Andric    void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
1720b57cec5SDimitry Andric    void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
1730b57cec5SDimitry Andric    void open(const filesystem::path& s,
1740b57cec5SDimitry Andric              ios_base::openmode mode = ios_base::in|ios_base::out); // C++17
1750b57cec5SDimitry Andric
1760b57cec5SDimitry Andric    void close();
1770b57cec5SDimitry Andric};
1780b57cec5SDimitry Andric
1790b57cec5SDimitry Andrictemplate <class charT, class traits>
1800b57cec5SDimitry Andric  void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y);
1810b57cec5SDimitry Andric
1820b57cec5SDimitry Andrictypedef basic_fstream<char>    fstream;
1830b57cec5SDimitry Andrictypedef basic_fstream<wchar_t> wfstream;
1840b57cec5SDimitry Andric
1850b57cec5SDimitry Andric}  // std
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric*/
1880b57cec5SDimitry Andric
18981ad6265SDimitry Andric#include <__algorithm/max.h>
190*0fca6ea1SDimitry Andric#include <__assert>
191fe6060f1SDimitry Andric#include <__config>
19206c3fb27SDimitry Andric#include <__fwd/fstream.h>
1930b57cec5SDimitry Andric#include <__locale>
194*0fca6ea1SDimitry Andric#include <__type_traits/enable_if.h>
195*0fca6ea1SDimitry Andric#include <__type_traits/is_same.h>
19681ad6265SDimitry Andric#include <__utility/move.h>
19781ad6265SDimitry Andric#include <__utility/swap.h>
19881ad6265SDimitry Andric#include <__utility/unreachable.h>
1990b57cec5SDimitry Andric#include <cstdio>
20006c3fb27SDimitry Andric#include <filesystem>
201fe6060f1SDimitry Andric#include <istream>
202fe6060f1SDimitry Andric#include <ostream>
203bdd1243dSDimitry Andric#include <typeinfo>
20404eeddc0SDimitry Andric#include <version>
205e8d8bef9SDimitry Andric
2060b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2070b57cec5SDimitry Andric#  pragma GCC system_header
2080b57cec5SDimitry Andric#endif
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS
2110b57cec5SDimitry Andric#include <__undef_macros>
2120b57cec5SDimitry Andric
213fe6060f1SDimitry Andric#if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION)
214fe6060f1SDimitry Andric#  define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
215fe6060f1SDimitry Andric#endif
2160b57cec5SDimitry Andric
21706c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_FILESYSTEM)
218bdd1243dSDimitry Andric
2190b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
2200b57cec5SDimitry Andric
2211db9f3b2SDimitry Andric#  if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_WIN32API)
2221db9f3b2SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI void* __filebuf_windows_native_handle(FILE* __file) noexcept;
2231db9f3b2SDimitry Andric#  endif
2241db9f3b2SDimitry Andric
2250b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
226cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS basic_filebuf : public basic_streambuf<_CharT, _Traits> {
2270b57cec5SDimitry Andricpublic:
2280b57cec5SDimitry Andric  typedef _CharT char_type;
2290b57cec5SDimitry Andric  typedef _Traits traits_type;
2300b57cec5SDimitry Andric  typedef typename traits_type::int_type int_type;
2310b57cec5SDimitry Andric  typedef typename traits_type::pos_type pos_type;
2320b57cec5SDimitry Andric  typedef typename traits_type::off_type off_type;
2330b57cec5SDimitry Andric  typedef typename traits_type::state_type state_type;
2341db9f3b2SDimitry Andric#  if _LIBCPP_STD_VER >= 26
2351db9f3b2SDimitry Andric#    if defined(_LIBCPP_WIN32API)
2361db9f3b2SDimitry Andric  using native_handle_type = void*; // HANDLE
2371db9f3b2SDimitry Andric#    elif __has_include(<unistd.h>)
2381db9f3b2SDimitry Andric  using native_handle_type = int; // POSIX file descriptor
2391db9f3b2SDimitry Andric#    else
2401db9f3b2SDimitry Andric#      error "Provide a native file handle!"
2411db9f3b2SDimitry Andric#    endif
2421db9f3b2SDimitry Andric#  endif
2430b57cec5SDimitry Andric
2440b57cec5SDimitry Andric  // 27.9.1.2 Constructors/destructor:
2450b57cec5SDimitry Andric  basic_filebuf();
2460b57cec5SDimitry Andric  basic_filebuf(basic_filebuf&& __rhs);
247bdd1243dSDimitry Andric  ~basic_filebuf() override;
2480b57cec5SDimitry Andric
2490b57cec5SDimitry Andric  // 27.9.1.3 Assign/swap:
250cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_filebuf& operator=(basic_filebuf&& __rhs);
2510b57cec5SDimitry Andric  void swap(basic_filebuf& __rhs);
2520b57cec5SDimitry Andric
2530b57cec5SDimitry Andric  // 27.9.1.4 Members:
254cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
2550b57cec5SDimitry Andric  basic_filebuf* open(const char* __s, ios_base::openmode __mode);
2560b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
2570b57cec5SDimitry Andric  basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode);
2580b57cec5SDimitry Andric#  endif
259cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const string& __s, ios_base::openmode __mode);
2600b57cec5SDimitry Andric
26106c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
262cb14a3feSDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI basic_filebuf*
263cb14a3feSDimitry Andric  open(const filesystem::path& __p, ios_base::openmode __mode) {
2640b57cec5SDimitry Andric    return open(__p.c_str(), __mode);
2650b57cec5SDimitry Andric  }
2660b57cec5SDimitry Andric#  endif
267cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_filebuf* __open(int __fd, ios_base::openmode __mode);
2680b57cec5SDimitry Andric  basic_filebuf* close();
2691db9f3b2SDimitry Andric#  if _LIBCPP_STD_VER >= 26
2701db9f3b2SDimitry Andric  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
2711db9f3b2SDimitry Andric    _LIBCPP_ASSERT_UNCATEGORIZED(this->is_open(), "File must be opened");
2721db9f3b2SDimitry Andric#    if defined(_LIBCPP_WIN32API)
2731db9f3b2SDimitry Andric    return std::__filebuf_windows_native_handle(__file_);
2741db9f3b2SDimitry Andric#    elif __has_include(<unistd.h>)
2751db9f3b2SDimitry Andric    return fileno(__file_);
2761db9f3b2SDimitry Andric#    else
2771db9f3b2SDimitry Andric#      error "Provide a way to determine the file native handle!"
2781db9f3b2SDimitry Andric#    endif
2791db9f3b2SDimitry Andric  }
2801db9f3b2SDimitry Andric#  endif //  _LIBCPP_STD_VER >= 26
2810b57cec5SDimitry Andric
282cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI inline static const char* __make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
283*0fca6ea1SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
284*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI inline static const wchar_t* __make_mdwstring(ios_base::openmode __mode) _NOEXCEPT;
285*0fca6ea1SDimitry Andric#  endif
2860b57cec5SDimitry Andric
2870b57cec5SDimitry Andricprotected:
2880b57cec5SDimitry Andric  // 27.9.1.5 Overridden virtual functions:
289bdd1243dSDimitry Andric  int_type underflow() override;
290bdd1243dSDimitry Andric  int_type pbackfail(int_type __c = traits_type::eof()) override;
291bdd1243dSDimitry Andric  int_type overflow(int_type __c = traits_type::eof()) override;
292bdd1243dSDimitry Andric  basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n) override;
293cb14a3feSDimitry Andric  pos_type
294cb14a3feSDimitry Andric  seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
295cb14a3feSDimitry Andric  pos_type seekpos(pos_type __sp, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
296bdd1243dSDimitry Andric  int sync() override;
297bdd1243dSDimitry Andric  void imbue(const locale& __loc) override;
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andricprivate:
3000b57cec5SDimitry Andric  char* __extbuf_;
3010b57cec5SDimitry Andric  const char* __extbufnext_;
3020b57cec5SDimitry Andric  const char* __extbufend_;
3030b57cec5SDimitry Andric  char __extbuf_min_[8];
3040b57cec5SDimitry Andric  size_t __ebs_;
3050b57cec5SDimitry Andric  char_type* __intbuf_;
3060b57cec5SDimitry Andric  size_t __ibs_;
3070b57cec5SDimitry Andric  FILE* __file_;
3080b57cec5SDimitry Andric  const codecvt<char_type, char, state_type>* __cv_;
3090b57cec5SDimitry Andric  state_type __st_;
3100b57cec5SDimitry Andric  state_type __st_last_;
3110b57cec5SDimitry Andric  ios_base::openmode __om_;
312*0fca6ea1SDimitry Andric  // There have been no file operations yet, which allows setting unbuffered
313*0fca6ea1SDimitry Andric  // I/O mode.
314*0fca6ea1SDimitry Andric  static const ios_base::openmode __no_io_operations = ios_base::trunc;
315*0fca6ea1SDimitry Andric  // Unbuffered I/O mode has been requested.
316*0fca6ea1SDimitry Andric  static const ios_base::openmode __use_unbuffered_io = ios_base::ate;
317*0fca6ea1SDimitry Andric  // Used to track the currently used mode and track whether the output should
318*0fca6ea1SDimitry Andric  // be unbuffered.
319*0fca6ea1SDimitry Andric  // [filebuf.virtuals]/12
320*0fca6ea1SDimitry Andric  //   If setbuf(0, 0) is called on a stream before any I/O has occurred on
321*0fca6ea1SDimitry Andric  //   that stream, the stream becomes unbuffered. Otherwise the results are
322*0fca6ea1SDimitry Andric  //   implementation-defined.
323*0fca6ea1SDimitry Andric  // This allows calling setbuf(0, 0)
324*0fca6ea1SDimitry Andric  // - before opening a file,
325*0fca6ea1SDimitry Andric  // - after opening a file, before
326*0fca6ea1SDimitry Andric  //   - a read
327*0fca6ea1SDimitry Andric  //   - a write
328*0fca6ea1SDimitry Andric  //   - a seek.
329*0fca6ea1SDimitry Andric  // Note that opening a file with ios_base::ate does a seek operation.
330*0fca6ea1SDimitry Andric  // Normally underflow, overflow, and sync change this flag to ios_base::in,
331*0fca6ea1SDimitry Andric  // ios_base_out, or 0.
332*0fca6ea1SDimitry Andric  //
333*0fca6ea1SDimitry Andric  // The ios_base::trunc and ios_base::ate flags are not used in __cm_. They
334*0fca6ea1SDimitry Andric  // are used to track the state of the unbuffered request. For readability
335*0fca6ea1SDimitry Andric  // they have the aliases __no_io_operations and __use_unbuffered_io
336*0fca6ea1SDimitry Andric  // respectively.
337*0fca6ea1SDimitry Andric  //
338*0fca6ea1SDimitry Andric  // The __no_io_operations and __use_unbuffered_io flags are used in the
339*0fca6ea1SDimitry Andric  // following way:
340*0fca6ea1SDimitry Andric  // - __no_io_operations is set upon construction to indicate the unbuffered
341*0fca6ea1SDimitry Andric  //   state can be set.
342*0fca6ea1SDimitry Andric  // - When requesting unbuffered output:
343*0fca6ea1SDimitry Andric  //   - If the file is open it sets the mode.
344*0fca6ea1SDimitry Andric  //   - Else places a request by adding the __use_unbuffered_io flag.
345*0fca6ea1SDimitry Andric  // - When a file is opened it checks whether both __no_io_operations and
346*0fca6ea1SDimitry Andric  //   __use_unbuffered_io are set. If so switches to unbuffered mode.
347*0fca6ea1SDimitry Andric  // - All file I/O operations change the mode effectively clearing the
348*0fca6ea1SDimitry Andric  //   __no_io_operations and __use_unbuffered_io flags.
3490b57cec5SDimitry Andric  ios_base::openmode __cm_;
3500b57cec5SDimitry Andric  bool __owns_eb_;
3510b57cec5SDimitry Andric  bool __owns_ib_;
3520b57cec5SDimitry Andric  bool __always_noconv_;
3530b57cec5SDimitry Andric
3540b57cec5SDimitry Andric  bool __read_mode();
3550b57cec5SDimitry Andric  void __write_mode();
356cb14a3feSDimitry Andric
357cb14a3feSDimitry Andric  _LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
358*0fca6ea1SDimitry Andric
359*0fca6ea1SDimitry Andric  // There are multiple (__)open function, they use different C-API open
360*0fca6ea1SDimitry Andric  // function. After that call these functions behave the same. This function
361*0fca6ea1SDimitry Andric  // does that part and determines the final return value.
362*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_filebuf* __do_open(FILE* __file, ios_base::openmode __mode) {
363*0fca6ea1SDimitry Andric    __file_ = __file;
364*0fca6ea1SDimitry Andric    if (!__file_)
365*0fca6ea1SDimitry Andric      return nullptr;
366*0fca6ea1SDimitry Andric
367*0fca6ea1SDimitry Andric    __om_ = __mode;
368*0fca6ea1SDimitry Andric    if (__cm_ == (__no_io_operations | __use_unbuffered_io)) {
369*0fca6ea1SDimitry Andric      std::setbuf(__file_, nullptr);
370*0fca6ea1SDimitry Andric      __cm_ = 0;
371*0fca6ea1SDimitry Andric    }
372*0fca6ea1SDimitry Andric
373*0fca6ea1SDimitry Andric    if (__mode & ios_base::ate) {
374*0fca6ea1SDimitry Andric      __cm_ = 0;
375*0fca6ea1SDimitry Andric      if (fseek(__file_, 0, SEEK_END)) {
376*0fca6ea1SDimitry Andric        fclose(__file_);
377*0fca6ea1SDimitry Andric        __file_ = nullptr;
378*0fca6ea1SDimitry Andric        return nullptr;
379*0fca6ea1SDimitry Andric      }
380*0fca6ea1SDimitry Andric    }
381*0fca6ea1SDimitry Andric
382*0fca6ea1SDimitry Andric    return this;
383*0fca6ea1SDimitry Andric  }
384*0fca6ea1SDimitry Andric
385*0fca6ea1SDimitry Andric  // If the file is already open, switch to unbuffered mode. Otherwise, record
386*0fca6ea1SDimitry Andric  // the request to use unbuffered mode so that we use that mode when we
387*0fca6ea1SDimitry Andric  // eventually open the file.
388*0fca6ea1SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __request_unbuffered_mode(char_type* __s, streamsize __n) {
389*0fca6ea1SDimitry Andric    if (__cm_ == __no_io_operations && __s == nullptr && __n == 0) {
390*0fca6ea1SDimitry Andric      if (__file_) {
391*0fca6ea1SDimitry Andric        std::setbuf(__file_, nullptr);
392*0fca6ea1SDimitry Andric        __cm_ = 0;
393*0fca6ea1SDimitry Andric      } else {
394*0fca6ea1SDimitry Andric        __cm_ = __no_io_operations | __use_unbuffered_io;
395*0fca6ea1SDimitry Andric      }
396*0fca6ea1SDimitry Andric    }
397*0fca6ea1SDimitry Andric  }
3980b57cec5SDimitry Andric};
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
4010b57cec5SDimitry Andricbasic_filebuf<_CharT, _Traits>::basic_filebuf()
402e8d8bef9SDimitry Andric    : __extbuf_(nullptr),
403e8d8bef9SDimitry Andric      __extbufnext_(nullptr),
404e8d8bef9SDimitry Andric      __extbufend_(nullptr),
4050b57cec5SDimitry Andric      __ebs_(0),
406e8d8bef9SDimitry Andric      __intbuf_(nullptr),
4070b57cec5SDimitry Andric      __ibs_(0),
408e8d8bef9SDimitry Andric      __file_(nullptr),
4090b57cec5SDimitry Andric      __cv_(nullptr),
4100b57cec5SDimitry Andric      __st_(),
4110b57cec5SDimitry Andric      __st_last_(),
4120b57cec5SDimitry Andric      __om_(0),
413*0fca6ea1SDimitry Andric      __cm_(__no_io_operations),
4140b57cec5SDimitry Andric      __owns_eb_(false),
4150b57cec5SDimitry Andric      __owns_ib_(false),
416cb14a3feSDimitry Andric      __always_noconv_(false) {
417cb14a3feSDimitry Andric  if (std::has_facet<codecvt<char_type, char, state_type> >(this->getloc())) {
418bdd1243dSDimitry Andric    __cv_            = &std::use_facet<codecvt<char_type, char, state_type> >(this->getloc());
4190b57cec5SDimitry Andric    __always_noconv_ = __cv_->always_noconv();
4200b57cec5SDimitry Andric  }
421e8d8bef9SDimitry Andric  setbuf(nullptr, 4096);
4220b57cec5SDimitry Andric}
4230b57cec5SDimitry Andric
4240b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
425cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) : basic_streambuf<_CharT, _Traits>(__rhs) {
426cb14a3feSDimitry Andric  if (__rhs.__extbuf_ == __rhs.__extbuf_min_) {
4270b57cec5SDimitry Andric    __extbuf_     = __extbuf_min_;
4280b57cec5SDimitry Andric    __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);
4290b57cec5SDimitry Andric    __extbufend_  = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);
430cb14a3feSDimitry Andric  } else {
4310b57cec5SDimitry Andric    __extbuf_     = __rhs.__extbuf_;
4320b57cec5SDimitry Andric    __extbufnext_ = __rhs.__extbufnext_;
4330b57cec5SDimitry Andric    __extbufend_  = __rhs.__extbufend_;
4340b57cec5SDimitry Andric  }
4350b57cec5SDimitry Andric  __ebs_           = __rhs.__ebs_;
4360b57cec5SDimitry Andric  __intbuf_        = __rhs.__intbuf_;
4370b57cec5SDimitry Andric  __ibs_           = __rhs.__ibs_;
4380b57cec5SDimitry Andric  __file_          = __rhs.__file_;
4390b57cec5SDimitry Andric  __cv_            = __rhs.__cv_;
4400b57cec5SDimitry Andric  __st_            = __rhs.__st_;
4410b57cec5SDimitry Andric  __st_last_       = __rhs.__st_last_;
4420b57cec5SDimitry Andric  __om_            = __rhs.__om_;
4430b57cec5SDimitry Andric  __cm_            = __rhs.__cm_;
4440b57cec5SDimitry Andric  __owns_eb_       = __rhs.__owns_eb_;
4450b57cec5SDimitry Andric  __owns_ib_       = __rhs.__owns_ib_;
4460b57cec5SDimitry Andric  __always_noconv_ = __rhs.__always_noconv_;
447cb14a3feSDimitry Andric  if (__rhs.pbase()) {
4480b57cec5SDimitry Andric    if (__rhs.pbase() == __rhs.__intbuf_)
4490b57cec5SDimitry Andric      this->setp(__intbuf_, __intbuf_ + (__rhs.epptr() - __rhs.pbase()));
4500b57cec5SDimitry Andric    else
451cb14a3feSDimitry Andric      this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__rhs.epptr() - __rhs.pbase()));
4520b57cec5SDimitry Andric    this->__pbump(__rhs.pptr() - __rhs.pbase());
453cb14a3feSDimitry Andric  } else if (__rhs.eback()) {
4540b57cec5SDimitry Andric    if (__rhs.eback() == __rhs.__intbuf_)
455cb14a3feSDimitry Andric      this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()), __intbuf_ + (__rhs.egptr() - __rhs.eback()));
4560b57cec5SDimitry Andric    else
4570b57cec5SDimitry Andric      this->setg((char_type*)__extbuf_,
4580b57cec5SDimitry Andric                 (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),
4590b57cec5SDimitry Andric                 (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));
4600b57cec5SDimitry Andric  }
461e8d8bef9SDimitry Andric  __rhs.__extbuf_     = nullptr;
462e8d8bef9SDimitry Andric  __rhs.__extbufnext_ = nullptr;
463e8d8bef9SDimitry Andric  __rhs.__extbufend_  = nullptr;
4640b57cec5SDimitry Andric  __rhs.__ebs_        = 0;
4650b57cec5SDimitry Andric  __rhs.__intbuf_     = 0;
4660b57cec5SDimitry Andric  __rhs.__ibs_        = 0;
467e8d8bef9SDimitry Andric  __rhs.__file_       = nullptr;
4680b57cec5SDimitry Andric  __rhs.__st_         = state_type();
4690b57cec5SDimitry Andric  __rhs.__st_last_    = state_type();
4700b57cec5SDimitry Andric  __rhs.__om_         = 0;
4710b57cec5SDimitry Andric  __rhs.__cm_         = 0;
4720b57cec5SDimitry Andric  __rhs.__owns_eb_    = false;
4730b57cec5SDimitry Andric  __rhs.__owns_ib_    = false;
4740b57cec5SDimitry Andric  __rhs.setg(0, 0, 0);
4750b57cec5SDimitry Andric  __rhs.setp(0, 0);
4760b57cec5SDimitry Andric}
4770b57cec5SDimitry Andric
4780b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
479cb14a3feSDimitry Andricinline basic_filebuf<_CharT, _Traits>& basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) {
4800b57cec5SDimitry Andric  close();
4810b57cec5SDimitry Andric  swap(__rhs);
4820b57cec5SDimitry Andric  return *this;
4830b57cec5SDimitry Andric}
4840b57cec5SDimitry Andric
4850b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
486cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>::~basic_filebuf() {
48706c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
488cb14a3feSDimitry Andric  try {
48906c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
4900b57cec5SDimitry Andric    close();
49106c3fb27SDimitry Andric#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
492cb14a3feSDimitry Andric  } catch (...) {
4930b57cec5SDimitry Andric  }
49406c3fb27SDimitry Andric#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
4950b57cec5SDimitry Andric  if (__owns_eb_)
4960b57cec5SDimitry Andric    delete[] __extbuf_;
4970b57cec5SDimitry Andric  if (__owns_ib_)
4980b57cec5SDimitry Andric    delete[] __intbuf_;
4990b57cec5SDimitry Andric}
5000b57cec5SDimitry Andric
5010b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
502cb14a3feSDimitry Andricvoid basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) {
5030b57cec5SDimitry Andric  basic_streambuf<char_type, traits_type>::swap(__rhs);
504cb14a3feSDimitry Andric  if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
50581ad6265SDimitry Andric    // Neither *this nor __rhs uses the small buffer, so we can simply swap the pointers.
50681ad6265SDimitry Andric    std::swap(__extbuf_, __rhs.__extbuf_);
50781ad6265SDimitry Andric    std::swap(__extbufnext_, __rhs.__extbufnext_);
50881ad6265SDimitry Andric    std::swap(__extbufend_, __rhs.__extbufend_);
509cb14a3feSDimitry Andric  } else {
51081ad6265SDimitry Andric    ptrdiff_t __ln = __extbufnext_ ? __extbufnext_ - __extbuf_ : 0;
51181ad6265SDimitry Andric    ptrdiff_t __le = __extbufend_ ? __extbufend_ - __extbuf_ : 0;
51281ad6265SDimitry Andric    ptrdiff_t __rn = __rhs.__extbufnext_ ? __rhs.__extbufnext_ - __rhs.__extbuf_ : 0;
51381ad6265SDimitry Andric    ptrdiff_t __re = __rhs.__extbufend_ ? __rhs.__extbufend_ - __rhs.__extbuf_ : 0;
514cb14a3feSDimitry Andric    if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
51581ad6265SDimitry Andric      // *this uses the small buffer, but __rhs doesn't.
5160b57cec5SDimitry Andric      __extbuf_       = __rhs.__extbuf_;
5170b57cec5SDimitry Andric      __rhs.__extbuf_ = __rhs.__extbuf_min_;
51881ad6265SDimitry Andric      std::memmove(__rhs.__extbuf_min_, __extbuf_min_, sizeof(__extbuf_min_));
519cb14a3feSDimitry Andric    } else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_) {
52081ad6265SDimitry Andric      // *this doesn't use the small buffer, but __rhs does.
5210b57cec5SDimitry Andric      __rhs.__extbuf_ = __extbuf_;
5220b57cec5SDimitry Andric      __extbuf_       = __extbuf_min_;
52381ad6265SDimitry Andric      std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
524cb14a3feSDimitry Andric    } else {
52581ad6265SDimitry Andric      // Both *this and __rhs use the small buffer.
52681ad6265SDimitry Andric      char __tmp[sizeof(__extbuf_min_)];
52781ad6265SDimitry Andric      std::memmove(__tmp, __extbuf_min_, sizeof(__extbuf_min_));
52881ad6265SDimitry Andric      std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
52981ad6265SDimitry Andric      std::memmove(__rhs.__extbuf_min_, __tmp, sizeof(__extbuf_min_));
5300b57cec5SDimitry Andric    }
5310b57cec5SDimitry Andric    __extbufnext_       = __extbuf_ + __rn;
5320b57cec5SDimitry Andric    __extbufend_        = __extbuf_ + __re;
5330b57cec5SDimitry Andric    __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;
5340b57cec5SDimitry Andric    __rhs.__extbufend_  = __rhs.__extbuf_ + __le;
5350b57cec5SDimitry Andric  }
5365f757f3fSDimitry Andric  std::swap(__ebs_, __rhs.__ebs_);
5375f757f3fSDimitry Andric  std::swap(__intbuf_, __rhs.__intbuf_);
5385f757f3fSDimitry Andric  std::swap(__ibs_, __rhs.__ibs_);
5395f757f3fSDimitry Andric  std::swap(__file_, __rhs.__file_);
5405f757f3fSDimitry Andric  std::swap(__cv_, __rhs.__cv_);
5415f757f3fSDimitry Andric  std::swap(__st_, __rhs.__st_);
5425f757f3fSDimitry Andric  std::swap(__st_last_, __rhs.__st_last_);
5435f757f3fSDimitry Andric  std::swap(__om_, __rhs.__om_);
5445f757f3fSDimitry Andric  std::swap(__cm_, __rhs.__cm_);
5455f757f3fSDimitry Andric  std::swap(__owns_eb_, __rhs.__owns_eb_);
5465f757f3fSDimitry Andric  std::swap(__owns_ib_, __rhs.__owns_ib_);
5475f757f3fSDimitry Andric  std::swap(__always_noconv_, __rhs.__always_noconv_);
548cb14a3feSDimitry Andric  if (this->eback() == (char_type*)__rhs.__extbuf_min_) {
5490b57cec5SDimitry Andric    ptrdiff_t __n = this->gptr() - this->eback();
5500b57cec5SDimitry Andric    ptrdiff_t __e = this->egptr() - this->eback();
551cb14a3feSDimitry Andric    this->setg((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __n, (char_type*)__extbuf_min_ + __e);
552cb14a3feSDimitry Andric  } else if (this->pbase() == (char_type*)__rhs.__extbuf_min_) {
5530b57cec5SDimitry Andric    ptrdiff_t __n = this->pptr() - this->pbase();
5540b57cec5SDimitry Andric    ptrdiff_t __e = this->epptr() - this->pbase();
555cb14a3feSDimitry Andric    this->setp((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __e);
5560b57cec5SDimitry Andric    this->__pbump(__n);
5570b57cec5SDimitry Andric  }
558cb14a3feSDimitry Andric  if (__rhs.eback() == (char_type*)__extbuf_min_) {
5590b57cec5SDimitry Andric    ptrdiff_t __n = __rhs.gptr() - __rhs.eback();
5600b57cec5SDimitry Andric    ptrdiff_t __e = __rhs.egptr() - __rhs.eback();
561cb14a3feSDimitry Andric    __rhs.setg(
562cb14a3feSDimitry Andric        (char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __n, (char_type*)__rhs.__extbuf_min_ + __e);
563cb14a3feSDimitry Andric  } else if (__rhs.pbase() == (char_type*)__extbuf_min_) {
5640b57cec5SDimitry Andric    ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();
5650b57cec5SDimitry Andric    ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();
566cb14a3feSDimitry Andric    __rhs.setp((char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __e);
5670b57cec5SDimitry Andric    __rhs.__pbump(__n);
5680b57cec5SDimitry Andric  }
5690b57cec5SDimitry Andric}
5700b57cec5SDimitry Andric
5710b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
572cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) {
5730b57cec5SDimitry Andric  __x.swap(__y);
5740b57cec5SDimitry Andric}
5750b57cec5SDimitry Andric
5760b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
577cb14a3feSDimitry Andricinline bool basic_filebuf<_CharT, _Traits>::is_open() const {
578e8d8bef9SDimitry Andric  return __file_ != nullptr;
5790b57cec5SDimitry Andric}
5800b57cec5SDimitry Andric
5810b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
582cb14a3feSDimitry Andricconst char* basic_filebuf<_CharT, _Traits>::__make_mdstring(ios_base::openmode __mode) _NOEXCEPT {
5830b57cec5SDimitry Andric  switch (__mode & ~ios_base::ate) {
5840b57cec5SDimitry Andric  case ios_base::out:
5850b57cec5SDimitry Andric  case ios_base::out | ios_base::trunc:
586e40139ffSDimitry Andric    return "w" _LIBCPP_FOPEN_CLOEXEC_MODE;
5870b57cec5SDimitry Andric  case ios_base::out | ios_base::app:
5880b57cec5SDimitry Andric  case ios_base::app:
589e40139ffSDimitry Andric    return "a" _LIBCPP_FOPEN_CLOEXEC_MODE;
5900b57cec5SDimitry Andric  case ios_base::in:
591e40139ffSDimitry Andric    return "r" _LIBCPP_FOPEN_CLOEXEC_MODE;
5920b57cec5SDimitry Andric  case ios_base::in | ios_base::out:
593e40139ffSDimitry Andric    return "r+" _LIBCPP_FOPEN_CLOEXEC_MODE;
5940b57cec5SDimitry Andric  case ios_base::in | ios_base::out | ios_base::trunc:
595e40139ffSDimitry Andric    return "w+" _LIBCPP_FOPEN_CLOEXEC_MODE;
5960b57cec5SDimitry Andric  case ios_base::in | ios_base::out | ios_base::app:
5970b57cec5SDimitry Andric  case ios_base::in | ios_base::app:
598e40139ffSDimitry Andric    return "a+" _LIBCPP_FOPEN_CLOEXEC_MODE;
5990b57cec5SDimitry Andric  case ios_base::out | ios_base::binary:
6000b57cec5SDimitry Andric  case ios_base::out | ios_base::trunc | ios_base::binary:
601e40139ffSDimitry Andric    return "wb" _LIBCPP_FOPEN_CLOEXEC_MODE;
6020b57cec5SDimitry Andric  case ios_base::out | ios_base::app | ios_base::binary:
6030b57cec5SDimitry Andric  case ios_base::app | ios_base::binary:
604e40139ffSDimitry Andric    return "ab" _LIBCPP_FOPEN_CLOEXEC_MODE;
6050b57cec5SDimitry Andric  case ios_base::in | ios_base::binary:
606e40139ffSDimitry Andric    return "rb" _LIBCPP_FOPEN_CLOEXEC_MODE;
6070b57cec5SDimitry Andric  case ios_base::in | ios_base::out | ios_base::binary:
608e40139ffSDimitry Andric    return "r+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
6090b57cec5SDimitry Andric  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
610e40139ffSDimitry Andric    return "w+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
6110b57cec5SDimitry Andric  case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
6120b57cec5SDimitry Andric  case ios_base::in | ios_base::app | ios_base::binary:
613e40139ffSDimitry Andric    return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
6145f757f3fSDimitry Andric#  if _LIBCPP_STD_VER >= 23
6155f757f3fSDimitry Andric  case ios_base::out | ios_base::noreplace:
6165f757f3fSDimitry Andric  case ios_base::out | ios_base::trunc | ios_base::noreplace:
6175f757f3fSDimitry Andric    return "wx" _LIBCPP_FOPEN_CLOEXEC_MODE;
6185f757f3fSDimitry Andric  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
6195f757f3fSDimitry Andric    return "w+x" _LIBCPP_FOPEN_CLOEXEC_MODE;
6205f757f3fSDimitry Andric  case ios_base::out | ios_base::binary | ios_base::noreplace:
6215f757f3fSDimitry Andric  case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
6225f757f3fSDimitry Andric    return "wbx" _LIBCPP_FOPEN_CLOEXEC_MODE;
6235f757f3fSDimitry Andric  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
6245f757f3fSDimitry Andric    return "w+bx" _LIBCPP_FOPEN_CLOEXEC_MODE;
6255f757f3fSDimitry Andric#  endif // _LIBCPP_STD_VER >= 23
6260b57cec5SDimitry Andric  default:
6270b57cec5SDimitry Andric    return nullptr;
6280b57cec5SDimitry Andric  }
62981ad6265SDimitry Andric  __libcpp_unreachable();
6300b57cec5SDimitry Andric}
6310b57cec5SDimitry Andric
632*0fca6ea1SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
633*0fca6ea1SDimitry Andrictemplate <class _CharT, class _Traits>
634*0fca6ea1SDimitry Andricconst wchar_t* basic_filebuf<_CharT, _Traits>::__make_mdwstring(ios_base::openmode __mode) _NOEXCEPT {
635*0fca6ea1SDimitry Andric  switch (__mode & ~ios_base::ate) {
636*0fca6ea1SDimitry Andric  case ios_base::out:
637*0fca6ea1SDimitry Andric  case ios_base::out | ios_base::trunc:
638*0fca6ea1SDimitry Andric    return L"w";
639*0fca6ea1SDimitry Andric  case ios_base::out | ios_base::app:
640*0fca6ea1SDimitry Andric  case ios_base::app:
641*0fca6ea1SDimitry Andric    return L"a";
642*0fca6ea1SDimitry Andric  case ios_base::in:
643*0fca6ea1SDimitry Andric    return L"r";
644*0fca6ea1SDimitry Andric  case ios_base::in | ios_base::out:
645*0fca6ea1SDimitry Andric    return L"r+";
646*0fca6ea1SDimitry Andric  case ios_base::in | ios_base::out | ios_base::trunc:
647*0fca6ea1SDimitry Andric    return L"w+";
648*0fca6ea1SDimitry Andric  case ios_base::in | ios_base::out | ios_base::app:
649*0fca6ea1SDimitry Andric  case ios_base::in | ios_base::app:
650*0fca6ea1SDimitry Andric    return L"a+";
651*0fca6ea1SDimitry Andric  case ios_base::out | ios_base::binary:
652*0fca6ea1SDimitry Andric  case ios_base::out | ios_base::trunc | ios_base::binary:
653*0fca6ea1SDimitry Andric    return L"wb";
654*0fca6ea1SDimitry Andric  case ios_base::out | ios_base::app | ios_base::binary:
655*0fca6ea1SDimitry Andric  case ios_base::app | ios_base::binary:
656*0fca6ea1SDimitry Andric    return L"ab";
657*0fca6ea1SDimitry Andric  case ios_base::in | ios_base::binary:
658*0fca6ea1SDimitry Andric    return L"rb";
659*0fca6ea1SDimitry Andric  case ios_base::in | ios_base::out | ios_base::binary:
660*0fca6ea1SDimitry Andric    return L"r+b";
661*0fca6ea1SDimitry Andric  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
662*0fca6ea1SDimitry Andric    return L"w+b";
663*0fca6ea1SDimitry Andric  case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
664*0fca6ea1SDimitry Andric  case ios_base::in | ios_base::app | ios_base::binary:
665*0fca6ea1SDimitry Andric    return L"a+b";
666*0fca6ea1SDimitry Andric#    if _LIBCPP_STD_VER >= 23
667*0fca6ea1SDimitry Andric  case ios_base::out | ios_base::noreplace:
668*0fca6ea1SDimitry Andric  case ios_base::out | ios_base::trunc | ios_base::noreplace:
669*0fca6ea1SDimitry Andric    return L"wx";
670*0fca6ea1SDimitry Andric  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
671*0fca6ea1SDimitry Andric    return L"w+x";
672*0fca6ea1SDimitry Andric  case ios_base::out | ios_base::binary | ios_base::noreplace:
673*0fca6ea1SDimitry Andric  case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
674*0fca6ea1SDimitry Andric    return L"wbx";
675*0fca6ea1SDimitry Andric  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
676*0fca6ea1SDimitry Andric    return L"w+bx";
677*0fca6ea1SDimitry Andric#    endif // _LIBCPP_STD_VER >= 23
678*0fca6ea1SDimitry Andric  default:
679*0fca6ea1SDimitry Andric    return nullptr;
680*0fca6ea1SDimitry Andric  }
681*0fca6ea1SDimitry Andric  __libcpp_unreachable();
682*0fca6ea1SDimitry Andric}
683*0fca6ea1SDimitry Andric#  endif
684*0fca6ea1SDimitry Andric
6850b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
686cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
687*0fca6ea1SDimitry Andric  if (__file_)
688*0fca6ea1SDimitry Andric    return nullptr;
689*0fca6ea1SDimitry Andric  const char* __mdstr = __make_mdstring(__mode);
690*0fca6ea1SDimitry Andric  if (!__mdstr)
691*0fca6ea1SDimitry Andric    return nullptr;
692*0fca6ea1SDimitry Andric
693*0fca6ea1SDimitry Andric  return __do_open(fopen(__s, __mdstr), __mode);
6940b57cec5SDimitry Andric}
6950b57cec5SDimitry Andric
6960b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
697cb14a3feSDimitry Andricinline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
698*0fca6ea1SDimitry Andric  if (__file_)
699*0fca6ea1SDimitry Andric    return nullptr;
700*0fca6ea1SDimitry Andric  const char* __mdstr = __make_mdstring(__mode);
701*0fca6ea1SDimitry Andric  if (!__mdstr)
702*0fca6ea1SDimitry Andric    return nullptr;
703*0fca6ea1SDimitry Andric
704*0fca6ea1SDimitry Andric  return __do_open(fdopen(__fd, __mdstr), __mode);
7050b57cec5SDimitry Andric}
7060b57cec5SDimitry Andric
7070b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
7080b57cec5SDimitry Andric// This is basically the same as the char* overload except that it uses _wfopen
7090b57cec5SDimitry Andric// and long mode strings.
7100b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
711cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
712*0fca6ea1SDimitry Andric  if (__file_)
713*0fca6ea1SDimitry Andric    return nullptr;
714*0fca6ea1SDimitry Andric  const wchar_t* __mdstr = __make_mdwstring(__mode);
715*0fca6ea1SDimitry Andric  if (!__mdstr)
716*0fca6ea1SDimitry Andric    return nullptr;
717*0fca6ea1SDimitry Andric
718*0fca6ea1SDimitry Andric  return __do_open(_wfopen(__s, __mdstr), __mode);
7190b57cec5SDimitry Andric}
7200b57cec5SDimitry Andric#  endif
7210b57cec5SDimitry Andric
7220b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
723cb14a3feSDimitry Andricinline basic_filebuf<_CharT, _Traits>*
724cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
7250b57cec5SDimitry Andric  return open(__s.c_str(), __mode);
7260b57cec5SDimitry Andric}
7270b57cec5SDimitry Andric
7280b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
729cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::close() {
730e8d8bef9SDimitry Andric  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
731cb14a3feSDimitry Andric  if (__file_) {
7320b57cec5SDimitry Andric    __rt = this;
7330b57cec5SDimitry Andric    unique_ptr<FILE, int (*)(FILE*)> __h(__file_, fclose);
7340b57cec5SDimitry Andric    if (sync())
735e8d8bef9SDimitry Andric      __rt = nullptr;
736e40139ffSDimitry Andric    if (fclose(__h.release()))
737e8d8bef9SDimitry Andric      __rt = nullptr;
738e8d8bef9SDimitry Andric    __file_ = nullptr;
7390b57cec5SDimitry Andric    setbuf(0, 0);
7400b57cec5SDimitry Andric  }
7410b57cec5SDimitry Andric  return __rt;
7420b57cec5SDimitry Andric}
7430b57cec5SDimitry Andric
7440b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
745cb14a3feSDimitry Andrictypename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::underflow() {
746e8d8bef9SDimitry Andric  if (__file_ == nullptr)
7470b57cec5SDimitry Andric    return traits_type::eof();
7480b57cec5SDimitry Andric  bool __initial = __read_mode();
7490b57cec5SDimitry Andric  char_type __1buf;
750e8d8bef9SDimitry Andric  if (this->gptr() == nullptr)
7510b57cec5SDimitry Andric    this->setg(&__1buf, &__1buf + 1, &__1buf + 1);
752bdd1243dSDimitry Andric  const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
7530b57cec5SDimitry Andric  int_type __c            = traits_type::eof();
754cb14a3feSDimitry Andric  if (this->gptr() == this->egptr()) {
7555f757f3fSDimitry Andric    std::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
756cb14a3feSDimitry Andric    if (__always_noconv_) {
7570b57cec5SDimitry Andric      size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
758bdd1243dSDimitry Andric      __nmemb        = ::fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
759cb14a3feSDimitry Andric      if (__nmemb != 0) {
760cb14a3feSDimitry Andric        this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb);
7610b57cec5SDimitry Andric        __c = traits_type::to_int_type(*this->gptr());
7620b57cec5SDimitry Andric      }
763cb14a3feSDimitry Andric    } else {
764bdd1243dSDimitry Andric      if (__extbufend_ != __extbufnext_) {
7655f757f3fSDimitry Andric        _LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr");
7665f757f3fSDimitry Andric        _LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr");
7675f757f3fSDimitry Andric        std::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
768bdd1243dSDimitry Andric      }
7690b57cec5SDimitry Andric      __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
7700b57cec5SDimitry Andric      __extbufend_  = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
771cb14a3feSDimitry Andric      size_t __nmemb =
772cb14a3feSDimitry Andric          std::min(static_cast<size_t>(__ibs_ - __unget_sz), static_cast<size_t>(__extbufend_ - __extbufnext_));
7730b57cec5SDimitry Andric      codecvt_base::result __r;
7740b57cec5SDimitry Andric      __st_last_  = __st_;
7750b57cec5SDimitry Andric      size_t __nr = fread((void*)const_cast<char*>(__extbufnext_), 1, __nmemb, __file_);
776cb14a3feSDimitry Andric      if (__nr != 0) {
7770b57cec5SDimitry Andric        if (!__cv_)
7780b57cec5SDimitry Andric          __throw_bad_cast();
7790b57cec5SDimitry Andric
7800b57cec5SDimitry Andric        __extbufend_ = __extbufnext_ + __nr;
7810b57cec5SDimitry Andric        char_type* __inext;
782cb14a3feSDimitry Andric        __r = __cv_->in(
783cb14a3feSDimitry Andric            __st_, __extbuf_, __extbufend_, __extbufnext_, this->eback() + __unget_sz, this->eback() + __ibs_, __inext);
784cb14a3feSDimitry Andric        if (__r == codecvt_base::noconv) {
785cb14a3feSDimitry Andric          this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)const_cast<char*>(__extbufend_));
7860b57cec5SDimitry Andric          __c = traits_type::to_int_type(*this->gptr());
787cb14a3feSDimitry Andric        } else if (__inext != this->eback() + __unget_sz) {
7880b57cec5SDimitry Andric          this->setg(this->eback(), this->eback() + __unget_sz, __inext);
7890b57cec5SDimitry Andric          __c = traits_type::to_int_type(*this->gptr());
7900b57cec5SDimitry Andric        }
7910b57cec5SDimitry Andric      }
7920b57cec5SDimitry Andric    }
793cb14a3feSDimitry Andric  } else
7940b57cec5SDimitry Andric    __c = traits_type::to_int_type(*this->gptr());
7950b57cec5SDimitry Andric  if (this->eback() == &__1buf)
796e8d8bef9SDimitry Andric    this->setg(nullptr, nullptr, nullptr);
7970b57cec5SDimitry Andric  return __c;
7980b57cec5SDimitry Andric}
7990b57cec5SDimitry Andric
8000b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
801cb14a3feSDimitry Andrictypename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) {
802cb14a3feSDimitry Andric  if (__file_ && this->eback() < this->gptr()) {
803cb14a3feSDimitry Andric    if (traits_type::eq_int_type(__c, traits_type::eof())) {
8040b57cec5SDimitry Andric      this->gbump(-1);
8050b57cec5SDimitry Andric      return traits_type::not_eof(__c);
8060b57cec5SDimitry Andric    }
807cb14a3feSDimitry Andric    if ((__om_ & ios_base::out) || traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) {
8080b57cec5SDimitry Andric      this->gbump(-1);
8090b57cec5SDimitry Andric      *this->gptr() = traits_type::to_char_type(__c);
8100b57cec5SDimitry Andric      return __c;
8110b57cec5SDimitry Andric    }
8120b57cec5SDimitry Andric  }
8130b57cec5SDimitry Andric  return traits_type::eof();
8140b57cec5SDimitry Andric}
8150b57cec5SDimitry Andric
8160b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
817cb14a3feSDimitry Andrictypename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {
818e8d8bef9SDimitry Andric  if (__file_ == nullptr)
8190b57cec5SDimitry Andric    return traits_type::eof();
8200b57cec5SDimitry Andric  __write_mode();
8210b57cec5SDimitry Andric  char_type __1buf;
8220b57cec5SDimitry Andric  char_type* __pb_save  = this->pbase();
8230b57cec5SDimitry Andric  char_type* __epb_save = this->epptr();
824cb14a3feSDimitry Andric  if (!traits_type::eq_int_type(__c, traits_type::eof())) {
825e8d8bef9SDimitry Andric    if (this->pptr() == nullptr)
8260b57cec5SDimitry Andric      this->setp(&__1buf, &__1buf + 1);
8270b57cec5SDimitry Andric    *this->pptr() = traits_type::to_char_type(__c);
8280b57cec5SDimitry Andric    this->pbump(1);
8290b57cec5SDimitry Andric  }
830cb14a3feSDimitry Andric  if (this->pptr() != this->pbase()) {
831cb14a3feSDimitry Andric    if (__always_noconv_) {
8320b57cec5SDimitry Andric      size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
833bdd1243dSDimitry Andric      if (std::fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
8340b57cec5SDimitry Andric        return traits_type::eof();
835cb14a3feSDimitry Andric    } else {
8360b57cec5SDimitry Andric      char* __extbe = __extbuf_;
8370b57cec5SDimitry Andric      codecvt_base::result __r;
838cb14a3feSDimitry Andric      do {
8390b57cec5SDimitry Andric        if (!__cv_)
8400b57cec5SDimitry Andric          __throw_bad_cast();
8410b57cec5SDimitry Andric
8420b57cec5SDimitry Andric        const char_type* __e;
843cb14a3feSDimitry Andric        __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, __extbuf_, __extbuf_ + __ebs_, __extbe);
8440b57cec5SDimitry Andric        if (__e == this->pbase())
8450b57cec5SDimitry Andric          return traits_type::eof();
846cb14a3feSDimitry Andric        if (__r == codecvt_base::noconv) {
8470b57cec5SDimitry Andric          size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
848bdd1243dSDimitry Andric          if (std::fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
8490b57cec5SDimitry Andric            return traits_type::eof();
850cb14a3feSDimitry Andric        } else if (__r == codecvt_base::ok || __r == codecvt_base::partial) {
8510b57cec5SDimitry Andric          size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
8520b57cec5SDimitry Andric          if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
8530b57cec5SDimitry Andric            return traits_type::eof();
854cb14a3feSDimitry Andric          if (__r == codecvt_base::partial) {
8550b57cec5SDimitry Andric            this->setp(const_cast<char_type*>(__e), this->pptr());
8560b57cec5SDimitry Andric            this->__pbump(this->epptr() - this->pbase());
8570b57cec5SDimitry Andric          }
858cb14a3feSDimitry Andric        } else
8590b57cec5SDimitry Andric          return traits_type::eof();
8600b57cec5SDimitry Andric      } while (__r == codecvt_base::partial);
8610b57cec5SDimitry Andric    }
8620b57cec5SDimitry Andric    this->setp(__pb_save, __epb_save);
8630b57cec5SDimitry Andric  }
8640b57cec5SDimitry Andric  return traits_type::not_eof(__c);
8650b57cec5SDimitry Andric}
8660b57cec5SDimitry Andric
8670b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
868cb14a3feSDimitry Andricbasic_streambuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n) {
869e8d8bef9SDimitry Andric  this->setg(nullptr, nullptr, nullptr);
870e8d8bef9SDimitry Andric  this->setp(nullptr, nullptr);
871*0fca6ea1SDimitry Andric  __request_unbuffered_mode(__s, __n);
8720b57cec5SDimitry Andric  if (__owns_eb_)
8730b57cec5SDimitry Andric    delete[] __extbuf_;
8740b57cec5SDimitry Andric  if (__owns_ib_)
8750b57cec5SDimitry Andric    delete[] __intbuf_;
8760b57cec5SDimitry Andric  __ebs_ = __n;
877cb14a3feSDimitry Andric  if (__ebs_ > sizeof(__extbuf_min_)) {
878cb14a3feSDimitry Andric    if (__always_noconv_ && __s) {
8790b57cec5SDimitry Andric      __extbuf_  = (char*)__s;
8800b57cec5SDimitry Andric      __owns_eb_ = false;
881cb14a3feSDimitry Andric    } else {
8820b57cec5SDimitry Andric      __extbuf_  = new char[__ebs_];
8830b57cec5SDimitry Andric      __owns_eb_ = true;
8840b57cec5SDimitry Andric    }
885cb14a3feSDimitry Andric  } else {
8860b57cec5SDimitry Andric    __extbuf_  = __extbuf_min_;
8870b57cec5SDimitry Andric    __ebs_     = sizeof(__extbuf_min_);
8880b57cec5SDimitry Andric    __owns_eb_ = false;
8890b57cec5SDimitry Andric  }
890cb14a3feSDimitry Andric  if (!__always_noconv_) {
8910b57cec5SDimitry Andric    __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
892cb14a3feSDimitry Andric    if (__s && __ibs_ > sizeof(__extbuf_min_)) {
8930b57cec5SDimitry Andric      __intbuf_  = __s;
8940b57cec5SDimitry Andric      __owns_ib_ = false;
895cb14a3feSDimitry Andric    } else {
8960b57cec5SDimitry Andric      __intbuf_  = new char_type[__ibs_];
8970b57cec5SDimitry Andric      __owns_ib_ = true;
8980b57cec5SDimitry Andric    }
899cb14a3feSDimitry Andric  } else {
9000b57cec5SDimitry Andric    __ibs_     = 0;
901e8d8bef9SDimitry Andric    __intbuf_  = nullptr;
9020b57cec5SDimitry Andric    __owns_ib_ = false;
9030b57cec5SDimitry Andric  }
9040b57cec5SDimitry Andric  return this;
9050b57cec5SDimitry Andric}
9060b57cec5SDimitry Andric
9070b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
9080b57cec5SDimitry Andrictypename basic_filebuf<_CharT, _Traits>::pos_type
909cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) {
9100b57cec5SDimitry Andric  if (!__cv_)
9110b57cec5SDimitry Andric    __throw_bad_cast();
9120b57cec5SDimitry Andric
9130b57cec5SDimitry Andric  int __width = __cv_->encoding();
914e8d8bef9SDimitry Andric  if (__file_ == nullptr || (__width <= 0 && __off != 0) || sync())
9150b57cec5SDimitry Andric    return pos_type(off_type(-1));
9160b57cec5SDimitry Andric  // __width > 0 || __off == 0
9170b57cec5SDimitry Andric  int __whence;
918cb14a3feSDimitry Andric  switch (__way) {
9190b57cec5SDimitry Andric  case ios_base::beg:
9200b57cec5SDimitry Andric    __whence = SEEK_SET;
9210b57cec5SDimitry Andric    break;
9220b57cec5SDimitry Andric  case ios_base::cur:
9230b57cec5SDimitry Andric    __whence = SEEK_CUR;
9240b57cec5SDimitry Andric    break;
9250b57cec5SDimitry Andric  case ios_base::end:
9260b57cec5SDimitry Andric    __whence = SEEK_END;
9270b57cec5SDimitry Andric    break;
9280b57cec5SDimitry Andric  default:
9290b57cec5SDimitry Andric    return pos_type(off_type(-1));
9300b57cec5SDimitry Andric  }
9310b57cec5SDimitry Andric#  if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
9320b57cec5SDimitry Andric  if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
9330b57cec5SDimitry Andric    return pos_type(off_type(-1));
9340b57cec5SDimitry Andric  pos_type __r = ftell(__file_);
9350b57cec5SDimitry Andric#  else
936bdd1243dSDimitry Andric  if (::fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
9370b57cec5SDimitry Andric    return pos_type(off_type(-1));
9380b57cec5SDimitry Andric  pos_type __r = ftello(__file_);
9390b57cec5SDimitry Andric#  endif
9400b57cec5SDimitry Andric  __r.state(__st_);
9410b57cec5SDimitry Andric  return __r;
9420b57cec5SDimitry Andric}
9430b57cec5SDimitry Andric
9440b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
9450b57cec5SDimitry Andrictypename basic_filebuf<_CharT, _Traits>::pos_type
946cb14a3feSDimitry Andricbasic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) {
947e8d8bef9SDimitry Andric  if (__file_ == nullptr || sync())
9480b57cec5SDimitry Andric    return pos_type(off_type(-1));
9490b57cec5SDimitry Andric#  if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
9500b57cec5SDimitry Andric  if (fseek(__file_, __sp, SEEK_SET))
9510b57cec5SDimitry Andric    return pos_type(off_type(-1));
9520b57cec5SDimitry Andric#  else
953bdd1243dSDimitry Andric  if (::fseeko(__file_, __sp, SEEK_SET))
9540b57cec5SDimitry Andric    return pos_type(off_type(-1));
9550b57cec5SDimitry Andric#  endif
9560b57cec5SDimitry Andric  __st_ = __sp.state();
9570b57cec5SDimitry Andric  return __sp;
9580b57cec5SDimitry Andric}
9590b57cec5SDimitry Andric
9600b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
961cb14a3feSDimitry Andricint basic_filebuf<_CharT, _Traits>::sync() {
962e8d8bef9SDimitry Andric  if (__file_ == nullptr)
9630b57cec5SDimitry Andric    return 0;
9640b57cec5SDimitry Andric  if (!__cv_)
9650b57cec5SDimitry Andric    __throw_bad_cast();
9660b57cec5SDimitry Andric
967cb14a3feSDimitry Andric  if (__cm_ & ios_base::out) {
9680b57cec5SDimitry Andric    if (this->pptr() != this->pbase())
9690b57cec5SDimitry Andric      if (overflow() == traits_type::eof())
9700b57cec5SDimitry Andric        return -1;
9710b57cec5SDimitry Andric    codecvt_base::result __r;
972cb14a3feSDimitry Andric    do {
9730b57cec5SDimitry Andric      char* __extbe;
9740b57cec5SDimitry Andric      __r            = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
9750b57cec5SDimitry Andric      size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
9760b57cec5SDimitry Andric      if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
9770b57cec5SDimitry Andric        return -1;
9780b57cec5SDimitry Andric    } while (__r == codecvt_base::partial);
9790b57cec5SDimitry Andric    if (__r == codecvt_base::error)
9800b57cec5SDimitry Andric      return -1;
9810b57cec5SDimitry Andric    if (fflush(__file_))
9820b57cec5SDimitry Andric      return -1;
983cb14a3feSDimitry Andric  } else if (__cm_ & ios_base::in) {
9840b57cec5SDimitry Andric    off_type __c;
9850b57cec5SDimitry Andric    state_type __state = __st_last_;
9860b57cec5SDimitry Andric    bool __update_st   = false;
9870b57cec5SDimitry Andric    if (__always_noconv_)
9880b57cec5SDimitry Andric      __c = this->egptr() - this->gptr();
989cb14a3feSDimitry Andric    else {
9900b57cec5SDimitry Andric      int __width = __cv_->encoding();
9910b57cec5SDimitry Andric      __c         = __extbufend_ - __extbufnext_;
9920b57cec5SDimitry Andric      if (__width > 0)
9930b57cec5SDimitry Andric        __c += __width * (this->egptr() - this->gptr());
994cb14a3feSDimitry Andric      else {
995cb14a3feSDimitry Andric        if (this->gptr() != this->egptr()) {
996cb14a3feSDimitry Andric          const int __off = __cv_->length(__state, __extbuf_, __extbufnext_, this->gptr() - this->eback());
9970b57cec5SDimitry Andric          __c += __extbufnext_ - __extbuf_ - __off;
9980b57cec5SDimitry Andric          __update_st = true;
9990b57cec5SDimitry Andric        }
10000b57cec5SDimitry Andric      }
10010b57cec5SDimitry Andric    }
10020b57cec5SDimitry Andric#  if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
10030b57cec5SDimitry Andric    if (fseek(__file_, -__c, SEEK_CUR))
10040b57cec5SDimitry Andric      return -1;
10050b57cec5SDimitry Andric#  else
1006bdd1243dSDimitry Andric    if (::fseeko(__file_, -__c, SEEK_CUR))
10070b57cec5SDimitry Andric      return -1;
10080b57cec5SDimitry Andric#  endif
10090b57cec5SDimitry Andric    if (__update_st)
10100b57cec5SDimitry Andric      __st_ = __state;
10110b57cec5SDimitry Andric    __extbufnext_ = __extbufend_ = __extbuf_;
1012e8d8bef9SDimitry Andric    this->setg(nullptr, nullptr, nullptr);
10130b57cec5SDimitry Andric    __cm_ = 0;
10140b57cec5SDimitry Andric  }
10150b57cec5SDimitry Andric  return 0;
10160b57cec5SDimitry Andric}
10170b57cec5SDimitry Andric
10180b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1019cb14a3feSDimitry Andricvoid basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) {
10200b57cec5SDimitry Andric  sync();
1021bdd1243dSDimitry Andric  __cv_            = &std::use_facet<codecvt<char_type, char, state_type> >(__loc);
10220b57cec5SDimitry Andric  bool __old_anc   = __always_noconv_;
10230b57cec5SDimitry Andric  __always_noconv_ = __cv_->always_noconv();
1024cb14a3feSDimitry Andric  if (__old_anc != __always_noconv_) {
1025e8d8bef9SDimitry Andric    this->setg(nullptr, nullptr, nullptr);
1026e8d8bef9SDimitry Andric    this->setp(nullptr, nullptr);
10270b57cec5SDimitry Andric    // invariant, char_type is char, else we couldn't get here
10280b57cec5SDimitry Andric    if (__always_noconv_) // need to dump __intbuf_
10290b57cec5SDimitry Andric    {
10300b57cec5SDimitry Andric      if (__owns_eb_)
10310b57cec5SDimitry Andric        delete[] __extbuf_;
10320b57cec5SDimitry Andric      __owns_eb_ = __owns_ib_;
10330b57cec5SDimitry Andric      __ebs_     = __ibs_;
10340b57cec5SDimitry Andric      __extbuf_  = (char*)__intbuf_;
10350b57cec5SDimitry Andric      __ibs_     = 0;
1036e8d8bef9SDimitry Andric      __intbuf_  = nullptr;
10370b57cec5SDimitry Andric      __owns_ib_ = false;
1038cb14a3feSDimitry Andric    } else // need to obtain an __intbuf_.
10390b57cec5SDimitry Andric    {      // If __extbuf_ is user-supplied, use it, else new __intbuf_
1040cb14a3feSDimitry Andric      if (!__owns_eb_ && __extbuf_ != __extbuf_min_) {
10410b57cec5SDimitry Andric        __ibs_     = __ebs_;
10420b57cec5SDimitry Andric        __intbuf_  = (char_type*)__extbuf_;
10430b57cec5SDimitry Andric        __owns_ib_ = false;
10440b57cec5SDimitry Andric        __extbuf_  = new char[__ebs_];
10450b57cec5SDimitry Andric        __owns_eb_ = true;
1046cb14a3feSDimitry Andric      } else {
10470b57cec5SDimitry Andric        __ibs_     = __ebs_;
10480b57cec5SDimitry Andric        __intbuf_  = new char_type[__ibs_];
10490b57cec5SDimitry Andric        __owns_ib_ = true;
10500b57cec5SDimitry Andric      }
10510b57cec5SDimitry Andric    }
10520b57cec5SDimitry Andric  }
10530b57cec5SDimitry Andric}
10540b57cec5SDimitry Andric
10550b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1056cb14a3feSDimitry Andricbool basic_filebuf<_CharT, _Traits>::__read_mode() {
1057cb14a3feSDimitry Andric  if (!(__cm_ & ios_base::in)) {
1058e8d8bef9SDimitry Andric    this->setp(nullptr, nullptr);
10590b57cec5SDimitry Andric    if (__always_noconv_)
1060cb14a3feSDimitry Andric      this->setg((char_type*)__extbuf_, (char_type*)__extbuf_ + __ebs_, (char_type*)__extbuf_ + __ebs_);
10610b57cec5SDimitry Andric    else
10620b57cec5SDimitry Andric      this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
10630b57cec5SDimitry Andric    __cm_ = ios_base::in;
10640b57cec5SDimitry Andric    return true;
10650b57cec5SDimitry Andric  }
10660b57cec5SDimitry Andric  return false;
10670b57cec5SDimitry Andric}
10680b57cec5SDimitry Andric
10690b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1070cb14a3feSDimitry Andricvoid basic_filebuf<_CharT, _Traits>::__write_mode() {
1071cb14a3feSDimitry Andric  if (!(__cm_ & ios_base::out)) {
1072e8d8bef9SDimitry Andric    this->setg(nullptr, nullptr, nullptr);
1073cb14a3feSDimitry Andric    if (__ebs_ > sizeof(__extbuf_min_)) {
10740b57cec5SDimitry Andric      if (__always_noconv_)
1075cb14a3feSDimitry Andric        this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__ebs_ - 1));
10760b57cec5SDimitry Andric      else
10770b57cec5SDimitry Andric        this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
1078cb14a3feSDimitry Andric    } else
1079e8d8bef9SDimitry Andric      this->setp(nullptr, nullptr);
10800b57cec5SDimitry Andric    __cm_ = ios_base::out;
10810b57cec5SDimitry Andric  }
10820b57cec5SDimitry Andric}
10830b57cec5SDimitry Andric
10840b57cec5SDimitry Andric// basic_ifstream
10850b57cec5SDimitry Andric
10860b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1087cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS basic_ifstream : public basic_istream<_CharT, _Traits> {
10880b57cec5SDimitry Andricpublic:
10890b57cec5SDimitry Andric  typedef _CharT char_type;
10900b57cec5SDimitry Andric  typedef _Traits traits_type;
10910b57cec5SDimitry Andric  typedef typename traits_type::int_type int_type;
10920b57cec5SDimitry Andric  typedef typename traits_type::pos_type pos_type;
10930b57cec5SDimitry Andric  typedef typename traits_type::off_type off_type;
10941db9f3b2SDimitry Andric#  if _LIBCPP_STD_VER >= 26
10951db9f3b2SDimitry Andric  using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
10961db9f3b2SDimitry Andric#  endif
10970b57cec5SDimitry Andric
1098cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_ifstream();
1099cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
11000b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1101cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
11020b57cec5SDimitry Andric#  endif
1103cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
110406c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
1105*0fca6ea1SDimitry Andric  template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
1106*0fca6ea1SDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
1107*0fca6ea1SDimitry Andric      _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const _Tp& __p, ios_base::openmode __mode = ios_base::in)
11080b57cec5SDimitry Andric      : basic_ifstream(__p.c_str(), __mode) {}
11090b57cec5SDimitry Andric#  endif // _LIBCPP_STD_VER >= 17
1110cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_ifstream(basic_ifstream&& __rhs);
1111cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_ifstream& operator=(basic_ifstream&& __rhs);
1112cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs);
11130b57cec5SDimitry Andric
1114cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
11151db9f3b2SDimitry Andric#  if _LIBCPP_STD_VER >= 26
11161db9f3b2SDimitry Andric  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
11171db9f3b2SDimitry Andric#  endif
1118cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
11190b57cec5SDimitry Andric  void open(const char* __s, ios_base::openmode __mode = ios_base::in);
11200b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
11210b57cec5SDimitry Andric  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
11220b57cec5SDimitry Andric#  endif
11230b57cec5SDimitry Andric  void open(const string& __s, ios_base::openmode __mode = ios_base::in);
112406c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
1125cb14a3feSDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1126cb14a3feSDimitry Andric  open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) {
11270b57cec5SDimitry Andric    return open(__p.c_str(), __mode);
11280b57cec5SDimitry Andric  }
11290b57cec5SDimitry Andric#  endif // _LIBCPP_STD_VER >= 17
11300b57cec5SDimitry Andric
1131cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
1132cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void close();
11330b57cec5SDimitry Andric
11340b57cec5SDimitry Andricprivate:
11350b57cec5SDimitry Andric  basic_filebuf<char_type, traits_type> __sb_;
11360b57cec5SDimitry Andric};
11370b57cec5SDimitry Andric
11380b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1139cb14a3feSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream() : basic_istream<char_type, traits_type>(&__sb_) {}
11400b57cec5SDimitry Andric
11410b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1142cb14a3feSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
1143cb14a3feSDimitry Andric    : basic_istream<char_type, traits_type>(&__sb_) {
1144e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
11450b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
11460b57cec5SDimitry Andric}
11470b57cec5SDimitry Andric
11480b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
11490b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1150cb14a3feSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode)
1151cb14a3feSDimitry Andric    : basic_istream<char_type, traits_type>(&__sb_) {
1152e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
11530b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
11540b57cec5SDimitry Andric}
11550b57cec5SDimitry Andric#  endif
11560b57cec5SDimitry Andric
11570b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1158cb14a3feSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)
1159cb14a3feSDimitry Andric    : basic_istream<char_type, traits_type>(&__sb_) {
1160e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
11610b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
11620b57cec5SDimitry Andric}
11630b57cec5SDimitry Andric
11640b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1165cb14a3feSDimitry Andricinline basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
1166cb14a3feSDimitry Andric    : basic_istream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
11670b57cec5SDimitry Andric  this->set_rdbuf(&__sb_);
11680b57cec5SDimitry Andric}
11690b57cec5SDimitry Andric
11700b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1171cb14a3feSDimitry Andricinline basic_ifstream<_CharT, _Traits>& basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) {
11725f757f3fSDimitry Andric  basic_istream<char_type, traits_type>::operator=(std::move(__rhs));
11735f757f3fSDimitry Andric  __sb_ = std::move(__rhs.__sb_);
11740b57cec5SDimitry Andric  return *this;
11750b57cec5SDimitry Andric}
11760b57cec5SDimitry Andric
11770b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1178cb14a3feSDimitry Andricinline void basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) {
11790b57cec5SDimitry Andric  basic_istream<char_type, traits_type>::swap(__rhs);
11800b57cec5SDimitry Andric  __sb_.swap(__rhs.__sb_);
11810b57cec5SDimitry Andric}
11820b57cec5SDimitry Andric
11830b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1184cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) {
11850b57cec5SDimitry Andric  __x.swap(__y);
11860b57cec5SDimitry Andric}
11870b57cec5SDimitry Andric
11880b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1189cb14a3feSDimitry Andricinline basic_filebuf<_CharT, _Traits>* basic_ifstream<_CharT, _Traits>::rdbuf() const {
11900b57cec5SDimitry Andric  return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
11910b57cec5SDimitry Andric}
11920b57cec5SDimitry Andric
11930b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1194cb14a3feSDimitry Andricinline bool basic_ifstream<_CharT, _Traits>::is_open() const {
11950b57cec5SDimitry Andric  return __sb_.is_open();
11960b57cec5SDimitry Andric}
11970b57cec5SDimitry Andric
11980b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1199cb14a3feSDimitry Andricvoid basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
12000b57cec5SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::in))
12010b57cec5SDimitry Andric    this->clear();
12020b57cec5SDimitry Andric  else
12030b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
12040b57cec5SDimitry Andric}
12050b57cec5SDimitry Andric
12060b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
12070b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1208cb14a3feSDimitry Andricvoid basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
12090b57cec5SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::in))
12100b57cec5SDimitry Andric    this->clear();
12110b57cec5SDimitry Andric  else
12120b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
12130b57cec5SDimitry Andric}
12140b57cec5SDimitry Andric#  endif
12150b57cec5SDimitry Andric
12160b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1217cb14a3feSDimitry Andricvoid basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
12180b57cec5SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::in))
12190b57cec5SDimitry Andric    this->clear();
12200b57cec5SDimitry Andric  else
12210b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
12220b57cec5SDimitry Andric}
12230b57cec5SDimitry Andric
12240b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1225cb14a3feSDimitry Andricinline void basic_ifstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
12260b57cec5SDimitry Andric  if (__sb_.__open(__fd, __mode | ios_base::in))
12270b57cec5SDimitry Andric    this->clear();
12280b57cec5SDimitry Andric  else
12290b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
12300b57cec5SDimitry Andric}
12310b57cec5SDimitry Andric
12320b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1233cb14a3feSDimitry Andricinline void basic_ifstream<_CharT, _Traits>::close() {
12340b57cec5SDimitry Andric  if (__sb_.close() == 0)
12350b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
12360b57cec5SDimitry Andric}
12370b57cec5SDimitry Andric
12380b57cec5SDimitry Andric// basic_ofstream
12390b57cec5SDimitry Andric
12400b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1241cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS basic_ofstream : public basic_ostream<_CharT, _Traits> {
12420b57cec5SDimitry Andricpublic:
12430b57cec5SDimitry Andric  typedef _CharT char_type;
12440b57cec5SDimitry Andric  typedef _Traits traits_type;
12450b57cec5SDimitry Andric  typedef typename traits_type::int_type int_type;
12460b57cec5SDimitry Andric  typedef typename traits_type::pos_type pos_type;
12470b57cec5SDimitry Andric  typedef typename traits_type::off_type off_type;
12481db9f3b2SDimitry Andric#  if _LIBCPP_STD_VER >= 26
12491db9f3b2SDimitry Andric  using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
12501db9f3b2SDimitry Andric#  endif
12510b57cec5SDimitry Andric
1252cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_ofstream();
1253cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
12540b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1255cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
12560b57cec5SDimitry Andric#  endif
1257cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
12580b57cec5SDimitry Andric
125906c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
1260*0fca6ea1SDimitry Andric  template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
1261*0fca6ea1SDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY
1262*0fca6ea1SDimitry Andric      _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const _Tp& __p, ios_base::openmode __mode = ios_base::out)
12630b57cec5SDimitry Andric      : basic_ofstream(__p.c_str(), __mode) {}
12640b57cec5SDimitry Andric#  endif // _LIBCPP_STD_VER >= 17
12650b57cec5SDimitry Andric
1266cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_ofstream(basic_ofstream&& __rhs);
1267cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_ofstream& operator=(basic_ofstream&& __rhs);
1268cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream& __rhs);
12690b57cec5SDimitry Andric
1270cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
12711db9f3b2SDimitry Andric#  if _LIBCPP_STD_VER >= 26
12721db9f3b2SDimitry Andric  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
12731db9f3b2SDimitry Andric#  endif
1274cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
12750b57cec5SDimitry Andric  void open(const char* __s, ios_base::openmode __mode = ios_base::out);
12760b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
12770b57cec5SDimitry Andric  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
12780b57cec5SDimitry Andric#  endif
12790b57cec5SDimitry Andric  void open(const string& __s, ios_base::openmode __mode = ios_base::out);
12800b57cec5SDimitry Andric
128106c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
1282cb14a3feSDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1283cb14a3feSDimitry Andric  open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) {
1284cb14a3feSDimitry Andric    return open(__p.c_str(), __mode);
1285cb14a3feSDimitry Andric  }
12860b57cec5SDimitry Andric#  endif // _LIBCPP_STD_VER >= 17
12870b57cec5SDimitry Andric
1288cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
1289cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void close();
12900b57cec5SDimitry Andric
12910b57cec5SDimitry Andricprivate:
12920b57cec5SDimitry Andric  basic_filebuf<char_type, traits_type> __sb_;
12930b57cec5SDimitry Andric};
12940b57cec5SDimitry Andric
12950b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1296cb14a3feSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream() : basic_ostream<char_type, traits_type>(&__sb_) {}
12970b57cec5SDimitry Andric
12980b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1299cb14a3feSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
1300cb14a3feSDimitry Andric    : basic_ostream<char_type, traits_type>(&__sb_) {
1301e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
13020b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
13030b57cec5SDimitry Andric}
13040b57cec5SDimitry Andric
13050b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
13060b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1307cb14a3feSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode)
1308cb14a3feSDimitry Andric    : basic_ostream<char_type, traits_type>(&__sb_) {
1309e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
13100b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
13110b57cec5SDimitry Andric}
13120b57cec5SDimitry Andric#  endif
13130b57cec5SDimitry Andric
13140b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1315cb14a3feSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)
1316cb14a3feSDimitry Andric    : basic_ostream<char_type, traits_type>(&__sb_) {
1317e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
13180b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
13190b57cec5SDimitry Andric}
13200b57cec5SDimitry Andric
13210b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1322cb14a3feSDimitry Andricinline basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
1323cb14a3feSDimitry Andric    : basic_ostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
13240b57cec5SDimitry Andric  this->set_rdbuf(&__sb_);
13250b57cec5SDimitry Andric}
13260b57cec5SDimitry Andric
13270b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1328cb14a3feSDimitry Andricinline basic_ofstream<_CharT, _Traits>& basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) {
13295f757f3fSDimitry Andric  basic_ostream<char_type, traits_type>::operator=(std::move(__rhs));
13305f757f3fSDimitry Andric  __sb_ = std::move(__rhs.__sb_);
13310b57cec5SDimitry Andric  return *this;
13320b57cec5SDimitry Andric}
13330b57cec5SDimitry Andric
13340b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1335cb14a3feSDimitry Andricinline void basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) {
13360b57cec5SDimitry Andric  basic_ostream<char_type, traits_type>::swap(__rhs);
13370b57cec5SDimitry Andric  __sb_.swap(__rhs.__sb_);
13380b57cec5SDimitry Andric}
13390b57cec5SDimitry Andric
13400b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1341cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) {
13420b57cec5SDimitry Andric  __x.swap(__y);
13430b57cec5SDimitry Andric}
13440b57cec5SDimitry Andric
13450b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1346cb14a3feSDimitry Andricinline basic_filebuf<_CharT, _Traits>* basic_ofstream<_CharT, _Traits>::rdbuf() const {
13470b57cec5SDimitry Andric  return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
13480b57cec5SDimitry Andric}
13490b57cec5SDimitry Andric
13500b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1351cb14a3feSDimitry Andricinline bool basic_ofstream<_CharT, _Traits>::is_open() const {
13520b57cec5SDimitry Andric  return __sb_.is_open();
13530b57cec5SDimitry Andric}
13540b57cec5SDimitry Andric
13550b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1356cb14a3feSDimitry Andricvoid basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
13570b57cec5SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::out))
13580b57cec5SDimitry Andric    this->clear();
13590b57cec5SDimitry Andric  else
13600b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
13610b57cec5SDimitry Andric}
13620b57cec5SDimitry Andric
13630b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
13640b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1365cb14a3feSDimitry Andricvoid basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
13660b57cec5SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::out))
13670b57cec5SDimitry Andric    this->clear();
13680b57cec5SDimitry Andric  else
13690b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
13700b57cec5SDimitry Andric}
13710b57cec5SDimitry Andric#  endif
13720b57cec5SDimitry Andric
13730b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1374cb14a3feSDimitry Andricvoid basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
13750b57cec5SDimitry Andric  if (__sb_.open(__s, __mode | ios_base::out))
13760b57cec5SDimitry Andric    this->clear();
13770b57cec5SDimitry Andric  else
13780b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
13790b57cec5SDimitry Andric}
13800b57cec5SDimitry Andric
13810b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1382cb14a3feSDimitry Andricinline void basic_ofstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
13830b57cec5SDimitry Andric  if (__sb_.__open(__fd, __mode | ios_base::out))
13840b57cec5SDimitry Andric    this->clear();
13850b57cec5SDimitry Andric  else
13860b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
13870b57cec5SDimitry Andric}
13880b57cec5SDimitry Andric
13890b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1390cb14a3feSDimitry Andricinline void basic_ofstream<_CharT, _Traits>::close() {
1391e8d8bef9SDimitry Andric  if (__sb_.close() == nullptr)
13920b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
13930b57cec5SDimitry Andric}
13940b57cec5SDimitry Andric
13950b57cec5SDimitry Andric// basic_fstream
13960b57cec5SDimitry Andric
13970b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1398cb14a3feSDimitry Andricclass _LIBCPP_TEMPLATE_VIS basic_fstream : public basic_iostream<_CharT, _Traits> {
13990b57cec5SDimitry Andricpublic:
14000b57cec5SDimitry Andric  typedef _CharT char_type;
14010b57cec5SDimitry Andric  typedef _Traits traits_type;
14020b57cec5SDimitry Andric  typedef typename traits_type::int_type int_type;
14030b57cec5SDimitry Andric  typedef typename traits_type::pos_type pos_type;
14040b57cec5SDimitry Andric  typedef typename traits_type::off_type off_type;
14051db9f3b2SDimitry Andric#  if _LIBCPP_STD_VER >= 26
14061db9f3b2SDimitry Andric  using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
14071db9f3b2SDimitry Andric#  endif
14080b57cec5SDimitry Andric
1409cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_fstream();
1410cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const char* __s,
1411cb14a3feSDimitry Andric                                               ios_base::openmode __mode = ios_base::in | ios_base::out);
14120b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1413cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const wchar_t* __s,
1414cb14a3feSDimitry Andric                                               ios_base::openmode __mode = ios_base::in | ios_base::out);
14150b57cec5SDimitry Andric#  endif
1416cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const string& __s,
1417cb14a3feSDimitry Andric                                               ios_base::openmode __mode = ios_base::in | ios_base::out);
14180b57cec5SDimitry Andric
141906c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
1420*0fca6ea1SDimitry Andric  template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>
1421cb14a3feSDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(
1422*0fca6ea1SDimitry Andric      const _Tp& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
14230b57cec5SDimitry Andric      : basic_fstream(__p.c_str(), __mode) {}
14240b57cec5SDimitry Andric#  endif // _LIBCPP_STD_VER >= 17
14250b57cec5SDimitry Andric
1426cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_fstream(basic_fstream&& __rhs);
14270b57cec5SDimitry Andric
1428cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_fstream& operator=(basic_fstream&& __rhs);
1429fe6060f1SDimitry Andric
1430cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream& __rhs);
14310b57cec5SDimitry Andric
1432cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
14331db9f3b2SDimitry Andric#  if _LIBCPP_STD_VER >= 26
14341db9f3b2SDimitry Andric  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
14351db9f3b2SDimitry Andric#  endif
1436cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
143706c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
14380b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
14390b57cec5SDimitry Andric  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
14400b57cec5SDimitry Andric#  endif
144106c3fb27SDimitry Andric  _LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
14420b57cec5SDimitry Andric
144306c3fb27SDimitry Andric#  if _LIBCPP_STD_VER >= 17
1444cb14a3feSDimitry Andric  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1445cb14a3feSDimitry Andric  open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) {
1446cb14a3feSDimitry Andric    return open(__p.c_str(), __mode);
1447cb14a3feSDimitry Andric  }
14480b57cec5SDimitry Andric#  endif // _LIBCPP_STD_VER >= 17
14490b57cec5SDimitry Andric
1450cb14a3feSDimitry Andric  _LIBCPP_HIDE_FROM_ABI void close();
14510b57cec5SDimitry Andric
14520b57cec5SDimitry Andricprivate:
14530b57cec5SDimitry Andric  basic_filebuf<char_type, traits_type> __sb_;
14540b57cec5SDimitry Andric};
14550b57cec5SDimitry Andric
14560b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1457cb14a3feSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream() : basic_iostream<char_type, traits_type>(&__sb_) {}
14580b57cec5SDimitry Andric
14590b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1460cb14a3feSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
1461cb14a3feSDimitry Andric    : basic_iostream<char_type, traits_type>(&__sb_) {
1462e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode) == nullptr)
14630b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
14640b57cec5SDimitry Andric}
14650b57cec5SDimitry Andric
14660b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
14670b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1468cb14a3feSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode)
1469cb14a3feSDimitry Andric    : basic_iostream<char_type, traits_type>(&__sb_) {
1470e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode) == nullptr)
14710b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
14720b57cec5SDimitry Andric}
14730b57cec5SDimitry Andric#  endif
14740b57cec5SDimitry Andric
14750b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1476cb14a3feSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)
1477cb14a3feSDimitry Andric    : basic_iostream<char_type, traits_type>(&__sb_) {
1478e8d8bef9SDimitry Andric  if (__sb_.open(__s, __mode) == nullptr)
14790b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
14800b57cec5SDimitry Andric}
14810b57cec5SDimitry Andric
14820b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1483cb14a3feSDimitry Andricinline basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
1484cb14a3feSDimitry Andric    : basic_iostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
14850b57cec5SDimitry Andric  this->set_rdbuf(&__sb_);
14860b57cec5SDimitry Andric}
14870b57cec5SDimitry Andric
14880b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1489cb14a3feSDimitry Andricinline basic_fstream<_CharT, _Traits>& basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) {
14905f757f3fSDimitry Andric  basic_iostream<char_type, traits_type>::operator=(std::move(__rhs));
14915f757f3fSDimitry Andric  __sb_ = std::move(__rhs.__sb_);
14920b57cec5SDimitry Andric  return *this;
14930b57cec5SDimitry Andric}
14940b57cec5SDimitry Andric
14950b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1496cb14a3feSDimitry Andricinline void basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) {
14970b57cec5SDimitry Andric  basic_iostream<char_type, traits_type>::swap(__rhs);
14980b57cec5SDimitry Andric  __sb_.swap(__rhs.__sb_);
14990b57cec5SDimitry Andric}
15000b57cec5SDimitry Andric
15010b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1502cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) {
15030b57cec5SDimitry Andric  __x.swap(__y);
15040b57cec5SDimitry Andric}
15050b57cec5SDimitry Andric
15060b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1507cb14a3feSDimitry Andricinline basic_filebuf<_CharT, _Traits>* basic_fstream<_CharT, _Traits>::rdbuf() const {
15080b57cec5SDimitry Andric  return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
15090b57cec5SDimitry Andric}
15100b57cec5SDimitry Andric
15110b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1512cb14a3feSDimitry Andricinline bool basic_fstream<_CharT, _Traits>::is_open() const {
15130b57cec5SDimitry Andric  return __sb_.is_open();
15140b57cec5SDimitry Andric}
15150b57cec5SDimitry Andric
15160b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1517cb14a3feSDimitry Andricvoid basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
15180b57cec5SDimitry Andric  if (__sb_.open(__s, __mode))
15190b57cec5SDimitry Andric    this->clear();
15200b57cec5SDimitry Andric  else
15210b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
15220b57cec5SDimitry Andric}
15230b57cec5SDimitry Andric
15240b57cec5SDimitry Andric#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
15250b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1526cb14a3feSDimitry Andricvoid basic_fstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
15270b57cec5SDimitry Andric  if (__sb_.open(__s, __mode))
15280b57cec5SDimitry Andric    this->clear();
15290b57cec5SDimitry Andric  else
15300b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
15310b57cec5SDimitry Andric}
15320b57cec5SDimitry Andric#  endif
15330b57cec5SDimitry Andric
15340b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1535cb14a3feSDimitry Andricvoid basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
15360b57cec5SDimitry Andric  if (__sb_.open(__s, __mode))
15370b57cec5SDimitry Andric    this->clear();
15380b57cec5SDimitry Andric  else
15390b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
15400b57cec5SDimitry Andric}
15410b57cec5SDimitry Andric
15420b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
1543cb14a3feSDimitry Andricinline void basic_fstream<_CharT, _Traits>::close() {
1544e8d8bef9SDimitry Andric  if (__sb_.close() == nullptr)
15450b57cec5SDimitry Andric    this->setstate(ios_base::failbit);
15460b57cec5SDimitry Andric}
15470b57cec5SDimitry Andric
15485f757f3fSDimitry Andric#  if _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
154981ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ifstream<char>;
155081ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ofstream<char>;
155181ad6265SDimitry Andricextern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>;
1552e8d8bef9SDimitry Andric#  endif
1553e8d8bef9SDimitry Andric
15540b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
15550b57cec5SDimitry Andric
155606c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_FILESYSTEM
1557bdd1243dSDimitry Andric
15580b57cec5SDimitry Andric_LIBCPP_POP_MACROS
15590b57cec5SDimitry Andric
1560bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1561bdd1243dSDimitry Andric#  include <atomic>
1562bdd1243dSDimitry Andric#  include <concepts>
156306c3fb27SDimitry Andric#  include <cstdlib>
1564bdd1243dSDimitry Andric#  include <iosfwd>
1565bdd1243dSDimitry Andric#  include <limits>
15665f757f3fSDimitry Andric#  include <mutex>
1567bdd1243dSDimitry Andric#  include <new>
1568bdd1243dSDimitry Andric#  include <stdexcept>
1569bdd1243dSDimitry Andric#  include <type_traits>
1570bdd1243dSDimitry Andric#endif
1571bdd1243dSDimitry Andric
15720b57cec5SDimitry Andric#endif // _LIBCPP_FSTREAM
1573