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