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