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