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