blob: aa78d85f3d6ab0a76485a82bf29627052808bfad [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===------------------------- fstream ------------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00006// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00008//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_FSTREAM
12#define _LIBCPP_FSTREAM
13
14/*
15 fstream synopsis
16
17template <class charT, class traits = char_traits<charT> >
18class basic_filebuf
19 : public basic_streambuf<charT, traits>
20{
21public:
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* close();
42
43protected:
44 // 27.9.1.5 Overridden virtual functions:
45 virtual streamsize showmanyc();
46 virtual int_type underflow();
47 virtual int_type uflow();
48 virtual int_type pbackfail(int_type c = traits_type::eof());
49 virtual int_type overflow (int_type c = traits_type::eof());
50 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* s, streamsize n);
51 virtual pos_type seekoff(off_type off, ios_base::seekdir way,
52 ios_base::openmode which = ios_base::in | ios_base::out);
53 virtual pos_type seekpos(pos_type sp,
54 ios_base::openmode which = ios_base::in | ios_base::out);
55 virtual int sync();
56 virtual void imbue(const locale& loc);
57};
58
59template <class charT, class traits>
60 void
61 swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y);
62
63typedef basic_filebuf<char> filebuf;
64typedef basic_filebuf<wchar_t> wfilebuf;
65
66template <class charT, class traits = char_traits<charT> >
67class basic_ifstream
68 : public basic_istream<charT,traits>
69{
70public:
71 typedef charT char_type;
72 typedef traits traits_type;
73 typedef typename traits_type::int_type int_type;
74 typedef typename traits_type::pos_type pos_type;
75 typedef typename traits_type::off_type off_type;
76
77 basic_ifstream();
78 explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
79 explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);
80 basic_ifstream(basic_ifstream&& rhs);
81
82 basic_ifstream& operator=(basic_ifstream&& rhs);
83 void swap(basic_ifstream& rhs);
84
85 basic_filebuf<char_type, traits_type>* rdbuf() const;
86 bool is_open() const;
87 void open(const char* s, ios_base::openmode mode = ios_base::in);
88 void open(const string& s, ios_base::openmode mode = ios_base::in);
89 void close();
90};
91
92template <class charT, class traits>
93 void
94 swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y);
95
96typedef basic_ifstream<char> ifstream;
97typedef basic_ifstream<wchar_t> wifstream;
98
99template <class charT, class traits = char_traits<charT> >
100class basic_ofstream
101 : public basic_ostream<charT,traits>
102{
103public:
104 typedef charT char_type;
105 typedef traits traits_type;
106 typedef typename traits_type::int_type int_type;
107 typedef typename traits_type::pos_type pos_type;
108 typedef typename traits_type::off_type off_type;
109
110 basic_ofstream();
111 explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
112 explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);
113 basic_ofstream(basic_ofstream&& rhs);
114
115 basic_ofstream& operator=(basic_ofstream&& rhs);
116 void swap(basic_ofstream& rhs);
117
118 basic_filebuf<char_type, traits_type>* rdbuf() const;
119 bool is_open() const;
120 void open(const char* s, ios_base::openmode mode = ios_base::out);
121 void open(const string& s, ios_base::openmode mode = ios_base::out);
122 void close();
123};
124
Howard Hinnant324bb032010-08-22 00:02:43 +0000125template <class charT, class traits>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000126 void
127 swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y);
128
129typedef basic_ofstream<char> ofstream;
130typedef basic_ofstream<wchar_t> wofstream;
131
132template <class charT, class traits=char_traits<charT> >
133class basic_fstream
134 : public basic_iostream<charT,traits>
135{
136public:
137 typedef charT char_type;
138 typedef traits traits_type;
139 typedef typename traits_type::int_type int_type;
140 typedef typename traits_type::pos_type pos_type;
141 typedef typename traits_type::off_type off_type;
142
143 basic_fstream();
144 explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
145 explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
146 basic_fstream(basic_fstream&& rhs);
147
148 basic_fstream& operator=(basic_fstream&& rhs);
149 void swap(basic_fstream& rhs);
150
151 basic_filebuf<char_type, traits_type>* rdbuf() const;
152 bool is_open() const;
153 void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
154 void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
155 void close();
156};
157
158template <class charT, class traits>
159 void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y);
160
161typedef basic_fstream<char> fstream;
162typedef basic_fstream<wchar_t> wfstream;
163
164} // std
165
166*/
167
168#include <__config>
169#include <ostream>
170#include <istream>
171#include <__locale>
172#include <cstdio>
173
Howard Hinnant66c6f972011-11-29 16:45:27 +0000174#include <__undef_min_max>
175
Howard Hinnant08e17472011-10-17 20:05:10 +0000176#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000177#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +0000178#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000179
180_LIBCPP_BEGIN_NAMESPACE_STD
181
182template <class _CharT, class _Traits>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000183class _LIBCPP_VISIBLE basic_filebuf
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000184 : public basic_streambuf<_CharT, _Traits>
185{
186public:
187 typedef _CharT char_type;
188 typedef _Traits traits_type;
189 typedef typename traits_type::int_type int_type;
190 typedef typename traits_type::pos_type pos_type;
191 typedef typename traits_type::off_type off_type;
192 typedef typename traits_type::state_type state_type;
193
194 // 27.9.1.2 Constructors/destructor:
195 basic_filebuf();
Howard Hinnant73d21a42010-09-04 23:28:19 +0000196#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000197 basic_filebuf(basic_filebuf&& __rhs);
198#endif
199 virtual ~basic_filebuf();
200
201 // 27.9.1.3 Assign/swap:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000202#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000203 basic_filebuf& operator=(basic_filebuf&& __rhs);
204#endif
205 void swap(basic_filebuf& __rhs);
206
207 // 27.9.1.4 Members:
208 bool is_open() const;
209 basic_filebuf* open(const char* __s, ios_base::openmode __mode);
210 basic_filebuf* open(const string& __s, ios_base::openmode __mode);
211 basic_filebuf* close();
212
213protected:
214 // 27.9.1.5 Overridden virtual functions:
215 virtual int_type underflow();
216 virtual int_type pbackfail(int_type __c = traits_type::eof());
217 virtual int_type overflow (int_type __c = traits_type::eof());
218 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n);
219 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
220 ios_base::openmode __wch = ios_base::in | ios_base::out);
221 virtual pos_type seekpos(pos_type __sp,
222 ios_base::openmode __wch = ios_base::in | ios_base::out);
223 virtual int sync();
224 virtual void imbue(const locale& __loc);
225
226private:
227 char* __extbuf_;
228 const char* __extbufnext_;
229 const char* __extbufend_;
230 char __extbuf_min_[8];
231 size_t __ebs_;
232 char_type* __intbuf_;
233 size_t __ibs_;
234 FILE* __file_;
235 const codecvt<char_type, char, state_type>* __cv_;
236 state_type __st_;
237 ios_base::openmode __om_;
238 ios_base::openmode __cm_;
239 bool __owns_eb_;
240 bool __owns_ib_;
241 bool __always_noconv_;
242
243 bool __read_mode();
244 void __write_mode();
245};
246
247template <class _CharT, class _Traits>
248basic_filebuf<_CharT, _Traits>::basic_filebuf()
249 : __extbuf_(0),
250 __extbufnext_(0),
251 __extbufend_(0),
252 __ebs_(0),
253 __intbuf_(0),
254 __ibs_(0),
255 __file_(0),
Howard Hinnant8540d4c2012-08-24 16:52:47 +0000256 __cv_(nullptr),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000257 __st_(),
258 __om_(0),
259 __cm_(0),
260 __owns_eb_(false),
261 __owns_ib_(false),
Howard Hinnant8540d4c2012-08-24 16:52:47 +0000262 __always_noconv_(false)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000263{
Howard Hinnant8540d4c2012-08-24 16:52:47 +0000264 if (has_facet<codecvt<char_type, char, state_type> >(this->getloc()))
265 {
266 __cv_ = &use_facet<codecvt<char_type, char, state_type> >(this->getloc());
267 __always_noconv_ = __cv_->always_noconv();
268 }
Howard Hinnante7d59f22012-08-24 18:06:47 +0000269 setbuf(0, 4096);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000270}
271
Howard Hinnant73d21a42010-09-04 23:28:19 +0000272#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000273
274template <class _CharT, class _Traits>
275basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs)
276 : basic_streambuf<_CharT, _Traits>(__rhs)
277{
278 if (__rhs.__extbuf_ == __rhs.__extbuf_min_)
279 {
280 __extbuf_ = __extbuf_min_;
281 __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);
282 __extbufend_ = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);
283 }
284 else
285 {
286 __extbuf_ = __rhs.__extbuf_;
287 __extbufnext_ = __rhs.__extbufnext_;
288 __extbufend_ = __rhs.__extbufend_;
289 }
290 __ebs_ = __rhs.__ebs_;
291 __intbuf_ = __rhs.__intbuf_;
292 __ibs_ = __rhs.__ibs_;
293 __file_ = __rhs.__file_;
294 __cv_ = __rhs.__cv_;
295 __st_ = __rhs.__st_;
296 __om_ = __rhs.__om_;
297 __cm_ = __rhs.__cm_;
298 __owns_eb_ = __rhs.__owns_eb_;
299 __owns_ib_ = __rhs.__owns_ib_;
300 __always_noconv_ = __rhs.__always_noconv_;
301 if (__rhs.pbase())
302 {
303 if (__rhs.pbase() == __rhs.__intbuf_)
304 this->setp(__intbuf_, __intbuf_ + (__rhs. epptr() - __rhs.pbase()));
305 else
306 this->setp((char_type*)__extbuf_,
307 (char_type*)__extbuf_ + (__rhs. epptr() - __rhs.pbase()));
308 this->pbump(__rhs. pptr() - __rhs.pbase());
309 }
310 else if (__rhs.eback())
311 {
312 if (__rhs.eback() == __rhs.__intbuf_)
313 this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()),
314 __intbuf_ + (__rhs.egptr() - __rhs.eback()));
315 else
316 this->setg((char_type*)__extbuf_,
317 (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),
318 (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));
319 }
320 __rhs.__extbuf_ = 0;
321 __rhs.__extbufnext_ = 0;
322 __rhs.__extbufend_ = 0;
323 __rhs.__ebs_ = 0;
324 __rhs.__intbuf_ = 0;
325 __rhs.__ibs_ = 0;
326 __rhs.__file_ = 0;
327 __rhs.__st_ = state_type();
328 __rhs.__om_ = 0;
329 __rhs.__cm_ = 0;
330 __rhs.__owns_eb_ = false;
331 __rhs.__owns_ib_ = false;
332 __rhs.setg(0, 0, 0);
333 __rhs.setp(0, 0);
334}
335
336template <class _CharT, class _Traits>
337inline _LIBCPP_INLINE_VISIBILITY
338basic_filebuf<_CharT, _Traits>&
339basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs)
340{
341 close();
342 swap(__rhs);
343}
344
Howard Hinnant73d21a42010-09-04 23:28:19 +0000345#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000346
347template <class _CharT, class _Traits>
348basic_filebuf<_CharT, _Traits>::~basic_filebuf()
349{
350#ifndef _LIBCPP_NO_EXCEPTIONS
351 try
352 {
Howard Hinnant324bb032010-08-22 00:02:43 +0000353#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000354 close();
355#ifndef _LIBCPP_NO_EXCEPTIONS
356 }
357 catch (...)
358 {
359 }
Howard Hinnant324bb032010-08-22 00:02:43 +0000360#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000361 if (__owns_eb_)
362 delete [] __extbuf_;
363 if (__owns_ib_)
364 delete [] __intbuf_;
365}
366
367template <class _CharT, class _Traits>
368void
369basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs)
370{
371 basic_streambuf<char_type, traits_type>::swap(__rhs);
372 if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)
373 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000374 _VSTD::swap(__extbuf_, __rhs.__extbuf_);
375 _VSTD::swap(__extbufnext_, __rhs.__extbufnext_);
376 _VSTD::swap(__extbufend_, __rhs.__extbufend_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000377 }
378 else
379 {
380 ptrdiff_t __ln = __extbufnext_ - __extbuf_;
381 ptrdiff_t __le = __extbufend_ - __extbuf_;
382 ptrdiff_t __rn = __rhs.__extbufnext_ - __rhs.__extbuf_;
383 ptrdiff_t __re = __rhs.__extbufend_ - __rhs.__extbuf_;
384 if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)
385 {
386 __extbuf_ = __rhs.__extbuf_;
387 __rhs.__extbuf_ = __rhs.__extbuf_min_;
388 }
389 else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_)
390 {
391 __rhs.__extbuf_ = __extbuf_;
392 __extbuf_ = __extbuf_min_;
393 }
394 __extbufnext_ = __extbuf_ + __rn;
395 __extbufend_ = __extbuf_ + __re;
396 __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;
397 __rhs.__extbufend_ = __rhs.__extbuf_ + __le;
398 }
Howard Hinnant0949eed2011-06-30 21:18:19 +0000399 _VSTD::swap(__ebs_, __rhs.__ebs_);
400 _VSTD::swap(__intbuf_, __rhs.__intbuf_);
401 _VSTD::swap(__ibs_, __rhs.__ibs_);
402 _VSTD::swap(__file_, __rhs.__file_);
403 _VSTD::swap(__cv_, __rhs.__cv_);
404 _VSTD::swap(__st_, __rhs.__st_);
405 _VSTD::swap(__om_, __rhs.__om_);
406 _VSTD::swap(__cm_, __rhs.__cm_);
407 _VSTD::swap(__owns_eb_, __rhs.__owns_eb_);
408 _VSTD::swap(__owns_ib_, __rhs.__owns_ib_);
409 _VSTD::swap(__always_noconv_, __rhs.__always_noconv_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000410 if (this->eback() == (char_type*)__rhs.__extbuf_min_)
411 {
412 ptrdiff_t __n = this->gptr() - this->eback();
413 ptrdiff_t __e = this->egptr() - this->eback();
414 this->setg((char_type*)__extbuf_min_,
415 (char_type*)__extbuf_min_ + __n,
416 (char_type*)__extbuf_min_ + __e);
417 }
418 else if (this->pbase() == (char_type*)__rhs.__extbuf_min_)
419 {
420 ptrdiff_t __n = this->pptr() - this->pbase();
421 ptrdiff_t __e = this->epptr() - this->pbase();
422 this->setp((char_type*)__extbuf_min_,
423 (char_type*)__extbuf_min_ + __e);
424 this->pbump(__n);
425 }
426 if (__rhs.eback() == (char_type*)__extbuf_min_)
427 {
428 ptrdiff_t __n = __rhs.gptr() - __rhs.eback();
429 ptrdiff_t __e = __rhs.egptr() - __rhs.eback();
430 __rhs.setg((char_type*)__rhs.__extbuf_min_,
431 (char_type*)__rhs.__extbuf_min_ + __n,
432 (char_type*)__rhs.__extbuf_min_ + __e);
433 }
434 else if (__rhs.pbase() == (char_type*)__extbuf_min_)
435 {
436 ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();
437 ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();
438 __rhs.setp((char_type*)__rhs.__extbuf_min_,
439 (char_type*)__rhs.__extbuf_min_ + __e);
440 __rhs.pbump(__n);
441 }
442}
443
444template <class _CharT, class _Traits>
445inline _LIBCPP_INLINE_VISIBILITY
446void
447swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y)
448{
449 __x.swap(__y);
450}
451
452template <class _CharT, class _Traits>
453inline _LIBCPP_INLINE_VISIBILITY
454bool
455basic_filebuf<_CharT, _Traits>::is_open() const
456{
457 return __file_ != 0;
458}
459
460template <class _CharT, class _Traits>
461basic_filebuf<_CharT, _Traits>*
462basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
463{
464 basic_filebuf<_CharT, _Traits>* __rt = 0;
465 if (__file_ == 0)
466 {
467 __rt = this;
468 const char* __mdstr;
469 switch (__mode & ~ios_base::ate)
470 {
471 case ios_base::out:
472 case ios_base::out | ios_base::trunc:
473 __mdstr = "w";
474 break;
475 case ios_base::out | ios_base::app:
476 case ios_base::app:
477 __mdstr = "a";
478 break;
479 case ios_base::in:
480 __mdstr = "r";
481 break;
482 case ios_base::in | ios_base::out:
483 __mdstr = "r+";
484 break;
485 case ios_base::in | ios_base::out | ios_base::trunc:
486 __mdstr = "w+";
487 break;
488 case ios_base::in | ios_base::out | ios_base::app:
489 case ios_base::in | ios_base::app:
490 __mdstr = "a+";
491 break;
492 case ios_base::out | ios_base::binary:
493 case ios_base::out | ios_base::trunc | ios_base::binary:
494 __mdstr = "wb";
495 break;
496 case ios_base::out | ios_base::app | ios_base::binary:
497 case ios_base::app | ios_base::binary:
498 __mdstr = "ab";
499 break;
500 case ios_base::in | ios_base::binary:
501 __mdstr = "rb";
502 break;
503 case ios_base::in | ios_base::out | ios_base::binary:
504 __mdstr = "r+b";
505 break;
506 case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
507 __mdstr = "w+b";
508 break;
509 case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
510 case ios_base::in | ios_base::app | ios_base::binary:
511 __mdstr = "a+b";
512 break;
513 default:
514 __rt = 0;
515 break;
516 }
517 if (__rt)
518 {
519 __file_ = fopen(__s, __mdstr);
520 if (__file_)
521 {
522 __om_ = __mode;
523 if (__mode & ios_base::ate)
524 {
525 if (fseek(__file_, 0, SEEK_END))
526 {
527 fclose(__file_);
528 __file_ = 0;
529 __rt = 0;
530 }
531 }
532 }
533 else
534 __rt = 0;
535 }
536 }
537 return __rt;
538}
539
540template <class _CharT, class _Traits>
541inline _LIBCPP_INLINE_VISIBILITY
542basic_filebuf<_CharT, _Traits>*
543basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
544{
545 return open(__s.c_str(), __mode);
546}
547
548template <class _CharT, class _Traits>
549basic_filebuf<_CharT, _Traits>*
550basic_filebuf<_CharT, _Traits>::close()
551{
552 basic_filebuf<_CharT, _Traits>* __rt = 0;
553 if (__file_)
554 {
555 __rt = this;
556 unique_ptr<FILE, int(*)(FILE*)> __h(__file_, fclose);
Howard Hinnante1a7b042012-01-12 23:37:51 +0000557 if (sync())
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000558 __rt = 0;
559 if (fclose(__h.release()) == 0)
560 __file_ = 0;
561 else
562 __rt = 0;
563 }
564 return __rt;
565}
566
567template <class _CharT, class _Traits>
568typename basic_filebuf<_CharT, _Traits>::int_type
569basic_filebuf<_CharT, _Traits>::underflow()
570{
571 if (__file_ == 0)
572 return traits_type::eof();
573 bool __initial = __read_mode();
574 char_type __1buf;
575 if (this->gptr() == 0)
576 this->setg(&__1buf, &__1buf+1, &__1buf+1);
577 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
578 int_type __c = traits_type::eof();
579 if (this->gptr() == this->egptr())
580 {
581 memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
582 if (__always_noconv_)
583 {
584 size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
585 __nmemb = fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
586 if (__nmemb != 0)
587 {
588 this->setg(this->eback(),
589 this->eback() + __unget_sz,
590 this->eback() + __unget_sz + __nmemb);
Howard Hinnant47a7cce2011-02-02 17:37:16 +0000591 __c = traits_type::to_int_type(*this->gptr());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000592 }
593 }
594 else
595 {
596 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
597 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
598 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
Howard Hinnantec423cb2012-08-24 20:37:00 +0000599 size_t __nmemb = _VSTD::min(static_cast<size_t>(__ibs_ - __unget_sz),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000600 static_cast<size_t>(__extbufend_ - __extbufnext_));
601 codecvt_base::result __r;
602 state_type __svs = __st_;
603 size_t __nr = fread((void*)__extbufnext_, 1, __nmemb, __file_);
604 if (__nr != 0)
605 {
Howard Hinnant8540d4c2012-08-24 16:52:47 +0000606#ifndef _LIBCPP_NO_EXCEPTIONS
607 if (!__cv_)
608 throw bad_cast();
609#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000610 __extbufend_ = __extbufnext_ + __nr;
611 char_type* __inext;
612 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
613 this->eback() + __unget_sz,
Howard Hinnantec423cb2012-08-24 20:37:00 +0000614 this->eback() + __ibs_, __inext);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000615 if (__r == codecvt_base::noconv)
616 {
617 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
Howard Hinnant47a7cce2011-02-02 17:37:16 +0000618 __c = traits_type::to_int_type(*this->gptr());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000619 }
620 else if (__inext != this->eback() + __unget_sz)
621 {
622 this->setg(this->eback(), this->eback() + __unget_sz, __inext);
Howard Hinnant47a7cce2011-02-02 17:37:16 +0000623 __c = traits_type::to_int_type(*this->gptr());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000624 }
625 }
626 }
627 }
628 else
Howard Hinnant47a7cce2011-02-02 17:37:16 +0000629 __c = traits_type::to_int_type(*this->gptr());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000630 if (this->eback() == &__1buf)
631 this->setg(0, 0, 0);
632 return __c;
633}
634
635template <class _CharT, class _Traits>
636typename basic_filebuf<_CharT, _Traits>::int_type
637basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c)
638{
639 if (__file_ && this->eback() < this->gptr())
640 {
641 if (traits_type::eq_int_type(__c, traits_type::eof()))
642 {
643 this->gbump(-1);
644 return traits_type::not_eof(__c);
645 }
646 if ((__om_ & ios_base::out) ||
647 traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
648 {
649 this->gbump(-1);
650 *this->gptr() = traits_type::to_char_type(__c);
651 return __c;
652 }
653 }
654 return traits_type::eof();
655}
656
657template <class _CharT, class _Traits>
658typename basic_filebuf<_CharT, _Traits>::int_type
659basic_filebuf<_CharT, _Traits>::overflow(int_type __c)
660{
661 if (__file_ == 0)
662 return traits_type::eof();
663 __write_mode();
664 char_type __1buf;
665 char_type* __pb_save = this->pbase();
666 char_type* __epb_save = this->epptr();
667 if (!traits_type::eq_int_type(__c, traits_type::eof()))
668 {
669 if (this->pptr() == 0)
670 this->setp(&__1buf, &__1buf+1);
671 *this->pptr() = traits_type::to_char_type(__c);
672 this->pbump(1);
673 }
674 if (this->pptr() != this->pbase())
675 {
676 if (__always_noconv_)
677 {
678 size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
679 if (fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
680 return traits_type::eof();
681 }
682 else
683 {
684 char* __extbe = __extbuf_;
685 codecvt_base::result __r;
686 do
687 {
Howard Hinnant8540d4c2012-08-24 16:52:47 +0000688#ifndef _LIBCPP_NO_EXCEPTIONS
689 if (!__cv_)
690 throw bad_cast();
691#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000692 const char_type* __e;
693 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
694 __extbuf_, __extbuf_ + __ebs_, __extbe);
695 if (__e == this->pbase())
696 return traits_type::eof();
697 if (__r == codecvt_base::noconv)
698 {
699 size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
700 if (fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
701 return traits_type::eof();
702 }
703 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
704 {
705 size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
706 if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
707 return traits_type::eof();
708 if (__r == codecvt_base::partial)
709 {
710 this->setp((char_type*)__e, this->pptr());
711 this->pbump(this->epptr() - this->pbase());
712 }
713 }
714 else
715 return traits_type::eof();
716 } while (__r == codecvt_base::partial);
717 }
718 this->setp(__pb_save, __epb_save);
719 }
720 return traits_type::not_eof(__c);
721}
722
723template <class _CharT, class _Traits>
724basic_streambuf<_CharT, _Traits>*
725basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n)
726{
727 this->setg(0, 0, 0);
728 this->setp(0, 0);
729 if (__owns_eb_)
730 delete [] __extbuf_;
731 if (__owns_ib_)
732 delete [] __intbuf_;
733 __ebs_ = __n;
734 if (__ebs_ > sizeof(__extbuf_min_))
735 {
736 if (__always_noconv_ && __s)
737 {
738 __extbuf_ = (char*)__s;
739 __owns_eb_ = false;
740 }
741 else
742 {
743 __extbuf_ = new char[__ebs_];
744 __owns_eb_ = true;
745 }
746 }
747 else
748 {
749 __extbuf_ = __extbuf_min_;
750 __ebs_ = sizeof(__extbuf_min_);
751 __owns_eb_ = false;
752 }
753 if (!__always_noconv_)
754 {
755 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
756 if (__s && __ibs_ >= sizeof(__extbuf_min_))
757 {
758 __intbuf_ = __s;
759 __owns_ib_ = false;
760 }
761 else
762 {
763 __intbuf_ = new char_type[__ibs_];
764 __owns_ib_ = true;
765 }
766 }
767 else
768 {
769 __ibs_ = 0;
770 __intbuf_ = 0;
771 __owns_ib_ = false;
772 }
773 return this;
774}
775
776template <class _CharT, class _Traits>
777typename basic_filebuf<_CharT, _Traits>::pos_type
778basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way,
779 ios_base::openmode)
780{
Howard Hinnant8540d4c2012-08-24 16:52:47 +0000781#ifndef _LIBCPP_NO_EXCEPTIONS
782 if (!__cv_)
783 throw bad_cast();
784#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000785 int __width = __cv_->encoding();
786 if (__file_ == 0 || (__width <= 0 && __off != 0) || sync())
787 return pos_type(off_type(-1));
788 // __width > 0 || __off == 0
789 int __whence;
790 switch (__way)
791 {
792 case ios_base::beg:
793 __whence = SEEK_SET;
794 break;
795 case ios_base::cur:
796 __whence = SEEK_CUR;
797 break;
798 case ios_base::end:
799 __whence = SEEK_END;
800 break;
801 default:
802 return pos_type(off_type(-1));
803 }
804 if (fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
805 return pos_type(off_type(-1));
806 pos_type __r = ftello(__file_);
807 __r.state(__st_);
808 return __r;
809}
810
811template <class _CharT, class _Traits>
812typename basic_filebuf<_CharT, _Traits>::pos_type
Howard Hinnant639a6682010-07-15 18:18:07 +0000813basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000814{
815 if (__file_ == 0 || sync())
816 return pos_type(off_type(-1));
817 if (fseeko(__file_, __sp, SEEK_SET))
818 return pos_type(off_type(-1));
Howard Hinnantec423cb2012-08-24 20:37:00 +0000819 __st_ = __sp.state;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000820 return __sp;
821}
822
823template <class _CharT, class _Traits>
824int
825basic_filebuf<_CharT, _Traits>::sync()
826{
827 if (__file_ == 0)
828 return 0;
Howard Hinnant8540d4c2012-08-24 16:52:47 +0000829#ifndef _LIBCPP_NO_EXCEPTIONS
830 if (!__cv_)
831 throw bad_cast();
832#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000833 if (__cm_ & ios_base::out)
834 {
835 if (this->pptr() != this->pbase())
836 if (overflow() == traits_type::eof())
837 return -1;
838 codecvt_base::result __r;
839 do
840 {
841 char* __extbe;
842 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
843 size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
844 if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
845 return -1;
846 } while (__r == codecvt_base::partial);
847 if (__r == codecvt_base::error)
848 return -1;
849 if (fflush(__file_))
850 return -1;
851 }
852 else if (__cm_ & ios_base::in)
853 {
854 off_type __c;
855 if (__always_noconv_)
856 __c = this->egptr() - this->gptr();
857 else
858 {
859 int __width = __cv_->encoding();
860 __c = __extbufend_ - __extbufnext_;
861 if (__width > 0)
862 __c += __width * (this->egptr() - this->gptr());
863 else
864 {
865 if (this->gptr() != this->egptr())
866 {
867 reverse(this->gptr(), this->egptr());
868 codecvt_base::result __r;
869 const char_type* __e = this->gptr();
870 char* __extbe;
871 do
872 {
873 __r = __cv_->out(__st_, __e, this->egptr(), __e,
874 __extbuf_, __extbuf_ + __ebs_, __extbe);
875 switch (__r)
876 {
877 case codecvt_base::noconv:
878 __c += this->egptr() - this->gptr();
879 break;
880 case codecvt_base::ok:
881 case codecvt_base::partial:
882 __c += __extbe - __extbuf_;
883 break;
884 default:
885 return -1;
886 }
887 } while (__r == codecvt_base::partial);
888 }
889 }
890 }
891 if (fseeko(__file_, -__c, SEEK_CUR))
892 return -1;
893 this->setg(0, 0, 0);
894 __cm_ = 0;
895 }
896 return 0;
897}
898
899template <class _CharT, class _Traits>
900void
901basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc)
902{
903 sync();
904 __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
905 bool __old_anc = __always_noconv_;
906 __always_noconv_ = __cv_->always_noconv();
907 if (__old_anc != __always_noconv_)
908 {
909 this->setg(0, 0, 0);
910 this->setp(0, 0);
911 // invariant, char_type is char, else we couldn't get here
912 if (__always_noconv_) // need to dump __intbuf_
913 {
914 if (__owns_eb_)
915 delete [] __extbuf_;
916 __owns_eb_ = __owns_ib_;
917 __ebs_ = __ibs_;
918 __extbuf_ = (char*)__intbuf_;
919 __ibs_ = 0;
920 __intbuf_ = 0;
921 __owns_ib_ = false;
922 }
923 else // need to obtain an __intbuf_.
924 { // If __extbuf_ is user-supplied, use it, else new __intbuf_
925 if (!__owns_eb_ && __extbuf_ != __extbuf_min_)
926 {
927 __ibs_ = __ebs_;
928 __intbuf_ = (char_type*)__extbuf_;
929 __owns_ib_ = false;
930 __extbuf_ = new char[__ebs_];
931 __owns_eb_ = true;
932 }
933 else
934 {
935 __ibs_ = __ebs_;
936 __intbuf_ = new char_type[__ibs_];
937 __owns_ib_ = true;
938 }
939 }
940 }
941}
942
943template <class _CharT, class _Traits>
944bool
945basic_filebuf<_CharT, _Traits>::__read_mode()
946{
947 if (!(__cm_ & ios_base::in))
948 {
949 this->setp(0, 0);
950 if (__always_noconv_)
951 this->setg((char_type*)__extbuf_,
952 (char_type*)__extbuf_ + __ebs_,
953 (char_type*)__extbuf_ + __ebs_);
954 else
955 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
956 __cm_ = ios_base::in;
957 return true;
958 }
959 return false;
960}
961
962template <class _CharT, class _Traits>
963void
964basic_filebuf<_CharT, _Traits>::__write_mode()
965{
966 if (!(__cm_ & ios_base::out))
967 {
968 this->setg(0, 0, 0);
969 if (__ebs_ > sizeof(__extbuf_min_))
970 {
971 if (__always_noconv_)
972 this->setp((char_type*)__extbuf_,
973 (char_type*)__extbuf_ + (__ebs_ - 1));
974 else
975 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
976 }
977 else
978 this->setp(0, 0);
979 __cm_ = ios_base::out;
980 }
981}
982
983// basic_ifstream
984
985template <class _CharT, class _Traits>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000986class _LIBCPP_VISIBLE basic_ifstream
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000987 : public basic_istream<_CharT, _Traits>
988{
989public:
990 typedef _CharT char_type;
991 typedef _Traits traits_type;
992 typedef typename traits_type::int_type int_type;
993 typedef typename traits_type::pos_type pos_type;
994 typedef typename traits_type::off_type off_type;
995
996 basic_ifstream();
997 explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
998 explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000999#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001000 basic_ifstream(basic_ifstream&& __rhs);
1001#endif
1002
Howard Hinnant73d21a42010-09-04 23:28:19 +00001003#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001004 basic_ifstream& operator=(basic_ifstream&& __rhs);
1005#endif
1006 void swap(basic_ifstream& __rhs);
1007
1008 basic_filebuf<char_type, traits_type>* rdbuf() const;
1009 bool is_open() const;
1010 void open(const char* __s, ios_base::openmode __mode = ios_base::in);
1011 void open(const string& __s, ios_base::openmode __mode = ios_base::in);
1012 void close();
1013
1014private:
1015 basic_filebuf<char_type, traits_type> __sb_;
1016};
1017
1018template <class _CharT, class _Traits>
1019inline _LIBCPP_INLINE_VISIBILITY
1020basic_ifstream<_CharT, _Traits>::basic_ifstream()
1021 : basic_istream<char_type, traits_type>(&__sb_)
1022{
1023}
1024
1025template <class _CharT, class _Traits>
1026inline _LIBCPP_INLINE_VISIBILITY
1027basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
1028 : basic_istream<char_type, traits_type>(&__sb_)
1029{
1030 if (__sb_.open(__s, __mode | ios_base::in) == 0)
1031 this->setstate(ios_base::failbit);
1032}
1033
1034template <class _CharT, class _Traits>
1035inline _LIBCPP_INLINE_VISIBILITY
1036basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)
1037 : basic_istream<char_type, traits_type>(&__sb_)
1038{
1039 if (__sb_.open(__s, __mode | ios_base::in) == 0)
1040 this->setstate(ios_base::failbit);
1041}
1042
Howard Hinnant73d21a42010-09-04 23:28:19 +00001043#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001044
1045template <class _CharT, class _Traits>
1046inline _LIBCPP_INLINE_VISIBILITY
1047basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001048 : basic_istream<char_type, traits_type>(_VSTD::move(__rhs)),
1049 __sb_(_VSTD::move(__rhs.__sb_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001050{
1051 this->set_rdbuf(&__sb_);
1052}
1053
1054template <class _CharT, class _Traits>
1055inline _LIBCPP_INLINE_VISIBILITY
1056basic_ifstream<_CharT, _Traits>&
1057basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs)
1058{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001059 basic_istream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
1060 __sb_ = _VSTD::move(__rhs.__sb_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001061 return *this;
1062}
1063
Howard Hinnant73d21a42010-09-04 23:28:19 +00001064#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001065
1066template <class _CharT, class _Traits>
1067inline _LIBCPP_INLINE_VISIBILITY
1068void
1069basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs)
1070{
1071 basic_istream<char_type, traits_type>::swap(__rhs);
1072 __sb_.swap(__rhs.__sb_);
1073}
1074
1075template <class _CharT, class _Traits>
1076inline _LIBCPP_INLINE_VISIBILITY
1077void
1078swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y)
1079{
1080 __x.swap(__y);
1081}
1082
1083template <class _CharT, class _Traits>
1084inline _LIBCPP_INLINE_VISIBILITY
1085basic_filebuf<_CharT, _Traits>*
1086basic_ifstream<_CharT, _Traits>::rdbuf() const
1087{
1088 return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
1089}
1090
1091template <class _CharT, class _Traits>
1092inline _LIBCPP_INLINE_VISIBILITY
1093bool
1094basic_ifstream<_CharT, _Traits>::is_open() const
1095{
1096 return __sb_.is_open();
1097}
1098
1099template <class _CharT, class _Traits>
1100void
1101basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
1102{
1103 if (__sb_.open(__s, __mode | ios_base::in))
1104 this->clear();
1105 else
1106 this->setstate(ios_base::failbit);
1107}
1108
1109template <class _CharT, class _Traits>
1110void
1111basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
1112{
1113 if (__sb_.open(__s, __mode | ios_base::in))
1114 this->clear();
1115 else
1116 this->setstate(ios_base::failbit);
1117}
1118
1119template <class _CharT, class _Traits>
1120inline _LIBCPP_INLINE_VISIBILITY
1121void
1122basic_ifstream<_CharT, _Traits>::close()
1123{
1124 if (__sb_.close() == 0)
1125 this->setstate(ios_base::failbit);
1126}
1127
1128// basic_ofstream
1129
1130template <class _CharT, class _Traits>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001131class _LIBCPP_VISIBLE basic_ofstream
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001132 : public basic_ostream<_CharT, _Traits>
1133{
1134public:
1135 typedef _CharT char_type;
1136 typedef _Traits traits_type;
1137 typedef typename traits_type::int_type int_type;
1138 typedef typename traits_type::pos_type pos_type;
1139 typedef typename traits_type::off_type off_type;
1140
1141 basic_ofstream();
1142 explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
1143 explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001144#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001145 basic_ofstream(basic_ofstream&& __rhs);
1146#endif
1147
Howard Hinnant73d21a42010-09-04 23:28:19 +00001148#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001149 basic_ofstream& operator=(basic_ofstream&& __rhs);
1150#endif
1151 void swap(basic_ofstream& __rhs);
1152
1153 basic_filebuf<char_type, traits_type>* rdbuf() const;
1154 bool is_open() const;
1155 void open(const char* __s, ios_base::openmode __mode = ios_base::out);
1156 void open(const string& __s, ios_base::openmode __mode = ios_base::out);
1157 void close();
1158
1159private:
1160 basic_filebuf<char_type, traits_type> __sb_;
1161};
1162
1163template <class _CharT, class _Traits>
1164inline _LIBCPP_INLINE_VISIBILITY
1165basic_ofstream<_CharT, _Traits>::basic_ofstream()
1166 : basic_ostream<char_type, traits_type>(&__sb_)
1167{
1168}
1169
1170template <class _CharT, class _Traits>
1171inline _LIBCPP_INLINE_VISIBILITY
1172basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
1173 : basic_ostream<char_type, traits_type>(&__sb_)
1174{
1175 if (__sb_.open(__s, __mode | ios_base::out) == 0)
1176 this->setstate(ios_base::failbit);
1177}
1178
1179template <class _CharT, class _Traits>
1180inline _LIBCPP_INLINE_VISIBILITY
1181basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)
1182 : basic_ostream<char_type, traits_type>(&__sb_)
1183{
1184 if (__sb_.open(__s, __mode | ios_base::out) == 0)
1185 this->setstate(ios_base::failbit);
1186}
1187
Howard Hinnant73d21a42010-09-04 23:28:19 +00001188#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001189
1190template <class _CharT, class _Traits>
1191inline _LIBCPP_INLINE_VISIBILITY
1192basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001193 : basic_ostream<char_type, traits_type>(_VSTD::move(__rhs)),
1194 __sb_(_VSTD::move(__rhs.__sb_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001195{
1196 this->set_rdbuf(&__sb_);
1197}
1198
1199template <class _CharT, class _Traits>
1200inline _LIBCPP_INLINE_VISIBILITY
1201basic_ofstream<_CharT, _Traits>&
1202basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs)
1203{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001204 basic_ostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
1205 __sb_ = _VSTD::move(__rhs.__sb_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001206 return *this;
1207}
1208
Howard Hinnant73d21a42010-09-04 23:28:19 +00001209#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001210
1211template <class _CharT, class _Traits>
1212inline _LIBCPP_INLINE_VISIBILITY
1213void
1214basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs)
1215{
1216 basic_ostream<char_type, traits_type>::swap(__rhs);
1217 __sb_.swap(__rhs.__sb_);
1218}
1219
1220template <class _CharT, class _Traits>
1221inline _LIBCPP_INLINE_VISIBILITY
1222void
1223swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y)
1224{
1225 __x.swap(__y);
1226}
1227
1228template <class _CharT, class _Traits>
1229inline _LIBCPP_INLINE_VISIBILITY
1230basic_filebuf<_CharT, _Traits>*
1231basic_ofstream<_CharT, _Traits>::rdbuf() const
1232{
1233 return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
1234}
1235
1236template <class _CharT, class _Traits>
1237inline _LIBCPP_INLINE_VISIBILITY
1238bool
1239basic_ofstream<_CharT, _Traits>::is_open() const
1240{
1241 return __sb_.is_open();
1242}
1243
1244template <class _CharT, class _Traits>
1245void
1246basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
1247{
1248 if (__sb_.open(__s, __mode | ios_base::out))
1249 this->clear();
1250 else
1251 this->setstate(ios_base::failbit);
1252}
1253
1254template <class _CharT, class _Traits>
1255void
1256basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
1257{
1258 if (__sb_.open(__s, __mode | ios_base::out))
1259 this->clear();
1260 else
1261 this->setstate(ios_base::failbit);
1262}
1263
1264template <class _CharT, class _Traits>
1265inline _LIBCPP_INLINE_VISIBILITY
1266void
1267basic_ofstream<_CharT, _Traits>::close()
1268{
1269 if (__sb_.close() == 0)
1270 this->setstate(ios_base::failbit);
1271}
1272
1273// basic_fstream
1274
1275template <class _CharT, class _Traits>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001276class _LIBCPP_VISIBLE basic_fstream
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001277 : public basic_iostream<_CharT, _Traits>
1278{
1279public:
1280 typedef _CharT char_type;
1281 typedef _Traits traits_type;
1282 typedef typename traits_type::int_type int_type;
1283 typedef typename traits_type::pos_type pos_type;
1284 typedef typename traits_type::off_type off_type;
1285
1286 basic_fstream();
1287 explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1288 explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001289#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001290 basic_fstream(basic_fstream&& __rhs);
1291#endif
1292
Howard Hinnant73d21a42010-09-04 23:28:19 +00001293#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001294 basic_fstream& operator=(basic_fstream&& __rhs);
1295#endif
1296 void swap(basic_fstream& __rhs);
1297
1298 basic_filebuf<char_type, traits_type>* rdbuf() const;
1299 bool is_open() const;
1300 void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1301 void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1302 void close();
1303
1304private:
1305 basic_filebuf<char_type, traits_type> __sb_;
1306};
1307
1308template <class _CharT, class _Traits>
1309inline _LIBCPP_INLINE_VISIBILITY
1310basic_fstream<_CharT, _Traits>::basic_fstream()
1311 : basic_iostream<char_type, traits_type>(&__sb_)
1312{
1313}
1314
1315template <class _CharT, class _Traits>
1316inline _LIBCPP_INLINE_VISIBILITY
1317basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
1318 : basic_iostream<char_type, traits_type>(&__sb_)
1319{
1320 if (__sb_.open(__s, __mode) == 0)
1321 this->setstate(ios_base::failbit);
1322}
1323
1324template <class _CharT, class _Traits>
1325inline _LIBCPP_INLINE_VISIBILITY
1326basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)
1327 : basic_iostream<char_type, traits_type>(&__sb_)
1328{
1329 if (__sb_.open(__s, __mode) == 0)
1330 this->setstate(ios_base::failbit);
1331}
1332
Howard Hinnant73d21a42010-09-04 23:28:19 +00001333#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001334
1335template <class _CharT, class _Traits>
1336inline _LIBCPP_INLINE_VISIBILITY
1337basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
Howard Hinnant0949eed2011-06-30 21:18:19 +00001338 : basic_iostream<char_type, traits_type>(_VSTD::move(__rhs)),
1339 __sb_(_VSTD::move(__rhs.__sb_))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001340{
1341 this->set_rdbuf(&__sb_);
1342}
1343
1344template <class _CharT, class _Traits>
1345inline _LIBCPP_INLINE_VISIBILITY
1346basic_fstream<_CharT, _Traits>&
1347basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs)
1348{
Howard Hinnant0949eed2011-06-30 21:18:19 +00001349 basic_iostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
1350 __sb_ = _VSTD::move(__rhs.__sb_);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001351 return *this;
1352}
1353
Howard Hinnant73d21a42010-09-04 23:28:19 +00001354#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001355
1356template <class _CharT, class _Traits>
1357inline _LIBCPP_INLINE_VISIBILITY
1358void
1359basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs)
1360{
1361 basic_iostream<char_type, traits_type>::swap(__rhs);
1362 __sb_.swap(__rhs.__sb_);
1363}
1364
1365template <class _CharT, class _Traits>
1366inline _LIBCPP_INLINE_VISIBILITY
1367void
1368swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y)
1369{
1370 __x.swap(__y);
1371}
1372
1373template <class _CharT, class _Traits>
1374inline _LIBCPP_INLINE_VISIBILITY
1375basic_filebuf<_CharT, _Traits>*
1376basic_fstream<_CharT, _Traits>::rdbuf() const
1377{
1378 return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
1379}
1380
1381template <class _CharT, class _Traits>
1382inline _LIBCPP_INLINE_VISIBILITY
1383bool
1384basic_fstream<_CharT, _Traits>::is_open() const
1385{
1386 return __sb_.is_open();
1387}
1388
1389template <class _CharT, class _Traits>
1390void
1391basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
1392{
1393 if (__sb_.open(__s, __mode))
1394 this->clear();
1395 else
1396 this->setstate(ios_base::failbit);
1397}
1398
1399template <class _CharT, class _Traits>
1400void
1401basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
1402{
1403 if (__sb_.open(__s, __mode))
1404 this->clear();
1405 else
1406 this->setstate(ios_base::failbit);
1407}
1408
1409template <class _CharT, class _Traits>
1410inline _LIBCPP_INLINE_VISIBILITY
1411void
1412basic_fstream<_CharT, _Traits>::close()
1413{
1414 if (__sb_.close() == 0)
1415 this->setstate(ios_base::failbit);
1416}
1417
1418_LIBCPP_END_NAMESPACE_STD
1419
1420#endif // _LIBCPP_FSTREAM