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