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