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