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