blob: ea9aee6737bf6cf5c5acba708dbd9e154610db79 [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
174#pragma GCC system_header
175
176_LIBCPP_BEGIN_NAMESPACE_STD
177
178template <class _CharT, class _Traits>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000179class _LIBCPP_VISIBLE basic_filebuf
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000180 : public basic_streambuf<_CharT, _Traits>
181{
182public:
183 typedef _CharT char_type;
184 typedef _Traits traits_type;
185 typedef typename traits_type::int_type int_type;
186 typedef typename traits_type::pos_type pos_type;
187 typedef typename traits_type::off_type off_type;
188 typedef typename traits_type::state_type state_type;
189
190 // 27.9.1.2 Constructors/destructor:
191 basic_filebuf();
Howard Hinnant73d21a42010-09-04 23:28:19 +0000192#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000193 basic_filebuf(basic_filebuf&& __rhs);
194#endif
195 virtual ~basic_filebuf();
196
197 // 27.9.1.3 Assign/swap:
Howard Hinnant73d21a42010-09-04 23:28:19 +0000198#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000199 basic_filebuf& operator=(basic_filebuf&& __rhs);
200#endif
201 void swap(basic_filebuf& __rhs);
202
203 // 27.9.1.4 Members:
204 bool is_open() const;
205 basic_filebuf* open(const char* __s, ios_base::openmode __mode);
206 basic_filebuf* open(const string& __s, ios_base::openmode __mode);
207 basic_filebuf* close();
208
209protected:
210 // 27.9.1.5 Overridden virtual functions:
211 virtual int_type underflow();
212 virtual int_type pbackfail(int_type __c = traits_type::eof());
213 virtual int_type overflow (int_type __c = traits_type::eof());
214 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n);
215 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
216 ios_base::openmode __wch = ios_base::in | ios_base::out);
217 virtual pos_type seekpos(pos_type __sp,
218 ios_base::openmode __wch = ios_base::in | ios_base::out);
219 virtual int sync();
220 virtual void imbue(const locale& __loc);
221
222private:
223 char* __extbuf_;
224 const char* __extbufnext_;
225 const char* __extbufend_;
226 char __extbuf_min_[8];
227 size_t __ebs_;
228 char_type* __intbuf_;
229 size_t __ibs_;
230 FILE* __file_;
231 const codecvt<char_type, char, state_type>* __cv_;
232 state_type __st_;
233 ios_base::openmode __om_;
234 ios_base::openmode __cm_;
235 bool __owns_eb_;
236 bool __owns_ib_;
237 bool __always_noconv_;
238
239 bool __read_mode();
240 void __write_mode();
241};
242
243template <class _CharT, class _Traits>
244basic_filebuf<_CharT, _Traits>::basic_filebuf()
245 : __extbuf_(0),
246 __extbufnext_(0),
247 __extbufend_(0),
248 __ebs_(0),
249 __intbuf_(0),
250 __ibs_(0),
251 __file_(0),
252 __cv_(&use_facet<codecvt<char_type, char, state_type> >(this->getloc())),
253 __st_(),
254 __om_(0),
255 __cm_(0),
256 __owns_eb_(false),
257 __owns_ib_(false),
258 __always_noconv_(__cv_->always_noconv())
259{
260 setbuf(0, 4096);
261}
262
Howard Hinnant73d21a42010-09-04 23:28:19 +0000263#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000264
265template <class _CharT, class _Traits>
266basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs)
267 : basic_streambuf<_CharT, _Traits>(__rhs)
268{
269 if (__rhs.__extbuf_ == __rhs.__extbuf_min_)
270 {
271 __extbuf_ = __extbuf_min_;
272 __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);
273 __extbufend_ = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);
274 }
275 else
276 {
277 __extbuf_ = __rhs.__extbuf_;
278 __extbufnext_ = __rhs.__extbufnext_;
279 __extbufend_ = __rhs.__extbufend_;
280 }
281 __ebs_ = __rhs.__ebs_;
282 __intbuf_ = __rhs.__intbuf_;
283 __ibs_ = __rhs.__ibs_;
284 __file_ = __rhs.__file_;
285 __cv_ = __rhs.__cv_;
286 __st_ = __rhs.__st_;
287 __om_ = __rhs.__om_;
288 __cm_ = __rhs.__cm_;
289 __owns_eb_ = __rhs.__owns_eb_;
290 __owns_ib_ = __rhs.__owns_ib_;
291 __always_noconv_ = __rhs.__always_noconv_;
292 if (__rhs.pbase())
293 {
294 if (__rhs.pbase() == __rhs.__intbuf_)
295 this->setp(__intbuf_, __intbuf_ + (__rhs. epptr() - __rhs.pbase()));
296 else
297 this->setp((char_type*)__extbuf_,
298 (char_type*)__extbuf_ + (__rhs. epptr() - __rhs.pbase()));
299 this->pbump(__rhs. pptr() - __rhs.pbase());
300 }
301 else if (__rhs.eback())
302 {
303 if (__rhs.eback() == __rhs.__intbuf_)
304 this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()),
305 __intbuf_ + (__rhs.egptr() - __rhs.eback()));
306 else
307 this->setg((char_type*)__extbuf_,
308 (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),
309 (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));
310 }
311 __rhs.__extbuf_ = 0;
312 __rhs.__extbufnext_ = 0;
313 __rhs.__extbufend_ = 0;
314 __rhs.__ebs_ = 0;
315 __rhs.__intbuf_ = 0;
316 __rhs.__ibs_ = 0;
317 __rhs.__file_ = 0;
318 __rhs.__st_ = state_type();
319 __rhs.__om_ = 0;
320 __rhs.__cm_ = 0;
321 __rhs.__owns_eb_ = false;
322 __rhs.__owns_ib_ = false;
323 __rhs.setg(0, 0, 0);
324 __rhs.setp(0, 0);
325}
326
327template <class _CharT, class _Traits>
328inline _LIBCPP_INLINE_VISIBILITY
329basic_filebuf<_CharT, _Traits>&
330basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs)
331{
332 close();
333 swap(__rhs);
334}
335
Howard Hinnant73d21a42010-09-04 23:28:19 +0000336#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000337
338template <class _CharT, class _Traits>
339basic_filebuf<_CharT, _Traits>::~basic_filebuf()
340{
341#ifndef _LIBCPP_NO_EXCEPTIONS
342 try
343 {
Howard Hinnant324bb032010-08-22 00:02:43 +0000344#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000345 close();
346#ifndef _LIBCPP_NO_EXCEPTIONS
347 }
348 catch (...)
349 {
350 }
Howard Hinnant324bb032010-08-22 00:02:43 +0000351#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000352 if (__owns_eb_)
353 delete [] __extbuf_;
354 if (__owns_ib_)
355 delete [] __intbuf_;
356}
357
358template <class _CharT, class _Traits>
359void
360basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs)
361{
362 basic_streambuf<char_type, traits_type>::swap(__rhs);
363 if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)
364 {
365 _STD::swap(__extbuf_, __rhs.__extbuf_);
366 _STD::swap(__extbufnext_, __rhs.__extbufnext_);
367 _STD::swap(__extbufend_, __rhs.__extbufend_);
368 }
369 else
370 {
371 ptrdiff_t __ln = __extbufnext_ - __extbuf_;
372 ptrdiff_t __le = __extbufend_ - __extbuf_;
373 ptrdiff_t __rn = __rhs.__extbufnext_ - __rhs.__extbuf_;
374 ptrdiff_t __re = __rhs.__extbufend_ - __rhs.__extbuf_;
375 if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)
376 {
377 __extbuf_ = __rhs.__extbuf_;
378 __rhs.__extbuf_ = __rhs.__extbuf_min_;
379 }
380 else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_)
381 {
382 __rhs.__extbuf_ = __extbuf_;
383 __extbuf_ = __extbuf_min_;
384 }
385 __extbufnext_ = __extbuf_ + __rn;
386 __extbufend_ = __extbuf_ + __re;
387 __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;
388 __rhs.__extbufend_ = __rhs.__extbuf_ + __le;
389 }
390 _STD::swap(__ebs_, __rhs.__ebs_);
391 _STD::swap(__intbuf_, __rhs.__intbuf_);
392 _STD::swap(__ibs_, __rhs.__ibs_);
393 _STD::swap(__file_, __rhs.__file_);
394 _STD::swap(__cv_, __rhs.__cv_);
395 _STD::swap(__st_, __rhs.__st_);
396 _STD::swap(__om_, __rhs.__om_);
397 _STD::swap(__cm_, __rhs.__cm_);
398 _STD::swap(__owns_eb_, __rhs.__owns_eb_);
399 _STD::swap(__owns_ib_, __rhs.__owns_ib_);
400 _STD::swap(__always_noconv_, __rhs.__always_noconv_);
401 if (this->eback() == (char_type*)__rhs.__extbuf_min_)
402 {
403 ptrdiff_t __n = this->gptr() - this->eback();
404 ptrdiff_t __e = this->egptr() - this->eback();
405 this->setg((char_type*)__extbuf_min_,
406 (char_type*)__extbuf_min_ + __n,
407 (char_type*)__extbuf_min_ + __e);
408 }
409 else if (this->pbase() == (char_type*)__rhs.__extbuf_min_)
410 {
411 ptrdiff_t __n = this->pptr() - this->pbase();
412 ptrdiff_t __e = this->epptr() - this->pbase();
413 this->setp((char_type*)__extbuf_min_,
414 (char_type*)__extbuf_min_ + __e);
415 this->pbump(__n);
416 }
417 if (__rhs.eback() == (char_type*)__extbuf_min_)
418 {
419 ptrdiff_t __n = __rhs.gptr() - __rhs.eback();
420 ptrdiff_t __e = __rhs.egptr() - __rhs.eback();
421 __rhs.setg((char_type*)__rhs.__extbuf_min_,
422 (char_type*)__rhs.__extbuf_min_ + __n,
423 (char_type*)__rhs.__extbuf_min_ + __e);
424 }
425 else if (__rhs.pbase() == (char_type*)__extbuf_min_)
426 {
427 ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();
428 ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();
429 __rhs.setp((char_type*)__rhs.__extbuf_min_,
430 (char_type*)__rhs.__extbuf_min_ + __e);
431 __rhs.pbump(__n);
432 }
433}
434
435template <class _CharT, class _Traits>
436inline _LIBCPP_INLINE_VISIBILITY
437void
438swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y)
439{
440 __x.swap(__y);
441}
442
443template <class _CharT, class _Traits>
444inline _LIBCPP_INLINE_VISIBILITY
445bool
446basic_filebuf<_CharT, _Traits>::is_open() const
447{
448 return __file_ != 0;
449}
450
451template <class _CharT, class _Traits>
452basic_filebuf<_CharT, _Traits>*
453basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
454{
455 basic_filebuf<_CharT, _Traits>* __rt = 0;
456 if (__file_ == 0)
457 {
458 __rt = this;
459 const char* __mdstr;
460 switch (__mode & ~ios_base::ate)
461 {
462 case ios_base::out:
463 case ios_base::out | ios_base::trunc:
464 __mdstr = "w";
465 break;
466 case ios_base::out | ios_base::app:
467 case ios_base::app:
468 __mdstr = "a";
469 break;
470 case ios_base::in:
471 __mdstr = "r";
472 break;
473 case ios_base::in | ios_base::out:
474 __mdstr = "r+";
475 break;
476 case ios_base::in | ios_base::out | ios_base::trunc:
477 __mdstr = "w+";
478 break;
479 case ios_base::in | ios_base::out | ios_base::app:
480 case ios_base::in | ios_base::app:
481 __mdstr = "a+";
482 break;
483 case ios_base::out | ios_base::binary:
484 case ios_base::out | ios_base::trunc | ios_base::binary:
485 __mdstr = "wb";
486 break;
487 case ios_base::out | ios_base::app | ios_base::binary:
488 case ios_base::app | ios_base::binary:
489 __mdstr = "ab";
490 break;
491 case ios_base::in | ios_base::binary:
492 __mdstr = "rb";
493 break;
494 case ios_base::in | ios_base::out | ios_base::binary:
495 __mdstr = "r+b";
496 break;
497 case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
498 __mdstr = "w+b";
499 break;
500 case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
501 case ios_base::in | ios_base::app | ios_base::binary:
502 __mdstr = "a+b";
503 break;
504 default:
505 __rt = 0;
506 break;
507 }
508 if (__rt)
509 {
510 __file_ = fopen(__s, __mdstr);
511 if (__file_)
512 {
513 __om_ = __mode;
514 if (__mode & ios_base::ate)
515 {
516 if (fseek(__file_, 0, SEEK_END))
517 {
518 fclose(__file_);
519 __file_ = 0;
520 __rt = 0;
521 }
522 }
523 }
524 else
525 __rt = 0;
526 }
527 }
528 return __rt;
529}
530
531template <class _CharT, class _Traits>
532inline _LIBCPP_INLINE_VISIBILITY
533basic_filebuf<_CharT, _Traits>*
534basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
535{
536 return open(__s.c_str(), __mode);
537}
538
539template <class _CharT, class _Traits>
540basic_filebuf<_CharT, _Traits>*
541basic_filebuf<_CharT, _Traits>::close()
542{
543 basic_filebuf<_CharT, _Traits>* __rt = 0;
544 if (__file_)
545 {
546 __rt = this;
547 unique_ptr<FILE, int(*)(FILE*)> __h(__file_, fclose);
548 if ((__cm_ & ios_base::out) && sync())
549 __rt = 0;
550 if (fclose(__h.release()) == 0)
551 __file_ = 0;
552 else
553 __rt = 0;
554 }
555 return __rt;
556}
557
558template <class _CharT, class _Traits>
559typename basic_filebuf<_CharT, _Traits>::int_type
560basic_filebuf<_CharT, _Traits>::underflow()
561{
562 if (__file_ == 0)
563 return traits_type::eof();
564 bool __initial = __read_mode();
565 char_type __1buf;
566 if (this->gptr() == 0)
567 this->setg(&__1buf, &__1buf+1, &__1buf+1);
568 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
569 int_type __c = traits_type::eof();
570 if (this->gptr() == this->egptr())
571 {
572 memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
573 if (__always_noconv_)
574 {
575 size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
576 __nmemb = fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
577 if (__nmemb != 0)
578 {
579 this->setg(this->eback(),
580 this->eback() + __unget_sz,
581 this->eback() + __unget_sz + __nmemb);
Howard Hinnant47a7cce2011-02-02 17:37:16 +0000582 __c = traits_type::to_int_type(*this->gptr());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000583 }
584 }
585 else
586 {
587 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
588 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
589 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
Howard Hinnant6cf5d8c2011-02-14 19:12:38 +0000590 size_t __nmemb = _STD::min(static_cast<size_t>(this->egptr() - this->eback() - __unget_sz),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000591 static_cast<size_t>(__extbufend_ - __extbufnext_));
592 codecvt_base::result __r;
593 state_type __svs = __st_;
594 size_t __nr = fread((void*)__extbufnext_, 1, __nmemb, __file_);
595 if (__nr != 0)
596 {
597 __extbufend_ = __extbufnext_ + __nr;
598 char_type* __inext;
599 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
600 this->eback() + __unget_sz,
601 this->egptr(), __inext);
602 if (__r == codecvt_base::noconv)
603 {
604 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_);
Howard Hinnant47a7cce2011-02-02 17:37:16 +0000605 __c = traits_type::to_int_type(*this->gptr());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000606 }
607 else if (__inext != this->eback() + __unget_sz)
608 {
609 this->setg(this->eback(), this->eback() + __unget_sz, __inext);
Howard Hinnant47a7cce2011-02-02 17:37:16 +0000610 __c = traits_type::to_int_type(*this->gptr());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000611 }
612 }
613 }
614 }
615 else
Howard Hinnant47a7cce2011-02-02 17:37:16 +0000616 __c = traits_type::to_int_type(*this->gptr());
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000617 if (this->eback() == &__1buf)
618 this->setg(0, 0, 0);
619 return __c;
620}
621
622template <class _CharT, class _Traits>
623typename basic_filebuf<_CharT, _Traits>::int_type
624basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c)
625{
626 if (__file_ && this->eback() < this->gptr())
627 {
628 if (traits_type::eq_int_type(__c, traits_type::eof()))
629 {
630 this->gbump(-1);
631 return traits_type::not_eof(__c);
632 }
633 if ((__om_ & ios_base::out) ||
634 traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
635 {
636 this->gbump(-1);
637 *this->gptr() = traits_type::to_char_type(__c);
638 return __c;
639 }
640 }
641 return traits_type::eof();
642}
643
644template <class _CharT, class _Traits>
645typename basic_filebuf<_CharT, _Traits>::int_type
646basic_filebuf<_CharT, _Traits>::overflow(int_type __c)
647{
648 if (__file_ == 0)
649 return traits_type::eof();
650 __write_mode();
651 char_type __1buf;
652 char_type* __pb_save = this->pbase();
653 char_type* __epb_save = this->epptr();
654 if (!traits_type::eq_int_type(__c, traits_type::eof()))
655 {
656 if (this->pptr() == 0)
657 this->setp(&__1buf, &__1buf+1);
658 *this->pptr() = traits_type::to_char_type(__c);
659 this->pbump(1);
660 }
661 if (this->pptr() != this->pbase())
662 {
663 if (__always_noconv_)
664 {
665 size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
666 if (fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
667 return traits_type::eof();
668 }
669 else
670 {
671 char* __extbe = __extbuf_;
672 codecvt_base::result __r;
673 do
674 {
675 const char_type* __e;
676 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
677 __extbuf_, __extbuf_ + __ebs_, __extbe);
678 if (__e == this->pbase())
679 return traits_type::eof();
680 if (__r == codecvt_base::noconv)
681 {
682 size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
683 if (fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
684 return traits_type::eof();
685 }
686 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
687 {
688 size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
689 if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
690 return traits_type::eof();
691 if (__r == codecvt_base::partial)
692 {
693 this->setp((char_type*)__e, this->pptr());
694 this->pbump(this->epptr() - this->pbase());
695 }
696 }
697 else
698 return traits_type::eof();
699 } while (__r == codecvt_base::partial);
700 }
701 this->setp(__pb_save, __epb_save);
702 }
703 return traits_type::not_eof(__c);
704}
705
706template <class _CharT, class _Traits>
707basic_streambuf<_CharT, _Traits>*
708basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n)
709{
710 this->setg(0, 0, 0);
711 this->setp(0, 0);
712 if (__owns_eb_)
713 delete [] __extbuf_;
714 if (__owns_ib_)
715 delete [] __intbuf_;
716 __ebs_ = __n;
717 if (__ebs_ > sizeof(__extbuf_min_))
718 {
719 if (__always_noconv_ && __s)
720 {
721 __extbuf_ = (char*)__s;
722 __owns_eb_ = false;
723 }
724 else
725 {
726 __extbuf_ = new char[__ebs_];
727 __owns_eb_ = true;
728 }
729 }
730 else
731 {
732 __extbuf_ = __extbuf_min_;
733 __ebs_ = sizeof(__extbuf_min_);
734 __owns_eb_ = false;
735 }
736 if (!__always_noconv_)
737 {
738 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
739 if (__s && __ibs_ >= sizeof(__extbuf_min_))
740 {
741 __intbuf_ = __s;
742 __owns_ib_ = false;
743 }
744 else
745 {
746 __intbuf_ = new char_type[__ibs_];
747 __owns_ib_ = true;
748 }
749 }
750 else
751 {
752 __ibs_ = 0;
753 __intbuf_ = 0;
754 __owns_ib_ = false;
755 }
756 return this;
757}
758
759template <class _CharT, class _Traits>
760typename basic_filebuf<_CharT, _Traits>::pos_type
761basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way,
762 ios_base::openmode)
763{
764 int __width = __cv_->encoding();
765 if (__file_ == 0 || (__width <= 0 && __off != 0) || sync())
766 return pos_type(off_type(-1));
767 // __width > 0 || __off == 0
768 int __whence;
769 switch (__way)
770 {
771 case ios_base::beg:
772 __whence = SEEK_SET;
773 break;
774 case ios_base::cur:
775 __whence = SEEK_CUR;
776 break;
777 case ios_base::end:
778 __whence = SEEK_END;
779 break;
780 default:
781 return pos_type(off_type(-1));
782 }
783 if (fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
784 return pos_type(off_type(-1));
785 pos_type __r = ftello(__file_);
786 __r.state(__st_);
787 return __r;
788}
789
790template <class _CharT, class _Traits>
791typename basic_filebuf<_CharT, _Traits>::pos_type
Howard Hinnant639a6682010-07-15 18:18:07 +0000792basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000793{
794 if (__file_ == 0 || sync())
795 return pos_type(off_type(-1));
796 if (fseeko(__file_, __sp, SEEK_SET))
797 return pos_type(off_type(-1));
798 return __sp;
799}
800
801template <class _CharT, class _Traits>
802int
803basic_filebuf<_CharT, _Traits>::sync()
804{
805 if (__file_ == 0)
806 return 0;
807 if (__cm_ & ios_base::out)
808 {
809 if (this->pptr() != this->pbase())
810 if (overflow() == traits_type::eof())
811 return -1;
812 codecvt_base::result __r;
813 do
814 {
815 char* __extbe;
816 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
817 size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
818 if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
819 return -1;
820 } while (__r == codecvt_base::partial);
821 if (__r == codecvt_base::error)
822 return -1;
823 if (fflush(__file_))
824 return -1;
825 }
826 else if (__cm_ & ios_base::in)
827 {
828 off_type __c;
829 if (__always_noconv_)
830 __c = this->egptr() - this->gptr();
831 else
832 {
833 int __width = __cv_->encoding();
834 __c = __extbufend_ - __extbufnext_;
835 if (__width > 0)
836 __c += __width * (this->egptr() - this->gptr());
837 else
838 {
839 if (this->gptr() != this->egptr())
840 {
841 reverse(this->gptr(), this->egptr());
842 codecvt_base::result __r;
843 const char_type* __e = this->gptr();
844 char* __extbe;
845 do
846 {
847 __r = __cv_->out(__st_, __e, this->egptr(), __e,
848 __extbuf_, __extbuf_ + __ebs_, __extbe);
849 switch (__r)
850 {
851 case codecvt_base::noconv:
852 __c += this->egptr() - this->gptr();
853 break;
854 case codecvt_base::ok:
855 case codecvt_base::partial:
856 __c += __extbe - __extbuf_;
857 break;
858 default:
859 return -1;
860 }
861 } while (__r == codecvt_base::partial);
862 }
863 }
864 }
865 if (fseeko(__file_, -__c, SEEK_CUR))
866 return -1;
867 this->setg(0, 0, 0);
868 __cm_ = 0;
869 }
870 return 0;
871}
872
873template <class _CharT, class _Traits>
874void
875basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc)
876{
877 sync();
878 __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
879 bool __old_anc = __always_noconv_;
880 __always_noconv_ = __cv_->always_noconv();
881 if (__old_anc != __always_noconv_)
882 {
883 this->setg(0, 0, 0);
884 this->setp(0, 0);
885 // invariant, char_type is char, else we couldn't get here
886 if (__always_noconv_) // need to dump __intbuf_
887 {
888 if (__owns_eb_)
889 delete [] __extbuf_;
890 __owns_eb_ = __owns_ib_;
891 __ebs_ = __ibs_;
892 __extbuf_ = (char*)__intbuf_;
893 __ibs_ = 0;
894 __intbuf_ = 0;
895 __owns_ib_ = false;
896 }
897 else // need to obtain an __intbuf_.
898 { // If __extbuf_ is user-supplied, use it, else new __intbuf_
899 if (!__owns_eb_ && __extbuf_ != __extbuf_min_)
900 {
901 __ibs_ = __ebs_;
902 __intbuf_ = (char_type*)__extbuf_;
903 __owns_ib_ = false;
904 __extbuf_ = new char[__ebs_];
905 __owns_eb_ = true;
906 }
907 else
908 {
909 __ibs_ = __ebs_;
910 __intbuf_ = new char_type[__ibs_];
911 __owns_ib_ = true;
912 }
913 }
914 }
915}
916
917template <class _CharT, class _Traits>
918bool
919basic_filebuf<_CharT, _Traits>::__read_mode()
920{
921 if (!(__cm_ & ios_base::in))
922 {
923 this->setp(0, 0);
924 if (__always_noconv_)
925 this->setg((char_type*)__extbuf_,
926 (char_type*)__extbuf_ + __ebs_,
927 (char_type*)__extbuf_ + __ebs_);
928 else
929 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
930 __cm_ = ios_base::in;
931 return true;
932 }
933 return false;
934}
935
936template <class _CharT, class _Traits>
937void
938basic_filebuf<_CharT, _Traits>::__write_mode()
939{
940 if (!(__cm_ & ios_base::out))
941 {
942 this->setg(0, 0, 0);
943 if (__ebs_ > sizeof(__extbuf_min_))
944 {
945 if (__always_noconv_)
946 this->setp((char_type*)__extbuf_,
947 (char_type*)__extbuf_ + (__ebs_ - 1));
948 else
949 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
950 }
951 else
952 this->setp(0, 0);
953 __cm_ = ios_base::out;
954 }
955}
956
957// basic_ifstream
958
959template <class _CharT, class _Traits>
Howard Hinnant42a63a72010-09-21 22:55:27 +0000960class _LIBCPP_VISIBLE basic_ifstream
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000961 : public basic_istream<_CharT, _Traits>
962{
963public:
964 typedef _CharT char_type;
965 typedef _Traits traits_type;
966 typedef typename traits_type::int_type int_type;
967 typedef typename traits_type::pos_type pos_type;
968 typedef typename traits_type::off_type off_type;
969
970 basic_ifstream();
971 explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
972 explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
Howard Hinnant73d21a42010-09-04 23:28:19 +0000973#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000974 basic_ifstream(basic_ifstream&& __rhs);
975#endif
976
Howard Hinnant73d21a42010-09-04 23:28:19 +0000977#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000978 basic_ifstream& operator=(basic_ifstream&& __rhs);
979#endif
980 void swap(basic_ifstream& __rhs);
981
982 basic_filebuf<char_type, traits_type>* rdbuf() const;
983 bool is_open() const;
984 void open(const char* __s, ios_base::openmode __mode = ios_base::in);
985 void open(const string& __s, ios_base::openmode __mode = ios_base::in);
986 void close();
987
988private:
989 basic_filebuf<char_type, traits_type> __sb_;
990};
991
992template <class _CharT, class _Traits>
993inline _LIBCPP_INLINE_VISIBILITY
994basic_ifstream<_CharT, _Traits>::basic_ifstream()
995 : basic_istream<char_type, traits_type>(&__sb_)
996{
997}
998
999template <class _CharT, class _Traits>
1000inline _LIBCPP_INLINE_VISIBILITY
1001basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
1002 : basic_istream<char_type, traits_type>(&__sb_)
1003{
1004 if (__sb_.open(__s, __mode | ios_base::in) == 0)
1005 this->setstate(ios_base::failbit);
1006}
1007
1008template <class _CharT, class _Traits>
1009inline _LIBCPP_INLINE_VISIBILITY
1010basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)
1011 : basic_istream<char_type, traits_type>(&__sb_)
1012{
1013 if (__sb_.open(__s, __mode | ios_base::in) == 0)
1014 this->setstate(ios_base::failbit);
1015}
1016
Howard Hinnant73d21a42010-09-04 23:28:19 +00001017#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001018
1019template <class _CharT, class _Traits>
1020inline _LIBCPP_INLINE_VISIBILITY
1021basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
1022 : basic_istream<char_type, traits_type>(_STD::move(__rhs)),
1023 __sb_(_STD::move(__rhs.__sb_))
1024{
1025 this->set_rdbuf(&__sb_);
1026}
1027
1028template <class _CharT, class _Traits>
1029inline _LIBCPP_INLINE_VISIBILITY
1030basic_ifstream<_CharT, _Traits>&
1031basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs)
1032{
1033 basic_istream<char_type, traits_type>::operator=(_STD::move(__rhs));
1034 __sb_ = _STD::move(__rhs.__sb_);
1035 return *this;
1036}
1037
Howard Hinnant73d21a42010-09-04 23:28:19 +00001038#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001039
1040template <class _CharT, class _Traits>
1041inline _LIBCPP_INLINE_VISIBILITY
1042void
1043basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs)
1044{
1045 basic_istream<char_type, traits_type>::swap(__rhs);
1046 __sb_.swap(__rhs.__sb_);
1047}
1048
1049template <class _CharT, class _Traits>
1050inline _LIBCPP_INLINE_VISIBILITY
1051void
1052swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y)
1053{
1054 __x.swap(__y);
1055}
1056
1057template <class _CharT, class _Traits>
1058inline _LIBCPP_INLINE_VISIBILITY
1059basic_filebuf<_CharT, _Traits>*
1060basic_ifstream<_CharT, _Traits>::rdbuf() const
1061{
1062 return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
1063}
1064
1065template <class _CharT, class _Traits>
1066inline _LIBCPP_INLINE_VISIBILITY
1067bool
1068basic_ifstream<_CharT, _Traits>::is_open() const
1069{
1070 return __sb_.is_open();
1071}
1072
1073template <class _CharT, class _Traits>
1074void
1075basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
1076{
1077 if (__sb_.open(__s, __mode | ios_base::in))
1078 this->clear();
1079 else
1080 this->setstate(ios_base::failbit);
1081}
1082
1083template <class _CharT, class _Traits>
1084void
1085basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
1086{
1087 if (__sb_.open(__s, __mode | ios_base::in))
1088 this->clear();
1089 else
1090 this->setstate(ios_base::failbit);
1091}
1092
1093template <class _CharT, class _Traits>
1094inline _LIBCPP_INLINE_VISIBILITY
1095void
1096basic_ifstream<_CharT, _Traits>::close()
1097{
1098 if (__sb_.close() == 0)
1099 this->setstate(ios_base::failbit);
1100}
1101
1102// basic_ofstream
1103
1104template <class _CharT, class _Traits>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001105class _LIBCPP_VISIBLE basic_ofstream
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001106 : public basic_ostream<_CharT, _Traits>
1107{
1108public:
1109 typedef _CharT char_type;
1110 typedef _Traits traits_type;
1111 typedef typename traits_type::int_type int_type;
1112 typedef typename traits_type::pos_type pos_type;
1113 typedef typename traits_type::off_type off_type;
1114
1115 basic_ofstream();
1116 explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
1117 explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001118#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001119 basic_ofstream(basic_ofstream&& __rhs);
1120#endif
1121
Howard Hinnant73d21a42010-09-04 23:28:19 +00001122#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001123 basic_ofstream& operator=(basic_ofstream&& __rhs);
1124#endif
1125 void swap(basic_ofstream& __rhs);
1126
1127 basic_filebuf<char_type, traits_type>* rdbuf() const;
1128 bool is_open() const;
1129 void open(const char* __s, ios_base::openmode __mode = ios_base::out);
1130 void open(const string& __s, ios_base::openmode __mode = ios_base::out);
1131 void close();
1132
1133private:
1134 basic_filebuf<char_type, traits_type> __sb_;
1135};
1136
1137template <class _CharT, class _Traits>
1138inline _LIBCPP_INLINE_VISIBILITY
1139basic_ofstream<_CharT, _Traits>::basic_ofstream()
1140 : basic_ostream<char_type, traits_type>(&__sb_)
1141{
1142}
1143
1144template <class _CharT, class _Traits>
1145inline _LIBCPP_INLINE_VISIBILITY
1146basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
1147 : basic_ostream<char_type, traits_type>(&__sb_)
1148{
1149 if (__sb_.open(__s, __mode | ios_base::out) == 0)
1150 this->setstate(ios_base::failbit);
1151}
1152
1153template <class _CharT, class _Traits>
1154inline _LIBCPP_INLINE_VISIBILITY
1155basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)
1156 : basic_ostream<char_type, traits_type>(&__sb_)
1157{
1158 if (__sb_.open(__s, __mode | ios_base::out) == 0)
1159 this->setstate(ios_base::failbit);
1160}
1161
Howard Hinnant73d21a42010-09-04 23:28:19 +00001162#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001163
1164template <class _CharT, class _Traits>
1165inline _LIBCPP_INLINE_VISIBILITY
1166basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
1167 : basic_ostream<char_type, traits_type>(_STD::move(__rhs)),
1168 __sb_(_STD::move(__rhs.__sb_))
1169{
1170 this->set_rdbuf(&__sb_);
1171}
1172
1173template <class _CharT, class _Traits>
1174inline _LIBCPP_INLINE_VISIBILITY
1175basic_ofstream<_CharT, _Traits>&
1176basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs)
1177{
1178 basic_ostream<char_type, traits_type>::operator=(_STD::move(__rhs));
1179 __sb_ = _STD::move(__rhs.__sb_);
1180 return *this;
1181}
1182
Howard Hinnant73d21a42010-09-04 23:28:19 +00001183#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001184
1185template <class _CharT, class _Traits>
1186inline _LIBCPP_INLINE_VISIBILITY
1187void
1188basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs)
1189{
1190 basic_ostream<char_type, traits_type>::swap(__rhs);
1191 __sb_.swap(__rhs.__sb_);
1192}
1193
1194template <class _CharT, class _Traits>
1195inline _LIBCPP_INLINE_VISIBILITY
1196void
1197swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y)
1198{
1199 __x.swap(__y);
1200}
1201
1202template <class _CharT, class _Traits>
1203inline _LIBCPP_INLINE_VISIBILITY
1204basic_filebuf<_CharT, _Traits>*
1205basic_ofstream<_CharT, _Traits>::rdbuf() const
1206{
1207 return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
1208}
1209
1210template <class _CharT, class _Traits>
1211inline _LIBCPP_INLINE_VISIBILITY
1212bool
1213basic_ofstream<_CharT, _Traits>::is_open() const
1214{
1215 return __sb_.is_open();
1216}
1217
1218template <class _CharT, class _Traits>
1219void
1220basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
1221{
1222 if (__sb_.open(__s, __mode | ios_base::out))
1223 this->clear();
1224 else
1225 this->setstate(ios_base::failbit);
1226}
1227
1228template <class _CharT, class _Traits>
1229void
1230basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
1231{
1232 if (__sb_.open(__s, __mode | ios_base::out))
1233 this->clear();
1234 else
1235 this->setstate(ios_base::failbit);
1236}
1237
1238template <class _CharT, class _Traits>
1239inline _LIBCPP_INLINE_VISIBILITY
1240void
1241basic_ofstream<_CharT, _Traits>::close()
1242{
1243 if (__sb_.close() == 0)
1244 this->setstate(ios_base::failbit);
1245}
1246
1247// basic_fstream
1248
1249template <class _CharT, class _Traits>
Howard Hinnant42a63a72010-09-21 22:55:27 +00001250class _LIBCPP_VISIBLE basic_fstream
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001251 : public basic_iostream<_CharT, _Traits>
1252{
1253public:
1254 typedef _CharT char_type;
1255 typedef _Traits traits_type;
1256 typedef typename traits_type::int_type int_type;
1257 typedef typename traits_type::pos_type pos_type;
1258 typedef typename traits_type::off_type off_type;
1259
1260 basic_fstream();
1261 explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1262 explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
Howard Hinnant73d21a42010-09-04 23:28:19 +00001263#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001264 basic_fstream(basic_fstream&& __rhs);
1265#endif
1266
Howard Hinnant73d21a42010-09-04 23:28:19 +00001267#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001268 basic_fstream& operator=(basic_fstream&& __rhs);
1269#endif
1270 void swap(basic_fstream& __rhs);
1271
1272 basic_filebuf<char_type, traits_type>* rdbuf() const;
1273 bool is_open() const;
1274 void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1275 void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
1276 void close();
1277
1278private:
1279 basic_filebuf<char_type, traits_type> __sb_;
1280};
1281
1282template <class _CharT, class _Traits>
1283inline _LIBCPP_INLINE_VISIBILITY
1284basic_fstream<_CharT, _Traits>::basic_fstream()
1285 : basic_iostream<char_type, traits_type>(&__sb_)
1286{
1287}
1288
1289template <class _CharT, class _Traits>
1290inline _LIBCPP_INLINE_VISIBILITY
1291basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
1292 : basic_iostream<char_type, traits_type>(&__sb_)
1293{
1294 if (__sb_.open(__s, __mode) == 0)
1295 this->setstate(ios_base::failbit);
1296}
1297
1298template <class _CharT, class _Traits>
1299inline _LIBCPP_INLINE_VISIBILITY
1300basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)
1301 : basic_iostream<char_type, traits_type>(&__sb_)
1302{
1303 if (__sb_.open(__s, __mode) == 0)
1304 this->setstate(ios_base::failbit);
1305}
1306
Howard Hinnant73d21a42010-09-04 23:28:19 +00001307#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001308
1309template <class _CharT, class _Traits>
1310inline _LIBCPP_INLINE_VISIBILITY
1311basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
1312 : basic_iostream<char_type, traits_type>(_STD::move(__rhs)),
1313 __sb_(_STD::move(__rhs.__sb_))
1314{
1315 this->set_rdbuf(&__sb_);
1316}
1317
1318template <class _CharT, class _Traits>
1319inline _LIBCPP_INLINE_VISIBILITY
1320basic_fstream<_CharT, _Traits>&
1321basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs)
1322{
1323 basic_iostream<char_type, traits_type>::operator=(_STD::move(__rhs));
1324 __sb_ = _STD::move(__rhs.__sb_);
1325 return *this;
1326}
1327
Howard Hinnant73d21a42010-09-04 23:28:19 +00001328#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001329
1330template <class _CharT, class _Traits>
1331inline _LIBCPP_INLINE_VISIBILITY
1332void
1333basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs)
1334{
1335 basic_iostream<char_type, traits_type>::swap(__rhs);
1336 __sb_.swap(__rhs.__sb_);
1337}
1338
1339template <class _CharT, class _Traits>
1340inline _LIBCPP_INLINE_VISIBILITY
1341void
1342swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y)
1343{
1344 __x.swap(__y);
1345}
1346
1347template <class _CharT, class _Traits>
1348inline _LIBCPP_INLINE_VISIBILITY
1349basic_filebuf<_CharT, _Traits>*
1350basic_fstream<_CharT, _Traits>::rdbuf() const
1351{
1352 return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
1353}
1354
1355template <class _CharT, class _Traits>
1356inline _LIBCPP_INLINE_VISIBILITY
1357bool
1358basic_fstream<_CharT, _Traits>::is_open() const
1359{
1360 return __sb_.is_open();
1361}
1362
1363template <class _CharT, class _Traits>
1364void
1365basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
1366{
1367 if (__sb_.open(__s, __mode))
1368 this->clear();
1369 else
1370 this->setstate(ios_base::failbit);
1371}
1372
1373template <class _CharT, class _Traits>
1374void
1375basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
1376{
1377 if (__sb_.open(__s, __mode))
1378 this->clear();
1379 else
1380 this->setstate(ios_base::failbit);
1381}
1382
1383template <class _CharT, class _Traits>
1384inline _LIBCPP_INLINE_VISIBILITY
1385void
1386basic_fstream<_CharT, _Traits>::close()
1387{
1388 if (__sb_.close() == 0)
1389 this->setstate(ios_base::failbit);
1390}
1391
1392_LIBCPP_END_NAMESPACE_STD
1393
1394#endif // _LIBCPP_FSTREAM