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>
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#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
283  _LIBCPP_HIDE_FROM_ABI inline static const wchar_t* __make_mdwstring(ios_base::openmode __mode) _NOEXCEPT;
284#  endif
285
286protected:
287  // 27.9.1.5 Overridden virtual functions:
288  int_type underflow() override;
289  int_type pbackfail(int_type __c = traits_type::eof()) override;
290  int_type overflow(int_type __c = traits_type::eof()) override;
291  basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n) override;
292  pos_type
293  seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
294  pos_type seekpos(pos_type __sp, ios_base::openmode __wch = ios_base::in | ios_base::out) override;
295  int sync() override;
296  void imbue(const locale& __loc) override;
297
298private:
299  char* __extbuf_;
300  const char* __extbufnext_;
301  const char* __extbufend_;
302  char __extbuf_min_[8];
303  size_t __ebs_;
304  char_type* __intbuf_;
305  size_t __ibs_;
306  FILE* __file_;
307  const codecvt<char_type, char, state_type>* __cv_;
308  state_type __st_;
309  state_type __st_last_;
310  ios_base::openmode __om_;
311  ios_base::openmode __cm_;
312  bool __owns_eb_;
313  bool __owns_ib_;
314  bool __always_noconv_;
315
316  bool __read_mode();
317  void __write_mode();
318
319  _LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);
320
321  // There are multiple (__)open function, they use different C-API open
322  // function. After that call these functions behave the same. This function
323  // does that part and determines the final return value.
324  _LIBCPP_HIDE_FROM_ABI basic_filebuf* __do_open(FILE* __file, ios_base::openmode __mode) {
325    __file_ = __file;
326    if (!__file_)
327      return nullptr;
328
329    __om_ = __mode;
330    if (__mode & ios_base::ate) {
331      if (fseek(__file_, 0, SEEK_END)) {
332        fclose(__file_);
333        __file_ = nullptr;
334        return nullptr;
335      }
336    }
337
338    return this;
339  }
340};
341
342template <class _CharT, class _Traits>
343basic_filebuf<_CharT, _Traits>::basic_filebuf()
344    : __extbuf_(nullptr),
345      __extbufnext_(nullptr),
346      __extbufend_(nullptr),
347      __ebs_(0),
348      __intbuf_(nullptr),
349      __ibs_(0),
350      __file_(nullptr),
351      __cv_(nullptr),
352      __st_(),
353      __st_last_(),
354      __om_(0),
355      __cm_(0),
356      __owns_eb_(false),
357      __owns_ib_(false),
358      __always_noconv_(false) {
359  if (std::has_facet<codecvt<char_type, char, state_type> >(this->getloc())) {
360    __cv_            = &std::use_facet<codecvt<char_type, char, state_type> >(this->getloc());
361    __always_noconv_ = __cv_->always_noconv();
362  }
363  setbuf(nullptr, 4096);
364}
365
366template <class _CharT, class _Traits>
367basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) : basic_streambuf<_CharT, _Traits>(__rhs) {
368  if (__rhs.__extbuf_ == __rhs.__extbuf_min_) {
369    __extbuf_     = __extbuf_min_;
370    __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);
371    __extbufend_  = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);
372  } else {
373    __extbuf_     = __rhs.__extbuf_;
374    __extbufnext_ = __rhs.__extbufnext_;
375    __extbufend_  = __rhs.__extbufend_;
376  }
377  __ebs_           = __rhs.__ebs_;
378  __intbuf_        = __rhs.__intbuf_;
379  __ibs_           = __rhs.__ibs_;
380  __file_          = __rhs.__file_;
381  __cv_            = __rhs.__cv_;
382  __st_            = __rhs.__st_;
383  __st_last_       = __rhs.__st_last_;
384  __om_            = __rhs.__om_;
385  __cm_            = __rhs.__cm_;
386  __owns_eb_       = __rhs.__owns_eb_;
387  __owns_ib_       = __rhs.__owns_ib_;
388  __always_noconv_ = __rhs.__always_noconv_;
389  if (__rhs.pbase()) {
390    if (__rhs.pbase() == __rhs.__intbuf_)
391      this->setp(__intbuf_, __intbuf_ + (__rhs.epptr() - __rhs.pbase()));
392    else
393      this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__rhs.epptr() - __rhs.pbase()));
394    this->__pbump(__rhs.pptr() - __rhs.pbase());
395  } else if (__rhs.eback()) {
396    if (__rhs.eback() == __rhs.__intbuf_)
397      this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()), __intbuf_ + (__rhs.egptr() - __rhs.eback()));
398    else
399      this->setg((char_type*)__extbuf_,
400                 (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),
401                 (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));
402  }
403  __rhs.__extbuf_     = nullptr;
404  __rhs.__extbufnext_ = nullptr;
405  __rhs.__extbufend_  = nullptr;
406  __rhs.__ebs_        = 0;
407  __rhs.__intbuf_     = 0;
408  __rhs.__ibs_        = 0;
409  __rhs.__file_       = nullptr;
410  __rhs.__st_         = state_type();
411  __rhs.__st_last_    = state_type();
412  __rhs.__om_         = 0;
413  __rhs.__cm_         = 0;
414  __rhs.__owns_eb_    = false;
415  __rhs.__owns_ib_    = false;
416  __rhs.setg(0, 0, 0);
417  __rhs.setp(0, 0);
418}
419
420template <class _CharT, class _Traits>
421inline basic_filebuf<_CharT, _Traits>& basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) {
422  close();
423  swap(__rhs);
424  return *this;
425}
426
427template <class _CharT, class _Traits>
428basic_filebuf<_CharT, _Traits>::~basic_filebuf() {
429#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
430  try {
431#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
432    close();
433#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
434  } catch (...) {
435  }
436#  endif // _LIBCPP_HAS_NO_EXCEPTIONS
437  if (__owns_eb_)
438    delete[] __extbuf_;
439  if (__owns_ib_)
440    delete[] __intbuf_;
441}
442
443template <class _CharT, class _Traits>
444void basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) {
445  basic_streambuf<char_type, traits_type>::swap(__rhs);
446  if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
447    // Neither *this nor __rhs uses the small buffer, so we can simply swap the pointers.
448    std::swap(__extbuf_, __rhs.__extbuf_);
449    std::swap(__extbufnext_, __rhs.__extbufnext_);
450    std::swap(__extbufend_, __rhs.__extbufend_);
451  } else {
452    ptrdiff_t __ln = __extbufnext_ ? __extbufnext_ - __extbuf_ : 0;
453    ptrdiff_t __le = __extbufend_ ? __extbufend_ - __extbuf_ : 0;
454    ptrdiff_t __rn = __rhs.__extbufnext_ ? __rhs.__extbufnext_ - __rhs.__extbuf_ : 0;
455    ptrdiff_t __re = __rhs.__extbufend_ ? __rhs.__extbufend_ - __rhs.__extbuf_ : 0;
456    if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {
457      // *this uses the small buffer, but __rhs doesn't.
458      __extbuf_       = __rhs.__extbuf_;
459      __rhs.__extbuf_ = __rhs.__extbuf_min_;
460      std::memmove(__rhs.__extbuf_min_, __extbuf_min_, sizeof(__extbuf_min_));
461    } else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_) {
462      // *this doesn't use the small buffer, but __rhs does.
463      __rhs.__extbuf_ = __extbuf_;
464      __extbuf_       = __extbuf_min_;
465      std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
466    } else {
467      // Both *this and __rhs use the small buffer.
468      char __tmp[sizeof(__extbuf_min_)];
469      std::memmove(__tmp, __extbuf_min_, sizeof(__extbuf_min_));
470      std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));
471      std::memmove(__rhs.__extbuf_min_, __tmp, sizeof(__extbuf_min_));
472    }
473    __extbufnext_       = __extbuf_ + __rn;
474    __extbufend_        = __extbuf_ + __re;
475    __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;
476    __rhs.__extbufend_  = __rhs.__extbuf_ + __le;
477  }
478  std::swap(__ebs_, __rhs.__ebs_);
479  std::swap(__intbuf_, __rhs.__intbuf_);
480  std::swap(__ibs_, __rhs.__ibs_);
481  std::swap(__file_, __rhs.__file_);
482  std::swap(__cv_, __rhs.__cv_);
483  std::swap(__st_, __rhs.__st_);
484  std::swap(__st_last_, __rhs.__st_last_);
485  std::swap(__om_, __rhs.__om_);
486  std::swap(__cm_, __rhs.__cm_);
487  std::swap(__owns_eb_, __rhs.__owns_eb_);
488  std::swap(__owns_ib_, __rhs.__owns_ib_);
489  std::swap(__always_noconv_, __rhs.__always_noconv_);
490  if (this->eback() == (char_type*)__rhs.__extbuf_min_) {
491    ptrdiff_t __n = this->gptr() - this->eback();
492    ptrdiff_t __e = this->egptr() - this->eback();
493    this->setg((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __n, (char_type*)__extbuf_min_ + __e);
494  } else if (this->pbase() == (char_type*)__rhs.__extbuf_min_) {
495    ptrdiff_t __n = this->pptr() - this->pbase();
496    ptrdiff_t __e = this->epptr() - this->pbase();
497    this->setp((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __e);
498    this->__pbump(__n);
499  }
500  if (__rhs.eback() == (char_type*)__extbuf_min_) {
501    ptrdiff_t __n = __rhs.gptr() - __rhs.eback();
502    ptrdiff_t __e = __rhs.egptr() - __rhs.eback();
503    __rhs.setg(
504        (char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __n, (char_type*)__rhs.__extbuf_min_ + __e);
505  } else if (__rhs.pbase() == (char_type*)__extbuf_min_) {
506    ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();
507    ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();
508    __rhs.setp((char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __e);
509    __rhs.__pbump(__n);
510  }
511}
512
513template <class _CharT, class _Traits>
514inline _LIBCPP_HIDE_FROM_ABI void swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) {
515  __x.swap(__y);
516}
517
518template <class _CharT, class _Traits>
519inline bool basic_filebuf<_CharT, _Traits>::is_open() const {
520  return __file_ != nullptr;
521}
522
523template <class _CharT, class _Traits>
524const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(ios_base::openmode __mode) _NOEXCEPT {
525  switch (__mode & ~ios_base::ate) {
526  case ios_base::out:
527  case ios_base::out | ios_base::trunc:
528    return "w" _LIBCPP_FOPEN_CLOEXEC_MODE;
529  case ios_base::out | ios_base::app:
530  case ios_base::app:
531    return "a" _LIBCPP_FOPEN_CLOEXEC_MODE;
532  case ios_base::in:
533    return "r" _LIBCPP_FOPEN_CLOEXEC_MODE;
534  case ios_base::in | ios_base::out:
535    return "r+" _LIBCPP_FOPEN_CLOEXEC_MODE;
536  case ios_base::in | ios_base::out | ios_base::trunc:
537    return "w+" _LIBCPP_FOPEN_CLOEXEC_MODE;
538  case ios_base::in | ios_base::out | ios_base::app:
539  case ios_base::in | ios_base::app:
540    return "a+" _LIBCPP_FOPEN_CLOEXEC_MODE;
541  case ios_base::out | ios_base::binary:
542  case ios_base::out | ios_base::trunc | ios_base::binary:
543    return "wb" _LIBCPP_FOPEN_CLOEXEC_MODE;
544  case ios_base::out | ios_base::app | ios_base::binary:
545  case ios_base::app | ios_base::binary:
546    return "ab" _LIBCPP_FOPEN_CLOEXEC_MODE;
547  case ios_base::in | ios_base::binary:
548    return "rb" _LIBCPP_FOPEN_CLOEXEC_MODE;
549  case ios_base::in | ios_base::out | ios_base::binary:
550    return "r+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
551  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
552    return "w+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
553  case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
554  case ios_base::in | ios_base::app | ios_base::binary:
555    return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
556#  if _LIBCPP_STD_VER >= 23
557  case ios_base::out | ios_base::noreplace:
558  case ios_base::out | ios_base::trunc | ios_base::noreplace:
559    return "wx" _LIBCPP_FOPEN_CLOEXEC_MODE;
560  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
561    return "w+x" _LIBCPP_FOPEN_CLOEXEC_MODE;
562  case ios_base::out | ios_base::binary | ios_base::noreplace:
563  case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
564    return "wbx" _LIBCPP_FOPEN_CLOEXEC_MODE;
565  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
566    return "w+bx" _LIBCPP_FOPEN_CLOEXEC_MODE;
567#  endif // _LIBCPP_STD_VER >= 23
568  default:
569    return nullptr;
570  }
571  __libcpp_unreachable();
572}
573
574#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
575template <class _CharT, class _Traits>
576const wchar_t* basic_filebuf<_CharT, _Traits>::__make_mdwstring(ios_base::openmode __mode) _NOEXCEPT {
577  switch (__mode & ~ios_base::ate) {
578  case ios_base::out:
579  case ios_base::out | ios_base::trunc:
580    return L"w";
581  case ios_base::out | ios_base::app:
582  case ios_base::app:
583    return L"a";
584  case ios_base::in:
585    return L"r";
586  case ios_base::in | ios_base::out:
587    return L"r+";
588  case ios_base::in | ios_base::out | ios_base::trunc:
589    return L"w+";
590  case ios_base::in | ios_base::out | ios_base::app:
591  case ios_base::in | ios_base::app:
592    return L"a+";
593  case ios_base::out | ios_base::binary:
594  case ios_base::out | ios_base::trunc | ios_base::binary:
595    return L"wb";
596  case ios_base::out | ios_base::app | ios_base::binary:
597  case ios_base::app | ios_base::binary:
598    return L"ab";
599  case ios_base::in | ios_base::binary:
600    return L"rb";
601  case ios_base::in | ios_base::out | ios_base::binary:
602    return L"r+b";
603  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
604    return L"w+b";
605  case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
606  case ios_base::in | ios_base::app | ios_base::binary:
607    return L"a+b";
608#    if _LIBCPP_STD_VER >= 23
609  case ios_base::out | ios_base::noreplace:
610  case ios_base::out | ios_base::trunc | ios_base::noreplace:
611    return L"wx";
612  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
613    return L"w+x";
614  case ios_base::out | ios_base::binary | ios_base::noreplace:
615  case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
616    return L"wbx";
617  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
618    return L"w+bx";
619#    endif // _LIBCPP_STD_VER >= 23
620  default:
621    return nullptr;
622  }
623  __libcpp_unreachable();
624}
625#  endif
626
627template <class _CharT, class _Traits>
628basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
629  if (__file_)
630    return nullptr;
631  const char* __mdstr = __make_mdstring(__mode);
632  if (!__mdstr)
633    return nullptr;
634
635  return __do_open(fopen(__s, __mdstr), __mode);
636}
637
638template <class _CharT, class _Traits>
639inline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
640  if (__file_)
641    return nullptr;
642  const char* __mdstr = __make_mdstring(__mode);
643  if (!__mdstr)
644    return nullptr;
645
646  return __do_open(fdopen(__fd, __mdstr), __mode);
647}
648
649#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
650// This is basically the same as the char* overload except that it uses _wfopen
651// and long mode strings.
652template <class _CharT, class _Traits>
653basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
654  if (__file_)
655    return nullptr;
656  const wchar_t* __mdstr = __make_mdwstring(__mode);
657  if (!__mdstr)
658    return nullptr;
659
660  return __do_open(_wfopen(__s, __mdstr), __mode);
661}
662#  endif
663
664template <class _CharT, class _Traits>
665inline basic_filebuf<_CharT, _Traits>*
666basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
667  return open(__s.c_str(), __mode);
668}
669
670template <class _CharT, class _Traits>
671basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::close() {
672  basic_filebuf<_CharT, _Traits>* __rt = nullptr;
673  if (__file_) {
674    __rt = this;
675    unique_ptr<FILE, int (*)(FILE*)> __h(__file_, fclose);
676    if (sync())
677      __rt = nullptr;
678    if (fclose(__h.release()))
679      __rt = nullptr;
680    __file_ = nullptr;
681    setbuf(0, 0);
682  }
683  return __rt;
684}
685
686template <class _CharT, class _Traits>
687typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::underflow() {
688  if (__file_ == nullptr)
689    return traits_type::eof();
690  bool __initial = __read_mode();
691  char_type __1buf;
692  if (this->gptr() == nullptr)
693    this->setg(&__1buf, &__1buf + 1, &__1buf + 1);
694  const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
695  int_type __c            = traits_type::eof();
696  if (this->gptr() == this->egptr()) {
697    std::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
698    if (__always_noconv_) {
699      size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
700      __nmemb        = ::fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
701      if (__nmemb != 0) {
702        this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb);
703        __c = traits_type::to_int_type(*this->gptr());
704      }
705    } else {
706      if (__extbufend_ != __extbufnext_) {
707        _LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr");
708        _LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr");
709        std::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
710      }
711      __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
712      __extbufend_  = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
713      size_t __nmemb =
714          std::min(static_cast<size_t>(__ibs_ - __unget_sz), static_cast<size_t>(__extbufend_ - __extbufnext_));
715      codecvt_base::result __r;
716      __st_last_  = __st_;
717      size_t __nr = fread((void*)const_cast<char*>(__extbufnext_), 1, __nmemb, __file_);
718      if (__nr != 0) {
719        if (!__cv_)
720          __throw_bad_cast();
721
722        __extbufend_ = __extbufnext_ + __nr;
723        char_type* __inext;
724        __r = __cv_->in(
725            __st_, __extbuf_, __extbufend_, __extbufnext_, this->eback() + __unget_sz, this->eback() + __ibs_, __inext);
726        if (__r == codecvt_base::noconv) {
727          this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)const_cast<char*>(__extbufend_));
728          __c = traits_type::to_int_type(*this->gptr());
729        } else if (__inext != this->eback() + __unget_sz) {
730          this->setg(this->eback(), this->eback() + __unget_sz, __inext);
731          __c = traits_type::to_int_type(*this->gptr());
732        }
733      }
734    }
735  } else
736    __c = traits_type::to_int_type(*this->gptr());
737  if (this->eback() == &__1buf)
738    this->setg(nullptr, nullptr, nullptr);
739  return __c;
740}
741
742template <class _CharT, class _Traits>
743typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) {
744  if (__file_ && this->eback() < this->gptr()) {
745    if (traits_type::eq_int_type(__c, traits_type::eof())) {
746      this->gbump(-1);
747      return traits_type::not_eof(__c);
748    }
749    if ((__om_ & ios_base::out) || traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) {
750      this->gbump(-1);
751      *this->gptr() = traits_type::to_char_type(__c);
752      return __c;
753    }
754  }
755  return traits_type::eof();
756}
757
758template <class _CharT, class _Traits>
759typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {
760  if (__file_ == nullptr)
761    return traits_type::eof();
762  __write_mode();
763  char_type __1buf;
764  char_type* __pb_save  = this->pbase();
765  char_type* __epb_save = this->epptr();
766  if (!traits_type::eq_int_type(__c, traits_type::eof())) {
767    if (this->pptr() == nullptr)
768      this->setp(&__1buf, &__1buf + 1);
769    *this->pptr() = traits_type::to_char_type(__c);
770    this->pbump(1);
771  }
772  if (this->pptr() != this->pbase()) {
773    if (__always_noconv_) {
774      size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
775      if (std::fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
776        return traits_type::eof();
777    } else {
778      char* __extbe = __extbuf_;
779      codecvt_base::result __r;
780      do {
781        if (!__cv_)
782          __throw_bad_cast();
783
784        const char_type* __e;
785        __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, __extbuf_, __extbuf_ + __ebs_, __extbe);
786        if (__e == this->pbase())
787          return traits_type::eof();
788        if (__r == codecvt_base::noconv) {
789          size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
790          if (std::fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
791            return traits_type::eof();
792        } else if (__r == codecvt_base::ok || __r == codecvt_base::partial) {
793          size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
794          if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
795            return traits_type::eof();
796          if (__r == codecvt_base::partial) {
797            this->setp(const_cast<char_type*>(__e), this->pptr());
798            this->__pbump(this->epptr() - this->pbase());
799          }
800        } else
801          return traits_type::eof();
802      } while (__r == codecvt_base::partial);
803    }
804    this->setp(__pb_save, __epb_save);
805  }
806  return traits_type::not_eof(__c);
807}
808
809template <class _CharT, class _Traits>
810basic_streambuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n) {
811  this->setg(nullptr, nullptr, nullptr);
812  this->setp(nullptr, nullptr);
813  if (__owns_eb_)
814    delete[] __extbuf_;
815  if (__owns_ib_)
816    delete[] __intbuf_;
817  __ebs_ = __n;
818  if (__ebs_ > sizeof(__extbuf_min_)) {
819    if (__always_noconv_ && __s) {
820      __extbuf_  = (char*)__s;
821      __owns_eb_ = false;
822    } else {
823      __extbuf_  = new char[__ebs_];
824      __owns_eb_ = true;
825    }
826  } else {
827    __extbuf_  = __extbuf_min_;
828    __ebs_     = sizeof(__extbuf_min_);
829    __owns_eb_ = false;
830  }
831  if (!__always_noconv_) {
832    __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
833    if (__s && __ibs_ > sizeof(__extbuf_min_)) {
834      __intbuf_  = __s;
835      __owns_ib_ = false;
836    } else {
837      __intbuf_  = new char_type[__ibs_];
838      __owns_ib_ = true;
839    }
840  } else {
841    __ibs_     = 0;
842    __intbuf_  = nullptr;
843    __owns_ib_ = false;
844  }
845  return this;
846}
847
848template <class _CharT, class _Traits>
849typename basic_filebuf<_CharT, _Traits>::pos_type
850basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) {
851  if (!__cv_)
852    __throw_bad_cast();
853
854  int __width = __cv_->encoding();
855  if (__file_ == nullptr || (__width <= 0 && __off != 0) || sync())
856    return pos_type(off_type(-1));
857  // __width > 0 || __off == 0
858  int __whence;
859  switch (__way) {
860  case ios_base::beg:
861    __whence = SEEK_SET;
862    break;
863  case ios_base::cur:
864    __whence = SEEK_CUR;
865    break;
866  case ios_base::end:
867    __whence = SEEK_END;
868    break;
869  default:
870    return pos_type(off_type(-1));
871  }
872#  if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
873  if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
874    return pos_type(off_type(-1));
875  pos_type __r = ftell(__file_);
876#  else
877  if (::fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
878    return pos_type(off_type(-1));
879  pos_type __r = ftello(__file_);
880#  endif
881  __r.state(__st_);
882  return __r;
883}
884
885template <class _CharT, class _Traits>
886typename basic_filebuf<_CharT, _Traits>::pos_type
887basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) {
888  if (__file_ == nullptr || sync())
889    return pos_type(off_type(-1));
890#  if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
891  if (fseek(__file_, __sp, SEEK_SET))
892    return pos_type(off_type(-1));
893#  else
894  if (::fseeko(__file_, __sp, SEEK_SET))
895    return pos_type(off_type(-1));
896#  endif
897  __st_ = __sp.state();
898  return __sp;
899}
900
901template <class _CharT, class _Traits>
902int basic_filebuf<_CharT, _Traits>::sync() {
903  if (__file_ == nullptr)
904    return 0;
905  if (!__cv_)
906    __throw_bad_cast();
907
908  if (__cm_ & ios_base::out) {
909    if (this->pptr() != this->pbase())
910      if (overflow() == traits_type::eof())
911        return -1;
912    codecvt_base::result __r;
913    do {
914      char* __extbe;
915      __r            = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
916      size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
917      if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
918        return -1;
919    } while (__r == codecvt_base::partial);
920    if (__r == codecvt_base::error)
921      return -1;
922    if (fflush(__file_))
923      return -1;
924  } else if (__cm_ & ios_base::in) {
925    off_type __c;
926    state_type __state = __st_last_;
927    bool __update_st   = false;
928    if (__always_noconv_)
929      __c = this->egptr() - this->gptr();
930    else {
931      int __width = __cv_->encoding();
932      __c         = __extbufend_ - __extbufnext_;
933      if (__width > 0)
934        __c += __width * (this->egptr() - this->gptr());
935      else {
936        if (this->gptr() != this->egptr()) {
937          const int __off = __cv_->length(__state, __extbuf_, __extbufnext_, this->gptr() - this->eback());
938          __c += __extbufnext_ - __extbuf_ - __off;
939          __update_st = true;
940        }
941      }
942    }
943#  if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
944    if (fseek(__file_, -__c, SEEK_CUR))
945      return -1;
946#  else
947    if (::fseeko(__file_, -__c, SEEK_CUR))
948      return -1;
949#  endif
950    if (__update_st)
951      __st_ = __state;
952    __extbufnext_ = __extbufend_ = __extbuf_;
953    this->setg(nullptr, nullptr, nullptr);
954    __cm_ = 0;
955  }
956  return 0;
957}
958
959template <class _CharT, class _Traits>
960void basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) {
961  sync();
962  __cv_            = &std::use_facet<codecvt<char_type, char, state_type> >(__loc);
963  bool __old_anc   = __always_noconv_;
964  __always_noconv_ = __cv_->always_noconv();
965  if (__old_anc != __always_noconv_) {
966    this->setg(nullptr, nullptr, nullptr);
967    this->setp(nullptr, nullptr);
968    // invariant, char_type is char, else we couldn't get here
969    if (__always_noconv_) // need to dump __intbuf_
970    {
971      if (__owns_eb_)
972        delete[] __extbuf_;
973      __owns_eb_ = __owns_ib_;
974      __ebs_     = __ibs_;
975      __extbuf_  = (char*)__intbuf_;
976      __ibs_     = 0;
977      __intbuf_  = nullptr;
978      __owns_ib_ = false;
979    } else // need to obtain an __intbuf_.
980    {      // If __extbuf_ is user-supplied, use it, else new __intbuf_
981      if (!__owns_eb_ && __extbuf_ != __extbuf_min_) {
982        __ibs_     = __ebs_;
983        __intbuf_  = (char_type*)__extbuf_;
984        __owns_ib_ = false;
985        __extbuf_  = new char[__ebs_];
986        __owns_eb_ = true;
987      } else {
988        __ibs_     = __ebs_;
989        __intbuf_  = new char_type[__ibs_];
990        __owns_ib_ = true;
991      }
992    }
993  }
994}
995
996template <class _CharT, class _Traits>
997bool basic_filebuf<_CharT, _Traits>::__read_mode() {
998  if (!(__cm_ & ios_base::in)) {
999    this->setp(nullptr, nullptr);
1000    if (__always_noconv_)
1001      this->setg((char_type*)__extbuf_, (char_type*)__extbuf_ + __ebs_, (char_type*)__extbuf_ + __ebs_);
1002    else
1003      this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
1004    __cm_ = ios_base::in;
1005    return true;
1006  }
1007  return false;
1008}
1009
1010template <class _CharT, class _Traits>
1011void basic_filebuf<_CharT, _Traits>::__write_mode() {
1012  if (!(__cm_ & ios_base::out)) {
1013    this->setg(nullptr, nullptr, nullptr);
1014    if (__ebs_ > sizeof(__extbuf_min_)) {
1015      if (__always_noconv_)
1016        this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__ebs_ - 1));
1017      else
1018        this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
1019    } else
1020      this->setp(nullptr, nullptr);
1021    __cm_ = ios_base::out;
1022  }
1023}
1024
1025// basic_ifstream
1026
1027template <class _CharT, class _Traits>
1028class _LIBCPP_TEMPLATE_VIS basic_ifstream : public basic_istream<_CharT, _Traits> {
1029public:
1030  typedef _CharT char_type;
1031  typedef _Traits traits_type;
1032  typedef typename traits_type::int_type int_type;
1033  typedef typename traits_type::pos_type pos_type;
1034  typedef typename traits_type::off_type off_type;
1035#  if _LIBCPP_STD_VER >= 26
1036  using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
1037#  endif
1038
1039  _LIBCPP_HIDE_FROM_ABI basic_ifstream();
1040  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
1041#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1042  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
1043#  endif
1044  _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
1045#  if _LIBCPP_STD_VER >= 17
1046  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(
1047      const filesystem::path& __p, ios_base::openmode __mode = ios_base::in)
1048      : basic_ifstream(__p.c_str(), __mode) {}
1049#  endif // _LIBCPP_STD_VER >= 17
1050  _LIBCPP_HIDE_FROM_ABI basic_ifstream(basic_ifstream&& __rhs);
1051  _LIBCPP_HIDE_FROM_ABI basic_ifstream& operator=(basic_ifstream&& __rhs);
1052  _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs);
1053
1054  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
1055#  if _LIBCPP_STD_VER >= 26
1056  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
1057#  endif
1058  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
1059  void open(const char* __s, ios_base::openmode __mode = ios_base::in);
1060#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1061  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
1062#  endif
1063  void open(const string& __s, ios_base::openmode __mode = ios_base::in);
1064#  if _LIBCPP_STD_VER >= 17
1065  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1066  open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) {
1067    return open(__p.c_str(), __mode);
1068  }
1069#  endif // _LIBCPP_STD_VER >= 17
1070
1071  _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
1072  _LIBCPP_HIDE_FROM_ABI void close();
1073
1074private:
1075  basic_filebuf<char_type, traits_type> __sb_;
1076};
1077
1078template <class _CharT, class _Traits>
1079inline basic_ifstream<_CharT, _Traits>::basic_ifstream() : basic_istream<char_type, traits_type>(&__sb_) {}
1080
1081template <class _CharT, class _Traits>
1082inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
1083    : basic_istream<char_type, traits_type>(&__sb_) {
1084  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
1085    this->setstate(ios_base::failbit);
1086}
1087
1088#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1089template <class _CharT, class _Traits>
1090inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode)
1091    : basic_istream<char_type, traits_type>(&__sb_) {
1092  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
1093    this->setstate(ios_base::failbit);
1094}
1095#  endif
1096
1097template <class _CharT, class _Traits>
1098inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)
1099    : basic_istream<char_type, traits_type>(&__sb_) {
1100  if (__sb_.open(__s, __mode | ios_base::in) == nullptr)
1101    this->setstate(ios_base::failbit);
1102}
1103
1104template <class _CharT, class _Traits>
1105inline basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
1106    : basic_istream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
1107  this->set_rdbuf(&__sb_);
1108}
1109
1110template <class _CharT, class _Traits>
1111inline basic_ifstream<_CharT, _Traits>& basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) {
1112  basic_istream<char_type, traits_type>::operator=(std::move(__rhs));
1113  __sb_ = std::move(__rhs.__sb_);
1114  return *this;
1115}
1116
1117template <class _CharT, class _Traits>
1118inline void basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) {
1119  basic_istream<char_type, traits_type>::swap(__rhs);
1120  __sb_.swap(__rhs.__sb_);
1121}
1122
1123template <class _CharT, class _Traits>
1124inline _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) {
1125  __x.swap(__y);
1126}
1127
1128template <class _CharT, class _Traits>
1129inline basic_filebuf<_CharT, _Traits>* basic_ifstream<_CharT, _Traits>::rdbuf() const {
1130  return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
1131}
1132
1133template <class _CharT, class _Traits>
1134inline bool basic_ifstream<_CharT, _Traits>::is_open() const {
1135  return __sb_.is_open();
1136}
1137
1138template <class _CharT, class _Traits>
1139void basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
1140  if (__sb_.open(__s, __mode | ios_base::in))
1141    this->clear();
1142  else
1143    this->setstate(ios_base::failbit);
1144}
1145
1146#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1147template <class _CharT, class _Traits>
1148void basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
1149  if (__sb_.open(__s, __mode | ios_base::in))
1150    this->clear();
1151  else
1152    this->setstate(ios_base::failbit);
1153}
1154#  endif
1155
1156template <class _CharT, class _Traits>
1157void basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
1158  if (__sb_.open(__s, __mode | ios_base::in))
1159    this->clear();
1160  else
1161    this->setstate(ios_base::failbit);
1162}
1163
1164template <class _CharT, class _Traits>
1165inline void basic_ifstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
1166  if (__sb_.__open(__fd, __mode | ios_base::in))
1167    this->clear();
1168  else
1169    this->setstate(ios_base::failbit);
1170}
1171
1172template <class _CharT, class _Traits>
1173inline void basic_ifstream<_CharT, _Traits>::close() {
1174  if (__sb_.close() == 0)
1175    this->setstate(ios_base::failbit);
1176}
1177
1178// basic_ofstream
1179
1180template <class _CharT, class _Traits>
1181class _LIBCPP_TEMPLATE_VIS basic_ofstream : public basic_ostream<_CharT, _Traits> {
1182public:
1183  typedef _CharT char_type;
1184  typedef _Traits traits_type;
1185  typedef typename traits_type::int_type int_type;
1186  typedef typename traits_type::pos_type pos_type;
1187  typedef typename traits_type::off_type off_type;
1188#  if _LIBCPP_STD_VER >= 26
1189  using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
1190#  endif
1191
1192  _LIBCPP_HIDE_FROM_ABI basic_ofstream();
1193  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
1194#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1195  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
1196#  endif
1197  _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
1198
1199#  if _LIBCPP_STD_VER >= 17
1200  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(
1201      const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
1202      : basic_ofstream(__p.c_str(), __mode) {}
1203#  endif // _LIBCPP_STD_VER >= 17
1204
1205  _LIBCPP_HIDE_FROM_ABI basic_ofstream(basic_ofstream&& __rhs);
1206  _LIBCPP_HIDE_FROM_ABI basic_ofstream& operator=(basic_ofstream&& __rhs);
1207  _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream& __rhs);
1208
1209  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
1210#  if _LIBCPP_STD_VER >= 26
1211  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
1212#  endif
1213  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
1214  void open(const char* __s, ios_base::openmode __mode = ios_base::out);
1215#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1216  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
1217#  endif
1218  void open(const string& __s, ios_base::openmode __mode = ios_base::out);
1219
1220#  if _LIBCPP_STD_VER >= 17
1221  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1222  open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) {
1223    return open(__p.c_str(), __mode);
1224  }
1225#  endif // _LIBCPP_STD_VER >= 17
1226
1227  _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);
1228  _LIBCPP_HIDE_FROM_ABI void close();
1229
1230private:
1231  basic_filebuf<char_type, traits_type> __sb_;
1232};
1233
1234template <class _CharT, class _Traits>
1235inline basic_ofstream<_CharT, _Traits>::basic_ofstream() : basic_ostream<char_type, traits_type>(&__sb_) {}
1236
1237template <class _CharT, class _Traits>
1238inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
1239    : basic_ostream<char_type, traits_type>(&__sb_) {
1240  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
1241    this->setstate(ios_base::failbit);
1242}
1243
1244#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1245template <class _CharT, class _Traits>
1246inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode)
1247    : basic_ostream<char_type, traits_type>(&__sb_) {
1248  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
1249    this->setstate(ios_base::failbit);
1250}
1251#  endif
1252
1253template <class _CharT, class _Traits>
1254inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)
1255    : basic_ostream<char_type, traits_type>(&__sb_) {
1256  if (__sb_.open(__s, __mode | ios_base::out) == nullptr)
1257    this->setstate(ios_base::failbit);
1258}
1259
1260template <class _CharT, class _Traits>
1261inline basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
1262    : basic_ostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
1263  this->set_rdbuf(&__sb_);
1264}
1265
1266template <class _CharT, class _Traits>
1267inline basic_ofstream<_CharT, _Traits>& basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) {
1268  basic_ostream<char_type, traits_type>::operator=(std::move(__rhs));
1269  __sb_ = std::move(__rhs.__sb_);
1270  return *this;
1271}
1272
1273template <class _CharT, class _Traits>
1274inline void basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) {
1275  basic_ostream<char_type, traits_type>::swap(__rhs);
1276  __sb_.swap(__rhs.__sb_);
1277}
1278
1279template <class _CharT, class _Traits>
1280inline _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) {
1281  __x.swap(__y);
1282}
1283
1284template <class _CharT, class _Traits>
1285inline basic_filebuf<_CharT, _Traits>* basic_ofstream<_CharT, _Traits>::rdbuf() const {
1286  return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
1287}
1288
1289template <class _CharT, class _Traits>
1290inline bool basic_ofstream<_CharT, _Traits>::is_open() const {
1291  return __sb_.is_open();
1292}
1293
1294template <class _CharT, class _Traits>
1295void basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
1296  if (__sb_.open(__s, __mode | ios_base::out))
1297    this->clear();
1298  else
1299    this->setstate(ios_base::failbit);
1300}
1301
1302#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1303template <class _CharT, class _Traits>
1304void basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
1305  if (__sb_.open(__s, __mode | ios_base::out))
1306    this->clear();
1307  else
1308    this->setstate(ios_base::failbit);
1309}
1310#  endif
1311
1312template <class _CharT, class _Traits>
1313void basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
1314  if (__sb_.open(__s, __mode | ios_base::out))
1315    this->clear();
1316  else
1317    this->setstate(ios_base::failbit);
1318}
1319
1320template <class _CharT, class _Traits>
1321inline void basic_ofstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
1322  if (__sb_.__open(__fd, __mode | ios_base::out))
1323    this->clear();
1324  else
1325    this->setstate(ios_base::failbit);
1326}
1327
1328template <class _CharT, class _Traits>
1329inline void basic_ofstream<_CharT, _Traits>::close() {
1330  if (__sb_.close() == nullptr)
1331    this->setstate(ios_base::failbit);
1332}
1333
1334// basic_fstream
1335
1336template <class _CharT, class _Traits>
1337class _LIBCPP_TEMPLATE_VIS basic_fstream : public basic_iostream<_CharT, _Traits> {
1338public:
1339  typedef _CharT char_type;
1340  typedef _Traits traits_type;
1341  typedef typename traits_type::int_type int_type;
1342  typedef typename traits_type::pos_type pos_type;
1343  typedef typename traits_type::off_type off_type;
1344#  if _LIBCPP_STD_VER >= 26
1345  using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;
1346#  endif
1347
1348  _LIBCPP_HIDE_FROM_ABI basic_fstream();
1349  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const char* __s,
1350                                               ios_base::openmode __mode = ios_base::in | ios_base::out);
1351#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1352  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const wchar_t* __s,
1353                                               ios_base::openmode __mode = ios_base::in | ios_base::out);
1354#  endif
1355  _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const string& __s,
1356                                               ios_base::openmode __mode = ios_base::in | ios_base::out);
1357
1358#  if _LIBCPP_STD_VER >= 17
1359  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(
1360      const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
1361      : basic_fstream(__p.c_str(), __mode) {}
1362#  endif // _LIBCPP_STD_VER >= 17
1363
1364  _LIBCPP_HIDE_FROM_ABI basic_fstream(basic_fstream&& __rhs);
1365
1366  _LIBCPP_HIDE_FROM_ABI basic_fstream& operator=(basic_fstream&& __rhs);
1367
1368  _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream& __rhs);
1369
1370  _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;
1371#  if _LIBCPP_STD_VER >= 26
1372  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }
1373#  endif
1374  _LIBCPP_HIDE_FROM_ABI bool is_open() const;
1375  _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1376#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1377  void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1378#  endif
1379  _LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1380
1381#  if _LIBCPP_STD_VER >= 17
1382  _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_HIDE_FROM_ABI void
1383  open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) {
1384    return open(__p.c_str(), __mode);
1385  }
1386#  endif // _LIBCPP_STD_VER >= 17
1387
1388  _LIBCPP_HIDE_FROM_ABI void close();
1389
1390private:
1391  basic_filebuf<char_type, traits_type> __sb_;
1392};
1393
1394template <class _CharT, class _Traits>
1395inline basic_fstream<_CharT, _Traits>::basic_fstream() : basic_iostream<char_type, traits_type>(&__sb_) {}
1396
1397template <class _CharT, class _Traits>
1398inline basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
1399    : basic_iostream<char_type, traits_type>(&__sb_) {
1400  if (__sb_.open(__s, __mode) == nullptr)
1401    this->setstate(ios_base::failbit);
1402}
1403
1404#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1405template <class _CharT, class _Traits>
1406inline basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode)
1407    : basic_iostream<char_type, traits_type>(&__sb_) {
1408  if (__sb_.open(__s, __mode) == nullptr)
1409    this->setstate(ios_base::failbit);
1410}
1411#  endif
1412
1413template <class _CharT, class _Traits>
1414inline basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)
1415    : basic_iostream<char_type, traits_type>(&__sb_) {
1416  if (__sb_.open(__s, __mode) == nullptr)
1417    this->setstate(ios_base::failbit);
1418}
1419
1420template <class _CharT, class _Traits>
1421inline basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
1422    : basic_iostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
1423  this->set_rdbuf(&__sb_);
1424}
1425
1426template <class _CharT, class _Traits>
1427inline basic_fstream<_CharT, _Traits>& basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) {
1428  basic_iostream<char_type, traits_type>::operator=(std::move(__rhs));
1429  __sb_ = std::move(__rhs.__sb_);
1430  return *this;
1431}
1432
1433template <class _CharT, class _Traits>
1434inline void basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) {
1435  basic_iostream<char_type, traits_type>::swap(__rhs);
1436  __sb_.swap(__rhs.__sb_);
1437}
1438
1439template <class _CharT, class _Traits>
1440inline _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) {
1441  __x.swap(__y);
1442}
1443
1444template <class _CharT, class _Traits>
1445inline basic_filebuf<_CharT, _Traits>* basic_fstream<_CharT, _Traits>::rdbuf() const {
1446  return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
1447}
1448
1449template <class _CharT, class _Traits>
1450inline bool basic_fstream<_CharT, _Traits>::is_open() const {
1451  return __sb_.is_open();
1452}
1453
1454template <class _CharT, class _Traits>
1455void basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {
1456  if (__sb_.open(__s, __mode))
1457    this->clear();
1458  else
1459    this->setstate(ios_base::failbit);
1460}
1461
1462#  ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
1463template <class _CharT, class _Traits>
1464void basic_fstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {
1465  if (__sb_.open(__s, __mode))
1466    this->clear();
1467  else
1468    this->setstate(ios_base::failbit);
1469}
1470#  endif
1471
1472template <class _CharT, class _Traits>
1473void basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {
1474  if (__sb_.open(__s, __mode))
1475    this->clear();
1476  else
1477    this->setstate(ios_base::failbit);
1478}
1479
1480template <class _CharT, class _Traits>
1481inline void basic_fstream<_CharT, _Traits>::close() {
1482  if (__sb_.close() == nullptr)
1483    this->setstate(ios_base::failbit);
1484}
1485
1486#  if _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
1487extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ifstream<char>;
1488extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ofstream<char>;
1489extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>;
1490#  endif
1491
1492_LIBCPP_END_NAMESPACE_STD
1493
1494#endif // _LIBCPP_HAS_NO_FILESYSTEM
1495
1496_LIBCPP_POP_MACROS
1497
1498#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1499#  include <atomic>
1500#  include <concepts>
1501#  include <cstdlib>
1502#  include <iosfwd>
1503#  include <limits>
1504#  include <mutex>
1505#  include <new>
1506#  include <stdexcept>
1507#  include <type_traits>
1508#endif
1509
1510#endif // _LIBCPP_FSTREAM
1511