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