xref: /freebsd/contrib/llvm-project/libcxx/include/fstream (revision 6580f5c38dd5b01aeeaed16b370f1a12423437f0)
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_FSTREAM
11#define _LIBCPP_FSTREAM
12
13/*
14    fstream synopsis
15
16template <class charT, class traits = char_traits<charT> >
17class basic_filebuf
18    : public basic_streambuf<charT, traits>
19{
20public:
21    typedef charT                          char_type;
22    typedef traits                         traits_type;
23    typedef typename traits_type::int_type int_type;
24    typedef typename traits_type::pos_type pos_type;
25    typedef typename traits_type::off_type off_type;
26
27    // 27.9.1.2 Constructors/destructor:
28    basic_filebuf();
29    basic_filebuf(basic_filebuf&& rhs);
30    virtual ~basic_filebuf();
31
32    // 27.9.1.3 Assign/swap:
33    basic_filebuf& operator=(basic_filebuf&& rhs);
34    void swap(basic_filebuf& rhs);
35
36    // 27.9.1.4 Members:
37    bool is_open() const;
38    basic_filebuf* open(const char* s, ios_base::openmode mode);
39    basic_filebuf* open(const string& s, ios_base::openmode mode);
40    basic_filebuf* open(const filesystem::path& p, ios_base::openmode mode); // C++17
41    basic_filebuf* close();
42
43protected:
44    // 27.9.1.5 Overridden virtual functions:
45    virtual streamsize showmanyc();
46    virtual int_type underflow();
47    virtual int_type uflow();
48    virtual int_type pbackfail(int_type c = traits_type::eof());
49    virtual int_type overflow (int_type c = traits_type::eof());
50    virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* s, streamsize n);
51    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
52                             ios_base::openmode which = ios_base::in | ios_base::out);
53    virtual pos_type seekpos(pos_type sp,
54                             ios_base::openmode which = ios_base::in | ios_base::out);
55    virtual int sync();
56    virtual void imbue(const locale& loc);
57};
58
59template <class charT, class traits>
60  void
61  swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y);
62
63typedef basic_filebuf<char>    filebuf;
64typedef basic_filebuf<wchar_t> wfilebuf;
65
66template <class charT, class traits = char_traits<charT> >
67class basic_ifstream
68    : public basic_istream<charT,traits>
69{
70public:
71    typedef charT                          char_type;
72    typedef traits                         traits_type;
73    typedef typename traits_type::int_type int_type;
74    typedef typename traits_type::pos_type pos_type;
75    typedef typename traits_type::off_type off_type;
76    using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
77
78    basic_ifstream();
79    explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
80    explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);
81    explicit basic_ifstream(const filesystem::path& p,
82                            ios_base::openmode mode = ios_base::in); // C++17
83    basic_ifstream(basic_ifstream&& rhs);
84
85    basic_ifstream& operator=(basic_ifstream&& rhs);
86    void swap(basic_ifstream& rhs);
87
88    basic_filebuf<char_type, traits_type>* rdbuf() const;
89    native_handle_type native_handle() const noexcept; // Since C++26
90    bool is_open() const;
91    void open(const char* s, ios_base::openmode mode = ios_base::in);
92    void open(const string& s, ios_base::openmode mode = ios_base::in);
93    void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++17
94
95    void close();
96};
97
98template <class charT, class traits>
99  void
100  swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y);
101
102typedef basic_ifstream<char>    ifstream;
103typedef basic_ifstream<wchar_t> wifstream;
104
105template <class charT, class traits = char_traits<charT> >
106class basic_ofstream
107    : public basic_ostream<charT,traits>
108{
109public:
110    typedef charT                          char_type;
111    typedef traits                         traits_type;
112    typedef typename traits_type::int_type int_type;
113    typedef typename traits_type::pos_type pos_type;
114    typedef typename traits_type::off_type off_type;
115    using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
116
117    basic_ofstream();
118    explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
119    explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);
120    explicit basic_ofstream(const filesystem::path& p,
121                            ios_base::openmode mode = ios_base::out); // C++17
122    basic_ofstream(basic_ofstream&& rhs);
123
124    basic_ofstream& operator=(basic_ofstream&& rhs);
125    void swap(basic_ofstream& rhs);
126
127    basic_filebuf<char_type, traits_type>* rdbuf() const;
128    native_handle_type native_handle() const noexcept; // Since C++26
129
130    bool is_open() const;
131    void open(const char* s, ios_base::openmode mode = ios_base::out);
132    void open(const string& s, ios_base::openmode mode = ios_base::out);
133    void open(const filesystem::path& p,
134              ios_base::openmode mode = ios_base::out); // C++17
135
136    void close();
137};
138
139template <class charT, class traits>
140  void
141  swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y);
142
143typedef basic_ofstream<char>    ofstream;
144typedef basic_ofstream<wchar_t> wofstream;
145
146template <class charT, class traits=char_traits<charT> >
147class basic_fstream
148    : public basic_iostream<charT,traits>
149{
150public:
151    typedef charT                          char_type;
152    typedef traits                         traits_type;
153    typedef typename traits_type::int_type int_type;
154    typedef typename traits_type::pos_type pos_type;
155    typedef typename traits_type::off_type off_type;
156    using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26
157
158    basic_fstream();
159    explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
160    explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
161    explicit basic_fstream(const filesystem::path& p,
162                           ios_base::openmode mode = ios_base::in|ios_base::out); C++17
163    basic_fstream(basic_fstream&& rhs);
164
165    basic_fstream& operator=(basic_fstream&& rhs);
166    void swap(basic_fstream& rhs);
167
168    basic_filebuf<char_type, traits_type>* rdbuf() const;
169    native_handle_type native_handle() const noexcept; // Since C++26
170    bool is_open() const;
171    void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
172    void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
173    void open(const filesystem::path& s,
174              ios_base::openmode mode = ios_base::in|ios_base::out); // C++17
175
176    void close();
177};
178
179template <class charT, class traits>
180  void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y);
181
182typedef basic_fstream<char>    fstream;
183typedef basic_fstream<wchar_t> wfstream;
184
185}  // std
186
187*/
188
189#include <__algorithm/max.h>
190#include <__assert> // all public C++ headers provide the assertion handler
191#include <__availability>
192#include <__config>
193#include <__fwd/fstream.h>
194#include <__locale>
195#include <__utility/move.h>
196#include <__utility/swap.h>
197#include <__utility/unreachable.h>
198#include <cstdio>
199#include <filesystem>
200#include <istream>
201#include <ostream>
202#include <typeinfo>
203#include <version>
204
205#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
206#  pragma GCC system_header
207#endif
208
209_LIBCPP_PUSH_MACROS
210#include <__undef_macros>
211
212#if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION)
213#  define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
214#endif
215
216#if !defined(_LIBCPP_HAS_NO_FILESYSTEM)
217
218_LIBCPP_BEGIN_NAMESPACE_STD
219
220#  if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_WIN32API)
221_LIBCPP_EXPORTED_FROM_ABI void* __filebuf_windows_native_handle(FILE* __file) noexcept;
222#  endif
223
224template <class _CharT, class _Traits>
225class _LIBCPP_TEMPLATE_VIS basic_filebuf : public basic_streambuf<_CharT, _Traits> {
226public:
227  typedef _CharT char_type;
228  typedef _Traits traits_type;
229  typedef typename traits_type::int_type int_type;
230  typedef typename traits_type::pos_type pos_type;
231  typedef typename traits_type::off_type off_type;
232  typedef typename traits_type::state_type state_type;
233#  if _LIBCPP_STD_VER >= 26
234#    if defined(_LIBCPP_WIN32API)
235  using native_handle_type = void*; // HANDLE
236#    elif __has_include(<unistd.h>)
237  using native_handle_type = int; // POSIX file descriptor
238#    else
239#      error "Provide a native file handle!"
240#    endif
241#  endif
242
243  // 27.9.1.2 Constructors/destructor:
244  basic_filebuf();
245  basic_filebuf(basic_filebuf&& __rhs);
246  ~basic_filebuf() override;
247
248  // 27.9.1.3 Assign/swap:
249  _LIBCPP_HIDE_FROM_ABI basic_filebuf& operator=(basic_filebuf&& __rhs);
250  void swap(basic_filebuf& __rhs);
251
252  // 27.9.1.4 Members:
253  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
254  basic_filebuf* open(const char* __s, ios_base::openmode __mode);
255#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
256  basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode);
257#  endif
258  _LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const string& __s, ios_base::openmode __mode);
259
260#  if _LIBCPP_STD_VER >= 17
261  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI basic_filebuf*
262  open(const filesystem::path& __p, ios_base::openmode __mode) {
263    return open(__p.c_str(), __mode);
264  }
265#  endif
266  _LIBCPP_HIDE_FROM_ABI basic_filebuf* __open(int __fd, ios_base::openmode __mode);
267  basic_filebuf* close();
268#  if _LIBCPP_STD_VER >= 26
269  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {
270    _LIBCPP_ASSERT_UNCATEGORIZED(this->is_open(), "File must be opened");
271#    if defined(_LIBCPP_WIN32API)
272    return std::__filebuf_windows_native_handle(__file_);
273#    elif __has_include(<unistd.h>)
274    return fileno(__file_);
275#    else
276#      error "Provide a way to determine the file native handle!"
277#    endif
278  }
279#  endif //  _LIBCPP_STD_VER >= 26
280
281  _LIBCPP_HIDE_FROM_ABI inline static const char* __make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
282
283protected:
284  // 27.9.1.5 Overridden virtual functions:
285  int_type underflow() override;
286  int_type pbackfail(int_type __c = traits_type::eof()) override;
287  int_type overflow(int_type __c = traits_type::eof()) override;
288  basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n) override;
289  pos_type
290  seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
291  pos_type seekpos(pos_type __sp, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
292  int sync() override;
293  void imbue(const locale& __loc) override;
294
295private:
296  char* __extbuf_;
297  const char* __extbufnext_;
298  const char* __extbufend_;
299  char __extbuf_min_[8];
300  size_t __ebs_;
301  char_type* __intbuf_;
302  size_t __ibs_;
303  FILE* __file_;
304  const codecvt<char_type, char, state_type>* __cv_;
305  state_type __st_;
306  state_type __st_last_;
307  ios_base::openmode __om_;
308  ios_base::openmode __cm_;
309  bool __owns_eb_;
310  bool __owns_ib_;
311  bool __always_noconv_;
312
313  bool __read_mode();
314  void __write_mode();
315
316  _LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
317};
318
319template <class _CharT, class _Traits>
320basic_filebuf<_CharT, _Traits>::basic_filebuf()
321    : __extbuf_(nullptr),
322      __extbufnext_(nullptr),
323      __extbufend_(nullptr),
324      __ebs_(0),
325      __intbuf_(nullptr),
326      __ibs_(0),
327      __file_(nullptr),
328      __cv_(nullptr),
329      __st_(),
330      __st_last_(),
331      __om_(0),
332      __cm_(0),
333      __owns_eb_(false),
334      __owns_ib_(false),
335      __always_noconv_(false) {
336  if (std::has_facet<codecvt<char_type, char, state_type> >(this->getloc())) {
337    __cv_            = &std::use_facet<codecvt<char_type, char, state_type> >(this->getloc());
338    __always_noconv_ = __cv_->always_noconv();
339  }
340  setbuf(nullptr, 4096);
341}
342
343template <class _CharT, class _Traits>
344basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) : basic_streambuf<_CharT, _Traits>(__rhs) {
345  if (__rhs.__extbuf_ == __rhs.__extbuf_min_) {
346    __extbuf_     = __extbuf_min_;
347    __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);
348    __extbufend_  = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);
349  } else {
350    __extbuf_     = __rhs.__extbuf_;
351    __extbufnext_ = __rhs.__extbufnext_;
352    __extbufend_  = __rhs.__extbufend_;
353  }
354  __ebs_           = __rhs.__ebs_;
355  __intbuf_        = __rhs.__intbuf_;
356  __ibs_           = __rhs.__ibs_;
357  __file_          = __rhs.__file_;
358  __cv_            = __rhs.__cv_;
359  __st_            = __rhs.__st_;
360  __st_last_       = __rhs.__st_last_;
361  __om_            = __rhs.__om_;
362  __cm_            = __rhs.__cm_;
363  __owns_eb_       = __rhs.__owns_eb_;
364  __owns_ib_       = __rhs.__owns_ib_;
365  __always_noconv_ = __rhs.__always_noconv_;
366  if (__rhs.pbase()) {
367    if (__rhs.pbase() == __rhs.__intbuf_)
368      this->setp(__intbuf_, __intbuf_ + (__rhs.epptr() - __rhs.pbase()));
369    else
370      this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__rhs.epptr() - __rhs.pbase()));
371    this->__pbump(__rhs.pptr() - __rhs.pbase());
372  } else if (__rhs.eback()) {
373    if (__rhs.eback() == __rhs.__intbuf_)
374      this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()), __intbuf_ + (__rhs.egptr() - __rhs.eback()));
375    else
376      this->setg((char_type*)__extbuf_,
377                 (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),
378                 (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));
379  }
380  __rhs.__extbuf_     = nullptr;
381  __rhs.__extbufnext_ = nullptr;
382  __rhs.__extbufend_  = nullptr;
383  __rhs.__ebs_        = 0;
384  __rhs.__intbuf_     = 0;
385  __rhs.__ibs_        = 0;
386  __rhs.__file_       = nullptr;
387  __rhs.__st_         = state_type();
388  __rhs.__st_last_    = state_type();
389  __rhs.__om_         = 0;
390  __rhs.__cm_         = 0;
391  __rhs.__owns_eb_    = false;
392  __rhs.__owns_ib_    = false;
393  __rhs.setg(0, 0, 0);
394  __rhs.setp(0, 0);
395}
396
397template <class _CharT, class _Traits>
398inline basic_filebuf<_CharT, _Traits>& basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) {
399  close();
400  swap(__rhs);
401  return *this;
402}
403
404template <class _CharT, class _Traits>
405basic_filebuf<_CharT, _Traits>::~basic_filebuf() {
406#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
407  try {
408#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
409    close();
410#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
411  } catch (...) {
412  }
413#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
414  if (__owns_eb_)
415    delete[] __extbuf_;
416  if (__owns_ib_)
417    delete[] __intbuf_;
418}
419
420template <class _CharT, class _Traits>
421void basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) {
422  basic_streambuf<char_type, traits_type>::swap(__rhs);
423  if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
424    // Neither *this nor __rhs uses the small buffer, so we can simply swap the pointers.
425    std::swap(__extbuf_, __rhs.__extbuf_);
426    std::swap(__extbufnext_, __rhs.__extbufnext_);
427    std::swap(__extbufend_, __rhs.__extbufend_);
428  } else {
429    ptrdiff_t __ln = __extbufnext_ ? __extbufnext_ - __extbuf_ : 0;
430    ptrdiff_t __le = __extbufend_ ? __extbufend_ - __extbuf_ : 0;
431    ptrdiff_t __rn = __rhs.__extbufnext_ ? __rhs.__extbufnext_ - __rhs.__extbuf_ : 0;
432    ptrdiff_t __re = __rhs.__extbufend_ ? __rhs.__extbufend_ - __rhs.__extbuf_ : 0;
433    if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
434      // *this uses the small buffer, but __rhs doesn't.
435      __extbuf_       = __rhs.__extbuf_;
436      __rhs.__extbuf_ = __rhs.__extbuf_min_;
437      std::memmove(__rhs.__extbuf_min_, __extbuf_min_, sizeof(__extbuf_min_));
438    } else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_) {
439      // *this doesn't use the small buffer, but __rhs does.
440      __rhs.__extbuf_ = __extbuf_;
441      __extbuf_       = __extbuf_min_;
442      std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
443    } else {
444      // Both *this and __rhs use the small buffer.
445      char __tmp[sizeof(__extbuf_min_)];
446      std::memmove(__tmp, __extbuf_min_, sizeof(__extbuf_min_));
447      std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
448      std::memmove(__rhs.__extbuf_min_, __tmp, sizeof(__extbuf_min_));
449    }
450    __extbufnext_       = __extbuf_ + __rn;
451    __extbufend_        = __extbuf_ + __re;
452    __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;
453    __rhs.__extbufend_  = __rhs.__extbuf_ + __le;
454  }
455  std::swap(__ebs_, __rhs.__ebs_);
456  std::swap(__intbuf_, __rhs.__intbuf_);
457  std::swap(__ibs_, __rhs.__ibs_);
458  std::swap(__file_, __rhs.__file_);
459  std::swap(__cv_, __rhs.__cv_);
460  std::swap(__st_, __rhs.__st_);
461  std::swap(__st_last_, __rhs.__st_last_);
462  std::swap(__om_, __rhs.__om_);
463  std::swap(__cm_, __rhs.__cm_);
464  std::swap(__owns_eb_, __rhs.__owns_eb_);
465  std::swap(__owns_ib_, __rhs.__owns_ib_);
466  std::swap(__always_noconv_, __rhs.__always_noconv_);
467  if (this->eback() == (char_type*)__rhs.__extbuf_min_) {
468    ptrdiff_t __n = this->gptr() - this->eback();
469    ptrdiff_t __e = this->egptr() - this->eback();
470    this->setg((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __n, (char_type*)__extbuf_min_ + __e);
471  } else if (this->pbase() == (char_type*)__rhs.__extbuf_min_) {
472    ptrdiff_t __n = this->pptr() - this->pbase();
473    ptrdiff_t __e = this->epptr() - this->pbase();
474    this->setp((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __e);
475    this->__pbump(__n);
476  }
477  if (__rhs.eback() == (char_type*)__extbuf_min_) {
478    ptrdiff_t __n = __rhs.gptr() - __rhs.eback();
479    ptrdiff_t __e = __rhs.egptr() - __rhs.eback();
480    __rhs.setg(
481        (char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __n, (char_type*)__rhs.__extbuf_min_ + __e);
482  } else if (__rhs.pbase() == (char_type*)__extbuf_min_) {
483    ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();
484    ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();
485    __rhs.setp((char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __e);
486    __rhs.__pbump(__n);
487  }
488}
489
490template <class _CharT, class _Traits>
491inline _LIBCPP_HIDE_FROM_ABI void swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) {
492  __x.swap(__y);
493}
494
495template <class _CharT, class _Traits>
496inline bool basic_filebuf<_CharT, _Traits>::is_open() const {
497  return __file_ != nullptr;
498}
499
500template <class _CharT, class _Traits>
501const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(ios_base::openmode __mode) _NOEXCEPT {
502  switch (__mode & ~ios_base::ate) {
503  case ios_base::out:
504  case ios_base::out | ios_base::trunc:
505    return "w" _LIBCPP_FOPEN_CLOEXEC_MODE;
506  case ios_base::out | ios_base::app:
507  case ios_base::app:
508    return "a" _LIBCPP_FOPEN_CLOEXEC_MODE;
509  case ios_base::in:
510    return "r" _LIBCPP_FOPEN_CLOEXEC_MODE;
511  case ios_base::in | ios_base::out:
512    return "r+" _LIBCPP_FOPEN_CLOEXEC_MODE;
513  case ios_base::in | ios_base::out | ios_base::trunc:
514    return "w+" _LIBCPP_FOPEN_CLOEXEC_MODE;
515  case ios_base::in | ios_base::out | ios_base::app:
516  case ios_base::in | ios_base::app:
517    return "a+" _LIBCPP_FOPEN_CLOEXEC_MODE;
518  case ios_base::out | ios_base::binary:
519  case ios_base::out | ios_base::trunc | ios_base::binary:
520    return "wb" _LIBCPP_FOPEN_CLOEXEC_MODE;
521  case ios_base::out | ios_base::app | ios_base::binary:
522  case ios_base::app | ios_base::binary:
523    return "ab" _LIBCPP_FOPEN_CLOEXEC_MODE;
524  case ios_base::in | ios_base::binary:
525    return "rb" _LIBCPP_FOPEN_CLOEXEC_MODE;
526  case ios_base::in | ios_base::out | ios_base::binary:
527    return "r+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
528  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
529    return "w+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
530  case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
531  case ios_base::in | ios_base::app | ios_base::binary:
532    return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
533#  if _LIBCPP_STD_VER >= 23
534  case ios_base::out | ios_base::noreplace:
535  case ios_base::out | ios_base::trunc | ios_base::noreplace:
536    return "wx" _LIBCPP_FOPEN_CLOEXEC_MODE;
537  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
538    return "w+x" _LIBCPP_FOPEN_CLOEXEC_MODE;
539  case ios_base::out | ios_base::binary | ios_base::noreplace:
540  case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
541    return "wbx" _LIBCPP_FOPEN_CLOEXEC_MODE;
542  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
543    return "w+bx" _LIBCPP_FOPEN_CLOEXEC_MODE;
544#  endif // _LIBCPP_STD_VER >= 23
545  default:
546    return nullptr;
547  }
548  __libcpp_unreachable();
549}
550
551template <class _CharT, class _Traits>
552basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
553  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
554  if (__file_ == nullptr) {
555    if (const char* __mdstr = __make_mdstring(__mode)) {
556      __rt    = this;
557      __file_ = fopen(__s, __mdstr);
558      if (__file_) {
559        __om_ = __mode;
560        if (__mode & ios_base::ate) {
561          if (fseek(__file_, 0, SEEK_END)) {
562            fclose(__file_);
563            __file_ = nullptr;
564            __rt    = nullptr;
565          }
566        }
567      } else
568        __rt = nullptr;
569    }
570  }
571  return __rt;
572}
573
574template <class _CharT, class _Traits>
575inline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
576  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
577  if (__file_ == nullptr) {
578    if (const char* __mdstr = __make_mdstring(__mode)) {
579      __rt    = this;
580      __file_ = fdopen(__fd, __mdstr);
581      if (__file_) {
582        __om_ = __mode;
583        if (__mode & ios_base::ate) {
584          if (fseek(__file_, 0, SEEK_END)) {
585            fclose(__file_);
586            __file_ = nullptr;
587            __rt    = nullptr;
588          }
589        }
590      } else
591        __rt = nullptr;
592    }
593  }
594  return __rt;
595}
596
597#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
598// This is basically the same as the char* overload except that it uses _wfopen
599// and long mode strings.
600template <class _CharT, class _Traits>
601basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
602  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
603  if (__file_ == nullptr) {
604    __rt = this;
605    const wchar_t* __mdstr;
606    switch (__mode & ~ios_base::ate) {
607    case ios_base::out:
608    case ios_base::out | ios_base::trunc:
609      __mdstr = L"w";
610      break;
611    case ios_base::out | ios_base::app:
612    case ios_base::app:
613      __mdstr = L"a";
614      break;
615    case ios_base::in:
616      __mdstr = L"r";
617      break;
618    case ios_base::in | ios_base::out:
619      __mdstr = L"r+";
620      break;
621    case ios_base::in | ios_base::out | ios_base::trunc:
622      __mdstr = L"w+";
623      break;
624    case ios_base::in | ios_base::out | ios_base::app:
625    case ios_base::in | ios_base::app:
626      __mdstr = L"a+";
627      break;
628    case ios_base::out | ios_base::binary:
629    case ios_base::out | ios_base::trunc | ios_base::binary:
630      __mdstr = L"wb";
631      break;
632    case ios_base::out | ios_base::app | ios_base::binary:
633    case ios_base::app | ios_base::binary:
634      __mdstr = L"ab";
635      break;
636    case ios_base::in | ios_base::binary:
637      __mdstr = L"rb";
638      break;
639    case ios_base::in | ios_base::out | ios_base::binary:
640      __mdstr = L"r+b";
641      break;
642    case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
643      __mdstr = L"w+b";
644      break;
645    case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
646    case ios_base::in | ios_base::app | ios_base::binary:
647      __mdstr = L"a+b";
648      break;
649#    if _LIBCPP_STD_VER >= 23
650    case ios_base::out | ios_base::noreplace:
651    case ios_base::out | ios_base::trunc | ios_base::noreplace:
652      __mdstr = L"wx";
653      break;
654    case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
655      __mdstr = L"w+x";
656      break;
657    case ios_base::out | ios_base::binary | ios_base::noreplace:
658    case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
659      __mdstr = L"wbx";
660      break;
661    case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
662      __mdstr = L"w+bx";
663      break;
664#    endif // _LIBCPP_STD_VER >= 23
665    default:
666      __rt = nullptr;
667      break;
668    }
669    if (__rt) {
670      __file_ = _wfopen(__s, __mdstr);
671      if (__file_) {
672        __om_ = __mode;
673        if (__mode & ios_base::ate) {
674          if (fseek(__file_, 0, SEEK_END)) {
675            fclose(__file_);
676            __file_ = nullptr;
677            __rt    = nullptr;
678          }
679        }
680      } else
681        __rt = nullptr;
682    }
683  }
684  return __rt;
685}
686#  endif
687
688template <class _CharT, class _Traits>
689inline basic_filebuf<_CharT, _Traits>*
690basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
691  return open(__s.c_str(), __mode);
692}
693
694template <class _CharT, class _Traits>
695basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::close() {
696  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
697  if (__file_) {
698    __rt = this;
699    unique_ptr<FILE, int (*)(FILE*)> __h(__file_, fclose);
700    if (sync())
701      __rt = nullptr;
702    if (fclose(__h.release()))
703      __rt = nullptr;
704    __file_ = nullptr;
705    setbuf(0, 0);
706  }
707  return __rt;
708}
709
710template <class _CharT, class _Traits>
711typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::underflow() {
712  if (__file_ == nullptr)
713    return traits_type::eof();
714  bool __initial = __read_mode();
715  char_type __1buf;
716  if (this->gptr() == nullptr)
717    this->setg(&__1buf, &__1buf + 1, &__1buf + 1);
718  const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
719  int_type __c            = traits_type::eof();
720  if (this->gptr() == this->egptr()) {
721    std::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
722    if (__always_noconv_) {
723      size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
724      __nmemb        = ::fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
725      if (__nmemb != 0) {
726        this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb);
727        __c = traits_type::to_int_type(*this->gptr());
728      }
729    } else {
730      if (__extbufend_ != __extbufnext_) {
731        _LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr");
732        _LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr");
733        std::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
734      }
735      __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
736      __extbufend_  = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
737      size_t __nmemb =
738          std::min(static_cast<size_t>(__ibs_ - __unget_sz), static_cast<size_t>(__extbufend_ - __extbufnext_));
739      codecvt_base::result __r;
740      __st_last_  = __st_;
741      size_t __nr = fread((void*)const_cast<char*>(__extbufnext_), 1, __nmemb, __file_);
742      if (__nr != 0) {
743        if (!__cv_)
744          __throw_bad_cast();
745
746        __extbufend_ = __extbufnext_ + __nr;
747        char_type* __inext;
748        __r = __cv_->in(
749            __st_, __extbuf_, __extbufend_, __extbufnext_, this->eback() + __unget_sz, this->eback() + __ibs_, __inext);
750        if (__r == codecvt_base::noconv) {
751          this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)const_cast<char*>(__extbufend_));
752          __c = traits_type::to_int_type(*this->gptr());
753        } else if (__inext != this->eback() + __unget_sz) {
754          this->setg(this->eback(), this->eback() + __unget_sz, __inext);
755          __c = traits_type::to_int_type(*this->gptr());
756        }
757      }
758    }
759  } else
760    __c = traits_type::to_int_type(*this->gptr());
761  if (this->eback() == &__1buf)
762    this->setg(nullptr, nullptr, nullptr);
763  return __c;
764}
765
766template <class _CharT, class _Traits>
767typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) {
768  if (__file_ && this->eback() < this->gptr()) {
769    if (traits_type::eq_int_type(__c, traits_type::eof())) {
770      this->gbump(-1);
771      return traits_type::not_eof(__c);
772    }
773    if ((__om_ & ios_base::out) || traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) {
774      this->gbump(-1);
775      *this->gptr() = traits_type::to_char_type(__c);
776      return __c;
777    }
778  }
779  return traits_type::eof();
780}
781
782template <class _CharT, class _Traits>
783typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {
784  if (__file_ == nullptr)
785    return traits_type::eof();
786  __write_mode();
787  char_type __1buf;
788  char_type* __pb_save  = this->pbase();
789  char_type* __epb_save = this->epptr();
790  if (!traits_type::eq_int_type(__c, traits_type::eof())) {
791    if (this->pptr() == nullptr)
792      this->setp(&__1buf, &__1buf + 1);
793    *this->pptr() = traits_type::to_char_type(__c);
794    this->pbump(1);
795  }
796  if (this->pptr() != this->pbase()) {
797    if (__always_noconv_) {
798      size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
799      if (std::fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
800        return traits_type::eof();
801    } else {
802      char* __extbe = __extbuf_;
803      codecvt_base::result __r;
804      do {
805        if (!__cv_)
806          __throw_bad_cast();
807
808        const char_type* __e;
809        __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, __extbuf_, __extbuf_ + __ebs_, __extbe);
810        if (__e == this->pbase())
811          return traits_type::eof();
812        if (__r == codecvt_base::noconv) {
813          size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
814          if (std::fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
815            return traits_type::eof();
816        } else if (__r == codecvt_base::ok || __r == codecvt_base::partial) {
817          size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
818          if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
819            return traits_type::eof();
820          if (__r == codecvt_base::partial) {
821            this->setp(const_cast<char_type*>(__e), this->pptr());
822            this->__pbump(this->epptr() - this->pbase());
823          }
824        } else
825          return traits_type::eof();
826      } while (__r == codecvt_base::partial);
827    }
828    this->setp(__pb_save, __epb_save);
829  }
830  return traits_type::not_eof(__c);
831}
832
833template <class _CharT, class _Traits>
834basic_streambuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n) {
835  this->setg(nullptr, nullptr, nullptr);
836  this->setp(nullptr, nullptr);
837  if (__owns_eb_)
838    delete[] __extbuf_;
839  if (__owns_ib_)
840    delete[] __intbuf_;
841  __ebs_ = __n;
842  if (__ebs_ > sizeof(__extbuf_min_)) {
843    if (__always_noconv_ && __s) {
844      __extbuf_  = (char*)__s;
845      __owns_eb_ = false;
846    } else {
847      __extbuf_  = new char[__ebs_];
848      __owns_eb_ = true;
849    }
850  } else {
851    __extbuf_  = __extbuf_min_;
852    __ebs_     = sizeof(__extbuf_min_);
853    __owns_eb_ = false;
854  }
855  if (!__always_noconv_) {
856    __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
857    if (__s && __ibs_ > sizeof(__extbuf_min_)) {
858      __intbuf_  = __s;
859      __owns_ib_ = false;
860    } else {
861      __intbuf_  = new char_type[__ibs_];
862      __owns_ib_ = true;
863    }
864  } else {
865    __ibs_     = 0;
866    __intbuf_  = nullptr;
867    __owns_ib_ = false;
868  }
869  return this;
870}
871
872template <class _CharT, class _Traits>
873typename basic_filebuf<_CharT, _Traits>::pos_type
874basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) {
875  if (!__cv_)
876    __throw_bad_cast();
877
878  int __width = __cv_->encoding();
879  if (__file_ == nullptr || (__width <= 0 && __off != 0) || sync())
880    return pos_type(off_type(-1));
881  // __width > 0 || __off == 0
882  int __whence;
883  switch (__way) {
884  case ios_base::beg:
885    __whence = SEEK_SET;
886    break;
887  case ios_base::cur:
888    __whence = SEEK_CUR;
889    break;
890  case ios_base::end:
891    __whence = SEEK_END;
892    break;
893  default:
894    return pos_type(off_type(-1));
895  }
896#  if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
897  if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
898    return pos_type(off_type(-1));
899  pos_type __r = ftell(__file_);
900#  else
901  if (::fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
902    return pos_type(off_type(-1));
903  pos_type __r = ftello(__file_);
904#  endif
905  __r.state(__st_);
906  return __r;
907}
908
909template <class _CharT, class _Traits>
910typename basic_filebuf<_CharT, _Traits>::pos_type
911basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) {
912  if (__file_ == nullptr || sync())
913    return pos_type(off_type(-1));
914#  if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
915  if (fseek(__file_, __sp, SEEK_SET))
916    return pos_type(off_type(-1));
917#  else
918  if (::fseeko(__file_, __sp, SEEK_SET))
919    return pos_type(off_type(-1));
920#  endif
921  __st_ = __sp.state();
922  return __sp;
923}
924
925template <class _CharT, class _Traits>
926int basic_filebuf<_CharT, _Traits>::sync() {
927  if (__file_ == nullptr)
928    return 0;
929  if (!__cv_)
930    __throw_bad_cast();
931
932  if (__cm_ & ios_base::out) {
933    if (this->pptr() != this->pbase())
934      if (overflow() == traits_type::eof())
935        return -1;
936    codecvt_base::result __r;
937    do {
938      char* __extbe;
939      __r            = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
940      size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
941      if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
942        return -1;
943    } while (__r == codecvt_base::partial);
944    if (__r == codecvt_base::error)
945      return -1;
946    if (fflush(__file_))
947      return -1;
948  } else if (__cm_ & ios_base::in) {
949    off_type __c;
950    state_type __state = __st_last_;
951    bool __update_st   = false;
952    if (__always_noconv_)
953      __c = this->egptr() - this->gptr();
954    else {
955      int __width = __cv_->encoding();
956      __c         = __extbufend_ - __extbufnext_;
957      if (__width > 0)
958        __c += __width * (this->egptr() - this->gptr());
959      else {
960        if (this->gptr() != this->egptr()) {
961          const int __off = __cv_->length(__state, __extbuf_, __extbufnext_, this->gptr() - this->eback());
962          __c += __extbufnext_ - __extbuf_ - __off;
963          __update_st = true;
964        }
965      }
966    }
967#  if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
968    if (fseek(__file_, -__c, SEEK_CUR))
969      return -1;
970#  else
971    if (::fseeko(__file_, -__c, SEEK_CUR))
972      return -1;
973#  endif
974    if (__update_st)
975      __st_ = __state;
976    __extbufnext_ = __extbufend_ = __extbuf_;
977    this->setg(nullptr, nullptr, nullptr);
978    __cm_ = 0;
979  }
980  return 0;
981}
982
983template <class _CharT, class _Traits>
984void basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) {
985  sync();
986  __cv_            = &std::use_facet<codecvt<char_type, char, state_type> >(__loc);
987  bool __old_anc   = __always_noconv_;
988  __always_noconv_ = __cv_->always_noconv();
989  if (__old_anc != __always_noconv_) {
990    this->setg(nullptr, nullptr, nullptr);
991    this->setp(nullptr, nullptr);
992    // invariant, char_type is char, else we couldn't get here
993    if (__always_noconv_) // need to dump __intbuf_
994    {
995      if (__owns_eb_)
996        delete[] __extbuf_;
997      __owns_eb_ = __owns_ib_;
998      __ebs_     = __ibs_;
999      __extbuf_  = (char*)__intbuf_;
1000      __ibs_     = 0;
1001      __intbuf_  = nullptr;
1002      __owns_ib_ = false;
1003    } else // need to obtain an __intbuf_.
1004    {      // If __extbuf_ is user-supplied, use it, else new __intbuf_
1005      if (!__owns_eb_ && __extbuf_ != __extbuf_min_) {
1006        __ibs_     = __ebs_;
1007        __intbuf_  = (char_type*)__extbuf_;
1008        __owns_ib_ = false;
1009        __extbuf_  = new char[__ebs_];
1010        __owns_eb_ = true;
1011      } else {
1012        __ibs_     = __ebs_;
1013        __intbuf_  = new char_type[__ibs_];
1014        __owns_ib_ = true;
1015      }
1016    }
1017  }
1018}
1019
1020template <class _CharT, class _Traits>
1021bool basic_filebuf<_CharT, _Traits>::__read_mode() {
1022  if (!(__cm_ & ios_base::in)) {
1023    this->setp(nullptr, nullptr);
1024    if (__always_noconv_)
1025      this->setg((char_type*)__extbuf_, (char_type*)__extbuf_ + __ebs_, (char_type*)__extbuf_ + __ebs_);
1026    else
1027      this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
1028    __cm_ = ios_base::in;
1029    return true;
1030  }
1031  return false;
1032}
1033
1034template <class _CharT, class _Traits>
1035void basic_filebuf<_CharT, _Traits>::__write_mode() {
1036  if (!(__cm_ & ios_base::out)) {
1037    this->setg(nullptr, nullptr, nullptr);
1038    if (__ebs_ > sizeof(__extbuf_min_)) {
1039      if (__always_noconv_)
1040        this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__ebs_ - 1));
1041      else
1042        this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
1043    } else
1044      this->setp(nullptr, nullptr);
1045    __cm_ = ios_base::out;
1046  }
1047}
1048
1049// basic_ifstream
1050
1051template <class _CharT, class _Traits>
1052class _LIBCPP_TEMPLATE_VIS basic_ifstream : public basic_istream<_CharT, _Traits> {
1053public:
1054  typedef _CharT char_type;
1055  typedef _Traits traits_type;
1056  typedef typename traits_type::int_type int_type;
1057  typedef typename traits_type::pos_type pos_type;
1058  typedef typename traits_type::off_type off_type;
1059#  if _LIBCPP_STD_VER >= 26
1060  using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
1061#  endif
1062
1063  _LIBCPP_HIDE_FROM_ABI basic_ifstream();
1064  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
1065#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1066  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
1067#  endif
1068  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
1069#  if _LIBCPP_STD_VER >= 17
1070  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(
1071      const filesystem::path& __p, ios_base::openmode __mode = ios_base::in)
1072      : basic_ifstream(__p.c_str(), __mode) {}
1073#  endif // _LIBCPP_STD_VER >= 17
1074  _LIBCPP_HIDE_FROM_ABI basic_ifstream(basic_ifstream&& __rhs);
1075  _LIBCPP_HIDE_FROM_ABI basic_ifstream& operator=(basic_ifstream&& __rhs);
1076  _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs);
1077
1078  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
1079#  if _LIBCPP_STD_VER >= 26
1080  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
1081#  endif
1082  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
1083  void open(const char* __s, ios_base::openmode __mode = ios_base::in);
1084#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1085  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
1086#  endif
1087  void open(const string& __s, ios_base::openmode __mode = ios_base::in);
1088#  if _LIBCPP_STD_VER >= 17
1089  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1090  open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) {
1091    return open(__p.c_str(), __mode);
1092  }
1093#  endif // _LIBCPP_STD_VER >= 17
1094
1095  _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
1096  _LIBCPP_HIDE_FROM_ABI void close();
1097
1098private:
1099  basic_filebuf<char_type, traits_type> __sb_;
1100};
1101
1102template <class _CharT, class _Traits>
1103inline basic_ifstream<_CharT, _Traits>::basic_ifstream() : basic_istream<char_type, traits_type>(&__sb_) {}
1104
1105template <class _CharT, class _Traits>
1106inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
1107    : basic_istream<char_type, traits_type>(&__sb_) {
1108  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
1109    this->setstate(ios_base::failbit);
1110}
1111
1112#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1113template <class _CharT, class _Traits>
1114inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode)
1115    : basic_istream<char_type, traits_type>(&__sb_) {
1116  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
1117    this->setstate(ios_base::failbit);
1118}
1119#  endif
1120
1121template <class _CharT, class _Traits>
1122inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)
1123    : basic_istream<char_type, traits_type>(&__sb_) {
1124  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
1125    this->setstate(ios_base::failbit);
1126}
1127
1128template <class _CharT, class _Traits>
1129inline basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
1130    : basic_istream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
1131  this->set_rdbuf(&__sb_);
1132}
1133
1134template <class _CharT, class _Traits>
1135inline basic_ifstream<_CharT, _Traits>& basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) {
1136  basic_istream<char_type, traits_type>::operator=(std::move(__rhs));
1137  __sb_ = std::move(__rhs.__sb_);
1138  return *this;
1139}
1140
1141template <class _CharT, class _Traits>
1142inline void basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) {
1143  basic_istream<char_type, traits_type>::swap(__rhs);
1144  __sb_.swap(__rhs.__sb_);
1145}
1146
1147template <class _CharT, class _Traits>
1148inline _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) {
1149  __x.swap(__y);
1150}
1151
1152template <class _CharT, class _Traits>
1153inline basic_filebuf<_CharT, _Traits>* basic_ifstream<_CharT, _Traits>::rdbuf() const {
1154  return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
1155}
1156
1157template <class _CharT, class _Traits>
1158inline bool basic_ifstream<_CharT, _Traits>::is_open() const {
1159  return __sb_.is_open();
1160}
1161
1162template <class _CharT, class _Traits>
1163void basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
1164  if (__sb_.open(__s, __mode | ios_base::in))
1165    this->clear();
1166  else
1167    this->setstate(ios_base::failbit);
1168}
1169
1170#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1171template <class _CharT, class _Traits>
1172void basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
1173  if (__sb_.open(__s, __mode | ios_base::in))
1174    this->clear();
1175  else
1176    this->setstate(ios_base::failbit);
1177}
1178#  endif
1179
1180template <class _CharT, class _Traits>
1181void basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
1182  if (__sb_.open(__s, __mode | ios_base::in))
1183    this->clear();
1184  else
1185    this->setstate(ios_base::failbit);
1186}
1187
1188template <class _CharT, class _Traits>
1189inline void basic_ifstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
1190  if (__sb_.__open(__fd, __mode | ios_base::in))
1191    this->clear();
1192  else
1193    this->setstate(ios_base::failbit);
1194}
1195
1196template <class _CharT, class _Traits>
1197inline void basic_ifstream<_CharT, _Traits>::close() {
1198  if (__sb_.close() == 0)
1199    this->setstate(ios_base::failbit);
1200}
1201
1202// basic_ofstream
1203
1204template <class _CharT, class _Traits>
1205class _LIBCPP_TEMPLATE_VIS basic_ofstream : public basic_ostream<_CharT, _Traits> {
1206public:
1207  typedef _CharT char_type;
1208  typedef _Traits traits_type;
1209  typedef typename traits_type::int_type int_type;
1210  typedef typename traits_type::pos_type pos_type;
1211  typedef typename traits_type::off_type off_type;
1212#  if _LIBCPP_STD_VER >= 26
1213  using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
1214#  endif
1215
1216  _LIBCPP_HIDE_FROM_ABI basic_ofstream();
1217  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
1218#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1219  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
1220#  endif
1221  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
1222
1223#  if _LIBCPP_STD_VER >= 17
1224  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(
1225      const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
1226      : basic_ofstream(__p.c_str(), __mode) {}
1227#  endif // _LIBCPP_STD_VER >= 17
1228
1229  _LIBCPP_HIDE_FROM_ABI basic_ofstream(basic_ofstream&& __rhs);
1230  _LIBCPP_HIDE_FROM_ABI basic_ofstream& operator=(basic_ofstream&& __rhs);
1231  _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream& __rhs);
1232
1233  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
1234#  if _LIBCPP_STD_VER >= 26
1235  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
1236#  endif
1237  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
1238  void open(const char* __s, ios_base::openmode __mode = ios_base::out);
1239#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1240  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
1241#  endif
1242  void open(const string& __s, ios_base::openmode __mode = ios_base::out);
1243
1244#  if _LIBCPP_STD_VER >= 17
1245  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1246  open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) {
1247    return open(__p.c_str(), __mode);
1248  }
1249#  endif // _LIBCPP_STD_VER >= 17
1250
1251  _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
1252  _LIBCPP_HIDE_FROM_ABI void close();
1253
1254private:
1255  basic_filebuf<char_type, traits_type> __sb_;
1256};
1257
1258template <class _CharT, class _Traits>
1259inline basic_ofstream<_CharT, _Traits>::basic_ofstream() : basic_ostream<char_type, traits_type>(&__sb_) {}
1260
1261template <class _CharT, class _Traits>
1262inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
1263    : basic_ostream<char_type, traits_type>(&__sb_) {
1264  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
1265    this->setstate(ios_base::failbit);
1266}
1267
1268#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1269template <class _CharT, class _Traits>
1270inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode)
1271    : basic_ostream<char_type, traits_type>(&__sb_) {
1272  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
1273    this->setstate(ios_base::failbit);
1274}
1275#  endif
1276
1277template <class _CharT, class _Traits>
1278inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)
1279    : basic_ostream<char_type, traits_type>(&__sb_) {
1280  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
1281    this->setstate(ios_base::failbit);
1282}
1283
1284template <class _CharT, class _Traits>
1285inline basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
1286    : basic_ostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
1287  this->set_rdbuf(&__sb_);
1288}
1289
1290template <class _CharT, class _Traits>
1291inline basic_ofstream<_CharT, _Traits>& basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) {
1292  basic_ostream<char_type, traits_type>::operator=(std::move(__rhs));
1293  __sb_ = std::move(__rhs.__sb_);
1294  return *this;
1295}
1296
1297template <class _CharT, class _Traits>
1298inline void basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) {
1299  basic_ostream<char_type, traits_type>::swap(__rhs);
1300  __sb_.swap(__rhs.__sb_);
1301}
1302
1303template <class _CharT, class _Traits>
1304inline _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) {
1305  __x.swap(__y);
1306}
1307
1308template <class _CharT, class _Traits>
1309inline basic_filebuf<_CharT, _Traits>* basic_ofstream<_CharT, _Traits>::rdbuf() const {
1310  return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
1311}
1312
1313template <class _CharT, class _Traits>
1314inline bool basic_ofstream<_CharT, _Traits>::is_open() const {
1315  return __sb_.is_open();
1316}
1317
1318template <class _CharT, class _Traits>
1319void basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
1320  if (__sb_.open(__s, __mode | ios_base::out))
1321    this->clear();
1322  else
1323    this->setstate(ios_base::failbit);
1324}
1325
1326#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1327template <class _CharT, class _Traits>
1328void basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
1329  if (__sb_.open(__s, __mode | ios_base::out))
1330    this->clear();
1331  else
1332    this->setstate(ios_base::failbit);
1333}
1334#  endif
1335
1336template <class _CharT, class _Traits>
1337void basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
1338  if (__sb_.open(__s, __mode | ios_base::out))
1339    this->clear();
1340  else
1341    this->setstate(ios_base::failbit);
1342}
1343
1344template <class _CharT, class _Traits>
1345inline void basic_ofstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
1346  if (__sb_.__open(__fd, __mode | ios_base::out))
1347    this->clear();
1348  else
1349    this->setstate(ios_base::failbit);
1350}
1351
1352template <class _CharT, class _Traits>
1353inline void basic_ofstream<_CharT, _Traits>::close() {
1354  if (__sb_.close() == nullptr)
1355    this->setstate(ios_base::failbit);
1356}
1357
1358// basic_fstream
1359
1360template <class _CharT, class _Traits>
1361class _LIBCPP_TEMPLATE_VIS basic_fstream : public basic_iostream<_CharT, _Traits> {
1362public:
1363  typedef _CharT char_type;
1364  typedef _Traits traits_type;
1365  typedef typename traits_type::int_type int_type;
1366  typedef typename traits_type::pos_type pos_type;
1367  typedef typename traits_type::off_type off_type;
1368#  if _LIBCPP_STD_VER >= 26
1369  using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
1370#  endif
1371
1372  _LIBCPP_HIDE_FROM_ABI basic_fstream();
1373  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const char* __s,
1374                                               ios_base::openmode __mode = ios_base::in | ios_base::out);
1375#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1376  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const wchar_t* __s,
1377                                               ios_base::openmode __mode = ios_base::in | ios_base::out);
1378#  endif
1379  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const string& __s,
1380                                               ios_base::openmode __mode = ios_base::in | ios_base::out);
1381
1382#  if _LIBCPP_STD_VER >= 17
1383  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(
1384      const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
1385      : basic_fstream(__p.c_str(), __mode) {}
1386#  endif // _LIBCPP_STD_VER >= 17
1387
1388  _LIBCPP_HIDE_FROM_ABI basic_fstream(basic_fstream&& __rhs);
1389
1390  _LIBCPP_HIDE_FROM_ABI basic_fstream& operator=(basic_fstream&& __rhs);
1391
1392  _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream& __rhs);
1393
1394  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
1395#  if _LIBCPP_STD_VER >= 26
1396  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
1397#  endif
1398  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
1399  _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1400#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1401  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1402#  endif
1403  _LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1404
1405#  if _LIBCPP_STD_VER >= 17
1406  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1407  open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) {
1408    return open(__p.c_str(), __mode);
1409  }
1410#  endif // _LIBCPP_STD_VER >= 17
1411
1412  _LIBCPP_HIDE_FROM_ABI void close();
1413
1414private:
1415  basic_filebuf<char_type, traits_type> __sb_;
1416};
1417
1418template <class _CharT, class _Traits>
1419inline basic_fstream<_CharT, _Traits>::basic_fstream() : basic_iostream<char_type, traits_type>(&__sb_) {}
1420
1421template <class _CharT, class _Traits>
1422inline basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
1423    : basic_iostream<char_type, traits_type>(&__sb_) {
1424  if (__sb_.open(__s, __mode) == nullptr)
1425    this->setstate(ios_base::failbit);
1426}
1427
1428#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1429template <class _CharT, class _Traits>
1430inline basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode)
1431    : basic_iostream<char_type, traits_type>(&__sb_) {
1432  if (__sb_.open(__s, __mode) == nullptr)
1433    this->setstate(ios_base::failbit);
1434}
1435#  endif
1436
1437template <class _CharT, class _Traits>
1438inline basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)
1439    : basic_iostream<char_type, traits_type>(&__sb_) {
1440  if (__sb_.open(__s, __mode) == nullptr)
1441    this->setstate(ios_base::failbit);
1442}
1443
1444template <class _CharT, class _Traits>
1445inline basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
1446    : basic_iostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
1447  this->set_rdbuf(&__sb_);
1448}
1449
1450template <class _CharT, class _Traits>
1451inline basic_fstream<_CharT, _Traits>& basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) {
1452  basic_iostream<char_type, traits_type>::operator=(std::move(__rhs));
1453  __sb_ = std::move(__rhs.__sb_);
1454  return *this;
1455}
1456
1457template <class _CharT, class _Traits>
1458inline void basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) {
1459  basic_iostream<char_type, traits_type>::swap(__rhs);
1460  __sb_.swap(__rhs.__sb_);
1461}
1462
1463template <class _CharT, class _Traits>
1464inline _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) {
1465  __x.swap(__y);
1466}
1467
1468template <class _CharT, class _Traits>
1469inline basic_filebuf<_CharT, _Traits>* basic_fstream<_CharT, _Traits>::rdbuf() const {
1470  return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
1471}
1472
1473template <class _CharT, class _Traits>
1474inline bool basic_fstream<_CharT, _Traits>::is_open() const {
1475  return __sb_.is_open();
1476}
1477
1478template <class _CharT, class _Traits>
1479void basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
1480  if (__sb_.open(__s, __mode))
1481    this->clear();
1482  else
1483    this->setstate(ios_base::failbit);
1484}
1485
1486#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1487template <class _CharT, class _Traits>
1488void basic_fstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
1489  if (__sb_.open(__s, __mode))
1490    this->clear();
1491  else
1492    this->setstate(ios_base::failbit);
1493}
1494#  endif
1495
1496template <class _CharT, class _Traits>
1497void basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
1498  if (__sb_.open(__s, __mode))
1499    this->clear();
1500  else
1501    this->setstate(ios_base::failbit);
1502}
1503
1504template <class _CharT, class _Traits>
1505inline void basic_fstream<_CharT, _Traits>::close() {
1506  if (__sb_.close() == nullptr)
1507    this->setstate(ios_base::failbit);
1508}
1509
1510#  if _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
1511extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ifstream<char>;
1512extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ofstream<char>;
1513extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>;
1514#  endif
1515
1516_LIBCPP_END_NAMESPACE_STD
1517
1518#endif // _LIBCPP_HAS_NO_FILESYSTEM
1519
1520_LIBCPP_POP_MACROS
1521
1522#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1523#  include <atomic>
1524#  include <concepts>
1525#  include <cstdlib>
1526#  include <iosfwd>
1527#  include <limits>
1528#  include <mutex>
1529#  include <new>
1530#  include <stdexcept>
1531#  include <type_traits>
1532#endif
1533
1534#endif // _LIBCPP_FSTREAM
1535