1632 lines · plain
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP_FSTREAM11#define _LIBCPP_FSTREAM12 13/*14 fstream synopsis15 16template <class charT, class traits = char_traits<charT> >17class basic_filebuf18 : public basic_streambuf<charT, traits>19{20public:21 typedef charT char_type;22 typedef traits traits_type;23 typedef typename traits_type::int_type int_type;24 typedef typename traits_type::pos_type pos_type;25 typedef typename traits_type::off_type off_type;26 27 // 27.9.1.2 Constructors/destructor:28 basic_filebuf();29 basic_filebuf(basic_filebuf&& rhs);30 virtual ~basic_filebuf();31 32 // 27.9.1.3 Assign/swap:33 basic_filebuf& operator=(basic_filebuf&& rhs);34 void swap(basic_filebuf& rhs);35 36 // 27.9.1.4 Members:37 bool is_open() const;38 basic_filebuf* open(const char* s, ios_base::openmode mode);39 basic_filebuf* open(const string& s, ios_base::openmode mode);40 basic_filebuf* open(const filesystem::path& p, ios_base::openmode mode); // C++1741 basic_filebuf* close();42 43protected:44 // 27.9.1.5 Overridden virtual functions:45 virtual streamsize showmanyc();46 virtual int_type underflow();47 virtual int_type uflow();48 virtual int_type pbackfail(int_type c = traits_type::eof());49 virtual int_type overflow (int_type c = traits_type::eof());50 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* s, streamsize n);51 virtual pos_type seekoff(off_type off, ios_base::seekdir way,52 ios_base::openmode which = ios_base::in | ios_base::out);53 virtual pos_type seekpos(pos_type sp,54 ios_base::openmode which = ios_base::in | ios_base::out);55 virtual int sync();56 virtual void imbue(const locale& loc);57};58 59template <class charT, class traits>60 void61 swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y);62 63typedef basic_filebuf<char> filebuf;64typedef basic_filebuf<wchar_t> wfilebuf;65 66template <class charT, class traits = char_traits<charT> >67class basic_ifstream68 : public basic_istream<charT,traits>69{70public:71 typedef charT char_type;72 typedef traits traits_type;73 typedef typename traits_type::int_type int_type;74 typedef typename traits_type::pos_type pos_type;75 typedef typename traits_type::off_type off_type;76 using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++2677 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 template<class T>82 explicit basic_ifstream(const T& s, ios_base::openmode mode = ios_base::in); // Since C++1783 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 native_handle_type native_handle() const noexcept; // Since C++2690 bool is_open() const;91 void open(const char* s, ios_base::openmode mode = ios_base::in);92 void open(const string& s, ios_base::openmode mode = ios_base::in);93 void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); // C++1794 95 void close();96};97 98template <class charT, class traits>99 void100 swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y);101 102typedef basic_ifstream<char> ifstream;103typedef basic_ifstream<wchar_t> wifstream;104 105template <class charT, class traits = char_traits<charT> >106class basic_ofstream107 : public basic_ostream<charT,traits>108{109public:110 typedef charT char_type;111 typedef traits traits_type;112 typedef typename traits_type::int_type int_type;113 typedef typename traits_type::pos_type pos_type;114 typedef typename traits_type::off_type off_type;115 using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26116 117 basic_ofstream();118 explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);119 explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);120 template<class T>121 explicit basic_ofstream(const T& s, ios_base::openmode mode = ios_base::out); // Since C++17122 basic_ofstream(basic_ofstream&& rhs);123 124 basic_ofstream& operator=(basic_ofstream&& rhs);125 void swap(basic_ofstream& rhs);126 127 basic_filebuf<char_type, traits_type>* rdbuf() const;128 native_handle_type native_handle() const noexcept; // Since C++26129 130 bool is_open() const;131 void open(const char* s, ios_base::openmode mode = ios_base::out);132 void open(const string& s, ios_base::openmode mode = ios_base::out);133 void open(const filesystem::path& p,134 ios_base::openmode mode = ios_base::out); // C++17135 136 void close();137};138 139template <class charT, class traits>140 void141 swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y);142 143typedef basic_ofstream<char> ofstream;144typedef basic_ofstream<wchar_t> wofstream;145 146template <class charT, class traits=char_traits<charT> >147class basic_fstream148 : public basic_iostream<charT,traits>149{150public:151 typedef charT char_type;152 typedef traits traits_type;153 typedef typename traits_type::int_type int_type;154 typedef typename traits_type::pos_type pos_type;155 typedef typename traits_type::off_type off_type;156 using native_handle_type = typename basic_filebuf<charT, traits>::native_handle_type; // Since C++26157 158 basic_fstream();159 explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);160 explicit basic_fstream(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);161 template<class T>162 explicit basic_fstream(const T& s, ios_base::openmode mode = ios_base::in | ios_base::out); // Since C++17163 basic_fstream(basic_fstream&& rhs);164 165 basic_fstream& operator=(basic_fstream&& rhs);166 void swap(basic_fstream& rhs);167 168 basic_filebuf<char_type, traits_type>* rdbuf() const;169 native_handle_type native_handle() const noexcept; // Since C++26170 bool is_open() const;171 void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);172 void open(const string& s, ios_base::openmode mode = ios_base::in|ios_base::out);173 void open(const filesystem::path& s,174 ios_base::openmode mode = ios_base::in|ios_base::out); // C++17175 176 void close();177};178 179template <class charT, class traits>180 void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y);181 182typedef basic_fstream<char> fstream;183typedef basic_fstream<wchar_t> wfstream;184 185} // std186 187*/188 189#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)190# include <__cxx03/fstream>191#else192# include <__config>193 194# if _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION195 196# include <__algorithm/max.h>197# include <__assert>198# include <__filesystem/path.h>199# include <__fwd/fstream.h>200# include <__locale>201# include <__memory/addressof.h>202# include <__memory/unique_ptr.h>203# include <__ostream/basic_ostream.h>204# include <__type_traits/enable_if.h>205# include <__type_traits/is_same.h>206# include <__utility/move.h>207# include <__utility/swap.h>208# include <__utility/unreachable.h>209# include <cstdio>210# include <istream>211# include <streambuf>212# include <typeinfo>213# include <version>214 215# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)216# pragma GCC system_header217# endif218 219_LIBCPP_PUSH_MACROS220# include <__undef_macros>221 222_LIBCPP_BEGIN_NAMESPACE_STD223 224# if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_WIN32API)225_LIBCPP_EXPORTED_FROM_ABI void* __filebuf_windows_native_handle(FILE* __file) noexcept;226# endif227 228template <class _CharT, class _Traits>229class basic_filebuf : public basic_streambuf<_CharT, _Traits> {230public:231 typedef _CharT char_type;232 typedef _Traits traits_type;233 typedef typename traits_type::int_type int_type;234 typedef typename traits_type::pos_type pos_type;235 typedef typename traits_type::off_type off_type;236 typedef typename traits_type::state_type state_type;237# if _LIBCPP_STD_VER >= 26238# if defined(_LIBCPP_WIN32API)239 using native_handle_type = void*; // HANDLE240# elif __has_include(<unistd.h>)241 using native_handle_type = int; // POSIX file descriptor242# else243# error "Provide a native file handle!"244# endif245# endif246 247 // 27.9.1.2 Constructors/destructor:248 basic_filebuf();249 basic_filebuf(basic_filebuf&& __rhs);250 ~basic_filebuf() override;251 252 // 27.9.1.3 Assign/swap:253 _LIBCPP_HIDE_FROM_ABI basic_filebuf& operator=(basic_filebuf&& __rhs);254 void swap(basic_filebuf& __rhs);255 256 // 27.9.1.4 Members:257 _LIBCPP_HIDE_FROM_ABI bool is_open() const;258 basic_filebuf* open(const char* __s, ios_base::openmode __mode);259# if _LIBCPP_HAS_OPEN_WITH_WCHAR260 basic_filebuf* open(const wchar_t* __s, ios_base::openmode __mode);261# endif262 _LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const string& __s, ios_base::openmode __mode);263 264# if _LIBCPP_STD_VER >= 17265 _LIBCPP_HIDE_FROM_ABI basic_filebuf* open(const filesystem::path& __p, ios_base::openmode __mode) {266 return open(__p.c_str(), __mode);267 }268# endif269 _LIBCPP_HIDE_FROM_ABI basic_filebuf* __open(int __fd, ios_base::openmode __mode);270 basic_filebuf* close();271# if _LIBCPP_STD_VER >= 26272 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept {273 _LIBCPP_ASSERT_UNCATEGORIZED(this->is_open(), "File must be opened");274# if defined(_LIBCPP_WIN32API)275 return std::__filebuf_windows_native_handle(__file_);276# elif __has_include(<unistd.h>)277 return fileno(__file_);278# else279# error "Provide a way to determine the file native handle!"280# endif281 }282# endif // _LIBCPP_STD_VER >= 26283 284 _LIBCPP_HIDE_FROM_ABI inline static const char* __make_mdstring(ios_base::openmode __mode) _NOEXCEPT;285# if _LIBCPP_HAS_OPEN_WITH_WCHAR286 _LIBCPP_HIDE_FROM_ABI inline static const wchar_t* __make_mdwstring(ios_base::openmode __mode) _NOEXCEPT;287# endif288 289protected:290 // 27.9.1.5 Overridden virtual functions:291 int_type underflow() override;292 int_type pbackfail(int_type __c = traits_type::eof()) override;293 int_type overflow(int_type __c = traits_type::eof()) override;294 basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, streamsize __n) override;295 pos_type296 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __wch = ios_base::in | ios_base::out) override;297 pos_type seekpos(pos_type __sp, ios_base::openmode __wch = ios_base::in | ios_base::out) override;298 int sync() override;299 void imbue(const locale& __loc) override;300 301 _LIBCPP_HIDE_FROM_ABI_VIRTUAL streamsize xsputn(const char_type* __str, streamsize __len) override {302 if (__always_noconv_ && __len >= (this->epptr() - this->pbase())) {303 if (traits_type::eq_int_type(overflow(), traits_type::eof()))304 return 0;305 306 return std::fwrite(__str, sizeof(char_type), __len, __file_);307 }308 return basic_streambuf<_CharT, _Traits>::xsputn(__str, __len);309 }310 311private:312 char* __extbuf_;313 const char* __extbufnext_;314 const char* __extbufend_;315 char __extbuf_min_[8];316 size_t __ebs_;317 char_type* __intbuf_;318 size_t __ibs_;319 FILE* __file_;320 const codecvt<char_type, char, state_type>* __cv_;321 state_type __st_;322 state_type __st_last_;323 ios_base::openmode __om_;324 // There have been no file operations yet, which allows setting unbuffered325 // I/O mode.326 static const ios_base::openmode __no_io_operations = ios_base::trunc;327 // Unbuffered I/O mode has been requested.328 static const ios_base::openmode __use_unbuffered_io = ios_base::ate;329 // Used to track the currently used mode and track whether the output should330 // be unbuffered.331 // [filebuf.virtuals]/12332 // If setbuf(0, 0) is called on a stream before any I/O has occurred on333 // that stream, the stream becomes unbuffered. Otherwise the results are334 // implementation-defined.335 // This allows calling setbuf(0, 0)336 // - before opening a file,337 // - after opening a file, before338 // - a read339 // - a write340 // - a seek.341 // Note that opening a file with ios_base::ate does a seek operation.342 // Normally underflow, overflow, and sync change this flag to ios_base::in,343 // ios_base_out, or 0.344 //345 // The ios_base::trunc and ios_base::ate flags are not used in __cm_. They346 // are used to track the state of the unbuffered request. For readability347 // they have the aliases __no_io_operations and __use_unbuffered_io348 // respectively.349 //350 // The __no_io_operations and __use_unbuffered_io flags are used in the351 // following way:352 // - __no_io_operations is set upon construction to indicate the unbuffered353 // state can be set.354 // - When requesting unbuffered output:355 // - If the file is open it sets the mode.356 // - Else places a request by adding the __use_unbuffered_io flag.357 // - When a file is opened it checks whether both __no_io_operations and358 // __use_unbuffered_io are set. If so switches to unbuffered mode.359 // - All file I/O operations change the mode effectively clearing the360 // __no_io_operations and __use_unbuffered_io flags.361 ios_base::openmode __cm_;362 bool __owns_eb_;363 bool __owns_ib_;364 bool __always_noconv_;365 366 bool __read_mode();367 void __write_mode();368 369 _LIBCPP_HIDE_FROM_ABI static int __fseek(FILE* __file, pos_type __offset, int __whence);370 _LIBCPP_HIDE_FROM_ABI static pos_type __ftell(FILE* __file);371 372 _LIBCPP_EXPORTED_FROM_ABI friend FILE* __get_ostream_file(ostream&);373 374 // There are multiple (__)open function, they use different C-API open375 // function. After that call these functions behave the same. This function376 // does that part and determines the final return value.377 _LIBCPP_HIDE_FROM_ABI basic_filebuf* __do_open(FILE* __file, ios_base::openmode __mode) {378 __file_ = __file;379 if (!__file_)380 return nullptr;381 382 __om_ = __mode;383 if (__cm_ == (__no_io_operations | __use_unbuffered_io)) {384 std::setbuf(__file_, nullptr);385 __cm_ = 0;386 }387 388 if (__mode & ios_base::ate) {389 __cm_ = 0;390 if (fseek(__file_, 0, SEEK_END)) {391 fclose(__file_);392 __file_ = nullptr;393 return nullptr;394 }395 }396 397 return this;398 }399 400 // If the file is already open, switch to unbuffered mode. Otherwise, record401 // the request to use unbuffered mode so that we use that mode when we402 // eventually open the file.403 _LIBCPP_HIDE_FROM_ABI void __request_unbuffered_mode(char_type* __s, streamsize __n) {404 if (__cm_ == __no_io_operations && __s == nullptr && __n == 0) {405 if (__file_) {406 std::setbuf(__file_, nullptr);407 __cm_ = 0;408 } else {409 __cm_ = __no_io_operations | __use_unbuffered_io;410 }411 }412 }413 414 _LIBCPP_HIDE_FROM_ABI typename traits_type::int_type __overflow_failed() {415 if (this->pptr() == this->epptr() + 1) {416 this->pbump(-1); // lose the character we overflowed above -- we don't really have a417 // choice since we couldn't commit the contents of the put area418 }419 return traits_type::eof();420 }421};422 423template <class _CharT, class _Traits>424basic_filebuf<_CharT, _Traits>::basic_filebuf()425 : __extbuf_(nullptr),426 __extbufnext_(nullptr),427 __extbufend_(nullptr),428 __ebs_(0),429 __intbuf_(nullptr),430 __ibs_(0),431 __file_(nullptr),432 __cv_(nullptr),433 __st_(),434 __st_last_(),435 __om_(0),436 __cm_(__no_io_operations),437 __owns_eb_(false),438 __owns_ib_(false),439 __always_noconv_(false) {440 if (std::has_facet<codecvt<char_type, char, state_type> >(this->getloc())) {441 __cv_ = std::addressof(std::use_facet<codecvt<char_type, char, state_type> >(this->getloc()));442 __always_noconv_ = __cv_->always_noconv();443 }444 setbuf(nullptr, 4096);445}446 447template <class _CharT, class _Traits>448basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) : basic_streambuf<_CharT, _Traits>(__rhs) {449 if (__rhs.__extbuf_ == __rhs.__extbuf_min_) {450 __extbuf_ = __extbuf_min_;451 __extbufnext_ = __extbuf_ + (__rhs.__extbufnext_ - __rhs.__extbuf_);452 __extbufend_ = __extbuf_ + (__rhs.__extbufend_ - __rhs.__extbuf_);453 } else {454 __extbuf_ = __rhs.__extbuf_;455 __extbufnext_ = __rhs.__extbufnext_;456 __extbufend_ = __rhs.__extbufend_;457 }458 __ebs_ = __rhs.__ebs_;459 __intbuf_ = __rhs.__intbuf_;460 __ibs_ = __rhs.__ibs_;461 __file_ = __rhs.__file_;462 __cv_ = __rhs.__cv_;463 __st_ = __rhs.__st_;464 __st_last_ = __rhs.__st_last_;465 __om_ = __rhs.__om_;466 __cm_ = __rhs.__cm_;467 __owns_eb_ = __rhs.__owns_eb_;468 __owns_ib_ = __rhs.__owns_ib_;469 __always_noconv_ = __rhs.__always_noconv_;470 if (__rhs.pbase()) {471 if (__rhs.pbase() == __rhs.__intbuf_)472 this->setp(__intbuf_, __intbuf_ + (__rhs.epptr() - __rhs.pbase()));473 else474 this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__rhs.epptr() - __rhs.pbase()));475 this->__pbump(__rhs.pptr() - __rhs.pbase());476 } else if (__rhs.eback()) {477 if (__rhs.eback() == __rhs.__intbuf_)478 this->setg(__intbuf_, __intbuf_ + (__rhs.gptr() - __rhs.eback()), __intbuf_ + (__rhs.egptr() - __rhs.eback()));479 else480 this->setg((char_type*)__extbuf_,481 (char_type*)__extbuf_ + (__rhs.gptr() - __rhs.eback()),482 (char_type*)__extbuf_ + (__rhs.egptr() - __rhs.eback()));483 }484 __rhs.__extbuf_ = nullptr;485 __rhs.__extbufnext_ = nullptr;486 __rhs.__extbufend_ = nullptr;487 __rhs.__ebs_ = 0;488 __rhs.__intbuf_ = 0;489 __rhs.__ibs_ = 0;490 __rhs.__file_ = nullptr;491 __rhs.__st_ = state_type();492 __rhs.__st_last_ = state_type();493 __rhs.__om_ = 0;494 __rhs.__cm_ = 0;495 __rhs.__owns_eb_ = false;496 __rhs.__owns_ib_ = false;497 __rhs.setg(0, 0, 0);498 __rhs.setp(0, 0);499}500 501template <class _CharT, class _Traits>502inline basic_filebuf<_CharT, _Traits>& basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) {503 close();504 swap(__rhs);505 return *this;506}507 508template <class _CharT, class _Traits>509basic_filebuf<_CharT, _Traits>::~basic_filebuf() {510# if _LIBCPP_HAS_EXCEPTIONS511 try {512# endif // _LIBCPP_HAS_EXCEPTIONS513 close();514# if _LIBCPP_HAS_EXCEPTIONS515 } catch (...) {516 }517# endif // _LIBCPP_HAS_EXCEPTIONS518 if (__owns_eb_)519 delete[] __extbuf_;520 if (__owns_ib_)521 delete[] __intbuf_;522}523 524template <class _CharT, class _Traits>525void basic_filebuf<_CharT, _Traits>::swap(basic_filebuf& __rhs) {526 basic_streambuf<char_type, traits_type>::swap(__rhs);527 if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {528 // Neither *this nor __rhs uses the small buffer, so we can simply swap the pointers.529 std::swap(__extbuf_, __rhs.__extbuf_);530 std::swap(__extbufnext_, __rhs.__extbufnext_);531 std::swap(__extbufend_, __rhs.__extbufend_);532 } else {533 ptrdiff_t __ln = __extbufnext_ ? __extbufnext_ - __extbuf_ : 0;534 ptrdiff_t __le = __extbufend_ ? __extbufend_ - __extbuf_ : 0;535 ptrdiff_t __rn = __rhs.__extbufnext_ ? __rhs.__extbufnext_ - __rhs.__extbuf_ : 0;536 ptrdiff_t __re = __rhs.__extbufend_ ? __rhs.__extbufend_ - __rhs.__extbuf_ : 0;537 if (__extbuf_ == __extbuf_min_ && __rhs.__extbuf_ != __rhs.__extbuf_min_) {538 // *this uses the small buffer, but __rhs doesn't.539 __extbuf_ = __rhs.__extbuf_;540 __rhs.__extbuf_ = __rhs.__extbuf_min_;541 std::memmove(__rhs.__extbuf_min_, __extbuf_min_, sizeof(__extbuf_min_));542 } else if (__extbuf_ != __extbuf_min_ && __rhs.__extbuf_ == __rhs.__extbuf_min_) {543 // *this doesn't use the small buffer, but __rhs does.544 __rhs.__extbuf_ = __extbuf_;545 __extbuf_ = __extbuf_min_;546 std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));547 } else {548 // Both *this and __rhs use the small buffer.549 char __tmp[sizeof(__extbuf_min_)];550 std::memmove(__tmp, __extbuf_min_, sizeof(__extbuf_min_));551 std::memmove(__extbuf_min_, __rhs.__extbuf_min_, sizeof(__extbuf_min_));552 std::memmove(__rhs.__extbuf_min_, __tmp, sizeof(__extbuf_min_));553 }554 __extbufnext_ = __extbuf_ + __rn;555 __extbufend_ = __extbuf_ + __re;556 __rhs.__extbufnext_ = __rhs.__extbuf_ + __ln;557 __rhs.__extbufend_ = __rhs.__extbuf_ + __le;558 }559 std::swap(__ebs_, __rhs.__ebs_);560 std::swap(__intbuf_, __rhs.__intbuf_);561 std::swap(__ibs_, __rhs.__ibs_);562 std::swap(__file_, __rhs.__file_);563 std::swap(__cv_, __rhs.__cv_);564 std::swap(__st_, __rhs.__st_);565 std::swap(__st_last_, __rhs.__st_last_);566 std::swap(__om_, __rhs.__om_);567 std::swap(__cm_, __rhs.__cm_);568 std::swap(__owns_eb_, __rhs.__owns_eb_);569 std::swap(__owns_ib_, __rhs.__owns_ib_);570 std::swap(__always_noconv_, __rhs.__always_noconv_);571 if (this->eback() == (char_type*)__rhs.__extbuf_min_) {572 ptrdiff_t __n = this->gptr() - this->eback();573 ptrdiff_t __e = this->egptr() - this->eback();574 this->setg((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __n, (char_type*)__extbuf_min_ + __e);575 } else if (this->pbase() == (char_type*)__rhs.__extbuf_min_) {576 ptrdiff_t __n = this->pptr() - this->pbase();577 ptrdiff_t __e = this->epptr() - this->pbase();578 this->setp((char_type*)__extbuf_min_, (char_type*)__extbuf_min_ + __e);579 this->__pbump(__n);580 }581 if (__rhs.eback() == (char_type*)__extbuf_min_) {582 ptrdiff_t __n = __rhs.gptr() - __rhs.eback();583 ptrdiff_t __e = __rhs.egptr() - __rhs.eback();584 __rhs.setg(585 (char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __n, (char_type*)__rhs.__extbuf_min_ + __e);586 } else if (__rhs.pbase() == (char_type*)__extbuf_min_) {587 ptrdiff_t __n = __rhs.pptr() - __rhs.pbase();588 ptrdiff_t __e = __rhs.epptr() - __rhs.pbase();589 __rhs.setp((char_type*)__rhs.__extbuf_min_, (char_type*)__rhs.__extbuf_min_ + __e);590 __rhs.__pbump(__n);591 }592}593 594template <class _CharT, class _Traits>595inline _LIBCPP_HIDE_FROM_ABI void swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) {596 __x.swap(__y);597}598 599template <class _CharT, class _Traits>600inline bool basic_filebuf<_CharT, _Traits>::is_open() const {601 return __file_ != nullptr;602}603 604template <class _CharT, class _Traits>605const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(ios_base::openmode __mode) _NOEXCEPT {606 switch (__mode & ~ios_base::ate) {607 case ios_base::out:608 case ios_base::out | ios_base::trunc:609 return "w" _LIBCPP_FOPEN_CLOEXEC_MODE;610 case ios_base::out | ios_base::app:611 case ios_base::app:612 return "a" _LIBCPP_FOPEN_CLOEXEC_MODE;613 case ios_base::in:614 return "r" _LIBCPP_FOPEN_CLOEXEC_MODE;615 case ios_base::in | ios_base::out:616 return "r+" _LIBCPP_FOPEN_CLOEXEC_MODE;617 case ios_base::in | ios_base::out | ios_base::trunc:618 return "w+" _LIBCPP_FOPEN_CLOEXEC_MODE;619 case ios_base::in | ios_base::out | ios_base::app:620 case ios_base::in | ios_base::app:621 return "a+" _LIBCPP_FOPEN_CLOEXEC_MODE;622 case ios_base::out | ios_base::binary:623 case ios_base::out | ios_base::trunc | ios_base::binary:624 return "wb" _LIBCPP_FOPEN_CLOEXEC_MODE;625 case ios_base::out | ios_base::app | ios_base::binary:626 case ios_base::app | ios_base::binary:627 return "ab" _LIBCPP_FOPEN_CLOEXEC_MODE;628 case ios_base::in | ios_base::binary:629 return "rb" _LIBCPP_FOPEN_CLOEXEC_MODE;630 case ios_base::in | ios_base::out | ios_base::binary:631 return "r+b" _LIBCPP_FOPEN_CLOEXEC_MODE;632 case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:633 return "w+b" _LIBCPP_FOPEN_CLOEXEC_MODE;634 case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:635 case ios_base::in | ios_base::app | ios_base::binary:636 return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE;637# if _LIBCPP_STD_VER >= 23638 case ios_base::out | ios_base::noreplace:639 case ios_base::out | ios_base::trunc | ios_base::noreplace:640 return "wx" _LIBCPP_FOPEN_CLOEXEC_MODE;641 case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:642 return "w+x" _LIBCPP_FOPEN_CLOEXEC_MODE;643 case ios_base::out | ios_base::binary | ios_base::noreplace:644 case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:645 return "wbx" _LIBCPP_FOPEN_CLOEXEC_MODE;646 case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:647 return "w+bx" _LIBCPP_FOPEN_CLOEXEC_MODE;648# endif // _LIBCPP_STD_VER >= 23649 default:650 return nullptr;651 }652 __libcpp_unreachable();653}654 655# if _LIBCPP_HAS_OPEN_WITH_WCHAR656template <class _CharT, class _Traits>657const wchar_t* basic_filebuf<_CharT, _Traits>::__make_mdwstring(ios_base::openmode __mode) _NOEXCEPT {658 switch (__mode & ~ios_base::ate) {659 case ios_base::out:660 case ios_base::out | ios_base::trunc:661 return L"w";662 case ios_base::out | ios_base::app:663 case ios_base::app:664 return L"a";665 case ios_base::in:666 return L"r";667 case ios_base::in | ios_base::out:668 return L"r+";669 case ios_base::in | ios_base::out | ios_base::trunc:670 return L"w+";671 case ios_base::in | ios_base::out | ios_base::app:672 case ios_base::in | ios_base::app:673 return L"a+";674 case ios_base::out | ios_base::binary:675 case ios_base::out | ios_base::trunc | ios_base::binary:676 return L"wb";677 case ios_base::out | ios_base::app | ios_base::binary:678 case ios_base::app | ios_base::binary:679 return L"ab";680 case ios_base::in | ios_base::binary:681 return L"rb";682 case ios_base::in | ios_base::out | ios_base::binary:683 return L"r+b";684 case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:685 return L"w+b";686 case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:687 case ios_base::in | ios_base::app | ios_base::binary:688 return L"a+b";689# if _LIBCPP_STD_VER >= 23690 case ios_base::out | ios_base::noreplace:691 case ios_base::out | ios_base::trunc | ios_base::noreplace:692 return L"wx";693 case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:694 return L"w+x";695 case ios_base::out | ios_base::binary | ios_base::noreplace:696 case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:697 return L"wbx";698 case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:699 return L"w+bx";700# endif // _LIBCPP_STD_VER >= 23701 default:702 return nullptr;703 }704 __libcpp_unreachable();705}706# endif707 708template <class _CharT, class _Traits>709basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {710 if (__file_)711 return nullptr;712 const char* __mdstr = __make_mdstring(__mode);713 if (!__mdstr)714 return nullptr;715 716 return __do_open(std::fopen(__s, __mdstr), __mode);717}718 719template <class _CharT, class _Traits>720inline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {721 if (__file_)722 return nullptr;723 const char* __mdstr = __make_mdstring(__mode);724 if (!__mdstr)725 return nullptr;726 727 return __do_open(fdopen(__fd, __mdstr), __mode);728}729 730# if _LIBCPP_HAS_OPEN_WITH_WCHAR731// This is basically the same as the char* overload except that it uses _wfopen732// and long mode strings.733template <class _CharT, class _Traits>734basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {735 if (__file_)736 return nullptr;737 const wchar_t* __mdstr = __make_mdwstring(__mode);738 if (!__mdstr)739 return nullptr;740 741 return __do_open(_wfopen(__s, __mdstr), __mode);742}743# endif744 745template <class _CharT, class _Traits>746inline basic_filebuf<_CharT, _Traits>*747basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {748 return open(__s.c_str(), __mode);749}750 751template <class _CharT, class _Traits>752basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::close() {753 basic_filebuf<_CharT, _Traits>* __rt = nullptr;754 if (__file_) {755 __rt = this;756 unique_ptr<FILE, int (*)(FILE*)> __h(__file_, fclose);757 if (sync())758 __rt = nullptr;759 if (fclose(__h.release()))760 __rt = nullptr;761 __file_ = nullptr;762 setbuf(0, 0);763 }764 return __rt;765}766 767template <class _CharT, class _Traits>768typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::underflow() {769 if (__file_ == nullptr)770 return traits_type::eof();771 bool __initial = __read_mode();772 char_type __1buf;773 if (this->gptr() == nullptr)774 this->setg(std::addressof(__1buf), std::addressof(__1buf) + 1, std::addressof(__1buf) + 1);775 const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);776 int_type __c = traits_type::eof();777 if (this->gptr() == this->egptr()) {778 std::memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type));779 if (__always_noconv_) {780 size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);781 __nmemb = std::fread(this->eback() + __unget_sz, 1, __nmemb, __file_);782 if (__nmemb != 0) {783 this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb);784 __c = traits_type::to_int_type(*this->gptr());785 }786 } else {787 if (__extbufend_ != __extbufnext_) {788 _LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr");789 _LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr");790 std::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);791 }792 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);793 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_);794 size_t __nmemb =795 std::min(static_cast<size_t>(__ibs_ - __unget_sz), static_cast<size_t>(__extbufend_ - __extbufnext_));796 codecvt_base::result __r;797 __st_last_ = __st_;798 size_t __nr = std::fread((void*)const_cast<char*>(__extbufnext_), 1, __nmemb, __file_);799 if (__nr != 0) {800 if (!__cv_)801 std::__throw_bad_cast();802 803 __extbufend_ = __extbufnext_ + __nr;804 char_type* __inext;805 __r = __cv_->in(806 __st_, __extbuf_, __extbufend_, __extbufnext_, this->eback() + __unget_sz, this->eback() + __ibs_, __inext);807 if (__r == codecvt_base::noconv) {808 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)const_cast<char*>(__extbufend_));809 __c = traits_type::to_int_type(*this->gptr());810 } else if (__inext != this->eback() + __unget_sz) {811 this->setg(this->eback(), this->eback() + __unget_sz, __inext);812 __c = traits_type::to_int_type(*this->gptr());813 }814 }815 }816 } else817 __c = traits_type::to_int_type(*this->gptr());818 if (this->eback() == std::addressof(__1buf))819 this->setg(nullptr, nullptr, nullptr);820 return __c;821}822 823template <class _CharT, class _Traits>824typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::pbackfail(int_type __c) {825 if (__file_ && this->eback() < this->gptr()) {826 if (traits_type::eq_int_type(__c, traits_type::eof())) {827 this->gbump(-1);828 return traits_type::not_eof(__c);829 }830 if ((__om_ & ios_base::out) || traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) {831 this->gbump(-1);832 *this->gptr() = traits_type::to_char_type(__c);833 return __c;834 }835 }836 return traits_type::eof();837}838 839template <class _CharT, class _Traits>840typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {841 if (__file_ == nullptr)842 return traits_type::eof();843 __write_mode();844 char_type __1buf;845 char_type* __pb_save = this->pbase();846 char_type* __epb_save = this->epptr();847 if (!traits_type::eq_int_type(__c, traits_type::eof())) {848 if (this->pptr() == nullptr)849 this->setp(std::addressof(__1buf), std::addressof(__1buf) + 1);850 *this->pptr() = traits_type::to_char_type(__c);851 this->pbump(1);852 }853 854 // There is nothing to write, early return855 if (this->pptr() == this->pbase()) {856 return traits_type::not_eof(__c);857 }858 859 if (__always_noconv_) {860 size_t __n = static_cast<size_t>(this->pptr() - this->pbase());861 if (std::fwrite(this->pbase(), sizeof(char_type), __n, __file_) != __n) {862 return __overflow_failed();863 }864 } else {865 if (!__cv_)866 std::__throw_bad_cast();867 868 // See [filebuf.virtuals]869 char_type* __b = this->pbase();870 char_type* __p = this->pptr();871 const char_type* __end;872 char* __extbuf_end = __extbuf_;873 do {874 codecvt_base::result __r = __cv_->out(__st_, __b, __p, __end, __extbuf_, __extbuf_ + __ebs_, __extbuf_end);875 if (__end == __b) {876 return __overflow_failed();877 }878 879 // No conversion needed: output characters directly to the file, done.880 if (__r == codecvt_base::noconv) {881 size_t __n = static_cast<size_t>(__p - __b);882 if (std::fwrite(__b, 1, __n, __file_) != __n) {883 return __overflow_failed();884 }885 break;886 887 // Conversion successful: output the converted characters to the file, done.888 } else if (__r == codecvt_base::ok) {889 size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);890 if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) {891 return __overflow_failed();892 }893 break;894 895 // Conversion partially successful: output converted characters to the file and repeat with the896 // remaining characters.897 } else if (__r == codecvt_base::partial) {898 size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);899 if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) {900 return __overflow_failed();901 }902 __b = const_cast<char_type*>(__end);903 continue;904 905 } else {906 return __overflow_failed();907 }908 } while (true);909 }910 this->setp(__pb_save, __epb_save);911 return traits_type::not_eof(__c);912}913 914template <class _CharT, class _Traits>915basic_streambuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::setbuf(char_type* __s, streamsize __n) {916 this->setg(nullptr, nullptr, nullptr);917 this->setp(nullptr, nullptr);918 __request_unbuffered_mode(__s, __n);919 if (__owns_eb_)920 delete[] __extbuf_;921 if (__owns_ib_)922 delete[] __intbuf_;923 __ebs_ = __n;924 if (__ebs_ > sizeof(__extbuf_min_)) {925 if (__always_noconv_ && __s) {926 __extbuf_ = (char*)__s;927 __owns_eb_ = false;928 } else {929 __extbuf_ = new char[__ebs_];930 __owns_eb_ = true;931 }932 } else {933 __extbuf_ = __extbuf_min_;934 __ebs_ = sizeof(__extbuf_min_);935 __owns_eb_ = false;936 }937 if (!__always_noconv_) {938 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_));939 if (__s && __ibs_ > sizeof(__extbuf_min_)) {940 __intbuf_ = __s;941 __owns_ib_ = false;942 } else {943 __intbuf_ = new char_type[__ibs_];944 __owns_ib_ = true;945 }946 } else {947 __ibs_ = 0;948 __intbuf_ = nullptr;949 __owns_ib_ = false;950 }951 return this;952}953 954template <class _CharT, class _Traits>955typename basic_filebuf<_CharT, _Traits>::pos_type956basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) {957 if (!__cv_)958 std::__throw_bad_cast();959 960 int __width = __cv_->encoding();961 if (__file_ == nullptr || (__width <= 0 && __off != 0) || sync())962 return pos_type(off_type(-1));963 // __width > 0 || __off == 0964 int __whence;965 switch (__way) {966 case ios_base::beg:967 __whence = SEEK_SET;968 break;969 case ios_base::cur:970 __whence = SEEK_CUR;971 break;972 case ios_base::end:973 __whence = SEEK_END;974 break;975 default:976 return pos_type(off_type(-1));977 }978 if (__fseek(__file_, __width > 0 ? __width * __off : 0, __whence))979 return pos_type(off_type(-1));980 pos_type __r = __ftell(__file_);981 __r.state(__st_);982 return __r;983}984 985template <class _CharT, class _Traits>986int basic_filebuf<_CharT, _Traits>::__fseek(FILE* __file, pos_type __offset, int __whence) {987# if defined(_LIBCPP_MSVCRT_LIKE)988 return _fseeki64(__file, __offset, __whence);989# elif _LIBCPP_LIBC_NEWLIB990 return fseek(__file, __offset, __whence);991# else992 return ::fseeko(__file, __offset, __whence);993# endif994}995 996template <class _CharT, class _Traits>997typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>::__ftell(FILE* __file) {998# if defined(_LIBCPP_MSVCRT_LIKE)999 return _ftelli64(__file);1000# elif _LIBCPP_LIBC_NEWLIB1001 return ftell(__file);1002# else1003 return ftello(__file);1004# endif1005}1006 1007template <class _CharT, class _Traits>1008typename basic_filebuf<_CharT, _Traits>::pos_type1009basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) {1010 if (__file_ == nullptr || sync())1011 return pos_type(off_type(-1));1012 if (__fseek(__file_, __sp, SEEK_SET))1013 return pos_type(off_type(-1));1014 __st_ = __sp.state();1015 return __sp;1016}1017 1018template <class _CharT, class _Traits>1019int basic_filebuf<_CharT, _Traits>::sync() {1020 if (__file_ == nullptr)1021 return 0;1022 if (!__cv_)1023 std::__throw_bad_cast();1024 1025 if (__cm_ & ios_base::out) {1026 if (this->pptr() != this->pbase())1027 if (overflow() == traits_type::eof())1028 return -1;1029 codecvt_base::result __r;1030 do {1031 char* __extbe;1032 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe);1033 size_t __nmemb = static_cast<size_t>(__extbe - __extbuf_);1034 if (std::fwrite(__extbuf_, 1, __nmemb, __file_) != __nmemb)1035 return -1;1036 } while (__r == codecvt_base::partial);1037 if (__r == codecvt_base::error)1038 return -1;1039 if (std::fflush(__file_))1040 return -1;1041 } else if (__cm_ & ios_base::in) {1042 off_type __c;1043 state_type __state = __st_last_;1044 bool __update_st = false;1045 if (__always_noconv_)1046 __c = this->egptr() - this->gptr();1047 else {1048 int __width = __cv_->encoding();1049 __c = __extbufend_ - __extbufnext_;1050 if (__width > 0)1051 __c += __width * (this->egptr() - this->gptr());1052 else {1053 if (this->gptr() != this->egptr()) {1054 const int __off = __cv_->length(__state, __extbuf_, __extbufnext_, this->gptr() - this->eback());1055 __c += __extbufnext_ - __extbuf_ - __off;1056 __update_st = true;1057 }1058 }1059 }1060 if (__fseek(__file_, -__c, SEEK_CUR))1061 return -1;1062 if (__update_st)1063 __st_ = __state;1064 __extbufnext_ = __extbufend_ = __extbuf_;1065 this->setg(nullptr, nullptr, nullptr);1066 __cm_ = 0;1067 }1068 return 0;1069}1070 1071template <class _CharT, class _Traits>1072void basic_filebuf<_CharT, _Traits>::imbue(const locale& __loc) {1073 sync();1074 __cv_ = std::addressof(std::use_facet<codecvt<char_type, char, state_type> >(__loc));1075 bool __old_anc = __always_noconv_;1076 __always_noconv_ = __cv_->always_noconv();1077 if (__old_anc != __always_noconv_) {1078 this->setg(nullptr, nullptr, nullptr);1079 this->setp(nullptr, nullptr);1080 // invariant, char_type is char, else we couldn't get here1081 if (__always_noconv_) // need to dump __intbuf_1082 {1083 if (__owns_eb_)1084 delete[] __extbuf_;1085 __owns_eb_ = __owns_ib_;1086 __ebs_ = __ibs_;1087 __extbuf_ = (char*)__intbuf_;1088 __ibs_ = 0;1089 __intbuf_ = nullptr;1090 __owns_ib_ = false;1091 } else // need to obtain an __intbuf_.1092 { // If __extbuf_ is user-supplied, use it, else new __intbuf_1093 if (!__owns_eb_ && __extbuf_ != __extbuf_min_) {1094 __ibs_ = __ebs_;1095 __intbuf_ = (char_type*)__extbuf_;1096 __owns_ib_ = false;1097 __extbuf_ = new char[__ebs_];1098 __owns_eb_ = true;1099 } else {1100 __ibs_ = __ebs_;1101 __intbuf_ = new char_type[__ibs_];1102 __owns_ib_ = true;1103 }1104 }1105 }1106}1107 1108template <class _CharT, class _Traits>1109bool basic_filebuf<_CharT, _Traits>::__read_mode() {1110 if (!(__cm_ & ios_base::in)) {1111 this->setp(nullptr, nullptr);1112 if (__always_noconv_)1113 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_ + __ebs_, (char_type*)__extbuf_ + __ebs_);1114 else1115 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_);1116 __cm_ = ios_base::in;1117 return true;1118 }1119 return false;1120}1121 1122template <class _CharT, class _Traits>1123void basic_filebuf<_CharT, _Traits>::__write_mode() {1124 if (!(__cm_ & ios_base::out)) {1125 this->setg(nullptr, nullptr, nullptr);1126 if (__ebs_ > sizeof(__extbuf_min_)) {1127 if (__always_noconv_)1128 this->setp((char_type*)__extbuf_, (char_type*)__extbuf_ + (__ebs_ - 1));1129 else1130 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1));1131 } else1132 this->setp(nullptr, nullptr);1133 __cm_ = ios_base::out;1134 }1135}1136 1137// basic_ifstream1138 1139template <class _CharT, class _Traits>1140class basic_ifstream : public basic_istream<_CharT, _Traits> {1141public:1142 typedef _CharT char_type;1143 typedef _Traits traits_type;1144 typedef typename traits_type::int_type int_type;1145 typedef typename traits_type::pos_type pos_type;1146 typedef typename traits_type::off_type off_type;1147# if _LIBCPP_STD_VER >= 261148 using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;1149# endif1150 1151 _LIBCPP_HIDE_FROM_ABI basic_ifstream();1152 _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in);1153# if _LIBCPP_HAS_OPEN_WITH_WCHAR1154 _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);1155# endif1156 _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in);1157# if _LIBCPP_STD_VER >= 171158 template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>1159 _LIBCPP_HIDE_FROM_ABI explicit basic_ifstream(const _Tp& __p, ios_base::openmode __mode = ios_base::in)1160 : basic_ifstream(__p.c_str(), __mode) {}1161# endif // _LIBCPP_STD_VER >= 171162 _LIBCPP_HIDE_FROM_ABI basic_ifstream(basic_ifstream&& __rhs);1163 _LIBCPP_HIDE_FROM_ABI basic_ifstream& operator=(basic_ifstream&& __rhs);1164 _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream& __rhs);1165 1166 _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;1167# if _LIBCPP_STD_VER >= 261168 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }1169# endif1170 _LIBCPP_HIDE_FROM_ABI bool is_open() const;1171 void open(const char* __s, ios_base::openmode __mode = ios_base::in);1172# if _LIBCPP_HAS_OPEN_WITH_WCHAR1173 void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in);1174# endif1175 void open(const string& __s, ios_base::openmode __mode = ios_base::in);1176# if _LIBCPP_STD_VER >= 171177 _LIBCPP_HIDE_FROM_ABI void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) {1178 return open(__p.c_str(), __mode);1179 }1180# endif // _LIBCPP_STD_VER >= 171181 1182 _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);1183 _LIBCPP_HIDE_FROM_ABI void close();1184 1185private:1186 basic_filebuf<char_type, traits_type> __sb_;1187};1188 1189template <class _CharT, class _Traits>1190inline basic_ifstream<_CharT, _Traits>::basic_ifstream()1191 : basic_istream<char_type, traits_type>(std::addressof(__sb_)) {}1192 1193template <class _CharT, class _Traits>1194inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode)1195 : basic_istream<char_type, traits_type>(std::addressof(__sb_)) {1196 if (__sb_.open(__s, __mode | ios_base::in) == nullptr)1197 this->setstate(ios_base::failbit);1198}1199 1200# if _LIBCPP_HAS_OPEN_WITH_WCHAR1201template <class _CharT, class _Traits>1202inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const wchar_t* __s, ios_base::openmode __mode)1203 : basic_istream<char_type, traits_type>(std::addressof(__sb_)) {1204 if (__sb_.open(__s, __mode | ios_base::in) == nullptr)1205 this->setstate(ios_base::failbit);1206}1207# endif1208 1209// extension1210template <class _CharT, class _Traits>1211inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode)1212 : basic_istream<char_type, traits_type>(std::addressof(__sb_)) {1213 if (__sb_.open(__s, __mode | ios_base::in) == nullptr)1214 this->setstate(ios_base::failbit);1215}1216 1217template <class _CharT, class _Traits>1218inline basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs)1219 : basic_istream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {1220 this->set_rdbuf(std::addressof(__sb_));1221}1222 1223template <class _CharT, class _Traits>1224inline basic_ifstream<_CharT, _Traits>& basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) {1225 basic_istream<char_type, traits_type>::operator=(std::move(__rhs));1226 __sb_ = std::move(__rhs.__sb_);1227 return *this;1228}1229 1230template <class _CharT, class _Traits>1231inline void basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) {1232 basic_istream<char_type, traits_type>::swap(__rhs);1233 __sb_.swap(__rhs.__sb_);1234}1235 1236template <class _CharT, class _Traits>1237inline _LIBCPP_HIDE_FROM_ABI void swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) {1238 __x.swap(__y);1239}1240 1241template <class _CharT, class _Traits>1242inline basic_filebuf<_CharT, _Traits>* basic_ifstream<_CharT, _Traits>::rdbuf() const {1243 return const_cast<basic_filebuf<char_type, traits_type>*>(std::addressof(__sb_));1244}1245 1246template <class _CharT, class _Traits>1247inline bool basic_ifstream<_CharT, _Traits>::is_open() const {1248 return __sb_.is_open();1249}1250 1251template <class _CharT, class _Traits>1252void basic_ifstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {1253 if (__sb_.open(__s, __mode | ios_base::in))1254 this->clear();1255 else1256 this->setstate(ios_base::failbit);1257}1258 1259# if _LIBCPP_HAS_OPEN_WITH_WCHAR1260template <class _CharT, class _Traits>1261void basic_ifstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {1262 if (__sb_.open(__s, __mode | ios_base::in))1263 this->clear();1264 else1265 this->setstate(ios_base::failbit);1266}1267# endif1268 1269template <class _CharT, class _Traits>1270void basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {1271 if (__sb_.open(__s, __mode | ios_base::in))1272 this->clear();1273 else1274 this->setstate(ios_base::failbit);1275}1276 1277template <class _CharT, class _Traits>1278inline void basic_ifstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {1279 if (__sb_.__open(__fd, __mode | ios_base::in))1280 this->clear();1281 else1282 this->setstate(ios_base::failbit);1283}1284 1285template <class _CharT, class _Traits>1286inline void basic_ifstream<_CharT, _Traits>::close() {1287 if (__sb_.close() == 0)1288 this->setstate(ios_base::failbit);1289}1290 1291// basic_ofstream1292 1293template <class _CharT, class _Traits>1294class basic_ofstream : public basic_ostream<_CharT, _Traits> {1295public:1296 typedef _CharT char_type;1297 typedef _Traits traits_type;1298 typedef typename traits_type::int_type int_type;1299 typedef typename traits_type::pos_type pos_type;1300 typedef typename traits_type::off_type off_type;1301# if _LIBCPP_STD_VER >= 261302 using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;1303# endif1304 1305 _LIBCPP_HIDE_FROM_ABI basic_ofstream();1306 _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out);1307# if _LIBCPP_HAS_OPEN_WITH_WCHAR1308 _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);1309# endif1310 _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out);1311 1312# if _LIBCPP_STD_VER >= 171313 template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>1314 _LIBCPP_HIDE_FROM_ABI explicit basic_ofstream(const _Tp& __p, ios_base::openmode __mode = ios_base::out)1315 : basic_ofstream(__p.c_str(), __mode) {}1316# endif // _LIBCPP_STD_VER >= 171317 1318 _LIBCPP_HIDE_FROM_ABI basic_ofstream(basic_ofstream&& __rhs);1319 _LIBCPP_HIDE_FROM_ABI basic_ofstream& operator=(basic_ofstream&& __rhs);1320 _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream& __rhs);1321 1322 _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;1323# if _LIBCPP_STD_VER >= 261324 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }1325# endif1326 _LIBCPP_HIDE_FROM_ABI bool is_open() const;1327 void open(const char* __s, ios_base::openmode __mode = ios_base::out);1328# if _LIBCPP_HAS_OPEN_WITH_WCHAR1329 void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out);1330# endif1331 void open(const string& __s, ios_base::openmode __mode = ios_base::out);1332 1333# if _LIBCPP_STD_VER >= 171334 _LIBCPP_HIDE_FROM_ABI void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) {1335 return open(__p.c_str(), __mode);1336 }1337# endif // _LIBCPP_STD_VER >= 171338 1339 _LIBCPP_HIDE_FROM_ABI void __open(int __fd, ios_base::openmode __mode);1340 _LIBCPP_HIDE_FROM_ABI void close();1341 1342private:1343 basic_filebuf<char_type, traits_type> __sb_;1344};1345 1346template <class _CharT, class _Traits>1347inline basic_ofstream<_CharT, _Traits>::basic_ofstream()1348 : basic_ostream<char_type, traits_type>(std::addressof(__sb_)) {}1349 1350template <class _CharT, class _Traits>1351inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode)1352 : basic_ostream<char_type, traits_type>(std::addressof(__sb_)) {1353 if (__sb_.open(__s, __mode | ios_base::out) == nullptr)1354 this->setstate(ios_base::failbit);1355}1356 1357# if _LIBCPP_HAS_OPEN_WITH_WCHAR1358template <class _CharT, class _Traits>1359inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const wchar_t* __s, ios_base::openmode __mode)1360 : basic_ostream<char_type, traits_type>(std::addressof(__sb_)) {1361 if (__sb_.open(__s, __mode | ios_base::out) == nullptr)1362 this->setstate(ios_base::failbit);1363}1364# endif1365 1366// extension1367template <class _CharT, class _Traits>1368inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode)1369 : basic_ostream<char_type, traits_type>(std::addressof(__sb_)) {1370 if (__sb_.open(__s, __mode | ios_base::out) == nullptr)1371 this->setstate(ios_base::failbit);1372}1373 1374template <class _CharT, class _Traits>1375inline basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs)1376 : basic_ostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {1377 this->set_rdbuf(std::addressof(__sb_));1378}1379 1380template <class _CharT, class _Traits>1381inline basic_ofstream<_CharT, _Traits>& basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) {1382 basic_ostream<char_type, traits_type>::operator=(std::move(__rhs));1383 __sb_ = std::move(__rhs.__sb_);1384 return *this;1385}1386 1387template <class _CharT, class _Traits>1388inline void basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) {1389 basic_ostream<char_type, traits_type>::swap(__rhs);1390 __sb_.swap(__rhs.__sb_);1391}1392 1393template <class _CharT, class _Traits>1394inline _LIBCPP_HIDE_FROM_ABI void swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) {1395 __x.swap(__y);1396}1397 1398template <class _CharT, class _Traits>1399inline basic_filebuf<_CharT, _Traits>* basic_ofstream<_CharT, _Traits>::rdbuf() const {1400 return const_cast<basic_filebuf<char_type, traits_type>*>(std::addressof(__sb_));1401}1402 1403template <class _CharT, class _Traits>1404inline bool basic_ofstream<_CharT, _Traits>::is_open() const {1405 return __sb_.is_open();1406}1407 1408template <class _CharT, class _Traits>1409void basic_ofstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {1410 if (__sb_.open(__s, __mode | ios_base::out))1411 this->clear();1412 else1413 this->setstate(ios_base::failbit);1414}1415 1416# if _LIBCPP_HAS_OPEN_WITH_WCHAR1417template <class _CharT, class _Traits>1418void basic_ofstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {1419 if (__sb_.open(__s, __mode | ios_base::out))1420 this->clear();1421 else1422 this->setstate(ios_base::failbit);1423}1424# endif1425 1426template <class _CharT, class _Traits>1427void basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {1428 if (__sb_.open(__s, __mode | ios_base::out))1429 this->clear();1430 else1431 this->setstate(ios_base::failbit);1432}1433 1434template <class _CharT, class _Traits>1435inline void basic_ofstream<_CharT, _Traits>::__open(int __fd, ios_base::openmode __mode) {1436 if (__sb_.__open(__fd, __mode | ios_base::out))1437 this->clear();1438 else1439 this->setstate(ios_base::failbit);1440}1441 1442template <class _CharT, class _Traits>1443inline void basic_ofstream<_CharT, _Traits>::close() {1444 if (__sb_.close() == nullptr)1445 this->setstate(ios_base::failbit);1446}1447 1448// basic_fstream1449 1450template <class _CharT, class _Traits>1451class basic_fstream : public basic_iostream<_CharT, _Traits> {1452public:1453 typedef _CharT char_type;1454 typedef _Traits traits_type;1455 typedef typename traits_type::int_type int_type;1456 typedef typename traits_type::pos_type pos_type;1457 typedef typename traits_type::off_type off_type;1458# if _LIBCPP_STD_VER >= 261459 using native_handle_type = typename basic_filebuf<_CharT, _Traits>::native_handle_type;1460# endif1461 1462 _LIBCPP_HIDE_FROM_ABI basic_fstream();1463 _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const char* __s,1464 ios_base::openmode __mode = ios_base::in | ios_base::out);1465# if _LIBCPP_HAS_OPEN_WITH_WCHAR1466 _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const wchar_t* __s,1467 ios_base::openmode __mode = ios_base::in | ios_base::out);1468# endif1469 _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const string& __s,1470 ios_base::openmode __mode = ios_base::in | ios_base::out);1471 1472# if _LIBCPP_STD_VER >= 171473 template <class _Tp, class = enable_if_t<is_same_v<_Tp, filesystem::path>>>1474 _LIBCPP_HIDE_FROM_ABI explicit basic_fstream(const _Tp& __p, ios_base::openmode __mode = ios_base::in | ios_base::out)1475 : basic_fstream(__p.c_str(), __mode) {}1476# endif // _LIBCPP_STD_VER >= 171477 1478 _LIBCPP_HIDE_FROM_ABI basic_fstream(basic_fstream&& __rhs);1479 1480 _LIBCPP_HIDE_FROM_ABI basic_fstream& operator=(basic_fstream&& __rhs);1481 1482 _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream& __rhs);1483 1484 _LIBCPP_HIDE_FROM_ABI basic_filebuf<char_type, traits_type>* rdbuf() const;1485# if _LIBCPP_STD_VER >= 261486 _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() const noexcept { return rdbuf()->native_handle(); }1487# endif1488 _LIBCPP_HIDE_FROM_ABI bool is_open() const;1489 _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);1490# if _LIBCPP_HAS_OPEN_WITH_WCHAR1491 void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out);1492# endif1493 _LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out);1494 1495# if _LIBCPP_STD_VER >= 171496 _LIBCPP_HIDE_FROM_ABI void1497 open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) {1498 return open(__p.c_str(), __mode);1499 }1500# endif // _LIBCPP_STD_VER >= 171501 1502 _LIBCPP_HIDE_FROM_ABI void close();1503 1504private:1505 basic_filebuf<char_type, traits_type> __sb_;1506};1507 1508template <class _CharT, class _Traits>1509inline basic_fstream<_CharT, _Traits>::basic_fstream()1510 : basic_iostream<char_type, traits_type>(std::addressof(__sb_)) {}1511 1512template <class _CharT, class _Traits>1513inline basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode)1514 : basic_iostream<char_type, traits_type>(std::addressof(__sb_)) {1515 if (__sb_.open(__s, __mode) == nullptr)1516 this->setstate(ios_base::failbit);1517}1518 1519# if _LIBCPP_HAS_OPEN_WITH_WCHAR1520template <class _CharT, class _Traits>1521inline basic_fstream<_CharT, _Traits>::basic_fstream(const wchar_t* __s, ios_base::openmode __mode)1522 : basic_iostream<char_type, traits_type>(std::addressof(__sb_)) {1523 if (__sb_.open(__s, __mode) == nullptr)1524 this->setstate(ios_base::failbit);1525}1526# endif1527 1528template <class _CharT, class _Traits>1529inline basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode)1530 : basic_iostream<char_type, traits_type>(std::addressof(__sb_)) {1531 if (__sb_.open(__s, __mode) == nullptr)1532 this->setstate(ios_base::failbit);1533}1534 1535// extension1536template <class _CharT, class _Traits>1537inline basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs)1538 : basic_iostream<char_type, traits_type>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {1539 this->set_rdbuf(std::addressof(__sb_));1540}1541 1542template <class _CharT, class _Traits>1543inline basic_fstream<_CharT, _Traits>& basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) {1544 basic_iostream<char_type, traits_type>::operator=(std::move(__rhs));1545 __sb_ = std::move(__rhs.__sb_);1546 return *this;1547}1548 1549template <class _CharT, class _Traits>1550inline void basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) {1551 basic_iostream<char_type, traits_type>::swap(__rhs);1552 __sb_.swap(__rhs.__sb_);1553}1554 1555template <class _CharT, class _Traits>1556inline _LIBCPP_HIDE_FROM_ABI void swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) {1557 __x.swap(__y);1558}1559 1560template <class _CharT, class _Traits>1561inline basic_filebuf<_CharT, _Traits>* basic_fstream<_CharT, _Traits>::rdbuf() const {1562 return const_cast<basic_filebuf<char_type, traits_type>*>(std::addressof(__sb_));1563}1564 1565template <class _CharT, class _Traits>1566inline bool basic_fstream<_CharT, _Traits>::is_open() const {1567 return __sb_.is_open();1568}1569 1570template <class _CharT, class _Traits>1571void basic_fstream<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) {1572 if (__sb_.open(__s, __mode))1573 this->clear();1574 else1575 this->setstate(ios_base::failbit);1576}1577 1578# if _LIBCPP_HAS_OPEN_WITH_WCHAR1579template <class _CharT, class _Traits>1580void basic_fstream<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mode) {1581 if (__sb_.open(__s, __mode))1582 this->clear();1583 else1584 this->setstate(ios_base::failbit);1585}1586# endif1587 1588template <class _CharT, class _Traits>1589void basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) {1590 if (__sb_.open(__s, __mode))1591 this->clear();1592 else1593 this->setstate(ios_base::failbit);1594}1595 1596template <class _CharT, class _Traits>1597inline void basic_fstream<_CharT, _Traits>::close() {1598 if (__sb_.close() == nullptr)1599 this->setstate(ios_base::failbit);1600}1601 1602# if _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_11603extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ifstream<char>;1604extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ofstream<char>;1605extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>;1606# endif1607 1608_LIBCPP_END_NAMESPACE_STD1609 1610_LIBCPP_POP_MACROS1611 1612# endif // _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION1613 1614# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 201615# include <atomic>1616# include <concepts>1617# include <cstdlib>1618# include <iosfwd>1619# include <limits>1620# include <mutex>1621# include <new>1622# include <stdexcept>1623# include <type_traits>1624# endif1625 1626# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 231627# include <filesystem>1628# endif1629#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)1630 1631#endif // _LIBCPP_FSTREAM1632