1// File based streams -*- C++ -*- 2 3// Copyright (C) 1997-2018 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 { this->close(); } 248 249#if __cplusplus >= 201103L 250 basic_filebuf& operator=(const basic_filebuf&) = delete; 251 basic_filebuf& operator=(basic_filebuf&&); 252 void swap(basic_filebuf&); 253#endif 254 255 // Members: 256 /** 257 * @brief Returns true if the external file is open. 258 */ 259 bool 260 is_open() const throw() 261 { return _M_file.is_open(); } 262 263 /** 264 * @brief Opens an external file. 265 * @param __s The name of the file. 266 * @param __mode The open mode flags. 267 * @return @c this on success, NULL on failure 268 * 269 * If a file is already open, this function immediately fails. 270 * Otherwise it tries to open the file named @a __s using the flags 271 * given in @a __mode. 272 * 273 * Table 92, adapted here, gives the relation between openmode 274 * combinations and the equivalent @c fopen() flags. 275 * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app, 276 * and binary|in|app per DR 596) 277 * <pre> 278 * +---------------------------------------------------------+ 279 * | ios_base Flag combination stdio equivalent | 280 * |binary in out trunc app | 281 * +---------------------------------------------------------+ 282 * | + w | 283 * | + + a | 284 * | + a | 285 * | + + w | 286 * | + r | 287 * | + + r+ | 288 * | + + + w+ | 289 * | + + + a+ | 290 * | + + a+ | 291 * +---------------------------------------------------------+ 292 * | + + wb | 293 * | + + + ab | 294 * | + + ab | 295 * | + + + wb | 296 * | + + rb | 297 * | + + + r+b | 298 * | + + + + w+b | 299 * | + + + + a+b | 300 * | + + + a+b | 301 * +---------------------------------------------------------+ 302 * </pre> 303 */ 304 __filebuf_type* 305 open(const char* __s, ios_base::openmode __mode); 306 307#if __cplusplus >= 201103L 308 /** 309 * @brief Opens an external file. 310 * @param __s The name of the file. 311 * @param __mode The open mode flags. 312 * @return @c this on success, NULL on failure 313 */ 314 __filebuf_type* 315 open(const std::string& __s, ios_base::openmode __mode) 316 { return open(__s.c_str(), __mode); } 317 318#if __cplusplus >= 201703L 319 /** 320 * @brief Opens an external file. 321 * @param __s The name of the file, as a filesystem::path. 322 * @param __mode The open mode flags. 323 * @return @c this on success, NULL on failure 324 */ 325 template<typename _Path> 326 _If_fs_path<_Path, __filebuf_type*> 327 open(const _Path& __s, ios_base::openmode __mode) 328 { return open(__s.c_str(), __mode); } 329#endif // C++17 330#endif // C++11 331 332 /** 333 * @brief Closes the currently associated file. 334 * @return @c this on success, NULL on failure 335 * 336 * If no file is currently open, this function immediately fails. 337 * 338 * If a <em>put buffer area</em> exists, @c overflow(eof) is 339 * called to flush all the characters. The file is then 340 * closed. 341 * 342 * If any operations fail, this function also fails. 343 */ 344 __filebuf_type* 345 close(); 346 347 protected: 348 void 349 _M_allocate_internal_buffer(); 350 351 void 352 _M_destroy_internal_buffer() throw(); 353 354 // [27.8.1.4] overridden virtual functions 355 virtual streamsize 356 showmanyc(); 357 358 // Stroustrup, 1998, p. 628 359 // underflow() and uflow() functions are called to get the next 360 // character from the real input source when the buffer is empty. 361 // Buffered input uses underflow() 362 363 virtual int_type 364 underflow(); 365 366 virtual int_type 367 pbackfail(int_type __c = _Traits::eof()); 368 369 // Stroustrup, 1998, p 648 370 // The overflow() function is called to transfer characters to the 371 // real output destination when the buffer is full. A call to 372 // overflow(c) outputs the contents of the buffer plus the 373 // character c. 374 // 27.5.2.4.5 375 // Consume some sequence of the characters in the pending sequence. 376 virtual int_type 377 overflow(int_type __c = _Traits::eof()); 378 379 // Convert internal byte sequence to external, char-based 380 // sequence via codecvt. 381 bool 382 _M_convert_to_external(char_type*, streamsize); 383 384 /** 385 * @brief Manipulates the buffer. 386 * @param __s Pointer to a buffer area. 387 * @param __n Size of @a __s. 388 * @return @c this 389 * 390 * If no file has been opened, and both @a __s and @a __n are zero, then 391 * the stream becomes unbuffered. Otherwise, @c __s is used as a 392 * buffer; see 393 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering 394 * for more. 395 */ 396 virtual __streambuf_type* 397 setbuf(char_type* __s, streamsize __n); 398 399 virtual pos_type 400 seekoff(off_type __off, ios_base::seekdir __way, 401 ios_base::openmode __mode = ios_base::in | ios_base::out); 402 403 virtual pos_type 404 seekpos(pos_type __pos, 405 ios_base::openmode __mode = ios_base::in | ios_base::out); 406 407 // Common code for seekoff, seekpos, and overflow 408 pos_type 409 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); 410 411 int 412 _M_get_ext_pos(__state_type &__state); 413 414 virtual int 415 sync(); 416 417 virtual void 418 imbue(const locale& __loc); 419 420 virtual streamsize 421 xsgetn(char_type* __s, streamsize __n); 422 423 virtual streamsize 424 xsputn(const char_type* __s, streamsize __n); 425 426 // Flushes output buffer, then writes unshift sequence. 427 bool 428 _M_terminate_output(); 429 430 /** 431 * This function sets the pointers of the internal buffer, both get 432 * and put areas. Typically: 433 * 434 * __off == egptr() - eback() upon underflow/uflow (@b read mode); 435 * __off == 0 upon overflow (@b write mode); 436 * __off == -1 upon open, setbuf, seekoff/pos (@b uncommitted mode). 437 * 438 * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size 439 * reflects the actual allocated memory and the last cell is reserved 440 * for the overflow char of a full put area. 441 */ 442 void 443 _M_set_buffer(streamsize __off) 444 { 445 const bool __testin = _M_mode & ios_base::in; 446 const bool __testout = (_M_mode & ios_base::out 447 || _M_mode & ios_base::app); 448 449 if (__testin && __off > 0) 450 this->setg(_M_buf, _M_buf, _M_buf + __off); 451 else 452 this->setg(_M_buf, _M_buf, _M_buf); 453 454 if (__testout && __off == 0 && _M_buf_size > 1 ) 455 this->setp(_M_buf, _M_buf + _M_buf_size - 1); 456 else 457 this->setp(0, 0); 458 } 459 }; 460 461 // [27.8.1.5] Template class basic_ifstream 462 /** 463 * @brief Controlling input for files. 464 * @ingroup io 465 * 466 * @tparam _CharT Type of character stream. 467 * @tparam _Traits Traits for character type, defaults to 468 * char_traits<_CharT>. 469 * 470 * This class supports reading from named files, using the inherited 471 * functions from std::basic_istream. To control the associated 472 * sequence, an instance of std::basic_filebuf is used, which this page 473 * refers to as @c sb. 474 */ 475 template<typename _CharT, typename _Traits> 476 class basic_ifstream : public basic_istream<_CharT, _Traits> 477 { 478 public: 479 // Types: 480 typedef _CharT char_type; 481 typedef _Traits traits_type; 482 typedef typename traits_type::int_type int_type; 483 typedef typename traits_type::pos_type pos_type; 484 typedef typename traits_type::off_type off_type; 485 486 // Non-standard types: 487 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 488 typedef basic_istream<char_type, traits_type> __istream_type; 489 490 private: 491 __filebuf_type _M_filebuf; 492 493 public: 494 // Constructors/Destructors: 495 /** 496 * @brief Default constructor. 497 * 498 * Initializes @c sb using its default constructor, and passes 499 * @c &sb to the base class initializer. Does not open any files 500 * (you haven't given it a filename to open). 501 */ 502 basic_ifstream() : __istream_type(), _M_filebuf() 503 { this->init(&_M_filebuf); } 504 505 /** 506 * @brief Create an input file stream. 507 * @param __s Null terminated string specifying the filename. 508 * @param __mode Open file in specified mode (see std::ios_base). 509 * 510 * @c ios_base::in is automatically included in @a __mode. 511 */ 512 explicit 513 basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) 514 : __istream_type(), _M_filebuf() 515 { 516 this->init(&_M_filebuf); 517 this->open(__s, __mode); 518 } 519 520#if __cplusplus >= 201103L 521 /** 522 * @brief Create an input file stream. 523 * @param __s std::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 std::string& __s, 530 ios_base::openmode __mode = ios_base::in) 531 : __istream_type(), _M_filebuf() 532 { 533 this->init(&_M_filebuf); 534 this->open(__s, __mode); 535 } 536 537#if __cplusplus >= 201703L 538 /** 539 * @param Create an input file stream. 540 * @param __s filesystem::path specifying the filename. 541 * @param __mode Open file in specified mode (see std::ios_base). 542 * 543 * @c ios_base::in is automatically included in @a __mode. 544 */ 545 template<typename _Path, typename _Require = _If_fs_path<_Path>> 546 basic_ifstream(const _Path& __s, 547 ios_base::openmode __mode = ios_base::in) 548 : basic_ifstream(__s.c_str(), __mode) 549 { } 550#endif // C++17 551 552 basic_ifstream(const basic_ifstream&) = delete; 553 554 basic_ifstream(basic_ifstream&& __rhs) 555 : __istream_type(std::move(__rhs)), 556 _M_filebuf(std::move(__rhs._M_filebuf)) 557 { __istream_type::set_rdbuf(&_M_filebuf); } 558#endif // C++11 559 560 /** 561 * @brief The destructor does nothing. 562 * 563 * The file is closed by the filebuf object, not the formatting 564 * stream. 565 */ 566 ~basic_ifstream() 567 { } 568 569#if __cplusplus >= 201103L 570 // 27.8.3.2 Assign and swap: 571 572 basic_ifstream& 573 operator=(const basic_ifstream&) = delete; 574 575 basic_ifstream& 576 operator=(basic_ifstream&& __rhs) 577 { 578 __istream_type::operator=(std::move(__rhs)); 579 _M_filebuf = std::move(__rhs._M_filebuf); 580 return *this; 581 } 582 583 void 584 swap(basic_ifstream& __rhs) 585 { 586 __istream_type::swap(__rhs); 587 _M_filebuf.swap(__rhs._M_filebuf); 588 } 589#endif 590 591 // Members: 592 /** 593 * @brief Accessing the underlying buffer. 594 * @return The current basic_filebuf buffer. 595 * 596 * This hides both signatures of std::basic_ios::rdbuf(). 597 */ 598 __filebuf_type* 599 rdbuf() const 600 { return const_cast<__filebuf_type*>(&_M_filebuf); } 601 602 /** 603 * @brief Wrapper to test for an open file. 604 * @return @c rdbuf()->is_open() 605 */ 606 bool 607 is_open() 608 { return _M_filebuf.is_open(); } 609 610 // _GLIBCXX_RESOLVE_LIB_DEFECTS 611 // 365. Lack of const-qualification in clause 27 612 bool 613 is_open() const 614 { return _M_filebuf.is_open(); } 615 616 /** 617 * @brief Opens an external file. 618 * @param __s The name of the file. 619 * @param __mode The open mode flags. 620 * 621 * Calls @c std::basic_filebuf::open(s,__mode|in). If that function 622 * fails, @c failbit is set in the stream's error state. 623 */ 624 void 625 open(const char* __s, ios_base::openmode __mode = ios_base::in) 626 { 627 if (!_M_filebuf.open(__s, __mode | ios_base::in)) 628 this->setstate(ios_base::failbit); 629 else 630 // _GLIBCXX_RESOLVE_LIB_DEFECTS 631 // 409. Closing an fstream should clear error state 632 this->clear(); 633 } 634 635#if __cplusplus >= 201103L 636 /** 637 * @brief Opens an external file. 638 * @param __s The name of the file. 639 * @param __mode The open mode flags. 640 * 641 * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function 642 * fails, @c failbit is set in the stream's error state. 643 */ 644 void 645 open(const std::string& __s, ios_base::openmode __mode = ios_base::in) 646 { 647 if (!_M_filebuf.open(__s, __mode | ios_base::in)) 648 this->setstate(ios_base::failbit); 649 else 650 // _GLIBCXX_RESOLVE_LIB_DEFECTS 651 // 409. Closing an fstream should clear error state 652 this->clear(); 653 } 654 655#if __cplusplus >= 201703L 656 /** 657 * @brief Opens an external file. 658 * @param __s The name of the file, as a filesystem::path. 659 * @param __mode The open mode flags. 660 * 661 * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function 662 * fails, @c failbit is set in the stream's error state. 663 */ 664 template<typename _Path> 665 _If_fs_path<_Path, void> 666 open(const _Path& __s, ios_base::openmode __mode = ios_base::in) 667 { open(__s.c_str(), __mode); } 668#endif // C++17 669#endif // C++11 670 671 /** 672 * @brief Close the file. 673 * 674 * Calls @c std::basic_filebuf::close(). If that function 675 * fails, @c failbit is set in the stream's error state. 676 */ 677 void 678 close() 679 { 680 if (!_M_filebuf.close()) 681 this->setstate(ios_base::failbit); 682 } 683 }; 684 685 686 // [27.8.1.8] Template class basic_ofstream 687 /** 688 * @brief Controlling output for files. 689 * @ingroup io 690 * 691 * @tparam _CharT Type of character stream. 692 * @tparam _Traits Traits for character type, defaults to 693 * char_traits<_CharT>. 694 * 695 * This class supports reading from named files, using the inherited 696 * functions from std::basic_ostream. To control the associated 697 * sequence, an instance of std::basic_filebuf is used, which this page 698 * refers to as @c sb. 699 */ 700 template<typename _CharT, typename _Traits> 701 class basic_ofstream : public basic_ostream<_CharT,_Traits> 702 { 703 public: 704 // Types: 705 typedef _CharT char_type; 706 typedef _Traits traits_type; 707 typedef typename traits_type::int_type int_type; 708 typedef typename traits_type::pos_type pos_type; 709 typedef typename traits_type::off_type off_type; 710 711 // Non-standard types: 712 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 713 typedef basic_ostream<char_type, traits_type> __ostream_type; 714 715 private: 716 __filebuf_type _M_filebuf; 717 718 public: 719 // Constructors: 720 /** 721 * @brief Default constructor. 722 * 723 * Initializes @c sb using its default constructor, and passes 724 * @c &sb to the base class initializer. Does not open any files 725 * (you haven't given it a filename to open). 726 */ 727 basic_ofstream(): __ostream_type(), _M_filebuf() 728 { this->init(&_M_filebuf); } 729 730 /** 731 * @brief Create an output file stream. 732 * @param __s Null terminated string specifying the filename. 733 * @param __mode Open file in specified mode (see std::ios_base). 734 * 735 * @c ios_base::out is automatically included in @a __mode. 736 */ 737 explicit 738 basic_ofstream(const char* __s, 739 ios_base::openmode __mode = ios_base::out) 740 : __ostream_type(), _M_filebuf() 741 { 742 this->init(&_M_filebuf); 743 this->open(__s, __mode); 744 } 745 746#if __cplusplus >= 201103L 747 /** 748 * @brief Create an output file stream. 749 * @param __s std::string specifying the filename. 750 * @param __mode Open file in specified mode (see std::ios_base). 751 * 752 * @c ios_base::out is automatically included in @a __mode. 753 */ 754 explicit 755 basic_ofstream(const std::string& __s, 756 ios_base::openmode __mode = ios_base::out) 757 : __ostream_type(), _M_filebuf() 758 { 759 this->init(&_M_filebuf); 760 this->open(__s, __mode); 761 } 762 763#if __cplusplus >= 201703L 764 /** 765 * @param Create an output file stream. 766 * @param __s filesystem::path specifying the filename. 767 * @param __mode Open file in specified mode (see std::ios_base). 768 * 769 * @c ios_base::out is automatically included in @a __mode. 770 */ 771 template<typename _Path, typename _Require = _If_fs_path<_Path>> 772 basic_ofstream(const _Path& __s, 773 ios_base::openmode __mode = ios_base::out) 774 : basic_ofstream(__s.c_str(), __mode) 775 { } 776#endif // C++17 777 778 basic_ofstream(const basic_ofstream&) = delete; 779 780 basic_ofstream(basic_ofstream&& __rhs) 781 : __ostream_type(std::move(__rhs)), 782 _M_filebuf(std::move(__rhs._M_filebuf)) 783 { __ostream_type::set_rdbuf(&_M_filebuf); } 784#endif 785 786 /** 787 * @brief The destructor does nothing. 788 * 789 * The file is closed by the filebuf object, not the formatting 790 * stream. 791 */ 792 ~basic_ofstream() 793 { } 794 795#if __cplusplus >= 201103L 796 // 27.8.3.2 Assign and swap: 797 798 basic_ofstream& 799 operator=(const basic_ofstream&) = delete; 800 801 basic_ofstream& 802 operator=(basic_ofstream&& __rhs) 803 { 804 __ostream_type::operator=(std::move(__rhs)); 805 _M_filebuf = std::move(__rhs._M_filebuf); 806 return *this; 807 } 808 809 void 810 swap(basic_ofstream& __rhs) 811 { 812 __ostream_type::swap(__rhs); 813 _M_filebuf.swap(__rhs._M_filebuf); 814 } 815#endif 816 817 // Members: 818 /** 819 * @brief Accessing the underlying buffer. 820 * @return The current basic_filebuf buffer. 821 * 822 * This hides both signatures of std::basic_ios::rdbuf(). 823 */ 824 __filebuf_type* 825 rdbuf() const 826 { return const_cast<__filebuf_type*>(&_M_filebuf); } 827 828 /** 829 * @brief Wrapper to test for an open file. 830 * @return @c rdbuf()->is_open() 831 */ 832 bool 833 is_open() 834 { return _M_filebuf.is_open(); } 835 836 // _GLIBCXX_RESOLVE_LIB_DEFECTS 837 // 365. Lack of const-qualification in clause 27 838 bool 839 is_open() const 840 { return _M_filebuf.is_open(); } 841 842 /** 843 * @brief Opens an external file. 844 * @param __s The name of the file. 845 * @param __mode The open mode flags. 846 * 847 * Calls @c std::basic_filebuf::open(__s,__mode|out). If that 848 * function fails, @c failbit is set in the stream's error state. 849 */ 850 void 851 open(const char* __s, ios_base::openmode __mode = ios_base::out) 852 { 853 if (!_M_filebuf.open(__s, __mode | ios_base::out)) 854 this->setstate(ios_base::failbit); 855 else 856 // _GLIBCXX_RESOLVE_LIB_DEFECTS 857 // 409. Closing an fstream should clear error state 858 this->clear(); 859 } 860 861#if __cplusplus >= 201103L 862 /** 863 * @brief Opens an external file. 864 * @param __s The name of the file. 865 * @param __mode The open mode flags. 866 * 867 * Calls @c std::basic_filebuf::open(s,mode|out). If that 868 * function fails, @c failbit is set in the stream's error state. 869 */ 870 void 871 open(const std::string& __s, ios_base::openmode __mode = ios_base::out) 872 { 873 if (!_M_filebuf.open(__s, __mode | ios_base::out)) 874 this->setstate(ios_base::failbit); 875 else 876 // _GLIBCXX_RESOLVE_LIB_DEFECTS 877 // 409. Closing an fstream should clear error state 878 this->clear(); 879 } 880 881#if __cplusplus >= 201703L 882 /** 883 * @brief Opens an external file. 884 * @param __s The name of the file, as a filesystem::path. 885 * @param __mode The open mode flags. 886 * 887 * Calls @c std::basic_filebuf::open(__s,__mode|out). If that 888 * function fails, @c failbit is set in the stream's error state. 889 */ 890 template<typename _Path> 891 _If_fs_path<_Path, void> 892 open(const _Path& __s, ios_base::openmode __mode = ios_base::out) 893 { open(__s.c_str(), __mode); } 894#endif // C++17 895#endif // C++11 896 897 /** 898 * @brief Close the file. 899 * 900 * Calls @c std::basic_filebuf::close(). If that function 901 * fails, @c failbit is set in the stream's error state. 902 */ 903 void 904 close() 905 { 906 if (!_M_filebuf.close()) 907 this->setstate(ios_base::failbit); 908 } 909 }; 910 911 912 // [27.8.1.11] Template class basic_fstream 913 /** 914 * @brief Controlling input and output for files. 915 * @ingroup io 916 * 917 * @tparam _CharT Type of character stream. 918 * @tparam _Traits Traits for character type, defaults to 919 * char_traits<_CharT>. 920 * 921 * This class supports reading from and writing to named files, using 922 * the inherited functions from std::basic_iostream. To control the 923 * associated sequence, an instance of std::basic_filebuf is used, which 924 * this page refers to as @c sb. 925 */ 926 template<typename _CharT, typename _Traits> 927 class basic_fstream : public basic_iostream<_CharT, _Traits> 928 { 929 public: 930 // Types: 931 typedef _CharT char_type; 932 typedef _Traits traits_type; 933 typedef typename traits_type::int_type int_type; 934 typedef typename traits_type::pos_type pos_type; 935 typedef typename traits_type::off_type off_type; 936 937 // Non-standard types: 938 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 939 typedef basic_ios<char_type, traits_type> __ios_type; 940 typedef basic_iostream<char_type, traits_type> __iostream_type; 941 942 private: 943 __filebuf_type _M_filebuf; 944 945 public: 946 // Constructors/destructor: 947 /** 948 * @brief Default constructor. 949 * 950 * Initializes @c sb using its default constructor, and passes 951 * @c &sb to the base class initializer. Does not open any files 952 * (you haven't given it a filename to open). 953 */ 954 basic_fstream() 955 : __iostream_type(), _M_filebuf() 956 { this->init(&_M_filebuf); } 957 958 /** 959 * @brief Create an input/output file stream. 960 * @param __s Null terminated string specifying the filename. 961 * @param __mode Open file in specified mode (see std::ios_base). 962 */ 963 explicit 964 basic_fstream(const char* __s, 965 ios_base::openmode __mode = ios_base::in | ios_base::out) 966 : __iostream_type(0), _M_filebuf() 967 { 968 this->init(&_M_filebuf); 969 this->open(__s, __mode); 970 } 971 972#if __cplusplus >= 201103L 973 /** 974 * @brief Create an input/output file stream. 975 * @param __s Null terminated string specifying the filename. 976 * @param __mode Open file in specified mode (see std::ios_base). 977 */ 978 explicit 979 basic_fstream(const std::string& __s, 980 ios_base::openmode __mode = ios_base::in | ios_base::out) 981 : __iostream_type(0), _M_filebuf() 982 { 983 this->init(&_M_filebuf); 984 this->open(__s, __mode); 985 } 986 987#if __cplusplus >= 201703L 988 /** 989 * @param Create an input/output file stream. 990 * @param __s filesystem::path specifying the filename. 991 * @param __mode Open file in specified mode (see std::ios_base). 992 */ 993 template<typename _Path, typename _Require = _If_fs_path<_Path>> 994 basic_fstream(const _Path& __s, 995 ios_base::openmode __mode = ios_base::in | ios_base::out) 996 : basic_fstream(__s.c_str(), __mode) 997 { } 998#endif // C++17 999 1000 basic_fstream(const basic_fstream&) = delete; 1001 1002 basic_fstream(basic_fstream&& __rhs) 1003 : __iostream_type(std::move(__rhs)), 1004 _M_filebuf(std::move(__rhs._M_filebuf)) 1005 { __iostream_type::set_rdbuf(&_M_filebuf); } 1006#endif 1007 1008 /** 1009 * @brief The destructor does nothing. 1010 * 1011 * The file is closed by the filebuf object, not the formatting 1012 * stream. 1013 */ 1014 ~basic_fstream() 1015 { } 1016 1017#if __cplusplus >= 201103L 1018 // 27.8.3.2 Assign and swap: 1019 1020 basic_fstream& 1021 operator=(const basic_fstream&) = delete; 1022 1023 basic_fstream& 1024 operator=(basic_fstream&& __rhs) 1025 { 1026 __iostream_type::operator=(std::move(__rhs)); 1027 _M_filebuf = std::move(__rhs._M_filebuf); 1028 return *this; 1029 } 1030 1031 void 1032 swap(basic_fstream& __rhs) 1033 { 1034 __iostream_type::swap(__rhs); 1035 _M_filebuf.swap(__rhs._M_filebuf); 1036 } 1037#endif 1038 1039 // Members: 1040 /** 1041 * @brief Accessing the underlying buffer. 1042 * @return The current basic_filebuf buffer. 1043 * 1044 * This hides both signatures of std::basic_ios::rdbuf(). 1045 */ 1046 __filebuf_type* 1047 rdbuf() const 1048 { return const_cast<__filebuf_type*>(&_M_filebuf); } 1049 1050 /** 1051 * @brief Wrapper to test for an open file. 1052 * @return @c rdbuf()->is_open() 1053 */ 1054 bool 1055 is_open() 1056 { return _M_filebuf.is_open(); } 1057 1058 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1059 // 365. Lack of const-qualification in clause 27 1060 bool 1061 is_open() const 1062 { return _M_filebuf.is_open(); } 1063 1064 /** 1065 * @brief Opens an external file. 1066 * @param __s The name of the file. 1067 * @param __mode The open mode flags. 1068 * 1069 * Calls @c std::basic_filebuf::open(__s,__mode). If that 1070 * function fails, @c failbit is set in the stream's error state. 1071 */ 1072 void 1073 open(const char* __s, 1074 ios_base::openmode __mode = ios_base::in | ios_base::out) 1075 { 1076 if (!_M_filebuf.open(__s, __mode)) 1077 this->setstate(ios_base::failbit); 1078 else 1079 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1080 // 409. Closing an fstream should clear error state 1081 this->clear(); 1082 } 1083 1084#if __cplusplus >= 201103L 1085 /** 1086 * @brief Opens an external file. 1087 * @param __s The name of the file. 1088 * @param __mode The open mode flags. 1089 * 1090 * Calls @c std::basic_filebuf::open(__s,__mode). If that 1091 * function fails, @c failbit is set in the stream's error state. 1092 */ 1093 void 1094 open(const std::string& __s, 1095 ios_base::openmode __mode = ios_base::in | ios_base::out) 1096 { 1097 if (!_M_filebuf.open(__s, __mode)) 1098 this->setstate(ios_base::failbit); 1099 else 1100 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1101 // 409. Closing an fstream should clear error state 1102 this->clear(); 1103 } 1104 1105#if __cplusplus >= 201703L 1106 /** 1107 * @brief Opens an external file. 1108 * @param __s The name of the file, as a filesystem::path. 1109 * @param __mode The open mode flags. 1110 * 1111 * Calls @c std::basic_filebuf::open(__s,__mode). If that 1112 * function fails, @c failbit is set in the stream's error state. 1113 */ 1114 template<typename _Path> 1115 _If_fs_path<_Path, void> 1116 open(const _Path& __s, 1117 ios_base::openmode __mode = ios_base::in | ios_base::out) 1118 { open(__s.c_str(), __mode); } 1119#endif // C++17 1120#endif // C++11 1121 1122 /** 1123 * @brief Close the file. 1124 * 1125 * Calls @c std::basic_filebuf::close(). If that function 1126 * fails, @c failbit is set in the stream's error state. 1127 */ 1128 void 1129 close() 1130 { 1131 if (!_M_filebuf.close()) 1132 this->setstate(ios_base::failbit); 1133 } 1134 }; 1135 1136#if __cplusplus >= 201103L 1137 /// Swap specialization for filebufs. 1138 template <class _CharT, class _Traits> 1139 inline void 1140 swap(basic_filebuf<_CharT, _Traits>& __x, 1141 basic_filebuf<_CharT, _Traits>& __y) 1142 { __x.swap(__y); } 1143 1144 /// Swap specialization for ifstreams. 1145 template <class _CharT, class _Traits> 1146 inline void 1147 swap(basic_ifstream<_CharT, _Traits>& __x, 1148 basic_ifstream<_CharT, _Traits>& __y) 1149 { __x.swap(__y); } 1150 1151 /// Swap specialization for ofstreams. 1152 template <class _CharT, class _Traits> 1153 inline void 1154 swap(basic_ofstream<_CharT, _Traits>& __x, 1155 basic_ofstream<_CharT, _Traits>& __y) 1156 { __x.swap(__y); } 1157 1158 /// Swap specialization for fstreams. 1159 template <class _CharT, class _Traits> 1160 inline void 1161 swap(basic_fstream<_CharT, _Traits>& __x, 1162 basic_fstream<_CharT, _Traits>& __y) 1163 { __x.swap(__y); } 1164#endif 1165 1166_GLIBCXX_END_NAMESPACE_VERSION 1167} // namespace 1168 1169#include <bits/fstream.tcc> 1170 1171#endif /* _GLIBCXX_FSTREAM */ 1172