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