libstdc++
|
00001 // File based streams -*- C++ -*- 00002 00003 // Copyright (C) 1997-2019 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file include/fstream 00026 * This is a Standard C++ Library header. 00027 */ 00028 00029 // 00030 // ISO C++ 14882: 27.8 File-based streams 00031 // 00032 00033 #ifndef _GLIBCXX_FSTREAM 00034 #define _GLIBCXX_FSTREAM 1 00035 00036 #pragma GCC system_header 00037 00038 #include <istream> 00039 #include <ostream> 00040 #include <bits/codecvt.h> 00041 #include <cstdio> // For BUFSIZ 00042 #include <bits/basic_file.h> // For __basic_file, __c_lock 00043 #if __cplusplus >= 201103L 00044 #include <string> // For std::string overloads. 00045 #endif 00046 00047 namespace std _GLIBCXX_VISIBILITY(default) 00048 { 00049 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00050 00051 #if __cplusplus >= 201703L 00052 // Enable if _Path is a filesystem::path or experimental::filesystem::path 00053 template<typename _Path, typename _Result = _Path, typename _Path2 00054 = decltype(std::declval<_Path&>().make_preferred().filename())> 00055 using _If_fs_path = enable_if_t<is_same_v<_Path, _Path2>, _Result>; 00056 #endif // C++17 00057 00058 00059 // [27.8.1.1] template class basic_filebuf 00060 /** 00061 * @brief The actual work of input and output (for files). 00062 * @ingroup io 00063 * 00064 * @tparam _CharT Type of character stream. 00065 * @tparam _Traits Traits for character type, defaults to 00066 * char_traits<_CharT>. 00067 * 00068 * This class associates both its input and output sequence with an 00069 * external disk file, and maintains a joint file position for both 00070 * sequences. Many of its semantics are described in terms of similar 00071 * behavior in the Standard C Library's @c FILE streams. 00072 * 00073 * Requirements on traits_type, specific to this class: 00074 * - traits_type::pos_type must be fpos<traits_type::state_type> 00075 * - traits_type::off_type must be streamoff 00076 * - traits_type::state_type must be Assignable and DefaultConstructible, 00077 * - traits_type::state_type() must be the initial state for codecvt. 00078 */ 00079 template<typename _CharT, typename _Traits> 00080 class basic_filebuf : public basic_streambuf<_CharT, _Traits> 00081 { 00082 #if __cplusplus >= 201103L 00083 template<typename _Tp> 00084 using __chk_state = __and_<is_copy_assignable<_Tp>, 00085 is_copy_constructible<_Tp>, 00086 is_default_constructible<_Tp>>; 00087 00088 static_assert(__chk_state<typename _Traits::state_type>::value, 00089 "state_type must be CopyAssignable, CopyConstructible" 00090 " and DefaultConstructible"); 00091 00092 static_assert(is_same<typename _Traits::pos_type, 00093 fpos<typename _Traits::state_type>>::value, 00094 "pos_type must be fpos<state_type>"); 00095 #endif 00096 public: 00097 // Types: 00098 typedef _CharT char_type; 00099 typedef _Traits traits_type; 00100 typedef typename traits_type::int_type int_type; 00101 typedef typename traits_type::pos_type pos_type; 00102 typedef typename traits_type::off_type off_type; 00103 00104 typedef basic_streambuf<char_type, traits_type> __streambuf_type; 00105 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 00106 typedef __basic_file<char> __file_type; 00107 typedef typename traits_type::state_type __state_type; 00108 typedef codecvt<char_type, char, __state_type> __codecvt_type; 00109 00110 friend class ios_base; // For sync_with_stdio. 00111 00112 protected: 00113 // Data Members: 00114 // MT lock inherited from libio or other low-level io library. 00115 __c_lock _M_lock; 00116 00117 // External buffer. 00118 __file_type _M_file; 00119 00120 /// Place to stash in || out || in | out settings for current filebuf. 00121 ios_base::openmode _M_mode; 00122 00123 // Beginning state type for codecvt. 00124 __state_type _M_state_beg; 00125 00126 // During output, the state that corresponds to pptr(), 00127 // during input, the state that corresponds to egptr() and 00128 // _M_ext_next. 00129 __state_type _M_state_cur; 00130 00131 // Not used for output. During input, the state that corresponds 00132 // to eback() and _M_ext_buf. 00133 __state_type _M_state_last; 00134 00135 /// Pointer to the beginning of internal buffer. 00136 char_type* _M_buf; 00137 00138 /** 00139 * Actual size of internal buffer. This number is equal to the size 00140 * of the put area + 1 position, reserved for the overflow char of 00141 * a full area. 00142 */ 00143 size_t _M_buf_size; 00144 00145 // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. 00146 bool _M_buf_allocated; 00147 00148 /** 00149 * _M_reading == false && _M_writing == false for @b uncommitted mode; 00150 * _M_reading == true for @b read mode; 00151 * _M_writing == true for @b write mode; 00152 * 00153 * NB: _M_reading == true && _M_writing == true is unused. 00154 */ 00155 bool _M_reading; 00156 bool _M_writing; 00157 00158 //@{ 00159 /** 00160 * Necessary bits for putback buffer management. 00161 * 00162 * @note pbacks of over one character are not currently supported. 00163 */ 00164 char_type _M_pback; 00165 char_type* _M_pback_cur_save; 00166 char_type* _M_pback_end_save; 00167 bool _M_pback_init; 00168 //@} 00169 00170 // Cached codecvt facet. 00171 const __codecvt_type* _M_codecvt; 00172 00173 /** 00174 * Buffer for external characters. Used for input when 00175 * codecvt::always_noconv() == false. When valid, this corresponds 00176 * to eback(). 00177 */ 00178 char* _M_ext_buf; 00179 00180 /** 00181 * Size of buffer held by _M_ext_buf. 00182 */ 00183 streamsize _M_ext_buf_size; 00184 00185 /** 00186 * Pointers into the buffer held by _M_ext_buf that delimit a 00187 * subsequence of bytes that have been read but not yet converted. 00188 * When valid, _M_ext_next corresponds to egptr(). 00189 */ 00190 const char* _M_ext_next; 00191 char* _M_ext_end; 00192 00193 /** 00194 * Initializes pback buffers, and moves normal buffers to safety. 00195 * Assumptions: 00196 * _M_in_cur has already been moved back 00197 */ 00198 void 00199 _M_create_pback() 00200 { 00201 if (!_M_pback_init) 00202 { 00203 _M_pback_cur_save = this->gptr(); 00204 _M_pback_end_save = this->egptr(); 00205 this->setg(&_M_pback, &_M_pback, &_M_pback + 1); 00206 _M_pback_init = true; 00207 } 00208 } 00209 00210 /** 00211 * Deactivates pback buffer contents, and restores normal buffer. 00212 * Assumptions: 00213 * The pback buffer has only moved forward. 00214 */ 00215 void 00216 _M_destroy_pback() throw() 00217 { 00218 if (_M_pback_init) 00219 { 00220 // Length _M_in_cur moved in the pback buffer. 00221 _M_pback_cur_save += this->gptr() != this->eback(); 00222 this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save); 00223 _M_pback_init = false; 00224 } 00225 } 00226 00227 public: 00228 // Constructors/destructor: 00229 /** 00230 * @brief Does not open any files. 00231 * 00232 * The default constructor initializes the parent class using its 00233 * own default ctor. 00234 */ 00235 basic_filebuf(); 00236 00237 #if __cplusplus >= 201103L 00238 basic_filebuf(const basic_filebuf&) = delete; 00239 basic_filebuf(basic_filebuf&&); 00240 #endif 00241 00242 /** 00243 * @brief The destructor closes the file first. 00244 */ 00245 virtual 00246 ~basic_filebuf() 00247 { 00248 __try 00249 { this->close(); } 00250 __catch(...) 00251 { } 00252 } 00253 00254 #if __cplusplus >= 201103L 00255 basic_filebuf& operator=(const basic_filebuf&) = delete; 00256 basic_filebuf& operator=(basic_filebuf&&); 00257 void swap(basic_filebuf&); 00258 #endif 00259 00260 // Members: 00261 /** 00262 * @brief Returns true if the external file is open. 00263 */ 00264 bool 00265 is_open() const throw() 00266 { return _M_file.is_open(); } 00267 00268 /** 00269 * @brief Opens an external file. 00270 * @param __s The name of the file. 00271 * @param __mode The open mode flags. 00272 * @return @c this on success, NULL on failure 00273 * 00274 * If a file is already open, this function immediately fails. 00275 * Otherwise it tries to open the file named @a __s using the flags 00276 * given in @a __mode. 00277 * 00278 * Table 92, adapted here, gives the relation between openmode 00279 * combinations and the equivalent @c fopen() flags. 00280 * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app, 00281 * and binary|in|app per DR 596) 00282 * <pre> 00283 * +---------------------------------------------------------+ 00284 * | ios_base Flag combination stdio equivalent | 00285 * |binary in out trunc app | 00286 * +---------------------------------------------------------+ 00287 * | + w | 00288 * | + + a | 00289 * | + a | 00290 * | + + w | 00291 * | + r | 00292 * | + + r+ | 00293 * | + + + w+ | 00294 * | + + + a+ | 00295 * | + + a+ | 00296 * +---------------------------------------------------------+ 00297 * | + + wb | 00298 * | + + + ab | 00299 * | + + ab | 00300 * | + + + wb | 00301 * | + + rb | 00302 * | + + + r+b | 00303 * | + + + + w+b | 00304 * | + + + + a+b | 00305 * | + + + a+b | 00306 * +---------------------------------------------------------+ 00307 * </pre> 00308 */ 00309 __filebuf_type* 00310 open(const char* __s, ios_base::openmode __mode); 00311 00312 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 00313 /** 00314 * @brief Opens an external file. 00315 * @param __s The name of the file, as a wide character string. 00316 * @param __mode The open mode flags. 00317 * @return @c this on success, NULL on failure 00318 */ 00319 __filebuf_type* 00320 open(const wchar_t* __s, ios_base::openmode __mode); 00321 #endif 00322 00323 #if __cplusplus >= 201103L 00324 /** 00325 * @brief Opens an external file. 00326 * @param __s The name of the file. 00327 * @param __mode The open mode flags. 00328 * @return @c this on success, NULL on failure 00329 */ 00330 __filebuf_type* 00331 open(const std::string& __s, ios_base::openmode __mode) 00332 { return open(__s.c_str(), __mode); } 00333 00334 #if __cplusplus >= 201703L 00335 /** 00336 * @brief Opens an external file. 00337 * @param __s The name of the file, as a filesystem::path. 00338 * @param __mode The open mode flags. 00339 * @return @c this on success, NULL on failure 00340 */ 00341 template<typename _Path> 00342 _If_fs_path<_Path, __filebuf_type*> 00343 open(const _Path& __s, ios_base::openmode __mode) 00344 { return open(__s.c_str(), __mode); } 00345 #endif // C++17 00346 #endif // C++11 00347 00348 /** 00349 * @brief Closes the currently associated file. 00350 * @return @c this on success, NULL on failure 00351 * 00352 * If no file is currently open, this function immediately fails. 00353 * 00354 * If a <em>put buffer area</em> exists, @c overflow(eof) is 00355 * called to flush all the characters. The file is then 00356 * closed. 00357 * 00358 * If any operations fail, this function also fails. 00359 */ 00360 __filebuf_type* 00361 close(); 00362 00363 protected: 00364 void 00365 _M_allocate_internal_buffer(); 00366 00367 void 00368 _M_destroy_internal_buffer() throw(); 00369 00370 // [27.8.1.4] overridden virtual functions 00371 virtual streamsize 00372 showmanyc(); 00373 00374 // Stroustrup, 1998, p. 628 00375 // underflow() and uflow() functions are called to get the next 00376 // character from the real input source when the buffer is empty. 00377 // Buffered input uses underflow() 00378 00379 virtual int_type 00380 underflow(); 00381 00382 virtual int_type 00383 pbackfail(int_type __c = _Traits::eof()); 00384 00385 // Stroustrup, 1998, p 648 00386 // The overflow() function is called to transfer characters to the 00387 // real output destination when the buffer is full. A call to 00388 // overflow(c) outputs the contents of the buffer plus the 00389 // character c. 00390 // 27.5.2.4.5 00391 // Consume some sequence of the characters in the pending sequence. 00392 virtual int_type 00393 overflow(int_type __c = _Traits::eof()); 00394 00395 // Convert internal byte sequence to external, char-based 00396 // sequence via codecvt. 00397 bool 00398 _M_convert_to_external(char_type*, streamsize); 00399 00400 /** 00401 * @brief Manipulates the buffer. 00402 * @param __s Pointer to a buffer area. 00403 * @param __n Size of @a __s. 00404 * @return @c this 00405 * 00406 * If no file has been opened, and both @a __s and @a __n are zero, then 00407 * the stream becomes unbuffered. Otherwise, @c __s is used as a 00408 * buffer; see 00409 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering 00410 * for more. 00411 */ 00412 virtual __streambuf_type* 00413 setbuf(char_type* __s, streamsize __n); 00414 00415 virtual pos_type 00416 seekoff(off_type __off, ios_base::seekdir __way, 00417 ios_base::openmode __mode = ios_base::in | ios_base::out); 00418 00419 virtual pos_type 00420 seekpos(pos_type __pos, 00421 ios_base::openmode __mode = ios_base::in | ios_base::out); 00422 00423 // Common code for seekoff, seekpos, and overflow 00424 pos_type 00425 _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); 00426 00427 int 00428 _M_get_ext_pos(__state_type &__state); 00429 00430 virtual int 00431 sync(); 00432 00433 virtual void 00434 imbue(const locale& __loc); 00435 00436 virtual streamsize 00437 xsgetn(char_type* __s, streamsize __n); 00438 00439 virtual streamsize 00440 xsputn(const char_type* __s, streamsize __n); 00441 00442 // Flushes output buffer, then writes unshift sequence. 00443 bool 00444 _M_terminate_output(); 00445 00446 /** 00447 * This function sets the pointers of the internal buffer, both get 00448 * and put areas. Typically: 00449 * 00450 * __off == egptr() - eback() upon underflow/uflow (@b read mode); 00451 * __off == 0 upon overflow (@b write mode); 00452 * __off == -1 upon open, setbuf, seekoff/pos (@b uncommitted mode). 00453 * 00454 * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size 00455 * reflects the actual allocated memory and the last cell is reserved 00456 * for the overflow char of a full put area. 00457 */ 00458 void 00459 _M_set_buffer(streamsize __off) 00460 { 00461 const bool __testin = _M_mode & ios_base::in; 00462 const bool __testout = (_M_mode & ios_base::out 00463 || _M_mode & ios_base::app); 00464 00465 if (__testin && __off > 0) 00466 this->setg(_M_buf, _M_buf, _M_buf + __off); 00467 else 00468 this->setg(_M_buf, _M_buf, _M_buf); 00469 00470 if (__testout && __off == 0 && _M_buf_size > 1 ) 00471 this->setp(_M_buf, _M_buf + _M_buf_size - 1); 00472 else 00473 this->setp(0, 0); 00474 } 00475 }; 00476 00477 // [27.8.1.5] Template class basic_ifstream 00478 /** 00479 * @brief Controlling input for files. 00480 * @ingroup io 00481 * 00482 * @tparam _CharT Type of character stream. 00483 * @tparam _Traits Traits for character type, defaults to 00484 * char_traits<_CharT>. 00485 * 00486 * This class supports reading from named files, using the inherited 00487 * functions from std::basic_istream. To control the associated 00488 * sequence, an instance of std::basic_filebuf is used, which this page 00489 * refers to as @c sb. 00490 */ 00491 template<typename _CharT, typename _Traits> 00492 class basic_ifstream : public basic_istream<_CharT, _Traits> 00493 { 00494 public: 00495 // Types: 00496 typedef _CharT char_type; 00497 typedef _Traits traits_type; 00498 typedef typename traits_type::int_type int_type; 00499 typedef typename traits_type::pos_type pos_type; 00500 typedef typename traits_type::off_type off_type; 00501 00502 // Non-standard types: 00503 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 00504 typedef basic_istream<char_type, traits_type> __istream_type; 00505 00506 private: 00507 __filebuf_type _M_filebuf; 00508 00509 public: 00510 // Constructors/Destructors: 00511 /** 00512 * @brief Default constructor. 00513 * 00514 * Initializes @c sb using its default constructor, and passes 00515 * @c &sb to the base class initializer. Does not open any files 00516 * (you haven't given it a filename to open). 00517 */ 00518 basic_ifstream() : __istream_type(), _M_filebuf() 00519 { this->init(&_M_filebuf); } 00520 00521 /** 00522 * @brief Create an input file stream. 00523 * @param __s Null terminated string specifying the filename. 00524 * @param __mode Open file in specified mode (see std::ios_base). 00525 * 00526 * @c ios_base::in is automatically included in @a __mode. 00527 */ 00528 explicit 00529 basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) 00530 : __istream_type(), _M_filebuf() 00531 { 00532 this->init(&_M_filebuf); 00533 this->open(__s, __mode); 00534 } 00535 00536 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 00537 /** 00538 * @param Create an input file stream. 00539 * @param __s Wide string specifying the filename. 00540 * @param __mode Open file in specified mode (see std::ios_base). 00541 * 00542 * @c ios_base::in is automatically included in @a __mode. 00543 */ 00544 basic_ifstream(const wchar_t* __s, 00545 ios_base::openmode __mode = ios_base::in) 00546 : __istream_type(), _M_filebuf() 00547 { 00548 this->init(&_M_filebuf); 00549 this->open(__s, __mode); 00550 } 00551 #endif 00552 00553 #if __cplusplus >= 201103L 00554 /** 00555 * @brief Create an input file stream. 00556 * @param __s std::string specifying the filename. 00557 * @param __mode Open file in specified mode (see std::ios_base). 00558 * 00559 * @c ios_base::in is automatically included in @a __mode. 00560 */ 00561 explicit 00562 basic_ifstream(const std::string& __s, 00563 ios_base::openmode __mode = ios_base::in) 00564 : __istream_type(), _M_filebuf() 00565 { 00566 this->init(&_M_filebuf); 00567 this->open(__s, __mode); 00568 } 00569 00570 #if __cplusplus >= 201703L 00571 /** 00572 * @param Create an input file stream. 00573 * @param __s filesystem::path specifying the filename. 00574 * @param __mode Open file in specified mode (see std::ios_base). 00575 * 00576 * @c ios_base::in is automatically included in @a __mode. 00577 */ 00578 template<typename _Path, typename _Require = _If_fs_path<_Path>> 00579 basic_ifstream(const _Path& __s, 00580 ios_base::openmode __mode = ios_base::in) 00581 : basic_ifstream(__s.c_str(), __mode) 00582 { } 00583 #endif // C++17 00584 00585 basic_ifstream(const basic_ifstream&) = delete; 00586 00587 basic_ifstream(basic_ifstream&& __rhs) 00588 : __istream_type(std::move(__rhs)), 00589 _M_filebuf(std::move(__rhs._M_filebuf)) 00590 { __istream_type::set_rdbuf(&_M_filebuf); } 00591 #endif // C++11 00592 00593 /** 00594 * @brief The destructor does nothing. 00595 * 00596 * The file is closed by the filebuf object, not the formatting 00597 * stream. 00598 */ 00599 ~basic_ifstream() 00600 { } 00601 00602 #if __cplusplus >= 201103L 00603 // 27.8.3.2 Assign and swap: 00604 00605 basic_ifstream& 00606 operator=(const basic_ifstream&) = delete; 00607 00608 basic_ifstream& 00609 operator=(basic_ifstream&& __rhs) 00610 { 00611 __istream_type::operator=(std::move(__rhs)); 00612 _M_filebuf = std::move(__rhs._M_filebuf); 00613 return *this; 00614 } 00615 00616 void 00617 swap(basic_ifstream& __rhs) 00618 { 00619 __istream_type::swap(__rhs); 00620 _M_filebuf.swap(__rhs._M_filebuf); 00621 } 00622 #endif 00623 00624 // Members: 00625 /** 00626 * @brief Accessing the underlying buffer. 00627 * @return The current basic_filebuf buffer. 00628 * 00629 * This hides both signatures of std::basic_ios::rdbuf(). 00630 */ 00631 __filebuf_type* 00632 rdbuf() const 00633 { return const_cast<__filebuf_type*>(&_M_filebuf); } 00634 00635 /** 00636 * @brief Wrapper to test for an open file. 00637 * @return @c rdbuf()->is_open() 00638 */ 00639 bool 00640 is_open() 00641 { return _M_filebuf.is_open(); } 00642 00643 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00644 // 365. Lack of const-qualification in clause 27 00645 bool 00646 is_open() const 00647 { return _M_filebuf.is_open(); } 00648 00649 /** 00650 * @brief Opens an external file. 00651 * @param __s The name of the file. 00652 * @param __mode The open mode flags. 00653 * 00654 * Calls @c std::basic_filebuf::open(s,__mode|in). If that function 00655 * fails, @c failbit is set in the stream's error state. 00656 */ 00657 void 00658 open(const char* __s, ios_base::openmode __mode = ios_base::in) 00659 { 00660 if (!_M_filebuf.open(__s, __mode | ios_base::in)) 00661 this->setstate(ios_base::failbit); 00662 else 00663 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00664 // 409. Closing an fstream should clear error state 00665 this->clear(); 00666 } 00667 00668 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 00669 /** 00670 * @brief Opens an external file. 00671 * @param __s The name of the file, as a wide character string. 00672 * @param __mode The open mode flags. 00673 * 00674 * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function 00675 * fails, @c failbit is set in the stream's error state. 00676 */ 00677 void 00678 open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in) 00679 { 00680 if (!_M_filebuf.open(__s, __mode | ios_base::in)) 00681 this->setstate(ios_base::failbit); 00682 else 00683 this->clear(); 00684 } 00685 #endif 00686 00687 #if __cplusplus >= 201103L 00688 /** 00689 * @brief Opens an external file. 00690 * @param __s The name of the file. 00691 * @param __mode The open mode flags. 00692 * 00693 * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function 00694 * fails, @c failbit is set in the stream's error state. 00695 */ 00696 void 00697 open(const std::string& __s, ios_base::openmode __mode = ios_base::in) 00698 { 00699 if (!_M_filebuf.open(__s, __mode | ios_base::in)) 00700 this->setstate(ios_base::failbit); 00701 else 00702 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00703 // 409. Closing an fstream should clear error state 00704 this->clear(); 00705 } 00706 00707 #if __cplusplus >= 201703L 00708 /** 00709 * @brief Opens an external file. 00710 * @param __s The name of the file, as a filesystem::path. 00711 * @param __mode The open mode flags. 00712 * 00713 * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function 00714 * fails, @c failbit is set in the stream's error state. 00715 */ 00716 template<typename _Path> 00717 _If_fs_path<_Path, void> 00718 open(const _Path& __s, ios_base::openmode __mode = ios_base::in) 00719 { open(__s.c_str(), __mode); } 00720 #endif // C++17 00721 #endif // C++11 00722 00723 /** 00724 * @brief Close the file. 00725 * 00726 * Calls @c std::basic_filebuf::close(). If that function 00727 * fails, @c failbit is set in the stream's error state. 00728 */ 00729 void 00730 close() 00731 { 00732 if (!_M_filebuf.close()) 00733 this->setstate(ios_base::failbit); 00734 } 00735 }; 00736 00737 00738 // [27.8.1.8] Template class basic_ofstream 00739 /** 00740 * @brief Controlling output for files. 00741 * @ingroup io 00742 * 00743 * @tparam _CharT Type of character stream. 00744 * @tparam _Traits Traits for character type, defaults to 00745 * char_traits<_CharT>. 00746 * 00747 * This class supports reading from named files, using the inherited 00748 * functions from std::basic_ostream. To control the associated 00749 * sequence, an instance of std::basic_filebuf is used, which this page 00750 * refers to as @c sb. 00751 */ 00752 template<typename _CharT, typename _Traits> 00753 class basic_ofstream : public basic_ostream<_CharT,_Traits> 00754 { 00755 public: 00756 // Types: 00757 typedef _CharT char_type; 00758 typedef _Traits traits_type; 00759 typedef typename traits_type::int_type int_type; 00760 typedef typename traits_type::pos_type pos_type; 00761 typedef typename traits_type::off_type off_type; 00762 00763 // Non-standard types: 00764 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 00765 typedef basic_ostream<char_type, traits_type> __ostream_type; 00766 00767 private: 00768 __filebuf_type _M_filebuf; 00769 00770 public: 00771 // Constructors: 00772 /** 00773 * @brief Default constructor. 00774 * 00775 * Initializes @c sb using its default constructor, and passes 00776 * @c &sb to the base class initializer. Does not open any files 00777 * (you haven't given it a filename to open). 00778 */ 00779 basic_ofstream(): __ostream_type(), _M_filebuf() 00780 { this->init(&_M_filebuf); } 00781 00782 /** 00783 * @brief Create an output file stream. 00784 * @param __s Null terminated string specifying the filename. 00785 * @param __mode Open file in specified mode (see std::ios_base). 00786 * 00787 * @c ios_base::out is automatically included in @a __mode. 00788 */ 00789 explicit 00790 basic_ofstream(const char* __s, 00791 ios_base::openmode __mode = ios_base::out) 00792 : __ostream_type(), _M_filebuf() 00793 { 00794 this->init(&_M_filebuf); 00795 this->open(__s, __mode); 00796 } 00797 00798 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 00799 /** 00800 * @param Create an output file stream. 00801 * @param __s Wide string specifying the filename. 00802 * @param __mode Open file in specified mode (see std::ios_base). 00803 * 00804 * @c ios_base::out | @c ios_base::trunc is automatically included in 00805 * @a __mode. 00806 */ 00807 basic_ofstream(const wchar_t* __s, 00808 ios_base::openmode __mode = ios_base::out|ios_base::trunc) 00809 : __ostream_type(), _M_filebuf() 00810 { 00811 this->init(&_M_filebuf); 00812 this->open(__s, __mode); 00813 } 00814 #endif 00815 00816 #if __cplusplus >= 201103L 00817 /** 00818 * @brief Create an output file stream. 00819 * @param __s std::string specifying the filename. 00820 * @param __mode Open file in specified mode (see std::ios_base). 00821 * 00822 * @c ios_base::out is automatically included in @a __mode. 00823 */ 00824 explicit 00825 basic_ofstream(const std::string& __s, 00826 ios_base::openmode __mode = ios_base::out) 00827 : __ostream_type(), _M_filebuf() 00828 { 00829 this->init(&_M_filebuf); 00830 this->open(__s, __mode); 00831 } 00832 00833 #if __cplusplus >= 201703L 00834 /** 00835 * @param Create an output file stream. 00836 * @param __s filesystem::path specifying the filename. 00837 * @param __mode Open file in specified mode (see std::ios_base). 00838 * 00839 * @c ios_base::out is automatically included in @a __mode. 00840 */ 00841 template<typename _Path, typename _Require = _If_fs_path<_Path>> 00842 basic_ofstream(const _Path& __s, 00843 ios_base::openmode __mode = ios_base::out) 00844 : basic_ofstream(__s.c_str(), __mode) 00845 { } 00846 #endif // C++17 00847 00848 basic_ofstream(const basic_ofstream&) = delete; 00849 00850 basic_ofstream(basic_ofstream&& __rhs) 00851 : __ostream_type(std::move(__rhs)), 00852 _M_filebuf(std::move(__rhs._M_filebuf)) 00853 { __ostream_type::set_rdbuf(&_M_filebuf); } 00854 #endif 00855 00856 /** 00857 * @brief The destructor does nothing. 00858 * 00859 * The file is closed by the filebuf object, not the formatting 00860 * stream. 00861 */ 00862 ~basic_ofstream() 00863 { } 00864 00865 #if __cplusplus >= 201103L 00866 // 27.8.3.2 Assign and swap: 00867 00868 basic_ofstream& 00869 operator=(const basic_ofstream&) = delete; 00870 00871 basic_ofstream& 00872 operator=(basic_ofstream&& __rhs) 00873 { 00874 __ostream_type::operator=(std::move(__rhs)); 00875 _M_filebuf = std::move(__rhs._M_filebuf); 00876 return *this; 00877 } 00878 00879 void 00880 swap(basic_ofstream& __rhs) 00881 { 00882 __ostream_type::swap(__rhs); 00883 _M_filebuf.swap(__rhs._M_filebuf); 00884 } 00885 #endif 00886 00887 // Members: 00888 /** 00889 * @brief Accessing the underlying buffer. 00890 * @return The current basic_filebuf buffer. 00891 * 00892 * This hides both signatures of std::basic_ios::rdbuf(). 00893 */ 00894 __filebuf_type* 00895 rdbuf() const 00896 { return const_cast<__filebuf_type*>(&_M_filebuf); } 00897 00898 /** 00899 * @brief Wrapper to test for an open file. 00900 * @return @c rdbuf()->is_open() 00901 */ 00902 bool 00903 is_open() 00904 { return _M_filebuf.is_open(); } 00905 00906 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00907 // 365. Lack of const-qualification in clause 27 00908 bool 00909 is_open() const 00910 { return _M_filebuf.is_open(); } 00911 00912 /** 00913 * @brief Opens an external file. 00914 * @param __s The name of the file. 00915 * @param __mode The open mode flags. 00916 * 00917 * Calls @c std::basic_filebuf::open(__s,__mode|out). If that 00918 * function fails, @c failbit is set in the stream's error state. 00919 */ 00920 void 00921 open(const char* __s, ios_base::openmode __mode = ios_base::out) 00922 { 00923 if (!_M_filebuf.open(__s, __mode | ios_base::out)) 00924 this->setstate(ios_base::failbit); 00925 else 00926 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00927 // 409. Closing an fstream should clear error state 00928 this->clear(); 00929 } 00930 00931 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 00932 /** 00933 * @brief Opens an external file. 00934 * @param __s The name of the file. 00935 * @param __mode The open mode flags. 00936 * 00937 * Calls @c std::basic_filebuf::open(__s,__mode|out). If that 00938 * function fails, @c failbit is set in the stream's error state. 00939 */ 00940 void 00941 open(const wchar_t* __s, ios_base::openmode __mode = ios_base::out) 00942 { 00943 if (!_M_filebuf.open(__s, __mode | ios_base::out)) 00944 this->setstate(ios_base::failbit); 00945 else 00946 this->clear(); 00947 } 00948 #endif 00949 00950 #if __cplusplus >= 201103L 00951 /** 00952 * @brief Opens an external file. 00953 * @param __s The name of the file. 00954 * @param __mode The open mode flags. 00955 * 00956 * Calls @c std::basic_filebuf::open(s,mode|out). If that 00957 * function fails, @c failbit is set in the stream's error state. 00958 */ 00959 void 00960 open(const std::string& __s, ios_base::openmode __mode = ios_base::out) 00961 { 00962 if (!_M_filebuf.open(__s, __mode | ios_base::out)) 00963 this->setstate(ios_base::failbit); 00964 else 00965 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00966 // 409. Closing an fstream should clear error state 00967 this->clear(); 00968 } 00969 00970 #if __cplusplus >= 201703L 00971 /** 00972 * @brief Opens an external file. 00973 * @param __s The name of the file, as a filesystem::path. 00974 * @param __mode The open mode flags. 00975 * 00976 * Calls @c std::basic_filebuf::open(__s,__mode|out). If that 00977 * function fails, @c failbit is set in the stream's error state. 00978 */ 00979 template<typename _Path> 00980 _If_fs_path<_Path, void> 00981 open(const _Path& __s, ios_base::openmode __mode = ios_base::out) 00982 { open(__s.c_str(), __mode); } 00983 #endif // C++17 00984 #endif // C++11 00985 00986 /** 00987 * @brief Close the file. 00988 * 00989 * Calls @c std::basic_filebuf::close(). If that function 00990 * fails, @c failbit is set in the stream's error state. 00991 */ 00992 void 00993 close() 00994 { 00995 if (!_M_filebuf.close()) 00996 this->setstate(ios_base::failbit); 00997 } 00998 }; 00999 01000 01001 // [27.8.1.11] Template class basic_fstream 01002 /** 01003 * @brief Controlling input and output for files. 01004 * @ingroup io 01005 * 01006 * @tparam _CharT Type of character stream. 01007 * @tparam _Traits Traits for character type, defaults to 01008 * char_traits<_CharT>. 01009 * 01010 * This class supports reading from and writing to named files, using 01011 * the inherited functions from std::basic_iostream. To control the 01012 * associated sequence, an instance of std::basic_filebuf is used, which 01013 * this page refers to as @c sb. 01014 */ 01015 template<typename _CharT, typename _Traits> 01016 class basic_fstream : public basic_iostream<_CharT, _Traits> 01017 { 01018 public: 01019 // Types: 01020 typedef _CharT char_type; 01021 typedef _Traits traits_type; 01022 typedef typename traits_type::int_type int_type; 01023 typedef typename traits_type::pos_type pos_type; 01024 typedef typename traits_type::off_type off_type; 01025 01026 // Non-standard types: 01027 typedef basic_filebuf<char_type, traits_type> __filebuf_type; 01028 typedef basic_ios<char_type, traits_type> __ios_type; 01029 typedef basic_iostream<char_type, traits_type> __iostream_type; 01030 01031 private: 01032 __filebuf_type _M_filebuf; 01033 01034 public: 01035 // Constructors/destructor: 01036 /** 01037 * @brief Default constructor. 01038 * 01039 * Initializes @c sb using its default constructor, and passes 01040 * @c &sb to the base class initializer. Does not open any files 01041 * (you haven't given it a filename to open). 01042 */ 01043 basic_fstream() 01044 : __iostream_type(), _M_filebuf() 01045 { this->init(&_M_filebuf); } 01046 01047 /** 01048 * @brief Create an input/output file stream. 01049 * @param __s Null terminated string specifying the filename. 01050 * @param __mode Open file in specified mode (see std::ios_base). 01051 */ 01052 explicit 01053 basic_fstream(const char* __s, 01054 ios_base::openmode __mode = ios_base::in | ios_base::out) 01055 : __iostream_type(0), _M_filebuf() 01056 { 01057 this->init(&_M_filebuf); 01058 this->open(__s, __mode); 01059 } 01060 01061 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 01062 /** 01063 * @param Create an input/output file stream. 01064 * @param __s Wide string specifying the filename. 01065 * @param __mode Open file in specified mode (see std::ios_base). 01066 */ 01067 basic_fstream(const wchar_t* __s, 01068 ios_base::openmode __mode = ios_base::in | ios_base::out) 01069 : __iostream_type(0), _M_filebuf() 01070 { 01071 this->init(&_M_filebuf); 01072 this->open(__s, __mode); 01073 } 01074 #endif 01075 01076 #if __cplusplus >= 201103L 01077 /** 01078 * @brief Create an input/output file stream. 01079 * @param __s Null terminated string specifying the filename. 01080 * @param __mode Open file in specified mode (see std::ios_base). 01081 */ 01082 explicit 01083 basic_fstream(const std::string& __s, 01084 ios_base::openmode __mode = ios_base::in | ios_base::out) 01085 : __iostream_type(0), _M_filebuf() 01086 { 01087 this->init(&_M_filebuf); 01088 this->open(__s, __mode); 01089 } 01090 01091 #if __cplusplus >= 201703L 01092 /** 01093 * @param Create an input/output file stream. 01094 * @param __s filesystem::path specifying the filename. 01095 * @param __mode Open file in specified mode (see std::ios_base). 01096 */ 01097 template<typename _Path, typename _Require = _If_fs_path<_Path>> 01098 basic_fstream(const _Path& __s, 01099 ios_base::openmode __mode = ios_base::in | ios_base::out) 01100 : basic_fstream(__s.c_str(), __mode) 01101 { } 01102 #endif // C++17 01103 01104 basic_fstream(const basic_fstream&) = delete; 01105 01106 basic_fstream(basic_fstream&& __rhs) 01107 : __iostream_type(std::move(__rhs)), 01108 _M_filebuf(std::move(__rhs._M_filebuf)) 01109 { __iostream_type::set_rdbuf(&_M_filebuf); } 01110 #endif 01111 01112 /** 01113 * @brief The destructor does nothing. 01114 * 01115 * The file is closed by the filebuf object, not the formatting 01116 * stream. 01117 */ 01118 ~basic_fstream() 01119 { } 01120 01121 #if __cplusplus >= 201103L 01122 // 27.8.3.2 Assign and swap: 01123 01124 basic_fstream& 01125 operator=(const basic_fstream&) = delete; 01126 01127 basic_fstream& 01128 operator=(basic_fstream&& __rhs) 01129 { 01130 __iostream_type::operator=(std::move(__rhs)); 01131 _M_filebuf = std::move(__rhs._M_filebuf); 01132 return *this; 01133 } 01134 01135 void 01136 swap(basic_fstream& __rhs) 01137 { 01138 __iostream_type::swap(__rhs); 01139 _M_filebuf.swap(__rhs._M_filebuf); 01140 } 01141 #endif 01142 01143 // Members: 01144 /** 01145 * @brief Accessing the underlying buffer. 01146 * @return The current basic_filebuf buffer. 01147 * 01148 * This hides both signatures of std::basic_ios::rdbuf(). 01149 */ 01150 __filebuf_type* 01151 rdbuf() const 01152 { return const_cast<__filebuf_type*>(&_M_filebuf); } 01153 01154 /** 01155 * @brief Wrapper to test for an open file. 01156 * @return @c rdbuf()->is_open() 01157 */ 01158 bool 01159 is_open() 01160 { return _M_filebuf.is_open(); } 01161 01162 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01163 // 365. Lack of const-qualification in clause 27 01164 bool 01165 is_open() const 01166 { return _M_filebuf.is_open(); } 01167 01168 /** 01169 * @brief Opens an external file. 01170 * @param __s The name of the file. 01171 * @param __mode The open mode flags. 01172 * 01173 * Calls @c std::basic_filebuf::open(__s,__mode). If that 01174 * function fails, @c failbit is set in the stream's error state. 01175 */ 01176 void 01177 open(const char* __s, 01178 ios_base::openmode __mode = ios_base::in | ios_base::out) 01179 { 01180 if (!_M_filebuf.open(__s, __mode)) 01181 this->setstate(ios_base::failbit); 01182 else 01183 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01184 // 409. Closing an fstream should clear error state 01185 this->clear(); 01186 } 01187 01188 #if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T 01189 /** 01190 * @brief Opens an external file. 01191 * @param __s The name of the file. 01192 * @param __mode The open mode flags. 01193 * 01194 * Calls @c std::basic_filebuf::open(__s,__mode). If that 01195 * function fails, @c failbit is set in the stream's error state. 01196 */ 01197 void 01198 open(const wchar_t* __s, 01199 ios_base::openmode __mode = ios_base::in | ios_base::out) 01200 { 01201 if (!_M_filebuf.open(__s, __mode)) 01202 this->setstate(ios_base::failbit); 01203 else 01204 this->clear(); 01205 } 01206 #endif 01207 01208 #if __cplusplus >= 201103L 01209 /** 01210 * @brief Opens an external file. 01211 * @param __s The name of the file. 01212 * @param __mode The open mode flags. 01213 * 01214 * Calls @c std::basic_filebuf::open(__s,__mode). If that 01215 * function fails, @c failbit is set in the stream's error state. 01216 */ 01217 void 01218 open(const std::string& __s, 01219 ios_base::openmode __mode = ios_base::in | ios_base::out) 01220 { 01221 if (!_M_filebuf.open(__s, __mode)) 01222 this->setstate(ios_base::failbit); 01223 else 01224 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01225 // 409. Closing an fstream should clear error state 01226 this->clear(); 01227 } 01228 01229 #if __cplusplus >= 201703L 01230 /** 01231 * @brief Opens an external file. 01232 * @param __s The name of the file, as a filesystem::path. 01233 * @param __mode The open mode flags. 01234 * 01235 * Calls @c std::basic_filebuf::open(__s,__mode). If that 01236 * function fails, @c failbit is set in the stream's error state. 01237 */ 01238 template<typename _Path> 01239 _If_fs_path<_Path, void> 01240 open(const _Path& __s, 01241 ios_base::openmode __mode = ios_base::in | ios_base::out) 01242 { open(__s.c_str(), __mode); } 01243 #endif // C++17 01244 #endif // C++11 01245 01246 /** 01247 * @brief Close the file. 01248 * 01249 * Calls @c std::basic_filebuf::close(). If that function 01250 * fails, @c failbit is set in the stream's error state. 01251 */ 01252 void 01253 close() 01254 { 01255 if (!_M_filebuf.close()) 01256 this->setstate(ios_base::failbit); 01257 } 01258 }; 01259 01260 #if __cplusplus >= 201103L 01261 /// Swap specialization for filebufs. 01262 template <class _CharT, class _Traits> 01263 inline void 01264 swap(basic_filebuf<_CharT, _Traits>& __x, 01265 basic_filebuf<_CharT, _Traits>& __y) 01266 { __x.swap(__y); } 01267 01268 /// Swap specialization for ifstreams. 01269 template <class _CharT, class _Traits> 01270 inline void 01271 swap(basic_ifstream<_CharT, _Traits>& __x, 01272 basic_ifstream<_CharT, _Traits>& __y) 01273 { __x.swap(__y); } 01274 01275 /// Swap specialization for ofstreams. 01276 template <class _CharT, class _Traits> 01277 inline void 01278 swap(basic_ofstream<_CharT, _Traits>& __x, 01279 basic_ofstream<_CharT, _Traits>& __y) 01280 { __x.swap(__y); } 01281 01282 /// Swap specialization for fstreams. 01283 template <class _CharT, class _Traits> 01284 inline void 01285 swap(basic_fstream<_CharT, _Traits>& __x, 01286 basic_fstream<_CharT, _Traits>& __y) 01287 { __x.swap(__y); } 01288 #endif 01289 01290 _GLIBCXX_END_NAMESPACE_VERSION 01291 } // namespace 01292 01293 #include <bits/fstream.tcc> 01294 01295 #endif /* _GLIBCXX_FSTREAM */