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