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