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#pragma GCC system_header
175
176_LIBCPP_BEGIN_NAMESPACE_STD
177
178template <class _CharT, class _Traits>
179class _LIBCPP_VISIBLE basic_filebuf
180    : 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();
192#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
193    basic_filebuf(basic_filebuf&& __rhs);
194#endif
195    virtual ~basic_filebuf();
196
197    // 27.9.1.3 Assign/swap:
198#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
199    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
263#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
264
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
336#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
337
338template <class _CharT, class _Traits>
339basic_filebuf<_CharT, _Traits>::~basic_filebuf()
340{
341#ifndef _LIBCPP_NO_EXCEPTIONS
342    try
343    {
344#endif  // _LIBCPP_NO_EXCEPTIONS
345        close();
346#ifndef _LIBCPP_NO_EXCEPTIONS
347    }
348    catch (...)
349    {
350    }
351#endif  // _LIBCPP_NO_EXCEPTIONS
352    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        _VSTD::swap(__extbuf_, __rhs.__extbuf_);
366        _VSTD::swap(__extbufnext_, __rhs.__extbufnext_);
367        _VSTD::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    _VSTD::swap(__ebs_, __rhs.__ebs_);
391    _VSTD::swap(__intbuf_, __rhs.__intbuf_);
392    _VSTD::swap(__ibs_, __rhs.__ibs_);
393    _VSTD::swap(__file_, __rhs.__file_);
394    _VSTD::swap(__cv_, __rhs.__cv_);
395    _VSTD::swap(__st_, __rhs.__st_);
396    _VSTD::swap(__om_, __rhs.__om_);
397    _VSTD::swap(__cm_, __rhs.__cm_);
398    _VSTD::swap(__owns_eb_, __rhs.__owns_eb_);
399    _VSTD::swap(__owns_ib_, __rhs.__owns_ib_);
400    _VSTD::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);
582                __c = traits_type::to_int_type(*this->gptr());
583            }
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_);
590            size_t __nmemb = _VSTD::min(static_cast<size_t>(this->egptr() - this->eback() - __unget_sz),
591                                 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_);
605                    __c = traits_type::to_int_type(*this->gptr());
606                }
607                else if (__inext != this->eback() + __unget_sz)
608                {
609                    this->setg(this->eback(), this->eback() + __unget_sz, __inext);
610                    __c = traits_type::to_int_type(*this->gptr());
611                }
612            }
613        }
614    }
615    else
616        __c = traits_type::to_int_type(*this->gptr());
617    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
792basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode)
793{
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>
960class _LIBCPP_VISIBLE basic_ifstream
961    : 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);
973#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
974    basic_ifstream(basic_ifstream&& __rhs);
975#endif
976
977#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
978    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
1017#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1018
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>(_VSTD::move(__rhs)),
1023      __sb_(_VSTD::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=(_VSTD::move(__rhs));
1034    __sb_ = _VSTD::move(__rhs.__sb_);
1035    return *this;
1036}
1037
1038#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1039
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>
1105class _LIBCPP_VISIBLE basic_ofstream
1106    : 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);
1118#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1119    basic_ofstream(basic_ofstream&& __rhs);
1120#endif
1121
1122#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1123    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
1162#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1163
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>(_VSTD::move(__rhs)),
1168      __sb_(_VSTD::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=(_VSTD::move(__rhs));
1179    __sb_ = _VSTD::move(__rhs.__sb_);
1180    return *this;
1181}
1182
1183#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1184
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>
1250class _LIBCPP_VISIBLE basic_fstream
1251    : 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);
1263#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1264    basic_fstream(basic_fstream&& __rhs);
1265#endif
1266
1267#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1268    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
1307#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
1308
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>(_VSTD::move(__rhs)),
1313      __sb_(_VSTD::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=(_VSTD::move(__rhs));
1324    __sb_ = _VSTD::move(__rhs.__sb_);
1325    return *this;
1326}
1327
1328#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
1329
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
1395