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* open(const filesystem::path& p, ios_base::openmode mode); // C++17
     42     basic_filebuf* close();
     43 
     44 protected:
     45     // 27.9.1.5 Overridden virtual functions:
     46     virtual streamsize showmanyc();
     47     virtual int_type underflow();
     48     virtual int_type uflow();
     49     virtual int_type pbackfail(int_type c = traits_type::eof());
     50     virtual int_type overflow (int_type c = traits_type::eof());
     51     virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* s, streamsize n);
     52     virtual pos_type seekoff(off_type off, ios_base::seekdir way,
     53                              ios_base::openmode which = ios_base::in | ios_base::out);
     54     virtual pos_type seekpos(pos_type sp,
     55                              ios_base::openmode which = ios_base::in | ios_base::out);
     56     virtual int sync();
     57     virtual void imbue(const locale& loc);
     58 };
     59 
     60 template <class charT, class traits>
     61   void
     62   swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y);
     63 
     64 typedef basic_filebuf<char>    filebuf;
     65 typedef basic_filebuf<wchar_t> wfilebuf;
     66 
     67 template <class charT, class traits = char_traits<charT> >
     68 class basic_ifstream
     69     : public basic_istream<charT,traits>
     70 {
     71 public:
     72     typedef charT                          char_type;
     73     typedef traits                         traits_type;
     74     typedef typename traits_type::int_type int_type;
     75     typedef typename traits_type::pos_type pos_type;
     76     typedef typename traits_type::off_type off_type;
     77 
     78     basic_ifstream();
     79     explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
     80     explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in);
     81     explicit basic_ifstream(const filesystem::path& p,
     82                             ios_base::openmode mode = ios_base::in); // C++17
     83     basic_ifstream(basic_ifstream&& rhs);
     84 
     85     basic_ifstream& operator=(basic_ifstream&& rhs);
     86     void swap(basic_ifstream& rhs);
     87 
     88     basic_filebuf<char_type, traits_type>* rdbuf() const;
     89     bool is_open() const;
     90     void open(const char* s, ios_base::openmode mode = ios_base::in);
     91     void open(const string& s, ios_base::openmode mode = ios_base::in);
     92     void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++17
     93 
     94     void close();
     95 };
     96 
     97 template <class charT, class traits>
     98   void
     99   swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y);
    100 
    101 typedef basic_ifstream<char>    ifstream;
    102 typedef basic_ifstream<wchar_t> wifstream;
    103 
    104 template <class charT, class traits = char_traits<charT> >
    105 class basic_ofstream
    106     : public basic_ostream<charT,traits>
    107 {
    108 public:
    109     typedef charT                          char_type;
    110     typedef traits                         traits_type;
    111     typedef typename traits_type::int_type int_type;
    112     typedef typename traits_type::pos_type pos_type;
    113     typedef typename traits_type::off_type off_type;
    114 
    115     basic_ofstream();
    116     explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
    117     explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);
    118     explicit basic_ofstream(const filesystem::path& p,
    119                             ios_base::openmode mode = ios_base::out); // C++17
    120     basic_ofstream(basic_ofstream&& rhs);
    121 
    122     basic_ofstream& operator=(basic_ofstream&& rhs);
    123     void swap(basic_ofstream& rhs);
    124 
    125     basic_filebuf<char_type, traits_type>* rdbuf() const;
    126     bool is_open() const;
    127     void open(const char* s, ios_base::openmode mode = ios_base::out);
    128     void open(const string& s, ios_base::openmode mode = ios_base::out);
    129     void open(const filesystem::path& p,
    130               ios_base::openmode mode = ios_base::out); // C++17
    131 
    132     void close();
    133 };
    134 
    135 template <class charT, class traits>
    136   void
    137   swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y);
    138 
    139 typedef basic_ofstream<char>    ofstream;
    140 typedef basic_ofstream<wchar_t> wofstream;
    141 
    142 template <class charT, class traits=char_traits<charT> >
    143 class basic_fstream
    144     : public basic_iostream<charT,traits>
    145 {
    146 public:
    147     typedef charT                          char_type;
    148     typedef traits                         traits_type;
    149     typedef typename traits_type::int_type int_type;
    150     typedef typename traits_type::pos_type pos_type;
    151     typedef typename traits_type::off_type off_type;
    152 
    153     basic_fstream();
    154     explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
    155     explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
    156     explicit basic_fstream(const filesystem::path& p,
    157                            ios_base::openmode mode = ios_base::in|ios_base::out); C++17
    158     basic_fstream(basic_fstream&& rhs);
    159 
    160     basic_fstream& operator=(basic_fstream&& rhs);
    161     void swap(basic_fstream& rhs);
    162 
    163     basic_filebuf<char_type, traits_type>* rdbuf() const;
    164     bool is_open() const;
    165     void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
    166     void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);
    167     void open(const filesystem::path& s,
    168               ios_base::openmode mode = ios_base::in|ios_base::out); // C++17
    169 
    170     void close();
    171 };
    172 
    173 template <class charT, class traits>
    174   void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y);
    175 
    176 typedef basic_fstream<char>    fstream;
    177 typedef basic_fstream<wchar_t> wfstream;
    178 
    179 }  // std
    180 
    181 */
    182 
    183 #include <__config>
    184 #include <ostream>
    185 #include <istream>
    186 #include <__locale>
    187 #include <cstdio>
    188 #include <cstdlib>
    189 #include <filesystem>
    190 
    191 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
    192 #pragma GCC system_header
    193 #endif
    194 
    195 _LIBCPP_PUSH_MACROS
    196 #include <__undef_macros>
    197 
    198 
    199 _LIBCPP_BEGIN_NAMESPACE_STD
    200 
    201 template <class _CharT, class _Traits>
    202 class _LIBCPP_TEMPLATE_VIS basic_filebuf
    203     : public basic_streambuf<_CharT, _Traits>
    204 {
    205 public:
    206     typedef _CharT                           char_type;
    207     typedef _Traits                          traits_type;
    208     typedef typename traits_type::int_type   int_type;
    209     typedef typename traits_type::pos_type   pos_type;
    210     typedef typename traits_type::off_type   off_type;
    211     typedef typename traits_type::state_type state_type;
    212 
    213     // 27.9.1.2 Constructors/destructor:
    214     basic_filebuf();
    215 #ifndef _LIBCPP_CXX03_LANG
    216     basic_filebuf(basic_filebuf&& __rhs);
    217 #endif
    218     virtual ~basic_filebuf();
    219 
    220     // 27.9.1.3 Assign/swap:
    221 #ifndef _LIBCPP_CXX03_LANG
    222     _LIBCPP_INLINE_VISIBILITY
    223     basic_filebuf& operator=(basic_filebuf&& __rhs);
    224 #endif
    225     void swap(basic_filebuf& __rhs);
    226 
    227     // 27.9.1.4 Members:
    228     _LIBCPP_INLINE_VISIBILITY
    229     bool is_open() const;
    230 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
    231     basic_filebuf* open(const char* __s, ios_base::openmode __mode);
    232 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
    233     basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode);
    234 #endif
    235     _LIBCPP_INLINE_VISIBILITY
    236     basic_filebuf* open(const string& __s, ios_base::openmode __mode);
    237 
    238 #if _LIBCPP_STD_VER >= 17
    239     _LIBCPP_INLINE_VISIBILITY
    240     basic_filebuf* open(const _VSTD_FS::path& __p, ios_base::openmode __mode) {
    241       return open(__p.c_str(), __mode);
    242     }
    243 #endif
    244     _LIBCPP_INLINE_VISIBILITY
    245     basic_filebuf* __open(int __fd, ios_base::openmode __mode);
    246 #endif
    247     basic_filebuf* close();
    248 
    249     _LIBCPP_INLINE_VISIBILITY
    250     inline static const char*
    251     __make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
    252 
    253   protected:
    254     // 27.9.1.5 Overridden virtual functions:
    255     virtual int_type underflow();
    256     virtual int_type pbackfail(int_type __c = traits_type::eof());
    257     virtual int_type overflow (int_type __c = traits_type::eof());
    258     virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n);
    259     virtual pos_type seekoff(off_type __off, ios_base::seekdir __way,
    260                              ios_base::openmode __wch = ios_base::in | ios_base::out);
    261     virtual pos_type seekpos(pos_type __sp,
    262                              ios_base::openmode __wch = ios_base::in | ios_base::out);
    263     virtual int sync();
    264     virtual void imbue(const locale& __loc);
    265 
    266 private:
    267   char* __extbuf_;
    268   const char* __extbufnext_;
    269   const char* __extbufend_;
    270   char __extbuf_min_[8];
    271   size_t __ebs_;
    272   char_type* __intbuf_;
    273   size_t __ibs_;
    274   FILE* __file_;
    275   const codecvt<char_type, char, state_type>* __cv_;
    276   state_type __st_;
    277   state_type __st_last_;
    278   ios_base::openmode __om_;
    279   ios_base::openmode __cm_;
    280   bool __owns_eb_;
    281   bool __owns_ib_;
    282   bool __always_noconv_;
    283 
    284   bool __read_mode();
    285   void __write_mode();
    286 };
    287 
    288 template <class _CharT, class _Traits>
    289 basic_filebuf<_CharT, _Traits>::basic_filebuf()
    290     : __extbuf_(0),
    291       __extbufnext_(0),
    292       __extbufend_(0),
    293       __ebs_(0),
    294       __intbuf_(0),
    295       __ibs_(0),
    296       __file_(0),
    297       __cv_(nullptr),
    298       __st_(),
    299       __st_last_(),
    300       __om_(0),
    301       __cm_(0),
    302       __owns_eb_(false),
    303       __owns_ib_(false),
    304       __always_noconv_(false)
    305 {
    306     if (has_facet<codecvt<char_type, char, state_type> >(this->getloc()))
    307     {
    308         __cv_ = &use_facet<codecvt<char_type, char, state_type> >(this->getloc());
    309         __always_noconv_ = __cv_->always_noconv();
    310     }
    311     setbuf(0, 4096);
    312 }
    313 
    314 #ifndef _LIBCPP_CXX03_LANG
    315 
    316 template <class _CharT, class _Traits>
    317 basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs)
    318     : basic_streambuf<_CharT, _Traits>(__rhs)
    319 {
    320     if (__rhs.__extbuf_ == __rhs.__extbuf_min_)
    321     {
    322         __extbuf_ = __extbuf_min_;
    323         __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);
    324         __extbufend_ = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);
    325     }
    326     else
    327     {
    328         __extbuf_ = __rhs.__extbuf_;
    329         __extbufnext_ = __rhs.__extbufnext_;
    330         __extbufend_ = __rhs.__extbufend_;
    331     }
    332     __ebs_ = __rhs.__ebs_;
    333     __intbuf_ = __rhs.__intbuf_;
    334     __ibs_ = __rhs.__ibs_;
    335     __file_ = __rhs.__file_;
    336     __cv_ = __rhs.__cv_;
    337     __st_ = __rhs.__st_;
    338     __st_last_ = __rhs.__st_last_;
    339     __om_ = __rhs.__om_;
    340     __cm_ = __rhs.__cm_;
    341     __owns_eb_ = __rhs.__owns_eb_;
    342     __owns_ib_ = __rhs.__owns_ib_;
    343     __always_noconv_ = __rhs.__always_noconv_;
    344     if (__rhs.pbase())
    345     {
    346         if (__rhs.pbase() == __rhs.__intbuf_)
    347             this->setp(__intbuf_, __intbuf_ + (__rhs. epptr() - __rhs.pbase()));
    348         else
    349             this->setp((char_type*)__extbuf_,
    350                        (char_type*)__extbuf_ + (__rhs. epptr() - __rhs.pbase()));
    351         this->__pbump(__rhs. pptr() - __rhs.pbase());
    352     }
    353     else if (__rhs.eback())
    354     {
    355         if (__rhs.eback() == __rhs.__intbuf_)
    356             this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()),
    357                                   __intbuf_ + (__rhs.egptr() - __rhs.eback()));
    358         else
    359             this->setg((char_type*)__extbuf_,
    360                        (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),
    361                        (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));
    362     }
    363     __rhs.__extbuf_ = 0;
    364     __rhs.__extbufnext_ = 0;
    365     __rhs.__extbufend_ = 0;
    366     __rhs.__ebs_ = 0;
    367     __rhs.__intbuf_ = 0;
    368     __rhs.__ibs_ = 0;
    369     __rhs.__file_ = 0;
    370     __rhs.__st_ = state_type();
    371     __rhs.__st_last_ = state_type();
    372     __rhs.__om_ = 0;
    373     __rhs.__cm_ = 0;
    374     __rhs.__owns_eb_ = false;
    375     __rhs.__owns_ib_ = false;
    376     __rhs.setg(0, 0, 0);
    377     __rhs.setp(0, 0);
    378 }
    379 
    380 template <class _CharT, class _Traits>
    381 inline
    382 basic_filebuf<_CharT, _Traits>&
    383 basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs)
    384 {
    385     close();
    386     swap(__rhs);
    387     return *this;
    388 }
    389 
    390 #endif  // _LIBCPP_CXX03_LANG
    391 
    392 template <class _CharT, class _Traits>
    393 basic_filebuf<_CharT, _Traits>::~basic_filebuf()
    394 {
    395 #ifndef _LIBCPP_NO_EXCEPTIONS
    396     try
    397     {
    398 #endif  // _LIBCPP_NO_EXCEPTIONS
    399         close();
    400 #ifndef _LIBCPP_NO_EXCEPTIONS
    401     }
    402     catch (...)
    403     {
    404     }
    405 #endif  // _LIBCPP_NO_EXCEPTIONS
    406     if (__owns_eb_)
    407         delete [] __extbuf_;
    408     if (__owns_ib_)
    409         delete [] __intbuf_;
    410 }
    411 
    412 template <class _CharT, class _Traits>
    413 void
    414 basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs)
    415 {
    416     basic_streambuf<char_type, traits_type>::swap(__rhs);
    417     if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)
    418     {
    419         _VSTD::swap(__extbuf_, __rhs.__extbuf_);
    420         _VSTD::swap(__extbufnext_, __rhs.__extbufnext_);
    421         _VSTD::swap(__extbufend_, __rhs.__extbufend_);
    422     }
    423     else
    424     {
    425         ptrdiff_t __ln = __extbufnext_ - __extbuf_;
    426         ptrdiff_t __le = __extbufend_ - __extbuf_;
    427         ptrdiff_t __rn = __rhs.__extbufnext_ - __rhs.__extbuf_;
    428         ptrdiff_t __re = __rhs.__extbufend_ - __rhs.__extbuf_;
    429         if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_)
    430         {
    431             __extbuf_ = __rhs.__extbuf_;
    432             __rhs.__extbuf_ = __rhs.__extbuf_min_;
    433         }
    434         else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_)
    435         {
    436             __rhs.__extbuf_ = __extbuf_;
    437             __extbuf_ = __extbuf_min_;
    438         }
    439         __extbufnext_ = __extbuf_ + __rn;
    440         __extbufend_ = __extbuf_ + __re;
    441         __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;
    442         __rhs.__extbufend_ = __rhs.__extbuf_ + __le;
    443     }
    444     _VSTD::swap(__ebs_, __rhs.__ebs_);
    445     _VSTD::swap(__intbuf_, __rhs.__intbuf_);
    446     _VSTD::swap(__ibs_, __rhs.__ibs_);
    447     _VSTD::swap(__file_, __rhs.__file_);
    448     _VSTD::swap(__cv_, __rhs.__cv_);
    449     _VSTD::swap(__st_, __rhs.__st_);
    450     _VSTD::swap(__st_last_, __rhs.__st_last_);
    451     _VSTD::swap(__om_, __rhs.__om_);
    452     _VSTD::swap(__cm_, __rhs.__cm_);
    453     _VSTD::swap(__owns_eb_, __rhs.__owns_eb_);
    454     _VSTD::swap(__owns_ib_, __rhs.__owns_ib_);
    455     _VSTD::swap(__always_noconv_, __rhs.__always_noconv_);
    456     if (this->eback() == (char_type*)__rhs.__extbuf_min_)
    457     {
    458         ptrdiff_t __n = this->gptr() - this->eback();
    459         ptrdiff_t __e = this->egptr() - this->eback();
    460         this->setg((char_type*)__extbuf_min_,
    461                    (char_type*)__extbuf_min_ + __n,
    462                    (char_type*)__extbuf_min_ + __e);
    463     }
    464     else if (this->pbase() == (char_type*)__rhs.__extbuf_min_)
    465     {
    466         ptrdiff_t __n = this->pptr() - this->pbase();
    467         ptrdiff_t __e = this->epptr() - this->pbase();
    468         this->setp((char_type*)__extbuf_min_,
    469                    (char_type*)__extbuf_min_ + __e);
    470         this->__pbump(__n);
    471     }
    472     if (__rhs.eback() == (char_type*)__extbuf_min_)
    473     {
    474         ptrdiff_t __n = __rhs.gptr() - __rhs.eback();
    475         ptrdiff_t __e = __rhs.egptr() - __rhs.eback();
    476         __rhs.setg((char_type*)__rhs.__extbuf_min_,
    477                    (char_type*)__rhs.__extbuf_min_ + __n,
    478                    (char_type*)__rhs.__extbuf_min_ + __e);
    479     }
    480     else if (__rhs.pbase() == (char_type*)__extbuf_min_)
    481     {
    482         ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();
    483         ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();
    484         __rhs.setp((char_type*)__rhs.__extbuf_min_,
    485                    (char_type*)__rhs.__extbuf_min_ + __e);
    486         __rhs.__pbump(__n);
    487     }
    488 }
    489 
    490 template <class _CharT, class _Traits>
    491 inline _LIBCPP_INLINE_VISIBILITY
    492 void
    493 swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y)
    494 {
    495     __x.swap(__y);
    496 }
    497 
    498 template <class _CharT, class _Traits>
    499 inline
    500 bool
    501 basic_filebuf<_CharT, _Traits>::is_open() const
    502 {
    503     return __file_ != 0;
    504 }
    505 
    506 template <class _CharT, class _Traits>
    507 const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(
    508     ios_base::openmode __mode) _NOEXCEPT {
    509   switch (__mode & ~ios_base::ate) {
    510   case ios_base::out:
    511   case ios_base::out | ios_base::trunc:
    512     return "w";
    513   case ios_base::out | ios_base::app:
    514   case ios_base::app:
    515     return "a";
    516   case ios_base::in:
    517     return "r";
    518   case ios_base::in | ios_base::out:
    519     return "r+";
    520   case ios_base::in | ios_base::out | ios_base::trunc:
    521     return "w+";
    522   case ios_base::in | ios_base::out | ios_base::app:
    523   case ios_base::in | ios_base::app:
    524     return "a+";
    525   case ios_base::out | ios_base::binary:
    526   case ios_base::out | ios_base::trunc | ios_base::binary:
    527     return "wb";
    528   case ios_base::out | ios_base::app | ios_base::binary:
    529   case ios_base::app | ios_base::binary:
    530     return "ab";
    531   case ios_base::in | ios_base::binary:
    532     return "rb";
    533   case ios_base::in | ios_base::out | ios_base::binary:
    534     return "r+b";
    535   case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
    536     return "w+b";
    537   case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
    538   case ios_base::in | ios_base::app | ios_base::binary:
    539     return "a+b";
    540   default:
    541     return nullptr;
    542   }
    543   _LIBCPP_UNREACHABLE();
    544 }
    545 
    546 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
    547 template <class _CharT, class _Traits>
    548 basic_filebuf<_CharT, _Traits>*
    549 basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
    550 {
    551     basic_filebuf<_CharT, _Traits>* __rt = 0;
    552     if (__file_ == 0)
    553     {
    554       if (const char* __mdstr = __make_mdstring(__mode)) {
    555         __rt = this;
    556         __file_ = fopen(__s, __mdstr);
    557         if (__file_) {
    558           __om_ = __mode;
    559           if (__mode & ios_base::ate) {
    560             if (fseek(__file_, 0, SEEK_END)) {
    561               fclose(__file_);
    562               __file_ = 0;
    563               __rt = 0;
    564             }
    565           }
    566         } else
    567           __rt = 0;
    568       }
    569     }
    570     return __rt;
    571 }
    572 
    573 template <class _CharT, class _Traits>
    574 _LIBCPP_INLINE_VISIBILITY basic_filebuf<_CharT, _Traits>*
    575 basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {
    576   basic_filebuf<_CharT, _Traits>* __rt = 0;
    577   if (__file_ == 0) {
    578     if (const char* __mdstr = __make_mdstring(__mode)) {
    579       __rt = this;
    580       __file_ = fdopen(__fd, __mdstr);
    581       if (__file_) {
    582         __om_ = __mode;
    583         if (__mode & ios_base::ate) {
    584           if (fseek(__file_, 0, SEEK_END)) {
    585             fclose(__file_);
    586             __file_ = 0;
    587             __rt = 0;
    588           }
    589         }
    590       } else
    591         __rt = 0;
    592     }
    593   }
    594   return __rt;
    595 }
    596 
    597 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
    598 // This is basically the same as the char* overload except that it uses _wfopen
    599 // and long mode strings.
    600 template <class _CharT, class _Traits>
    601 basic_filebuf<_CharT, _Traits>*
    602 basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode)
    603 {
    604     basic_filebuf<_CharT, _Traits>* __rt = 0;
    605     if (__file_ == 0)
    606     {
    607         __rt = this;
    608         const wchar_t* __mdstr;
    609         switch (__mode & ~ios_base::ate)
    610         {
    611         case ios_base::out:
    612         case ios_base::out | ios_base::trunc:
    613             __mdstr = L"w";
    614             break;
    615         case ios_base::out | ios_base::app:
    616         case ios_base::app:
    617             __mdstr = L"a";
    618             break;
    619         case ios_base::in:
    620             __mdstr = L"r";
    621             break;
    622         case ios_base::in | ios_base::out:
    623             __mdstr = L"r+";
    624             break;
    625         case ios_base::in | ios_base::out | ios_base::trunc:
    626             __mdstr = L"w+";
    627             break;
    628         case ios_base::in | ios_base::out | ios_base::app:
    629         case ios_base::in | ios_base::app:
    630             __mdstr = L"a+";
    631             break;
    632         case ios_base::out | ios_base::binary:
    633         case ios_base::out | ios_base::trunc | ios_base::binary:
    634             __mdstr = L"wb";
    635             break;
    636         case ios_base::out | ios_base::app | ios_base::binary:
    637         case ios_base::app | ios_base::binary:
    638             __mdstr = L"ab";
    639             break;
    640         case ios_base::in | ios_base::binary:
    641             __mdstr = L"rb";
    642             break;
    643         case ios_base::in | ios_base::out | ios_base::binary:
    644             __mdstr = L"r+b";
    645             break;
    646         case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
    647             __mdstr = L"w+b";
    648             break;
    649         case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
    650         case ios_base::in | ios_base::app | ios_base::binary:
    651             __mdstr = L"a+b";
    652             break;
    653         default:
    654             __rt = 0;
    655             break;
    656         }
    657         if (__rt)
    658         {
    659             __file_ = _wfopen(__s, __mdstr);
    660             if (__file_)
    661             {
    662                 __om_ = __mode;
    663                 if (__mode & ios_base::ate)
    664                 {
    665                     if (fseek(__file_, 0, SEEK_END))
    666                     {
    667                         fclose(__file_);
    668                         __file_ = 0;
    669                         __rt = 0;
    670                     }
    671                 }
    672             }
    673             else
    674                 __rt = 0;
    675         }
    676     }
    677     return __rt;
    678 }
    679 #endif
    680 
    681 template <class _CharT, class _Traits>
    682 inline
    683 basic_filebuf<_CharT, _Traits>*
    684 basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
    685 {
    686     return open(__s.c_str(), __mode);
    687 }
    688 #endif
    689 
    690 template <class _CharT, class _Traits>
    691 basic_filebuf<_CharT, _Traits>*
    692 basic_filebuf<_CharT, _Traits>::close()
    693 {
    694     basic_filebuf<_CharT, _Traits>* __rt = 0;
    695     if (__file_)
    696     {
    697         __rt = this;
    698         unique_ptr<FILE, int(*)(FILE*)> __h(__file_, fclose);
    699         if (sync())
    700             __rt = 0;
    701         if (fclose(__h.release()) == 0)
    702             __file_ = 0;
    703         else
    704             __rt = 0;
    705         setbuf(0, 0);
    706     }
    707     return __rt;
    708 }
    709 
    710 template <class _CharT, class _Traits>
    711 typename basic_filebuf<_CharT, _Traits>::int_type
    712 basic_filebuf<_CharT, _Traits>::underflow()
    713 {
    714     if (__file_ == 0)
    715         return traits_type::eof();
    716     bool __initial = __read_mode();
    717     char_type __1buf;
    718     if (this->gptr() == 0)
    719         this->setg(&__1buf, &__1buf+1, &__1buf+1);
    720     const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4);
    721     int_type __c = traits_type::eof();
    722     if (this->gptr() == this->egptr())
    723     {
    724         memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));
    725         if (__always_noconv_)
    726         {
    727             size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
    728             __nmemb = fread(this->eback() + __unget_sz, 1, __nmemb, __file_);
    729             if (__nmemb != 0)
    730             {
    731                 this->setg(this->eback(),
    732                            this->eback() + __unget_sz,
    733                            this->eback() + __unget_sz + __nmemb);
    734                 __c = traits_type::to_int_type(*this->gptr());
    735             }
    736         }
    737         else
    738         {
    739             _LIBCPP_ASSERT ( !(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" );
    740             if (__extbufend_ != __extbufnext_)
    741                 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
    742             __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
    743             __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);
    744             size_t __nmemb = _VSTD::min(static_cast<size_t>(__ibs_ - __unget_sz),
    745                                  static_cast<size_t>(__extbufend_ - __extbufnext_));
    746             codecvt_base::result __r;
    747             __st_last_ = __st_;
    748             size_t __nr = fread((void*) const_cast<char *>(__extbufnext_), 1, __nmemb, __file_);
    749             if (__nr != 0)
    750             {
    751                 if (!__cv_)
    752                     __throw_bad_cast();
    753 
    754                 __extbufend_ = __extbufnext_ + __nr;
    755                 char_type*  __inext;
    756                 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_,
    757                                        this->eback() + __unget_sz,
    758                                        this->eback() + __ibs_, __inext);
    759                 if (__r == codecvt_base::noconv)
    760                 {
    761                     this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, 
    762                                           (char_type*)const_cast<char *>(__extbufend_));
    763                     __c = traits_type::to_int_type(*this->gptr());
    764                 }
    765                 else if (__inext != this->eback() + __unget_sz)
    766                 {
    767                     this->setg(this->eback(), this->eback() + __unget_sz, __inext);
    768                     __c = traits_type::to_int_type(*this->gptr());
    769                 }
    770             }
    771         }
    772     }
    773     else
    774         __c = traits_type::to_int_type(*this->gptr());
    775     if (this->eback() == &__1buf)
    776         this->setg(0, 0, 0);
    777     return __c;
    778 }
    779 
    780 template <class _CharT, class _Traits>
    781 typename basic_filebuf<_CharT, _Traits>::int_type
    782 basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c)
    783 {
    784     if (__file_ && this->eback() < this->gptr())
    785     {
    786         if (traits_type::eq_int_type(__c, traits_type::eof()))
    787         {
    788             this->gbump(-1);
    789             return traits_type::not_eof(__c);
    790         }
    791         if ((__om_ & ios_base::out) ||
    792             traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
    793         {
    794             this->gbump(-1);
    795             *this->gptr() = traits_type::to_char_type(__c);
    796             return __c;
    797         }
    798     }
    799     return traits_type::eof();
    800 }
    801 
    802 template <class _CharT, class _Traits>
    803 typename basic_filebuf<_CharT, _Traits>::int_type
    804 basic_filebuf<_CharT, _Traits>::overflow(int_type __c)
    805 {
    806     if (__file_ == 0)
    807         return traits_type::eof();
    808     __write_mode();
    809     char_type __1buf;
    810     char_type* __pb_save = this->pbase();
    811     char_type* __epb_save = this->epptr();
    812     if (!traits_type::eq_int_type(__c, traits_type::eof()))
    813     {
    814         if (this->pptr() == 0)
    815             this->setp(&__1buf, &__1buf+1);
    816         *this->pptr() = traits_type::to_char_type(__c);
    817         this->pbump(1);
    818     }
    819     if (this->pptr() != this->pbase())
    820     {
    821         if (__always_noconv_)
    822         {
    823             size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
    824             if (fwrite(this->pbase(), sizeof(char_type), __nmemb, __file_) != __nmemb)
    825                 return traits_type::eof();
    826         }
    827         else
    828         {
    829             char* __extbe = __extbuf_;
    830             codecvt_base::result __r;
    831             do
    832             {
    833                 if (!__cv_)
    834                     __throw_bad_cast();
    835 
    836                 const char_type* __e;
    837                 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e,
    838                                         __extbuf_, __extbuf_ + __ebs_, __extbe);
    839                 if (__e == this->pbase())
    840                     return traits_type::eof();
    841                 if (__r == codecvt_base::noconv)
    842                 {
    843                     size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
    844                     if (fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
    845                         return traits_type::eof();
    846                 }
    847                 else if (__r == codecvt_base::ok || __r == codecvt_base::partial)
    848                 {
    849                     size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
    850                     if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
    851                         return traits_type::eof();
    852                     if (__r == codecvt_base::partial)
    853                     {
    854                         this->setp(const_cast<char_type*>(__e), this->pptr());
    855                         this->__pbump(this->epptr() - this->pbase());
    856                     }
    857                 }
    858                 else
    859                     return traits_type::eof();
    860             } while (__r == codecvt_base::partial);
    861         }
    862         this->setp(__pb_save, __epb_save);
    863     }
    864     return traits_type::not_eof(__c);
    865 }
    866 
    867 template <class _CharT, class _Traits>
    868 basic_streambuf<_CharT, _Traits>*
    869 basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n)
    870 {
    871     this->setg(0, 0, 0);
    872     this->setp(0, 0);
    873     if (__owns_eb_)
    874         delete [] __extbuf_;
    875     if (__owns_ib_)
    876         delete [] __intbuf_;
    877     __ebs_ = __n;
    878     if (__ebs_ > sizeof(__extbuf_min_))
    879     {
    880         if (__always_noconv_ && __s)
    881         {
    882             __extbuf_ = (char*)__s;
    883             __owns_eb_ = false;
    884         }
    885         else
    886         {
    887             __extbuf_ = new char[__ebs_];
    888             __owns_eb_ = true;
    889         }
    890     }
    891     else
    892     {
    893         __extbuf_ = __extbuf_min_;
    894         __ebs_ = sizeof(__extbuf_min_);
    895         __owns_eb_ = false;
    896     }
    897     if (!__always_noconv_)
    898     {
    899         __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));
    900         if (__s && __ibs_ >= sizeof(__extbuf_min_))
    901         {
    902             __intbuf_ = __s;
    903             __owns_ib_ = false;
    904         }
    905         else
    906         {
    907             __intbuf_ = new char_type[__ibs_];
    908             __owns_ib_ = true;
    909         }
    910     }
    911     else
    912     {
    913         __ibs_ = 0;
    914         __intbuf_ = 0;
    915         __owns_ib_ = false;
    916     }
    917     return this;
    918 }
    919 
    920 template <class _CharT, class _Traits>
    921 typename basic_filebuf<_CharT, _Traits>::pos_type
    922 basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way,
    923                                         ios_base::openmode)
    924 {
    925     if (!__cv_)
    926         __throw_bad_cast();
    927 
    928     int __width = __cv_->encoding();
    929     if (__file_ == 0 || (__width <= 0 && __off != 0) || sync())
    930         return pos_type(off_type(-1));
    931     // __width > 0 || __off == 0
    932     int __whence;
    933     switch (__way)
    934     {
    935     case ios_base::beg:
    936         __whence = SEEK_SET;
    937         break;
    938     case ios_base::cur:
    939         __whence = SEEK_CUR;
    940         break;
    941     case ios_base::end:
    942         __whence = SEEK_END;
    943         break;
    944     default:
    945         return pos_type(off_type(-1));
    946     }
    947 #if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
    948     if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence))
    949         return pos_type(off_type(-1));
    950     pos_type __r = ftell(__file_);
    951 #else
    952     if (fseeko(__file_, __width > 0 ? __width * __off : 0, __whence))
    953         return pos_type(off_type(-1));
    954     pos_type __r = ftello(__file_);
    955 #endif
    956     __r.state(__st_);
    957     return __r;
    958 }
    959 
    960 template <class _CharT, class _Traits>
    961 typename basic_filebuf<_CharT, _Traits>::pos_type
    962 basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode)
    963 {
    964     if (__file_ == 0 || sync())
    965         return pos_type(off_type(-1));
    966 #if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
    967     if (fseek(__file_, __sp, SEEK_SET))
    968         return pos_type(off_type(-1));
    969 #else
    970     if (fseeko(__file_, __sp, SEEK_SET))
    971         return pos_type(off_type(-1));
    972 #endif
    973     __st_ = __sp.state();
    974     return __sp;
    975 }
    976 
    977 template <class _CharT, class _Traits>
    978 int
    979 basic_filebuf<_CharT, _Traits>::sync()
    980 {
    981     if (__file_ == 0)
    982         return 0;
    983     if (!__cv_)
    984         __throw_bad_cast();
    985 
    986     if (__cm_ & ios_base::out)
    987     {
    988         if (this->pptr() != this->pbase())
    989             if (overflow() == traits_type::eof())
    990                 return -1;
    991         codecvt_base::result __r;
    992         do
    993         {
    994             char* __extbe;
    995             __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);
    996             size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);
    997             if (fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)
    998                 return -1;
    999         } while (__r == codecvt_base::partial);
   1000         if (__r == codecvt_base::error)
   1001             return -1;
   1002         if (fflush(__file_))
   1003             return -1;
   1004     }
   1005     else if (__cm_ & ios_base::in)
   1006     {
   1007         off_type __c;
   1008         state_type __state = __st_last_;
   1009         bool __update_st = false;
   1010         if (__always_noconv_)
   1011             __c = this->egptr() - this->gptr();
   1012         else
   1013         {
   1014             int __width = __cv_->encoding();
   1015             __c = __extbufend_ - __extbufnext_;
   1016             if (__width > 0)
   1017                 __c += __width * (this->egptr() - this->gptr());
   1018             else
   1019             {
   1020                 if (this->gptr() != this->egptr())
   1021                 {
   1022                     const int __off =  __cv_->length(__state, __extbuf_,
   1023                                                      __extbufnext_,
   1024                                                      this->gptr() - this->eback());
   1025                     __c += __extbufnext_ - __extbuf_ - __off;
   1026                     __update_st = true;
   1027                 }
   1028             }
   1029         }
   1030 #if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS)
   1031         if (fseek(__file_, -__c, SEEK_CUR))
   1032             return -1;
   1033 #else
   1034         if (fseeko(__file_, -__c, SEEK_CUR))
   1035             return -1;
   1036 #endif
   1037         if (__update_st)
   1038             __st_ = __state;
   1039         __extbufnext_ = __extbufend_ = __extbuf_;
   1040         this->setg(0, 0, 0);
   1041         __cm_ = 0;
   1042     }
   1043     return 0;
   1044 }
   1045 
   1046 template <class _CharT, class _Traits>
   1047 void
   1048 basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc)
   1049 {
   1050     sync();
   1051     __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc);
   1052     bool __old_anc = __always_noconv_;
   1053     __always_noconv_ = __cv_->always_noconv();
   1054     if (__old_anc != __always_noconv_)
   1055     {
   1056         this->setg(0, 0, 0);
   1057         this->setp(0, 0);
   1058         // invariant, char_type is char, else we couldn't get here
   1059         if (__always_noconv_)  // need to dump __intbuf_
   1060         {
   1061             if (__owns_eb_)
   1062                 delete [] __extbuf_;
   1063             __owns_eb_ = __owns_ib_;
   1064             __ebs_ = __ibs_;
   1065             __extbuf_ = (char*)__intbuf_;
   1066             __ibs_ = 0;
   1067             __intbuf_ = 0;
   1068             __owns_ib_ = false;
   1069         }
   1070         else  // need to obtain an __intbuf_.
   1071         {     // If __extbuf_ is user-supplied, use it, else new __intbuf_
   1072             if (!__owns_eb_ && __extbuf_ != __extbuf_min_)
   1073             {
   1074                 __ibs_ = __ebs_;
   1075                 __intbuf_ = (char_type*)__extbuf_;
   1076                 __owns_ib_ = false;
   1077                 __extbuf_ = new char[__ebs_];
   1078                 __owns_eb_ = true;
   1079             }
   1080             else
   1081             {
   1082                 __ibs_ = __ebs_;
   1083                 __intbuf_ = new char_type[__ibs_];
   1084                 __owns_ib_ = true;
   1085             }
   1086         }
   1087     }
   1088 }
   1089 
   1090 template <class _CharT, class _Traits>
   1091 bool
   1092 basic_filebuf<_CharT, _Traits>::__read_mode()
   1093 {
   1094     if (!(__cm_ & ios_base::in))
   1095     {
   1096         this->setp(0, 0);
   1097         if (__always_noconv_)
   1098             this->setg((char_type*)__extbuf_,
   1099                        (char_type*)__extbuf_ + __ebs_,
   1100                        (char_type*)__extbuf_ + __ebs_);
   1101         else
   1102             this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);
   1103         __cm_ = ios_base::in;
   1104         return true;
   1105     }
   1106     return false;
   1107 }
   1108 
   1109 template <class _CharT, class _Traits>
   1110 void
   1111 basic_filebuf<_CharT, _Traits>::__write_mode()
   1112 {
   1113     if (!(__cm_ & ios_base::out))
   1114     {
   1115         this->setg(0, 0, 0);
   1116         if (__ebs_ > sizeof(__extbuf_min_))
   1117         {
   1118             if (__always_noconv_)
   1119                 this->setp((char_type*)__extbuf_,
   1120                            (char_type*)__extbuf_ + (__ebs_ - 1));
   1121             else
   1122                 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));
   1123         }
   1124         else
   1125             this->setp(0, 0);
   1126         __cm_ = ios_base::out;
   1127     }
   1128 }
   1129 
   1130 // basic_ifstream
   1131 
   1132 template <class _CharT, class _Traits>
   1133 class _LIBCPP_TEMPLATE_VIS basic_ifstream
   1134     : public basic_istream<_CharT, _Traits>
   1135 {
   1136 public:
   1137     typedef _CharT                         char_type;
   1138     typedef _Traits                        traits_type;
   1139     typedef typename traits_type::int_type int_type;
   1140     typedef typename traits_type::pos_type pos_type;
   1141     typedef typename traits_type::off_type off_type;
   1142 
   1143     _LIBCPP_INLINE_VISIBILITY
   1144     basic_ifstream();
   1145 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
   1146     _LIBCPP_INLINE_VISIBILITY
   1147     explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);
   1148 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
   1149     _LIBCPP_INLINE_VISIBILITY
   1150     explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
   1151 #endif
   1152     _LIBCPP_INLINE_VISIBILITY
   1153     explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);
   1154 #if _LIBCPP_STD_VER >= 17
   1155     _LIBCPP_INLINE_VISIBILITY
   1156     explicit basic_ifstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in)
   1157       : basic_ifstream(__p.c_str(), __mode) {}
   1158 #endif // _LIBCPP_STD_VER >= 17
   1159 #endif
   1160 #ifndef _LIBCPP_CXX03_LANG
   1161     _LIBCPP_INLINE_VISIBILITY
   1162     basic_ifstream(basic_ifstream&& __rhs);
   1163 
   1164     _LIBCPP_INLINE_VISIBILITY
   1165     basic_ifstream& operator=(basic_ifstream&& __rhs);
   1166 #endif
   1167     _LIBCPP_INLINE_VISIBILITY
   1168     void swap(basic_ifstream& __rhs);
   1169 
   1170     _LIBCPP_INLINE_VISIBILITY
   1171     basic_filebuf<char_type, traits_type>* rdbuf() const;
   1172     _LIBCPP_INLINE_VISIBILITY
   1173     bool is_open() const;
   1174 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
   1175     void open(const char* __s, ios_base::openmode __mode = ios_base::in);
   1176 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
   1177     void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);
   1178 #endif
   1179     void open(const string& __s, ios_base::openmode __mode = ios_base::in);
   1180 #if _LIBCPP_STD_VER >= 17
   1181     _LIBCPP_INLINE_VISIBILITY
   1182     void open(const filesystem::path& __p,
   1183               ios_base::openmode __mode = ios_base::in) {
   1184       return open(__p.c_str(), __mode);
   1185     }
   1186 #endif // _LIBCPP_STD_VER >= 17
   1187 
   1188     _LIBCPP_INLINE_VISIBILITY
   1189     void __open(int __fd, ios_base::openmode __mode);
   1190 #endif
   1191     _LIBCPP_INLINE_VISIBILITY
   1192     void close();
   1193 
   1194 private:
   1195     basic_filebuf<char_type, traits_type> __sb_;
   1196 };
   1197 
   1198 template <class _CharT, class _Traits>
   1199 inline
   1200 basic_ifstream<_CharT, _Traits>::basic_ifstream()
   1201     : basic_istream<char_type, traits_type>(&__sb_)
   1202 {
   1203 }
   1204 
   1205 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
   1206 template <class _CharT, class _Traits>
   1207 inline
   1208 basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)
   1209     : basic_istream<char_type, traits_type>(&__sb_)
   1210 {
   1211     if (__sb_.open(__s, __mode | ios_base::in) == 0)
   1212         this->setstate(ios_base::failbit);
   1213 }
   1214 
   1215 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
   1216 template <class _CharT, class _Traits>
   1217 inline
   1218 basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode)
   1219     : basic_istream<char_type, traits_type>(&__sb_)
   1220 {
   1221     if (__sb_.open(__s, __mode | ios_base::in) == 0)
   1222         this->setstate(ios_base::failbit);
   1223 }
   1224 #endif
   1225 
   1226 template <class _CharT, class _Traits>
   1227 inline
   1228 basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)
   1229     : basic_istream<char_type, traits_type>(&__sb_)
   1230 {
   1231     if (__sb_.open(__s, __mode | ios_base::in) == 0)
   1232         this->setstate(ios_base::failbit);
   1233 }
   1234 #endif
   1235 
   1236 #ifndef _LIBCPP_CXX03_LANG
   1237 
   1238 template <class _CharT, class _Traits>
   1239 inline
   1240 basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)
   1241     : basic_istream<char_type, traits_type>(_VSTD::move(__rhs)),
   1242       __sb_(_VSTD::move(__rhs.__sb_))
   1243 {
   1244     this->set_rdbuf(&__sb_);
   1245 }
   1246 
   1247 template <class _CharT, class _Traits>
   1248 inline
   1249 basic_ifstream<_CharT, _Traits>&
   1250 basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs)
   1251 {
   1252     basic_istream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
   1253     __sb_ = _VSTD::move(__rhs.__sb_);
   1254     return *this;
   1255 }
   1256 
   1257 #endif  // _LIBCPP_CXX03_LANG
   1258 
   1259 template <class _CharT, class _Traits>
   1260 inline
   1261 void
   1262 basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs)
   1263 {
   1264     basic_istream<char_type, traits_type>::swap(__rhs);
   1265     __sb_.swap(__rhs.__sb_);
   1266 }
   1267 
   1268 template <class _CharT, class _Traits>
   1269 inline _LIBCPP_INLINE_VISIBILITY
   1270 void
   1271 swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y)
   1272 {
   1273     __x.swap(__y);
   1274 }
   1275 
   1276 template <class _CharT, class _Traits>
   1277 inline
   1278 basic_filebuf<_CharT, _Traits>*
   1279 basic_ifstream<_CharT, _Traits>::rdbuf() const
   1280 {
   1281     return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
   1282 }
   1283 
   1284 template <class _CharT, class _Traits>
   1285 inline
   1286 bool
   1287 basic_ifstream<_CharT, _Traits>::is_open() const
   1288 {
   1289     return __sb_.is_open();
   1290 }
   1291 
   1292 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
   1293 template <class _CharT, class _Traits>
   1294 void
   1295 basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
   1296 {
   1297     if (__sb_.open(__s, __mode | ios_base::in))
   1298         this->clear();
   1299     else
   1300         this->setstate(ios_base::failbit);
   1301 }
   1302 
   1303 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
   1304 template <class _CharT, class _Traits>
   1305 void
   1306 basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode)
   1307 {
   1308     if (__sb_.open(__s, __mode | ios_base::in))
   1309         this->clear();
   1310     else
   1311         this->setstate(ios_base::failbit);
   1312 }
   1313 #endif
   1314 
   1315 template <class _CharT, class _Traits>
   1316 void
   1317 basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
   1318 {
   1319     if (__sb_.open(__s, __mode | ios_base::in))
   1320         this->clear();
   1321     else
   1322         this->setstate(ios_base::failbit);
   1323 }
   1324 
   1325 template <class _CharT, class _Traits>
   1326 void basic_ifstream<_CharT, _Traits>::__open(int __fd,
   1327                                              ios_base::openmode __mode) {
   1328   if (__sb_.__open(__fd, __mode | ios_base::in))
   1329     this->clear();
   1330   else
   1331     this->setstate(ios_base::failbit);
   1332 }
   1333 #endif
   1334 
   1335 template <class _CharT, class _Traits>
   1336 inline
   1337 void
   1338 basic_ifstream<_CharT, _Traits>::close()
   1339 {
   1340     if (__sb_.close() == 0)
   1341         this->setstate(ios_base::failbit);
   1342 }
   1343 
   1344 // basic_ofstream
   1345 
   1346 template <class _CharT, class _Traits>
   1347 class _LIBCPP_TEMPLATE_VIS basic_ofstream
   1348     : public basic_ostream<_CharT, _Traits>
   1349 {
   1350 public:
   1351     typedef _CharT                         char_type;
   1352     typedef _Traits                        traits_type;
   1353     typedef typename traits_type::int_type int_type;
   1354     typedef typename traits_type::pos_type pos_type;
   1355     typedef typename traits_type::off_type off_type;
   1356 
   1357     _LIBCPP_INLINE_VISIBILITY
   1358     basic_ofstream();
   1359     _LIBCPP_INLINE_VISIBILITY
   1360     explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);
   1361 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
   1362     _LIBCPP_INLINE_VISIBILITY
   1363     explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
   1364 #endif
   1365     _LIBCPP_INLINE_VISIBILITY
   1366     explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);
   1367 
   1368 #if _LIBCPP_STD_VER >= 17
   1369     _LIBCPP_INLINE_VISIBILITY
   1370     explicit basic_ofstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
   1371       : basic_ofstream(__p.c_str(), __mode) {}
   1372 #endif // _LIBCPP_STD_VER >= 17
   1373 
   1374 #ifndef _LIBCPP_CXX03_LANG
   1375     _LIBCPP_INLINE_VISIBILITY
   1376     basic_ofstream(basic_ofstream&& __rhs);
   1377 
   1378     _LIBCPP_INLINE_VISIBILITY
   1379     basic_ofstream& operator=(basic_ofstream&& __rhs);
   1380 #endif
   1381     _LIBCPP_INLINE_VISIBILITY
   1382     void swap(basic_ofstream& __rhs);
   1383 
   1384     _LIBCPP_INLINE_VISIBILITY
   1385     basic_filebuf<char_type, traits_type>* rdbuf() const;
   1386     _LIBCPP_INLINE_VISIBILITY
   1387     bool is_open() const;
   1388 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
   1389     void open(const char* __s, ios_base::openmode __mode = ios_base::out);
   1390 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
   1391     void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);
   1392 #endif
   1393     void open(const string& __s, ios_base::openmode __mode = ios_base::out);
   1394 
   1395 #if _LIBCPP_STD_VER >= 17
   1396     _LIBCPP_INLINE_VISIBILITY
   1397     void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out)
   1398     { return open(__p.c_str(), __mode); }
   1399 #endif // _LIBCPP_STD_VER >= 17
   1400 
   1401     _LIBCPP_INLINE_VISIBILITY
   1402     void __open(int __fd, ios_base::openmode __mode);
   1403 #endif
   1404     _LIBCPP_INLINE_VISIBILITY
   1405     void close();
   1406 
   1407 private:
   1408     basic_filebuf<char_type, traits_type> __sb_;
   1409 };
   1410 
   1411 template <class _CharT, class _Traits>
   1412 inline
   1413 basic_ofstream<_CharT, _Traits>::basic_ofstream()
   1414     : basic_ostream<char_type, traits_type>(&__sb_)
   1415 {
   1416 }
   1417 
   1418 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
   1419 template <class _CharT, class _Traits>
   1420 inline
   1421 basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)
   1422     : basic_ostream<char_type, traits_type>(&__sb_)
   1423 {
   1424     if (__sb_.open(__s, __mode | ios_base::out) == 0)
   1425         this->setstate(ios_base::failbit);
   1426 }
   1427 
   1428 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
   1429 template <class _CharT, class _Traits>
   1430 inline
   1431 basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode)
   1432     : basic_ostream<char_type, traits_type>(&__sb_)
   1433 {
   1434     if (__sb_.open(__s, __mode | ios_base::out) == 0)
   1435         this->setstate(ios_base::failbit);
   1436 }
   1437 #endif
   1438 
   1439 template <class _CharT, class _Traits>
   1440 inline
   1441 basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)
   1442     : basic_ostream<char_type, traits_type>(&__sb_)
   1443 {
   1444     if (__sb_.open(__s, __mode | ios_base::out) == 0)
   1445         this->setstate(ios_base::failbit);
   1446 }
   1447 #endif
   1448 
   1449 #ifndef _LIBCPP_CXX03_LANG
   1450 
   1451 template <class _CharT, class _Traits>
   1452 inline
   1453 basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)
   1454     : basic_ostream<char_type, traits_type>(_VSTD::move(__rhs)),
   1455       __sb_(_VSTD::move(__rhs.__sb_))
   1456 {
   1457     this->set_rdbuf(&__sb_);
   1458 }
   1459 
   1460 template <class _CharT, class _Traits>
   1461 inline
   1462 basic_ofstream<_CharT, _Traits>&
   1463 basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs)
   1464 {
   1465     basic_ostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
   1466     __sb_ = _VSTD::move(__rhs.__sb_);
   1467     return *this;
   1468 }
   1469 
   1470 #endif  // _LIBCPP_CXX03_LANG
   1471 
   1472 template <class _CharT, class _Traits>
   1473 inline
   1474 void
   1475 basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs)
   1476 {
   1477     basic_ostream<char_type, traits_type>::swap(__rhs);
   1478     __sb_.swap(__rhs.__sb_);
   1479 }
   1480 
   1481 template <class _CharT, class _Traits>
   1482 inline _LIBCPP_INLINE_VISIBILITY
   1483 void
   1484 swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y)
   1485 {
   1486     __x.swap(__y);
   1487 }
   1488 
   1489 template <class _CharT, class _Traits>
   1490 inline
   1491 basic_filebuf<_CharT, _Traits>*
   1492 basic_ofstream<_CharT, _Traits>::rdbuf() const
   1493 {
   1494     return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
   1495 }
   1496 
   1497 template <class _CharT, class _Traits>
   1498 inline
   1499 bool
   1500 basic_ofstream<_CharT, _Traits>::is_open() const
   1501 {
   1502     return __sb_.is_open();
   1503 }
   1504 
   1505 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
   1506 template <class _CharT, class _Traits>
   1507 void
   1508 basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
   1509 {
   1510     if (__sb_.open(__s, __mode | ios_base::out))
   1511         this->clear();
   1512     else
   1513         this->setstate(ios_base::failbit);
   1514 }
   1515 
   1516 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
   1517 template <class _CharT, class _Traits>
   1518 void
   1519 basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode)
   1520 {
   1521     if (__sb_.open(__s, __mode | ios_base::out))
   1522         this->clear();
   1523     else
   1524         this->setstate(ios_base::failbit);
   1525 }
   1526 #endif
   1527 
   1528 template <class _CharT, class _Traits>
   1529 void
   1530 basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
   1531 {
   1532     if (__sb_.open(__s, __mode | ios_base::out))
   1533         this->clear();
   1534     else
   1535         this->setstate(ios_base::failbit);
   1536 }
   1537 
   1538 template <class _CharT, class _Traits>
   1539 void basic_ofstream<_CharT, _Traits>::__open(int __fd,
   1540                                              ios_base::openmode __mode) {
   1541   if (__sb_.__open(__fd, __mode | ios_base::out))
   1542     this->clear();
   1543   else
   1544     this->setstate(ios_base::failbit);
   1545 }
   1546 #endif
   1547 
   1548 template <class _CharT, class _Traits>
   1549 inline
   1550 void
   1551 basic_ofstream<_CharT, _Traits>::close()
   1552 {
   1553     if (__sb_.close() == 0)
   1554         this->setstate(ios_base::failbit);
   1555 }
   1556 
   1557 // basic_fstream
   1558 
   1559 template <class _CharT, class _Traits>
   1560 class _LIBCPP_TEMPLATE_VIS basic_fstream
   1561     : public basic_iostream<_CharT, _Traits>
   1562 {
   1563 public:
   1564     typedef _CharT                         char_type;
   1565     typedef _Traits                        traits_type;
   1566     typedef typename traits_type::int_type int_type;
   1567     typedef typename traits_type::pos_type pos_type;
   1568     typedef typename traits_type::off_type off_type;
   1569 
   1570     _LIBCPP_INLINE_VISIBILITY
   1571     basic_fstream();
   1572 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
   1573     _LIBCPP_INLINE_VISIBILITY
   1574     explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
   1575 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
   1576     _LIBCPP_INLINE_VISIBILITY
   1577     explicit basic_fstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
   1578 #endif
   1579     _LIBCPP_INLINE_VISIBILITY
   1580     explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
   1581 
   1582 #if _LIBCPP_STD_VER >= 17
   1583     _LIBCPP_INLINE_VISIBILITY
   1584     explicit basic_fstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)
   1585       : basic_fstream(__p.c_str(), __mode) {}
   1586 #endif // _LIBCPP_STD_VER >= 17
   1587 
   1588 #endif
   1589 #ifndef _LIBCPP_CXX03_LANG
   1590     _LIBCPP_INLINE_VISIBILITY
   1591     basic_fstream(basic_fstream&& __rhs);
   1592 
   1593     _LIBCPP_INLINE_VISIBILITY
   1594     basic_fstream& operator=(basic_fstream&& __rhs);
   1595 #endif
   1596     _LIBCPP_INLINE_VISIBILITY
   1597     void swap(basic_fstream& __rhs);
   1598 
   1599     _LIBCPP_INLINE_VISIBILITY
   1600     basic_filebuf<char_type, traits_type>* rdbuf() const;
   1601     _LIBCPP_INLINE_VISIBILITY
   1602     bool is_open() const;
   1603 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
   1604     void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
   1605 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
   1606     void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
   1607 #endif
   1608     void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);
   1609 
   1610 #if _LIBCPP_STD_VER >= 17
   1611     _LIBCPP_INLINE_VISIBILITY
   1612     void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in|ios_base::out)
   1613     { return open(__p.c_str(), __mode); }
   1614 #endif // _LIBCPP_STD_VER >= 17
   1615 
   1616 #endif
   1617     _LIBCPP_INLINE_VISIBILITY
   1618     void close();
   1619 
   1620 private:
   1621     basic_filebuf<char_type, traits_type> __sb_;
   1622 };
   1623 
   1624 template <class _CharT, class _Traits>
   1625 inline
   1626 basic_fstream<_CharT, _Traits>::basic_fstream()
   1627     : basic_iostream<char_type, traits_type>(&__sb_)
   1628 {
   1629 }
   1630 
   1631 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
   1632 template <class _CharT, class _Traits>
   1633 inline
   1634 basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)
   1635     : basic_iostream<char_type, traits_type>(&__sb_)
   1636 {
   1637     if (__sb_.open(__s, __mode) == 0)
   1638         this->setstate(ios_base::failbit);
   1639 }
   1640 
   1641 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
   1642 template <class _CharT, class _Traits>
   1643 inline
   1644 basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode)
   1645     : basic_iostream<char_type, traits_type>(&__sb_)
   1646 {
   1647     if (__sb_.open(__s, __mode) == 0)
   1648         this->setstate(ios_base::failbit);
   1649 }
   1650 #endif
   1651 
   1652 template <class _CharT, class _Traits>
   1653 inline
   1654 basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)
   1655     : basic_iostream<char_type, traits_type>(&__sb_)
   1656 {
   1657     if (__sb_.open(__s, __mode) == 0)
   1658         this->setstate(ios_base::failbit);
   1659 }
   1660 #endif
   1661 
   1662 #ifndef _LIBCPP_CXX03_LANG
   1663 
   1664 template <class _CharT, class _Traits>
   1665 inline
   1666 basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)
   1667     : basic_iostream<char_type, traits_type>(_VSTD::move(__rhs)),
   1668       __sb_(_VSTD::move(__rhs.__sb_))
   1669 {
   1670     this->set_rdbuf(&__sb_);
   1671 }
   1672 
   1673 template <class _CharT, class _Traits>
   1674 inline
   1675 basic_fstream<_CharT, _Traits>&
   1676 basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs)
   1677 {
   1678     basic_iostream<char_type, traits_type>::operator=(_VSTD::move(__rhs));
   1679     __sb_ = _VSTD::move(__rhs.__sb_);
   1680     return *this;
   1681 }
   1682 
   1683 #endif  // _LIBCPP_CXX03_LANG
   1684 
   1685 template <class _CharT, class _Traits>
   1686 inline
   1687 void
   1688 basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs)
   1689 {
   1690     basic_iostream<char_type, traits_type>::swap(__rhs);
   1691     __sb_.swap(__rhs.__sb_);
   1692 }
   1693 
   1694 template <class _CharT, class _Traits>
   1695 inline _LIBCPP_INLINE_VISIBILITY
   1696 void
   1697 swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y)
   1698 {
   1699     __x.swap(__y);
   1700 }
   1701 
   1702 template <class _CharT, class _Traits>
   1703 inline
   1704 basic_filebuf<_CharT, _Traits>*
   1705 basic_fstream<_CharT, _Traits>::rdbuf() const
   1706 {
   1707     return const_cast<basic_filebuf<char_type, traits_type>*>(&__sb_);
   1708 }
   1709 
   1710 template <class _CharT, class _Traits>
   1711 inline
   1712 bool
   1713 basic_fstream<_CharT, _Traits>::is_open() const
   1714 {
   1715     return __sb_.is_open();
   1716 }
   1717 
   1718 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
   1719 template <class _CharT, class _Traits>
   1720 void
   1721 basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode)
   1722 {
   1723     if (__sb_.open(__s, __mode))
   1724         this->clear();
   1725     else
   1726         this->setstate(ios_base::failbit);
   1727 }
   1728 
   1729 #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR
   1730 template <class _CharT, class _Traits>
   1731 void
   1732 basic_fstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode)
   1733 {
   1734     if (__sb_.open(__s, __mode))
   1735         this->clear();
   1736     else
   1737         this->setstate(ios_base::failbit);
   1738 }
   1739 #endif
   1740 
   1741 template <class _CharT, class _Traits>
   1742 void
   1743 basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode)
   1744 {
   1745     if (__sb_.open(__s, __mode))
   1746         this->clear();
   1747     else
   1748         this->setstate(ios_base::failbit);
   1749 }
   1750 #endif
   1751 
   1752 template <class _CharT, class _Traits>
   1753 inline
   1754 void
   1755 basic_fstream<_CharT, _Traits>::close()
   1756 {
   1757     if (__sb_.close() == 0)
   1758         this->setstate(ios_base::failbit);
   1759 }
   1760 
   1761 _LIBCPP_END_NAMESPACE_STD
   1762 
   1763 _LIBCPP_POP_MACROS
   1764 
   1765 #endif  // _LIBCPP_FSTREAM
   1766