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