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