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