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