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