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