1 // File based streams -*- C++ -*- 2 3 // Copyright (C) 1997-2024 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file include/fstream 26 * This is a Standard C++ Library header. 27 */ 28 29 // 30 // ISO C++ 14882: 27.8 File-based streams 31 // 32 33 #ifndef _GLIBCXX_FSTREAM 34 #define _GLIBCXX_FSTREAM 1 35 36 #pragma GCC system_header 37 38 #include <bits/requires_hosted.h> // iostreams 39 40 #include <istream> 41 #include <ostream> 42 #include <bits/codecvt.h> 43 #include <cstdio> // For BUFSIZ 44 #include <bits/basic_file.h> // For __basic_file, __c_lock 45 #if __cplusplus >= 201103L 46 #include <string> // For std::string overloads. 47 #endif 48 49 #define __glibcxx_want_fstream_native_handle 50 #include <bits/version.h> 51 52 // This can be overridden by the target's os_defines.h 53 #ifndef _GLIBCXX_BUFSIZ 54 # define _GLIBCXX_BUFSIZ BUFSIZ 55 #endif 56 57 namespace std _GLIBCXX_VISIBILITY(default) 58 { 59 _GLIBCXX_BEGIN_NAMESPACE_VERSION 60 61 #if __cplusplus >= 201703L 62 // Enable if _Path is a filesystem::path or experimental::filesystem::path 63 template<typename _Path, typename _Result = _Path, typename _Path2 64 = decltype(std::declval<_Path&>().make_preferred().filename())> 65 using _If_fs_path = enable_if_t<is_same_v<_Path, _Path2>, _Result>; 66 #endif // C++17 67 68 69 // [27.8.1.1] template class basic_filebuf 70 /** 71 * @brief The actual work of input and output (for files). 72 * @ingroup io 73 * 74 * @tparam _CharT Type of character stream. 75 * @tparam _Traits Traits for character type, defaults to 76 * char_traits<_CharT>. 77 * 78 * This class associates both its input and output sequence with an 79 * external disk file, and maintains a joint file position for both 80 * sequences. Many of its semantics are described in terms of similar 81 * behavior in the Standard C Library's @c FILE streams. 82 * 83 * Requirements on traits_type, specific to this class: 84 * - traits_type::pos_type must be fpos<traits_type::state_type> 85 * - traits_type::off_type must be streamoff 86 * - traits_type::state_type must be Assignable and DefaultConstructible, 87 * - traits_type::state_type() must be the initial state for codecvt. 88 */ 89 template<typename _CharT, typename _Traits> 90 class basic_filebuf : public basic_streambuf<_CharT, _Traits> 91 { 92 #if __cplusplus >= 201103L 93 template<typename _Tp> 94 using __chk_state = __and_<is_copy_assignable<_Tp>, 95 is_copy_constructible<_Tp>, 96 is_default_constructible<_Tp>>; 97 98 static_assert(__chk_state<typename _Traits::state_type>::value, 99 "state_type must be CopyAssignable, CopyConstructible" 100 " and DefaultConstructible"); 101 102 static_assert(is_same<typename _Traits::pos_type, 103 fpos<typename _Traits::state_type>>::value, 104 "pos_type must be fpos<state_type>"); 105 #endif 106 public: 107 // Types: 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 typedef basic_streambuf<char_type, traits_type> __streambuf_type; 115 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 116 typedef __basic_file<char> __file_type; 117 typedef typename traits_type::state_type __state_type; 118 typedef codecvt<char_type, char, __state_type> __codecvt_type; 119 120 friend class ios_base; // For sync_with_stdio. 121 122 protected: 123 // Data Members: 124 // MT lock inherited from libio or other low-level io library. 125 __c_lock _M_lock; 126 127 // External buffer. 128 __file_type _M_file; 129 130 /// Place to stash in || out || in | out settings for current filebuf. 131 ios_base::openmode _M_mode; 132 133 // Beginning state type for codecvt. 134 __state_type _M_state_beg; 135 136 // During output, the state that corresponds to pptr(), 137 // during input, the state that corresponds to egptr() and 138 // _M_ext_next. 139 __state_type _M_state_cur; 140 141 // Not used for output. During input, the state that corresponds 142 // to eback() and _M_ext_buf. 143 __state_type _M_state_last; 144 145 /// Pointer to the beginning of internal buffer. 146 char_type* _M_buf; 147 148 /** 149 * Actual size of internal buffer. This number is equal to the size 150 * of the put area + 1 position, reserved for the overflow char of 151 * a full area. 152 */ 153 size_t _M_buf_size; 154 155 // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. 156 bool _M_buf_allocated; 157 158 /** 159 * _M_reading == false && _M_writing == false for @b uncommitted mode; 160 * _M_reading == true for @b read mode; 161 * _M_writing == true for @b write mode; 162 * 163 * NB: _M_reading == true && _M_writing == true is unused. 164 */ 165 bool _M_reading; 166 bool _M_writing; 167 168 ///@{ 169 /** 170 * Necessary bits for putback buffer management. 171 * 172 * @note pbacks of over one character are not currently supported. 173 */ 174 char_type _M_pback; 175 char_type* _M_pback_cur_save; 176 char_type* _M_pback_end_save; 177 bool _M_pback_init; 178 ///@} 179 180 // Cached codecvt facet. 181 const __codecvt_type* _M_codecvt; 182 183 /** 184 * Buffer for external characters. Used for input when 185 * codecvt::always_noconv() == false. When valid, this corresponds 186 * to eback(). 187 */ 188 char* _M_ext_buf; 189 190 /** 191 * Size of buffer held by _M_ext_buf. 192 */ 193 streamsize _M_ext_buf_size; 194 195 /** 196 * Pointers into the buffer held by _M_ext_buf that delimit a 197 * subsequence of bytes that have been read but not yet converted. 198 * When valid, _M_ext_next corresponds to egptr(). 199 */ 200 const char* _M_ext_next; 201 char* _M_ext_end; 202 203 /** 204 * Initializes pback buffers, and moves normal buffers to safety. 205 * Assumptions: 206 * _M_in_cur has already been moved back 207 */ 208 void 209 _M_create_pback() 210 { 211 if (!_M_pback_init) 212 { 213 _M_pback_cur_save = this->gptr(); 214 _M_pback_end_save = this->egptr(); 215 this->setg(&_M_pback, &_M_pback, &_M_pback + 1); 216 _M_pback_init = true; 217 } 218 } 219 220 /** 221 * Deactivates pback buffer contents, and restores normal buffer. 222 * Assumptions: 223 * The pback buffer has only moved forward. 224 */ 225 void 226 _M_destroy_pback() throw() 227 { 228 if (_M_pback_init) 229 { 230 // Length _M_in_cur moved in the pback buffer. 231 _M_pback_cur_save += this->gptr() != this->eback(); 232 this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save); 233 _M_pback_init = false; 234 } 235 } 236 237 public: 238 // Constructors/destructor: 239 /** 240 * @brief Does not open any files. 241 * 242 * The default constructor initializes the parent class using its 243 * own default ctor. 244 */ 245 basic_filebuf(); 246 247 #if __cplusplus >= 201103L 248 basic_filebuf(const basic_filebuf&) = delete; 249 basic_filebuf(basic_filebuf&&); 250 #endif 251 252 /** 253 * @brief The destructor closes the file first. 254 */ 255 virtual 256 ~basic_filebuf() 257 { 258 __try 259 { this->close(); } 260 __catch(...) 261 { } 262 } 263 264 #if __cplusplus >= 201103L 265 basic_filebuf& operator=(const basic_filebuf&) = delete; 266 basic_filebuf& operator=(basic_filebuf&&); 267 void swap(basic_filebuf&); 268 #endif 269 270 // Members: 271 /** 272 * @brief Returns true if the external file is open. 273 */ 274 bool 275 is_open() const throw() 276 { return _M_file.is_open(); } 277 278 /** 279 * @brief Opens an external file. 280 * @param __s The name of the file. 281 * @param __mode The open mode flags. 282 * @return @c this on success, NULL on failure 283 * 284 * If a file is already open, this function immediately fails. 285 * Otherwise it tries to open the file named @a __s using the flags 286 * given in @a __mode. 287 * 288 * Table 92, adapted here, gives the relation between openmode 289 * combinations and the equivalent @c fopen() flags. 290 * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app, 291 * and binary|in|app per DR 596) 292 * <pre> 293 * +---------------------------------------------------------+ 294 * | ios_base Flag combination stdio equivalent | 295 * |binary in out trunc app | 296 * +---------------------------------------------------------+ 297 * | + w | 298 * | + + a | 299 * | + a | 300 * | + + w | 301 * | + r | 302 * | + + r+ | 303 * | + + + w+ | 304 * | + + + a+ | 305 * | + + a+ | 306 * +---------------------------------------------------------+ 307 * | + + wb | 308 * | + + + ab | 309 * | + + ab | 310 * | + + + wb | 311 * | + + rb | 312 * | + + + r+b | 313 * | + + + + w+b | 314 * | + + + + a+b | 315 * | + + + a+b | 316 * +---------------------------------------------------------+ 317 * </pre> 318 */ 319 __filebuf_type* 320 open(const char* __s, ios_base::openmode __mode); 321 322 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 323 /** 324 * @brief Opens an external file. 325 * @param __s The name of the file, as a wide character string. 326 * @param __mode The open mode flags. 327 * @return @c this on success, NULL on failure 328 */ 329 __filebuf_type* 330 open(const wchar_t* __s, ios_base::openmode __mode); 331 #endif 332 333 #if __cplusplus >= 201103L 334 /** 335 * @brief Opens an external file. 336 * @param __s The name of the file. 337 * @param __mode The open mode flags. 338 * @return @c this on success, NULL on failure 339 */ 340 __filebuf_type* 341 open(const std::string& __s, ios_base::openmode __mode) 342 { return open(__s.c_str(), __mode); } 343 344 #if __cplusplus >= 201703L 345 /** 346 * @brief Opens an external file. 347 * @param __s The name of the file, as a filesystem::path. 348 * @param __mode The open mode flags. 349 * @return @c this on success, NULL on failure 350 */ 351 template<typename _Path> 352 _If_fs_path<_Path, __filebuf_type*> 353 open(const _Path& __s, ios_base::openmode __mode) 354 { return open(__s.c_str(), __mode); } 355 #endif // C++17 356 #endif // C++11 357 358 /** 359 * @brief Closes the currently associated file. 360 * @return @c this on success, NULL on failure 361 * 362 * If no file is currently open, this function immediately fails. 363 * 364 * If a <em>put buffer area</em> exists, @c overflow(eof) is 365 * called to flush all the characters. The file is then 366 * closed. 367 * 368 * If any operations fail, this function also fails. 369 */ 370 __filebuf_type* 371 close(); 372 373 #if __cpp_lib_fstream_native_handle // C++ >= 26 374 /** 375 * @brief The platform-specific file handle type. 376 * 377 * The type is `int` for POSIX platforms that use file descriptors, 378 * or `HANDLE` for Windows, or `FILE*` if the library was configured 379 * with `--enable-cstdio=stdio_pure`. 380 * 381 * @since C++26 382 */ 383 using native_handle_type = typename __file_type::native_handle_type; 384 385 /** 386 * @brief Return the platform-specific native handle for the file. 387 * @pre `is_open()` is true. 388 * @return The native file handle associated with `*this`. 389 * 390 * The handle is invalidated when this filebuf is closed or destroyed. 391 * 392 * @since C++26 393 */ 394 [[__gnu__::__always_inline__]] 395 native_handle_type 396 native_handle() const noexcept 397 { 398 __glibcxx_assert(is_open()); 399 return _M_file.native_handle(); 400 } 401 #endif 402 403 protected: 404 void 405 _M_allocate_internal_buffer(); 406 407 void 408 _M_destroy_internal_buffer() throw(); 409 410 // [27.8.1.4] overridden virtual functions 411 virtual streamsize 412 showmanyc(); 413 414 // Stroustrup, 1998, p. 628 415 // underflow() and uflow() functions are called to get the next 416 // character from the real input source when the buffer is empty. 417 // Buffered input uses underflow() 418 419 virtual int_type 420 underflow(); 421 422 virtual int_type 423 pbackfail(int_type __c = _Traits::eof()); 424 425 // Stroustrup, 1998, p 648 426 // The overflow() function is called to transfer characters to the 427 // real output destination when the buffer is full. A call to 428 // overflow(c) outputs the contents of the buffer plus the 429 // character c. 430 // 27.5.2.4.5 431 // Consume some sequence of the characters in the pending sequence. 432 virtual int_type 433 overflow(int_type __c = _Traits::eof()); 434 435 // Convert internal byte sequence to external, char-based 436 // sequence via codecvt. 437 bool 438 _M_convert_to_external(char_type*, streamsize); 439 440 /** 441 * @brief Manipulates the buffer. 442 * @param __s Pointer to a buffer area. 443 * @param __n Size of @a __s. 444 * @return @c this 445 * 446 * If no file has been opened, and both @a __s and @a __n are zero, then 447 * the stream becomes unbuffered. Otherwise, @c __s is used as a 448 * buffer; see 449 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering 450 * for more. 451 */ 452 virtual __streambuf_type* 453 setbuf(char_type* __s, streamsize __n); 454 455 virtual pos_type 456 seekoff(off_type __off, ios_base::seekdir __way, 457 ios_base::openmode __mode = ios_base::in | ios_base::out); 458 459 virtual pos_type 460 seekpos(pos_type __pos, 461 ios_base::openmode __mode = ios_base::in | ios_base::out); 462 463 // Common code for seekoff, seekpos, and overflow 464 pos_type 465 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); 466 467 int 468 _M_get_ext_pos(__state_type &__state); 469 470 virtual int 471 sync(); 472 473 virtual void 474 imbue(const locale& __loc); 475 476 virtual streamsize 477 xsgetn(char_type* __s, streamsize __n); 478 479 virtual streamsize 480 xsputn(const char_type* __s, streamsize __n); 481 482 // Flushes output buffer, then writes unshift sequence. 483 bool 484 _M_terminate_output(); 485 486 /** 487 * This function sets the pointers of the internal buffer, both get 488 * and put areas. Typically: 489 * 490 * __off == egptr() - eback() upon underflow/uflow (@b read mode); 491 * __off == 0 upon overflow (@b write mode); 492 * __off == -1 upon open, setbuf, seekoff/pos (@b uncommitted mode). 493 * 494 * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size 495 * reflects the actual allocated memory and the last cell is reserved 496 * for the overflow char of a full put area. 497 */ 498 void 499 _M_set_buffer(streamsize __off) 500 { 501 const bool __testin = _M_mode & ios_base::in; 502 const bool __testout = (_M_mode & ios_base::out 503 || _M_mode & ios_base::app); 504 505 if (__testin && __off > 0) 506 this->setg(_M_buf, _M_buf, _M_buf + __off); 507 else 508 this->setg(_M_buf, _M_buf, _M_buf); 509 510 if (__testout && __off == 0 && _M_buf_size > 1 ) 511 this->setp(_M_buf, _M_buf + _M_buf_size - 1); 512 else 513 this->setp(0, 0); 514 } 515 }; 516 517 // [27.8.1.5] Template class basic_ifstream 518 /** 519 * @brief Controlling input for files. 520 * @ingroup io 521 * 522 * @tparam _CharT Type of character stream. 523 * @tparam _Traits Traits for character type, defaults to 524 * char_traits<_CharT>. 525 * 526 * This class supports reading from named files, using the inherited 527 * functions from std::basic_istream. To control the associated 528 * sequence, an instance of std::basic_filebuf is used, which this page 529 * refers to as @c sb. 530 */ 531 template<typename _CharT, typename _Traits> 532 class basic_ifstream : public basic_istream<_CharT, _Traits> 533 { 534 public: 535 // Types: 536 typedef _CharT char_type; 537 typedef _Traits traits_type; 538 typedef typename traits_type::int_type int_type; 539 typedef typename traits_type::pos_type pos_type; 540 typedef typename traits_type::off_type off_type; 541 542 // Non-standard types: 543 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 544 typedef basic_istream<char_type, traits_type> __istream_type; 545 546 private: 547 __filebuf_type _M_filebuf; 548 549 public: 550 // Constructors/Destructors: 551 /** 552 * @brief Default constructor. 553 * 554 * Initializes @c sb using its default constructor, and passes 555 * @c &sb to the base class initializer. Does not open any files 556 * (you haven't given it a filename to open). 557 */ 558 basic_ifstream() : __istream_type(), _M_filebuf() 559 { this->init(&_M_filebuf); } 560 561 /** 562 * @brief Create an input file stream. 563 * @param __s Null terminated string specifying the filename. 564 * @param __mode Open file in specified mode (see std::ios_base). 565 * 566 * @c ios_base::in is automatically included in @a __mode. 567 */ 568 explicit 569 basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) 570 : __istream_type(), _M_filebuf() 571 { 572 this->init(&_M_filebuf); 573 this->open(__s, __mode); 574 } 575 576 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 577 /** 578 * @param Create an input file stream. 579 * @param __s Wide string specifying the filename. 580 * @param __mode Open file in specified mode (see std::ios_base). 581 * 582 * @c ios_base::in is automatically included in @a __mode. 583 */ 584 basic_ifstream(const wchar_t* __s, 585 ios_base::openmode __mode = ios_base::in) 586 : __istream_type(), _M_filebuf() 587 { 588 this->init(&_M_filebuf); 589 this->open(__s, __mode); 590 } 591 #endif 592 593 #if __cplusplus >= 201103L 594 /** 595 * @brief Create an input file stream. 596 * @param __s std::string specifying the filename. 597 * @param __mode Open file in specified mode (see std::ios_base). 598 * 599 * @c ios_base::in is automatically included in @a __mode. 600 */ 601 explicit 602 basic_ifstream(const std::string& __s, 603 ios_base::openmode __mode = ios_base::in) 604 : __istream_type(), _M_filebuf() 605 { 606 this->init(&_M_filebuf); 607 this->open(__s, __mode); 608 } 609 610 #if __cplusplus >= 201703L 611 /** 612 * @brief Create an input file stream. 613 * @param __s filesystem::path specifying the filename. 614 * @param __mode Open file in specified mode (see std::ios_base). 615 * 616 * @c ios_base::in is automatically included in @a __mode. 617 */ 618 template<typename _Path, typename _Require = _If_fs_path<_Path>> 619 basic_ifstream(const _Path& __s, 620 ios_base::openmode __mode = ios_base::in) 621 : basic_ifstream(__s.c_str(), __mode) 622 { } 623 #endif // C++17 624 625 basic_ifstream(const basic_ifstream&) = delete; 626 627 basic_ifstream(basic_ifstream&& __rhs) 628 : __istream_type(std::move(__rhs)), 629 _M_filebuf(std::move(__rhs._M_filebuf)) 630 { __istream_type::set_rdbuf(&_M_filebuf); } 631 #endif // C++11 632 633 /** 634 * @brief The destructor does nothing. 635 * 636 * The file is closed by the filebuf object, not the formatting 637 * stream. 638 */ 639 ~basic_ifstream() 640 { } 641 642 #if __cplusplus >= 201103L 643 // 27.8.3.2 Assign and swap: 644 645 basic_ifstream& 646 operator=(const basic_ifstream&) = delete; 647 648 basic_ifstream& 649 operator=(basic_ifstream&& __rhs) 650 { 651 __istream_type::operator=(std::move(__rhs)); 652 _M_filebuf = std::move(__rhs._M_filebuf); 653 return *this; 654 } 655 656 void 657 swap(basic_ifstream& __rhs) 658 { 659 __istream_type::swap(__rhs); 660 _M_filebuf.swap(__rhs._M_filebuf); 661 } 662 #endif 663 664 // Members: 665 /** 666 * @brief Accessing the underlying buffer. 667 * @return The current basic_filebuf buffer. 668 * 669 * This hides both signatures of std::basic_ios::rdbuf(). 670 */ 671 __filebuf_type* 672 rdbuf() const 673 { return const_cast<__filebuf_type*>(&_M_filebuf); } 674 675 /** 676 * @brief Wrapper to test for an open file. 677 * @return @c rdbuf()->is_open() 678 */ 679 bool 680 is_open() 681 { return _M_filebuf.is_open(); } 682 683 // _GLIBCXX_RESOLVE_LIB_DEFECTS 684 // 365. Lack of const-qualification in clause 27 685 bool 686 is_open() const 687 { return _M_filebuf.is_open(); } 688 689 /** 690 * @brief Opens an external file. 691 * @param __s The name of the file. 692 * @param __mode The open mode flags. 693 * 694 * Calls @c std::basic_filebuf::open(s,__mode|in). If that function 695 * fails, @c failbit is set in the stream's error state. 696 */ 697 void 698 open(const char* __s, ios_base::openmode __mode = ios_base::in) 699 { 700 if (!_M_filebuf.open(__s, __mode | ios_base::in)) 701 this->setstate(ios_base::failbit); 702 else 703 // _GLIBCXX_RESOLVE_LIB_DEFECTS 704 // 409. Closing an fstream should clear error state 705 this->clear(); 706 } 707 708 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 709 /** 710 * @brief Opens an external file. 711 * @param __s The name of the file, as a wide character string. 712 * @param __mode The open mode flags. 713 * 714 * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function 715 * fails, @c failbit is set in the stream's error state. 716 */ 717 void 718 open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in) 719 { 720 if (!_M_filebuf.open(__s, __mode | ios_base::in)) 721 this->setstate(ios_base::failbit); 722 else 723 this->clear(); 724 } 725 #endif 726 727 #if __cplusplus >= 201103L 728 /** 729 * @brief Opens an external file. 730 * @param __s The name of the file. 731 * @param __mode The open mode flags. 732 * 733 * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function 734 * fails, @c failbit is set in the stream's error state. 735 */ 736 void 737 open(const std::string& __s, ios_base::openmode __mode = ios_base::in) 738 { 739 if (!_M_filebuf.open(__s, __mode | ios_base::in)) 740 this->setstate(ios_base::failbit); 741 else 742 // _GLIBCXX_RESOLVE_LIB_DEFECTS 743 // 409. Closing an fstream should clear error state 744 this->clear(); 745 } 746 747 #if __cplusplus >= 201703L 748 /** 749 * @brief Opens an external file. 750 * @param __s The name of the file, as a filesystem::path. 751 * @param __mode The open mode flags. 752 * 753 * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function 754 * fails, @c failbit is set in the stream's error state. 755 */ 756 template<typename _Path> 757 _If_fs_path<_Path, void> 758 open(const _Path& __s, ios_base::openmode __mode = ios_base::in) 759 { open(__s.c_str(), __mode); } 760 #endif // C++17 761 #endif // C++11 762 763 /** 764 * @brief Close the file. 765 * 766 * Calls @c std::basic_filebuf::close(). If that function 767 * fails, @c failbit is set in the stream's error state. 768 */ 769 void 770 close() 771 { 772 if (!_M_filebuf.close()) 773 this->setstate(ios_base::failbit); 774 } 775 776 #if __cpp_lib_fstream_native_handle // C++ >= 26 777 using native_handle_type = typename __filebuf_type::native_handle_type; 778 779 [[__gnu__::__always_inline__]] 780 native_handle_type 781 native_handle() const noexcept 782 { return _M_filebuf.native_handle(); } 783 #endif 784 }; 785 786 787 // [27.8.1.8] Template class basic_ofstream 788 /** 789 * @brief Controlling output for files. 790 * @ingroup io 791 * 792 * @tparam _CharT Type of character stream. 793 * @tparam _Traits Traits for character type, defaults to 794 * char_traits<_CharT>. 795 * 796 * This class supports reading from named files, using the inherited 797 * functions from std::basic_ostream. To control the associated 798 * sequence, an instance of std::basic_filebuf is used, which this page 799 * refers to as @c sb. 800 */ 801 template<typename _CharT, typename _Traits> 802 class basic_ofstream : public basic_ostream<_CharT,_Traits> 803 { 804 public: 805 // Types: 806 typedef _CharT char_type; 807 typedef _Traits traits_type; 808 typedef typename traits_type::int_type int_type; 809 typedef typename traits_type::pos_type pos_type; 810 typedef typename traits_type::off_type off_type; 811 812 // Non-standard types: 813 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 814 typedef basic_ostream<char_type, traits_type> __ostream_type; 815 816 private: 817 __filebuf_type _M_filebuf; 818 819 public: 820 // Constructors: 821 /** 822 * @brief Default constructor. 823 * 824 * Initializes @c sb using its default constructor, and passes 825 * @c &sb to the base class initializer. Does not open any files 826 * (you haven't given it a filename to open). 827 */ 828 basic_ofstream(): __ostream_type(), _M_filebuf() 829 { this->init(&_M_filebuf); } 830 831 /** 832 * @brief Create an output file stream. 833 * @param __s Null terminated string specifying the filename. 834 * @param __mode Open file in specified mode (see std::ios_base). 835 * 836 * @c ios_base::out is automatically included in @a __mode. 837 */ 838 explicit 839 basic_ofstream(const char* __s, 840 ios_base::openmode __mode = ios_base::out) 841 : __ostream_type(), _M_filebuf() 842 { 843 this->init(&_M_filebuf); 844 this->open(__s, __mode); 845 } 846 847 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 848 /** 849 * @param Create an output file stream. 850 * @param __s Wide string specifying the filename. 851 * @param __mode Open file in specified mode (see std::ios_base). 852 * 853 * @c ios_base::out | @c ios_base::trunc is automatically included in 854 * @a __mode. 855 */ 856 basic_ofstream(const wchar_t* __s, 857 ios_base::openmode __mode = ios_base::out|ios_base::trunc) 858 : __ostream_type(), _M_filebuf() 859 { 860 this->init(&_M_filebuf); 861 this->open(__s, __mode); 862 } 863 #endif 864 865 #if __cplusplus >= 201103L 866 /** 867 * @brief Create an output file stream. 868 * @param __s std::string specifying the filename. 869 * @param __mode Open file in specified mode (see std::ios_base). 870 * 871 * @c ios_base::out is automatically included in @a __mode. 872 */ 873 explicit 874 basic_ofstream(const std::string& __s, 875 ios_base::openmode __mode = ios_base::out) 876 : __ostream_type(), _M_filebuf() 877 { 878 this->init(&_M_filebuf); 879 this->open(__s, __mode); 880 } 881 882 #if __cplusplus >= 201703L 883 /** 884 * @brief Create an output file stream. 885 * @param __s filesystem::path specifying the filename. 886 * @param __mode Open file in specified mode (see std::ios_base). 887 * 888 * @c ios_base::out is automatically included in @a __mode. 889 */ 890 template<typename _Path, typename _Require = _If_fs_path<_Path>> 891 basic_ofstream(const _Path& __s, 892 ios_base::openmode __mode = ios_base::out) 893 : basic_ofstream(__s.c_str(), __mode) 894 { } 895 #endif // C++17 896 897 basic_ofstream(const basic_ofstream&) = delete; 898 899 basic_ofstream(basic_ofstream&& __rhs) 900 : __ostream_type(std::move(__rhs)), 901 _M_filebuf(std::move(__rhs._M_filebuf)) 902 { __ostream_type::set_rdbuf(&_M_filebuf); } 903 #endif 904 905 /** 906 * @brief The destructor does nothing. 907 * 908 * The file is closed by the filebuf object, not the formatting 909 * stream. 910 */ 911 ~basic_ofstream() 912 { } 913 914 #if __cplusplus >= 201103L 915 // 27.8.3.2 Assign and swap: 916 917 basic_ofstream& 918 operator=(const basic_ofstream&) = delete; 919 920 basic_ofstream& 921 operator=(basic_ofstream&& __rhs) 922 { 923 __ostream_type::operator=(std::move(__rhs)); 924 _M_filebuf = std::move(__rhs._M_filebuf); 925 return *this; 926 } 927 928 void 929 swap(basic_ofstream& __rhs) 930 { 931 __ostream_type::swap(__rhs); 932 _M_filebuf.swap(__rhs._M_filebuf); 933 } 934 #endif 935 936 // Members: 937 /** 938 * @brief Accessing the underlying buffer. 939 * @return The current basic_filebuf buffer. 940 * 941 * This hides both signatures of std::basic_ios::rdbuf(). 942 */ 943 __filebuf_type* 944 rdbuf() const 945 { return const_cast<__filebuf_type*>(&_M_filebuf); } 946 947 /** 948 * @brief Wrapper to test for an open file. 949 * @return @c rdbuf()->is_open() 950 */ 951 bool 952 is_open() 953 { return _M_filebuf.is_open(); } 954 955 // _GLIBCXX_RESOLVE_LIB_DEFECTS 956 // 365. Lack of const-qualification in clause 27 957 bool 958 is_open() const 959 { return _M_filebuf.is_open(); } 960 961 /** 962 * @brief Opens an external file. 963 * @param __s The name of the file. 964 * @param __mode The open mode flags. 965 * 966 * Calls @c std::basic_filebuf::open(__s,__mode|out). If that 967 * function fails, @c failbit is set in the stream's error state. 968 */ 969 void 970 open(const char* __s, ios_base::openmode __mode = ios_base::out) 971 { 972 if (!_M_filebuf.open(__s, __mode | ios_base::out)) 973 this->setstate(ios_base::failbit); 974 else 975 // _GLIBCXX_RESOLVE_LIB_DEFECTS 976 // 409. Closing an fstream should clear error state 977 this->clear(); 978 } 979 980 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 981 /** 982 * @brief Opens an external file. 983 * @param __s The name of the file. 984 * @param __mode The open mode flags. 985 * 986 * Calls @c std::basic_filebuf::open(__s,__mode|out). If that 987 * function fails, @c failbit is set in the stream's error state. 988 */ 989 void 990 open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out) 991 { 992 if (!_M_filebuf.open(__s, __mode | ios_base::out)) 993 this->setstate(ios_base::failbit); 994 else 995 this->clear(); 996 } 997 #endif 998 999 #if __cplusplus >= 201103L 1000 /** 1001 * @brief Opens an external file. 1002 * @param __s The name of the file. 1003 * @param __mode The open mode flags. 1004 * 1005 * Calls @c std::basic_filebuf::open(s,mode|out). If that 1006 * function fails, @c failbit is set in the stream's error state. 1007 */ 1008 void 1009 open(const std::string& __s, ios_base::openmode __mode = ios_base::out) 1010 { 1011 if (!_M_filebuf.open(__s, __mode | ios_base::out)) 1012 this->setstate(ios_base::failbit); 1013 else 1014 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1015 // 409. Closing an fstream should clear error state 1016 this->clear(); 1017 } 1018 1019 #if __cplusplus >= 201703L 1020 /** 1021 * @brief Opens an external file. 1022 * @param __s The name of the file, as a filesystem::path. 1023 * @param __mode The open mode flags. 1024 * 1025 * Calls @c std::basic_filebuf::open(__s,__mode|out). If that 1026 * function fails, @c failbit is set in the stream's error state. 1027 */ 1028 template<typename _Path> 1029 _If_fs_path<_Path, void> 1030 open(const _Path& __s, ios_base::openmode __mode = ios_base::out) 1031 { open(__s.c_str(), __mode); } 1032 #endif // C++17 1033 #endif // C++11 1034 1035 /** 1036 * @brief Close the file. 1037 * 1038 * Calls @c std::basic_filebuf::close(). If that function 1039 * fails, @c failbit is set in the stream's error state. 1040 */ 1041 void 1042 close() 1043 { 1044 if (!_M_filebuf.close()) 1045 this->setstate(ios_base::failbit); 1046 } 1047 1048 #if __cpp_lib_fstream_native_handle // C++ >= 26 1049 using native_handle_type = typename __filebuf_type::native_handle_type; 1050 1051 [[__gnu__::__always_inline__]] 1052 native_handle_type 1053 native_handle() const noexcept 1054 { return _M_filebuf.native_handle(); } 1055 #endif 1056 }; 1057 1058 1059 // [27.8.1.11] Template class basic_fstream 1060 /** 1061 * @brief Controlling input and output for files. 1062 * @ingroup io 1063 * 1064 * @tparam _CharT Type of character stream. 1065 * @tparam _Traits Traits for character type, defaults to 1066 * char_traits<_CharT>. 1067 * 1068 * This class supports reading from and writing to named files, using 1069 * the inherited functions from std::basic_iostream. To control the 1070 * associated sequence, an instance of std::basic_filebuf is used, which 1071 * this page refers to as @c sb. 1072 */ 1073 template<typename _CharT, typename _Traits> 1074 class basic_fstream : public basic_iostream<_CharT, _Traits> 1075 { 1076 public: 1077 // Types: 1078 typedef _CharT char_type; 1079 typedef _Traits traits_type; 1080 typedef typename traits_type::int_type int_type; 1081 typedef typename traits_type::pos_type pos_type; 1082 typedef typename traits_type::off_type off_type; 1083 1084 // Non-standard types: 1085 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 1086 typedef basic_ios<char_type, traits_type> __ios_type; 1087 typedef basic_iostream<char_type, traits_type> __iostream_type; 1088 1089 private: 1090 __filebuf_type _M_filebuf; 1091 1092 public: 1093 // Constructors/destructor: 1094 /** 1095 * @brief Default constructor. 1096 * 1097 * Initializes @c sb using its default constructor, and passes 1098 * @c &sb to the base class initializer. Does not open any files 1099 * (you haven't given it a filename to open). 1100 */ 1101 basic_fstream() 1102 : __iostream_type(), _M_filebuf() 1103 { this->init(&_M_filebuf); } 1104 1105 /** 1106 * @brief Create an input/output file stream. 1107 * @param __s Null terminated string specifying the filename. 1108 * @param __mode Open file in specified mode (see std::ios_base). 1109 */ 1110 explicit 1111 basic_fstream(const char* __s, 1112 ios_base::openmode __mode = ios_base::in | ios_base::out) 1113 : __iostream_type(0), _M_filebuf() 1114 { 1115 this->init(&_M_filebuf); 1116 this->open(__s, __mode); 1117 } 1118 1119 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 1120 /** 1121 * @param Create an input/output file stream. 1122 * @param __s Wide string specifying the filename. 1123 * @param __mode Open file in specified mode (see std::ios_base). 1124 */ 1125 basic_fstream(const wchar_t* __s, 1126 ios_base::openmode __mode = ios_base::in | ios_base::out) 1127 : __iostream_type(0), _M_filebuf() 1128 { 1129 this->init(&_M_filebuf); 1130 this->open(__s, __mode); 1131 } 1132 #endif 1133 1134 #if __cplusplus >= 201103L 1135 /** 1136 * @brief Create an input/output file stream. 1137 * @param __s Null terminated string specifying the filename. 1138 * @param __mode Open file in specified mode (see std::ios_base). 1139 */ 1140 explicit 1141 basic_fstream(const std::string& __s, 1142 ios_base::openmode __mode = ios_base::in | ios_base::out) 1143 : __iostream_type(0), _M_filebuf() 1144 { 1145 this->init(&_M_filebuf); 1146 this->open(__s, __mode); 1147 } 1148 1149 #if __cplusplus >= 201703L 1150 /** 1151 * @brief Create an input/output file stream. 1152 * @param __s filesystem::path specifying the filename. 1153 * @param __mode Open file in specified mode (see std::ios_base). 1154 */ 1155 template<typename _Path, typename _Require = _If_fs_path<_Path>> 1156 basic_fstream(const _Path& __s, 1157 ios_base::openmode __mode = ios_base::in | ios_base::out) 1158 : basic_fstream(__s.c_str(), __mode) 1159 { } 1160 #endif // C++17 1161 1162 basic_fstream(const basic_fstream&) = delete; 1163 1164 basic_fstream(basic_fstream&& __rhs) 1165 : __iostream_type(std::move(__rhs)), 1166 _M_filebuf(std::move(__rhs._M_filebuf)) 1167 { __iostream_type::set_rdbuf(&_M_filebuf); } 1168 #endif 1169 1170 /** 1171 * @brief The destructor does nothing. 1172 * 1173 * The file is closed by the filebuf object, not the formatting 1174 * stream. 1175 */ 1176 ~basic_fstream() 1177 { } 1178 1179 #if __cplusplus >= 201103L 1180 // 27.8.3.2 Assign and swap: 1181 1182 basic_fstream& 1183 operator=(const basic_fstream&) = delete; 1184 1185 basic_fstream& 1186 operator=(basic_fstream&& __rhs) 1187 { 1188 __iostream_type::operator=(std::move(__rhs)); 1189 _M_filebuf = std::move(__rhs._M_filebuf); 1190 return *this; 1191 } 1192 1193 void 1194 swap(basic_fstream& __rhs) 1195 { 1196 __iostream_type::swap(__rhs); 1197 _M_filebuf.swap(__rhs._M_filebuf); 1198 } 1199 #endif 1200 1201 // Members: 1202 /** 1203 * @brief Accessing the underlying buffer. 1204 * @return The current basic_filebuf buffer. 1205 * 1206 * This hides both signatures of std::basic_ios::rdbuf(). 1207 */ 1208 __filebuf_type* 1209 rdbuf() const 1210 { return const_cast<__filebuf_type*>(&_M_filebuf); } 1211 1212 /** 1213 * @brief Wrapper to test for an open file. 1214 * @return @c rdbuf()->is_open() 1215 */ 1216 bool 1217 is_open() 1218 { return _M_filebuf.is_open(); } 1219 1220 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1221 // 365. Lack of const-qualification in clause 27 1222 bool 1223 is_open() const 1224 { return _M_filebuf.is_open(); } 1225 1226 /** 1227 * @brief Opens an external file. 1228 * @param __s The name of the file. 1229 * @param __mode The open mode flags. 1230 * 1231 * Calls @c std::basic_filebuf::open(__s,__mode). If that 1232 * function fails, @c failbit is set in the stream's error state. 1233 */ 1234 void 1235 open(const char* __s, 1236 ios_base::openmode __mode = ios_base::in | ios_base::out) 1237 { 1238 if (!_M_filebuf.open(__s, __mode)) 1239 this->setstate(ios_base::failbit); 1240 else 1241 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1242 // 409. Closing an fstream should clear error state 1243 this->clear(); 1244 } 1245 1246 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 1247 /** 1248 * @brief Opens an external file. 1249 * @param __s The name of the file. 1250 * @param __mode The open mode flags. 1251 * 1252 * Calls @c std::basic_filebuf::open(__s,__mode). If that 1253 * function fails, @c failbit is set in the stream's error state. 1254 */ 1255 void 1256 open(const wchar_t* __s, 1257 ios_base::openmode __mode = ios_base::in | ios_base::out) 1258 { 1259 if (!_M_filebuf.open(__s, __mode)) 1260 this->setstate(ios_base::failbit); 1261 else 1262 this->clear(); 1263 } 1264 #endif 1265 1266 #if __cplusplus >= 201103L 1267 /** 1268 * @brief Opens an external file. 1269 * @param __s The name of the file. 1270 * @param __mode The open mode flags. 1271 * 1272 * Calls @c std::basic_filebuf::open(__s,__mode). If that 1273 * function fails, @c failbit is set in the stream's error state. 1274 */ 1275 void 1276 open(const std::string& __s, 1277 ios_base::openmode __mode = ios_base::in | ios_base::out) 1278 { 1279 if (!_M_filebuf.open(__s, __mode)) 1280 this->setstate(ios_base::failbit); 1281 else 1282 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1283 // 409. Closing an fstream should clear error state 1284 this->clear(); 1285 } 1286 1287 #if __cplusplus >= 201703L 1288 /** 1289 * @brief Opens an external file. 1290 * @param __s The name of the file, as a filesystem::path. 1291 * @param __mode The open mode flags. 1292 * 1293 * Calls @c std::basic_filebuf::open(__s,__mode). If that 1294 * function fails, @c failbit is set in the stream's error state. 1295 */ 1296 template<typename _Path> 1297 _If_fs_path<_Path, void> 1298 open(const _Path& __s, 1299 ios_base::openmode __mode = ios_base::in | ios_base::out) 1300 { open(__s.c_str(), __mode); } 1301 #endif // C++17 1302 #endif // C++11 1303 1304 /** 1305 * @brief Close the file. 1306 * 1307 * Calls @c std::basic_filebuf::close(). If that function 1308 * fails, @c failbit is set in the stream's error state. 1309 */ 1310 void 1311 close() 1312 { 1313 if (!_M_filebuf.close()) 1314 this->setstate(ios_base::failbit); 1315 } 1316 1317 #if __cpp_lib_fstream_native_handle // C++ >= 26 1318 using native_handle_type = typename __filebuf_type::native_handle_type; 1319 1320 [[__gnu__::__always_inline__]] 1321 native_handle_type 1322 native_handle() const noexcept 1323 { return _M_filebuf.native_handle(); } 1324 #endif 1325 }; 1326 1327 #if __cplusplus >= 201103L 1328 /// Swap specialization for filebufs. 1329 template <class _CharT, class _Traits> 1330 inline void 1331 swap(basic_filebuf<_CharT, _Traits>& __x, 1332 basic_filebuf<_CharT, _Traits>& __y) 1333 { __x.swap(__y); } 1334 1335 /// Swap specialization for ifstreams. 1336 template <class _CharT, class _Traits> 1337 inline void 1338 swap(basic_ifstream<_CharT, _Traits>& __x, 1339 basic_ifstream<_CharT, _Traits>& __y) 1340 { __x.swap(__y); } 1341 1342 /// Swap specialization for ofstreams. 1343 template <class _CharT, class _Traits> 1344 inline void 1345 swap(basic_ofstream<_CharT, _Traits>& __x, 1346 basic_ofstream<_CharT, _Traits>& __y) 1347 { __x.swap(__y); } 1348 1349 /// Swap specialization for fstreams. 1350 template <class _CharT, class _Traits> 1351 inline void 1352 swap(basic_fstream<_CharT, _Traits>& __x, 1353 basic_fstream<_CharT, _Traits>& __y) 1354 { __x.swap(__y); } 1355 #endif 1356 1357 _GLIBCXX_END_NAMESPACE_VERSION 1358 } // namespace 1359 1360 #include <bits/fstream.tcc> 1361 1362 #endif /* _GLIBCXX_FSTREAM */ 1363