fstream 33.1 KB
Newer Older
1
// File based streams -*- C++ -*-
2

3
// Copyright (C) 1997-2016 Free Software Foundation, Inc.
4 5 6 7
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
8
// Free Software Foundation; either version 3, or (at your option)
9 10 11 12 13 14 15
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

16 17 18 19 20 21 22 23
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.
24

25
/** @file include/fstream
26
 *  This is a Standard C++ Library header.
Phil Edwards committed
27 28
 */

29 30 31 32
//
// ISO C++ 14882: 27.8  File-based streams
//

33 34
#ifndef _GLIBCXX_FSTREAM
#define _GLIBCXX_FSTREAM 1
35 36 37 38 39

#pragma GCC system_header

#include <istream>
#include <ostream>
40
#include <bits/codecvt.h>
Paolo Carlini committed
41
#include <cstdio>             // For BUFSIZ
42
#include <bits/basic_file.h>  // For __basic_file, __c_lock
43
#if __cplusplus >= 201103L
Paolo Carlini committed
44 45
#include <string>             // For std::string overloads.
#endif
46

47 48 49
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
50

51 52 53
  // [27.8.1.1] template class basic_filebuf
  /**
   *  @brief  The actual work of input and output (for files).
Benjamin Kosnik committed
54
   *  @ingroup io
55
   *
56 57 58 59
   *  @tparam _CharT  Type of character stream.
   *  @tparam _Traits  Traits for character type, defaults to
   *                   char_traits<_CharT>.
   *
60 61
   *  This class associates both its input and output sequence with an
   *  external disk file, and maintains a joint file position for both
62
   *  sequences.  Many of its semantics are described in terms of similar
63
   *  behavior in the Standard C Library's @c FILE streams.
64 65 66 67 68 69
   *
   *  Requirements on traits_type, specific to this class:
   *  - traits_type::pos_type must be fpos<traits_type::state_type>
   *  - traits_type::off_type must be streamoff
   *  - traits_type::state_type must be Assignable and DefaultConstructible,
   *  - traits_type::state_type() must be the initial state for codecvt.
Paolo Carlini committed
70
   */
71 72 73
  template<typename _CharT, typename _Traits>
    class basic_filebuf : public basic_streambuf<_CharT, _Traits>
    {
74 75 76 77 78 79 80 81 82 83 84 85 86 87
#if __cplusplus >= 201103L
      template<typename _Tp>
	using __chk_state = __and_<is_copy_assignable<_Tp>,
				   is_copy_constructible<_Tp>,
				   is_default_constructible<_Tp>>;

      static_assert(__chk_state<typename _Traits::state_type>::value,
		    "state_type must be CopyAssignable, CopyConstructible"
		    " and DefaultConstructible");

      static_assert(is_same<typename _Traits::pos_type,
			    fpos<typename _Traits::state_type>>::value,
		    "pos_type must be fpos<state_type>");
#endif
88 89 90 91 92 93 94
    public:
      // Types:
      typedef _CharT                     	        char_type;
      typedef _Traits                    	        traits_type;
      typedef typename traits_type::int_type 		int_type;
      typedef typename traits_type::pos_type 		pos_type;
      typedef typename traits_type::off_type 		off_type;
Phil Edwards committed
95

96 97
      typedef basic_streambuf<char_type, traits_type>  	__streambuf_type;
      typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
98
      typedef __basic_file<char>		        __file_type;
99 100 101 102 103
      typedef typename traits_type::state_type          __state_type;
      typedef codecvt<char_type, char, __state_type>    __codecvt_type;

      friend class ios_base; // For sync_with_stdio.

104
    protected:
105
      // Data Members:
106 107 108
      // MT lock inherited from libio or other low-level io library.
      __c_lock          	_M_lock;

109
      // External buffer.
110
      __file_type 		_M_file;
111

Benjamin Kosnik committed
112
      /// Place to stash in || out || in | out settings for current filebuf.
113 114
      ios_base::openmode 	_M_mode;

115
      // Beginning state type for codecvt.
Phil Edwards committed
116
      __state_type 		_M_state_beg;
117

118 119 120 121 122 123 124 125 126
      // During output, the state that corresponds to pptr(),
      // during input, the state that corresponds to egptr() and
      // _M_ext_next.
      __state_type		_M_state_cur;

      // Not used for output. During input, the state that corresponds
      // to eback() and _M_ext_buf.
      __state_type		_M_state_last;

Benjamin Kosnik committed
127
      /// Pointer to the beginning of internal buffer.
128
      char_type*		_M_buf;
129

130 131 132 133
      /**
       *  Actual size of internal buffer. This number is equal to the size
       *  of the put area + 1 position, reserved for the overflow char of
       *  a full area.
Paolo Carlini committed
134
       */
135 136
      size_t			_M_buf_size;

137
      // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.
138
      bool			_M_buf_allocated;
Paolo Carlini committed
139

140
      /**
141 142 143
       *  _M_reading == false && _M_writing == false for @b uncommitted mode;
       *  _M_reading == true for @b read mode;
       *  _M_writing == true for @b write mode;
144 145
       *
       *  NB: _M_reading == true && _M_writing == true is unused.
Paolo Carlini committed
146
       */
Paolo Carlini committed
147 148 149
      bool                      _M_reading;
      bool                      _M_writing;

150 151 152 153 154
      //@{
      /**
       *  Necessary bits for putback buffer management.
       *
       *  @note pbacks of over one character are not currently supported.
Paolo Carlini committed
155 156
       */
      char_type			_M_pback;
157 158
      char_type*		_M_pback_cur_save;
      char_type*		_M_pback_end_save;
Paolo Carlini committed
159
      bool			_M_pback_init;
160 161
      //@}

162 163 164
      // Cached codecvt facet.
      const __codecvt_type* 	_M_codecvt;

165
      /**
166 167 168
       *  Buffer for external characters. Used for input when
       *  codecvt::always_noconv() == false. When valid, this corresponds
       *  to eback().
Paolo Carlini committed
169
       */
170 171 172 173
      char*			_M_ext_buf;

      /**
       *  Size of buffer held by _M_ext_buf.
Paolo Carlini committed
174
       */
175 176 177 178 179 180
      streamsize		_M_ext_buf_size;

      /**
       *  Pointers into the buffer held by _M_ext_buf that delimit a
       *  subsequence of bytes that have been read but not yet converted.
       *  When valid, _M_ext_next corresponds to egptr().
Paolo Carlini committed
181
       */
182 183 184 185
      const char*		_M_ext_next;
      char*			_M_ext_end;

      /**
186 187 188
       *  Initializes pback buffers, and moves normal buffers to safety.
       *  Assumptions:
       *  _M_in_cur has already been moved back
Paolo Carlini committed
189
       */
190
      void
191
      _M_create_pback()
192 193 194
      {
	if (!_M_pback_init)
	  {
Paolo Carlini committed
195 196
	    _M_pback_cur_save = this->gptr();
	    _M_pback_end_save = this->egptr();
197
	    this->setg(&_M_pback, &_M_pback, &_M_pback + 1);
198 199 200 201
	    _M_pback_init = true;
	  }
      }

202 203 204 205
      /**
       *  Deactivates pback buffer contents, and restores normal buffer.
       *  Assumptions:
       *  The pback buffer has only moved forward.
Paolo Carlini committed
206
       */
207
      void
208
      _M_destroy_pback() throw()
209 210 211 212
      {
	if (_M_pback_init)
	  {
	    // Length _M_in_cur moved in the pback buffer.
Paolo Carlini committed
213
	    _M_pback_cur_save += this->gptr() != this->eback();
214
	    this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save);
215 216 217 218
	    _M_pback_init = false;
	  }
      }

219 220
    public:
      // Constructors/destructor:
221 222 223 224 225
      /**
       *  @brief  Does not open any files.
       *
       *  The default constructor initializes the parent class using its
       *  own default ctor.
Paolo Carlini committed
226
       */
227 228
      basic_filebuf();

229 230 231 232 233
#if __cplusplus >= 201103L
      basic_filebuf(const basic_filebuf&) = delete;
      basic_filebuf(basic_filebuf&&);
#endif

234 235
      /**
       *  @brief  The destructor closes the file first.
Paolo Carlini committed
236
       */
Phil Edwards committed
237 238
      virtual
      ~basic_filebuf()
239
      { this->close(); }
240

241 242 243 244 245 246
#if __cplusplus >= 201103L
      basic_filebuf& operator=(const basic_filebuf&) = delete;
      basic_filebuf& operator=(basic_filebuf&&);
      void swap(basic_filebuf&);
#endif

247
      // Members:
248 249
      /**
       *  @brief  Returns true if the external file is open.
Paolo Carlini committed
250
       */
Phil Edwards committed
251
      bool
252 253
      is_open() const throw()
      { return _M_file.is_open(); }
Phil Edwards committed
254

255 256
      /**
       *  @brief  Opens an external file.
257 258
       *  @param  __s  The name of the file.
       *  @param  __mode  The open mode flags.
259 260 261
       *  @return  @c this on success, NULL on failure
       *
       *  If a file is already open, this function immediately fails.
262
       *  Otherwise it tries to open the file named @a __s using the flags
263
       *  given in @a __mode.
264
       *
265
       *  Table 92, adapted here, gives the relation between openmode
266
       *  combinations and the equivalent @c fopen() flags.
267 268
       *  (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app,
       *  and binary|in|app per DR 596)
269
       *  <pre>
270 271 272 273
       *  +---------------------------------------------------------+
       *  | ios_base Flag combination            stdio equivalent   |
       *  |binary  in  out  trunc  app                              |
       *  +---------------------------------------------------------+
274 275 276 277 278 279 280 281 282
       *  |             +                        w                  |
       *  |             +           +            a                  |
       *  |                         +            a                  |
       *  |             +     +                  w                  |
       *  |         +                            r                  |
       *  |         +   +                        r+                 |
       *  |         +   +     +                  w+                 |
       *  |         +   +           +            a+                 |
       *  |         +               +            a+                 |
283
       *  +---------------------------------------------------------+
284 285 286 287 288 289 290 291 292
       *  |   +         +                        wb                 |
       *  |   +         +           +            ab                 |
       *  |   +                     +            ab                 |
       *  |   +         +     +                  wb                 |
       *  |   +     +                            rb                 |
       *  |   +     +   +                        r+b                |
       *  |   +     +   +     +                  w+b                |
       *  |   +     +   +           +            a+b                |
       *  |   +     +               +            a+b                |
293
       *  +---------------------------------------------------------+
294
       *  </pre>
295
       */
Phil Edwards committed
296
      __filebuf_type*
297
      open(const char* __s, ios_base::openmode __mode);
Phil Edwards committed
298

299
#if __cplusplus >= 201103L
Paolo Carlini committed
300 301
      /**
       *  @brief  Opens an external file.
302 303
       *  @param  __s  The name of the file.
       *  @param  __mode  The open mode flags.
Paolo Carlini committed
304 305 306 307 308 309 310
       *  @return  @c this on success, NULL on failure
       */
      __filebuf_type*
      open(const std::string& __s, ios_base::openmode __mode)
      { return open(__s.c_str(), __mode); }
#endif

311 312 313 314 315 316
      /**
       *  @brief  Closes the currently associated file.
       *  @return  @c this on success, NULL on failure
       *
       *  If no file is currently open, this function immediately fails.
       *
317 318 319
       *  If a <em>put buffer area</em> exists, @c overflow(eof) is
       *  called to flush all the characters.  The file is then
       *  closed.
320 321
       *
       *  If any operations fail, this function also fails.
Paolo Carlini committed
322
       */
Phil Edwards committed
323
      __filebuf_type*
324
      close();
325 326

    protected:
Phil Edwards committed
327
      void
328 329
      _M_allocate_internal_buffer();

Phil Edwards committed
330
      void
331
      _M_destroy_internal_buffer() throw();
332

333
      // [27.8.1.4] overridden virtual functions
Phil Edwards committed
334
      virtual streamsize
335
      showmanyc();
Phil Edwards committed
336 337

      // Stroustrup, 1998, p. 628
338
      // underflow() and uflow() functions are called to get the next
339
      // character from the real input source when the buffer is empty.
340
      // Buffered input uses underflow()
341

Phil Edwards committed
342
      virtual int_type
343
      underflow();
344

Phil Edwards committed
345
      virtual int_type
346 347 348 349 350 351 352
      pbackfail(int_type __c = _Traits::eof());

      // Stroustrup, 1998, p 648
      // The overflow() function is called to transfer characters to the
      // real output destination when the buffer is full. A call to
      // overflow(c) outputs the contents of the buffer plus the
      // character c.
Phil Edwards committed
353
      // 27.5.2.4.5
354
      // Consume some sequence of the characters in the pending sequence.
355 356
      virtual int_type
      overflow(int_type __c = _Traits::eof());
Phil Edwards committed
357

358 359
      // Convert internal byte sequence to external, char-based
      // sequence via codecvt.
Benjamin Kosnik committed
360 361
      bool
      _M_convert_to_external(char_type*, streamsize);
362

363 364
      /**
       *  @brief  Manipulates the buffer.
365 366
       *  @param  __s  Pointer to a buffer area.
       *  @param  __n  Size of @a __s.
367 368
       *  @return  @c this
       *
369 370
       *  If no file has been opened, and both @a __s and @a __n are zero, then
       *  the stream becomes unbuffered.  Otherwise, @c __s is used as a
371
       *  buffer; see
372
       *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering
373
       *  for more.
Paolo Carlini committed
374
       */
Phil Edwards committed
375
      virtual __streambuf_type*
376
      setbuf(char_type* __s, streamsize __n);
Phil Edwards committed
377 378

      virtual pos_type
379 380 381
      seekoff(off_type __off, ios_base::seekdir __way,
	      ios_base::openmode __mode = ios_base::in | ios_base::out);

Phil Edwards committed
382
      virtual pos_type
383 384 385
      seekpos(pos_type __pos,
	      ios_base::openmode __mode = ios_base::in | ios_base::out);

386
      // Common code for seekoff, seekpos, and overflow
387
      pos_type
388
      _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state);
389

390 391
      int
      _M_get_ext_pos(__state_type &__state);
392

Phil Edwards committed
393
      virtual int
394
      sync();
Phil Edwards committed
395 396

      virtual void
397 398
      imbue(const locale& __loc);

Phil Edwards committed
399
      virtual streamsize
400
      xsgetn(char_type* __s, streamsize __n);
Phil Edwards committed
401 402

      virtual streamsize
Paolo Carlini committed
403
      xsputn(const char_type* __s, streamsize __n);
Phil Edwards committed
404

405 406 407
      // Flushes output buffer, then writes unshift sequence.
      bool
      _M_terminate_output();
408

409 410 411 412
      /**
       *  This function sets the pointers of the internal buffer, both get
       *  and put areas. Typically:
       *
413 414 415
       *   __off == egptr() - eback() upon underflow/uflow (@b read mode);
       *   __off == 0 upon overflow (@b write mode);
       *   __off == -1 upon open, setbuf, seekoff/pos (@b uncommitted mode).
Paolo Carlini committed
416
       *
417 418 419
       *  NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size
       *  reflects the actual allocated memory and the last cell is reserved
       *  for the overflow char of a full put area.
Paolo Carlini committed
420
       */
421 422 423
      void
      _M_set_buffer(streamsize __off)
      {
Paolo Carlini committed
424 425
	const bool __testin = _M_mode & ios_base::in;
	const bool __testout = (_M_mode & ios_base::out
426 427
				|| _M_mode & ios_base::app);

Paolo Carlini committed
428
	if (__testin && __off > 0)
429
	  this->setg(_M_buf, _M_buf, _M_buf + __off);
Paolo Carlini committed
430
	else
431
	  this->setg(_M_buf, _M_buf, _M_buf);
Paolo Carlini committed
432

433 434
	if (__testout && __off == 0 && _M_buf_size > 1 )
	  this->setp(_M_buf, _M_buf + _M_buf_size - 1);
Paolo Carlini committed
435
	else
436
	  this->setp(0, 0);
437
      }
438 439
    };

440
  // [27.8.1.5] Template class basic_ifstream
Phil Edwards committed
441
  /**
442
   *  @brief  Controlling input for files.
Benjamin Kosnik committed
443
   *  @ingroup io
444
   *
445 446 447 448
   *  @tparam _CharT  Type of character stream.
   *  @tparam _Traits  Traits for character type, defaults to
   *                   char_traits<_CharT>.
   *
449 450 451 452
   *  This class supports reading from named files, using the inherited
   *  functions from std::basic_istream.  To control the associated
   *  sequence, an instance of std::basic_filebuf is used, which this page
   *  refers to as @c sb.
Paolo Carlini committed
453
   */
454 455 456 457 458 459 460 461 462 463 464 465 466 467
  template<typename _CharT, typename _Traits>
    class basic_ifstream : public basic_istream<_CharT, _Traits>
    {
    public:
      // Types:
      typedef _CharT 					char_type;
      typedef _Traits 					traits_type;
      typedef typename traits_type::int_type 		int_type;
      typedef typename traits_type::pos_type 		pos_type;
      typedef typename traits_type::off_type 		off_type;

      // Non-standard types:
      typedef basic_filebuf<char_type, traits_type> 	__filebuf_type;
      typedef basic_istream<char_type, traits_type>	__istream_type;
Phil Edwards committed
468

469 470 471 472
    private:
      __filebuf_type	_M_filebuf;

    public:
473 474 475 476 477 478 479
      // Constructors/Destructors:
      /**
       *  @brief  Default constructor.
       *
       *  Initializes @c sb using its default constructor, and passes
       *  @c &sb to the base class initializer.  Does not open any files
       *  (you haven't given it a filename to open).
Paolo Carlini committed
480
       */
481
      basic_ifstream() : __istream_type(), _M_filebuf()
482 483
      { this->init(&_M_filebuf); }

Phil Edwards committed
484
      /**
485
       *  @brief  Create an input file stream.
486 487
       *  @param  __s  Null terminated string specifying the filename.
       *  @param  __mode  Open file in specified mode (see std::ios_base).
Phil Edwards committed
488
       *
489
       *  @c ios_base::in is automatically included in @a __mode.
490
       *
Phil Edwards committed
491 492
       *  Tip:  When using std::string to hold the filename, you must use
       *  .c_str() before passing it to this constructor.
Paolo Carlini committed
493
       */
Phil Edwards committed
494
      explicit
495
      basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
496
      : __istream_type(), _M_filebuf()
Phil Edwards committed
497 498 499
      {
	this->init(&_M_filebuf);
	this->open(__s, __mode);
500
      }
Phil Edwards committed
501

502
#if __cplusplus >= 201103L
Paolo Carlini committed
503 504
      /**
       *  @brief  Create an input file stream.
505 506
       *  @param  __s  std::string specifying the filename.
       *  @param  __mode  Open file in specified mode (see std::ios_base).
Paolo Carlini committed
507
       *
508
       *  @c ios_base::in is automatically included in @a __mode.
Paolo Carlini committed
509 510 511 512 513 514 515 516 517
       */
      explicit
      basic_ifstream(const std::string& __s,
		     ios_base::openmode __mode = ios_base::in)
      : __istream_type(), _M_filebuf()
      {
	this->init(&_M_filebuf);
	this->open(__s, __mode);
      }
518 519 520 521 522 523 524

      basic_ifstream(const basic_ifstream&) = delete;

      basic_ifstream(basic_ifstream&& __rhs)
      : __istream_type(std::move(__rhs)),
      _M_filebuf(std::move(__rhs._M_filebuf))
      { __istream_type::set_rdbuf(&_M_filebuf); }
Paolo Carlini committed
525 526
#endif

527 528 529 530 531
      /**
       *  @brief  The destructor does nothing.
       *
       *  The file is closed by the filebuf object, not the formatting
       *  stream.
Paolo Carlini committed
532
       */
533 534 535
      ~basic_ifstream()
      { }

536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
#if __cplusplus >= 201103L
      // 27.8.3.2 Assign and swap:

      basic_ifstream&
      operator=(const basic_ifstream&) = delete;

      basic_ifstream&
      operator=(basic_ifstream&& __rhs)
      {
	__istream_type::operator=(std::move(__rhs));
	_M_filebuf = std::move(__rhs._M_filebuf);
	return *this;
      }

      void
      swap(basic_ifstream& __rhs)
      {
	__istream_type::swap(__rhs);
	_M_filebuf.swap(__rhs._M_filebuf);
      }
#endif

558
      // Members:
Phil Edwards committed
559
      /**
560 561 562 563
       *  @brief  Accessing the underlying buffer.
       *  @return  The current basic_filebuf buffer.
       *
       *  This hides both signatures of std::basic_ios::rdbuf().
Paolo Carlini committed
564
       */
Phil Edwards committed
565 566
      __filebuf_type*
      rdbuf() const
567 568
      { return const_cast<__filebuf_type*>(&_M_filebuf); }

569 570 571
      /**
       *  @brief  Wrapper to test for an open file.
       *  @return  @c rdbuf()->is_open()
Paolo Carlini committed
572
       */
Phil Edwards committed
573
      bool
574 575 576 577 578 579 580 581
      is_open()
      { return _M_filebuf.is_open(); }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 365. Lack of const-qualification in clause 27
      bool
      is_open() const
      { return _M_filebuf.is_open(); }
582

583 584
      /**
       *  @brief  Opens an external file.
585 586
       *  @param  __s  The name of the file.
       *  @param  __mode  The open mode flags.
587
       *
588
       *  Calls @c std::basic_filebuf::open(s,__mode|in).  If that function
589 590 591 592
       *  fails, @c failbit is set in the stream's error state.
       *
       *  Tip:  When using std::string to hold the filename, you must use
       *  .c_str() before passing it to this constructor.
Paolo Carlini committed
593
       */
Phil Edwards committed
594
      void
595
      open(const char* __s, ios_base::openmode __mode = ios_base::in)
Phil Edwards committed
596
      {
597
	if (!_M_filebuf.open(__s, __mode | ios_base::in))
Phil Edwards committed
598
	  this->setstate(ios_base::failbit);
599 600 601 602
	else
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 409. Closing an fstream should clear error state
	  this->clear();
603 604
      }

605
#if __cplusplus >= 201103L
Paolo Carlini committed
606 607
      /**
       *  @brief  Opens an external file.
608 609
       *  @param  __s  The name of the file.
       *  @param  __mode  The open mode flags.
Paolo Carlini committed
610
       *
611
       *  Calls @c std::basic_filebuf::open(__s,__mode|in).  If that function
Paolo Carlini committed
612 613 614 615 616 617 618 619 620 621 622 623 624 625
       *  fails, @c failbit is set in the stream's error state.
       */
      void
      open(const std::string& __s, ios_base::openmode __mode = ios_base::in)
      {
	if (!_M_filebuf.open(__s, __mode | ios_base::in))
	  this->setstate(ios_base::failbit);
	else
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 409. Closing an fstream should clear error state
	  this->clear();
      }
#endif

626 627 628 629 630
      /**
       *  @brief  Close the file.
       *
       *  Calls @c std::basic_filebuf::close().  If that function
       *  fails, @c failbit is set in the stream's error state.
Paolo Carlini committed
631
       */
Phil Edwards committed
632
      void
633
      close()
Phil Edwards committed
634
      {
635
	if (!_M_filebuf.close())
Phil Edwards committed
636
	  this->setstate(ios_base::failbit);
637 638 639
      }
    };

Phil Edwards committed
640

641
  // [27.8.1.8] Template class basic_ofstream
Phil Edwards committed
642
  /**
643
   *  @brief  Controlling output for files.
Benjamin Kosnik committed
644
   *  @ingroup io
645
   *
646 647 648 649
   *  @tparam _CharT  Type of character stream.
   *  @tparam _Traits  Traits for character type, defaults to
   *                   char_traits<_CharT>.
   *
650 651 652 653
   *  This class supports reading from named files, using the inherited
   *  functions from std::basic_ostream.  To control the associated
   *  sequence, an instance of std::basic_filebuf is used, which this page
   *  refers to as @c sb.
Paolo Carlini committed
654
   */
655 656 657 658 659 660 661 662 663 664 665 666 667 668
  template<typename _CharT, typename _Traits>
    class basic_ofstream : public basic_ostream<_CharT,_Traits>
    {
    public:
      // Types:
      typedef _CharT 					char_type;
      typedef _Traits 					traits_type;
      typedef typename traits_type::int_type 		int_type;
      typedef typename traits_type::pos_type 		pos_type;
      typedef typename traits_type::off_type 		off_type;

      // Non-standard types:
      typedef basic_filebuf<char_type, traits_type> 	__filebuf_type;
      typedef basic_ostream<char_type, traits_type>	__ostream_type;
Phil Edwards committed
669

670 671 672 673 674
    private:
      __filebuf_type	_M_filebuf;

    public:
      // Constructors:
675 676 677 678 679 680
      /**
       *  @brief  Default constructor.
       *
       *  Initializes @c sb using its default constructor, and passes
       *  @c &sb to the base class initializer.  Does not open any files
       *  (you haven't given it a filename to open).
Paolo Carlini committed
681
       */
682
      basic_ofstream(): __ostream_type(), _M_filebuf()
683
      { this->init(&_M_filebuf); }
Phil Edwards committed
684 685

      /**
686
       *  @brief  Create an output file stream.
687 688
       *  @param  __s  Null terminated string specifying the filename.
       *  @param  __mode  Open file in specified mode (see std::ios_base).
Phil Edwards committed
689
       *
690 691
       *  @c ios_base::out | @c ios_base::trunc is automatically included in
       *  @a __mode.
692
       *
Phil Edwards committed
693 694
       *  Tip:  When using std::string to hold the filename, you must use
       *  .c_str() before passing it to this constructor.
Paolo Carlini committed
695
       */
Phil Edwards committed
696 697
      explicit
      basic_ofstream(const char* __s,
698
		     ios_base::openmode __mode = ios_base::out|ios_base::trunc)
699
      : __ostream_type(), _M_filebuf()
Phil Edwards committed
700 701 702
      {
	this->init(&_M_filebuf);
	this->open(__s, __mode);
703 704
      }

705
#if __cplusplus >= 201103L
Paolo Carlini committed
706 707
      /**
       *  @brief  Create an output file stream.
708 709
       *  @param  __s  std::string specifying the filename.
       *  @param  __mode  Open file in specified mode (see std::ios_base).
Paolo Carlini committed
710
       *
711
       *  @c ios_base::out | @c ios_base::trunc is automatically included in
712
       *  @a __mode.
Paolo Carlini committed
713 714 715 716 717 718 719 720 721
       */
      explicit
      basic_ofstream(const std::string& __s,
		     ios_base::openmode __mode = ios_base::out|ios_base::trunc)
      : __ostream_type(), _M_filebuf()
      {
	this->init(&_M_filebuf);
	this->open(__s, __mode);
      }
722 723 724 725 726 727 728

      basic_ofstream(const basic_ofstream&) = delete;

      basic_ofstream(basic_ofstream&& __rhs)
      : __ostream_type(std::move(__rhs)),
      _M_filebuf(std::move(__rhs._M_filebuf))
      { __ostream_type::set_rdbuf(&_M_filebuf); }
Paolo Carlini committed
729 730
#endif

731 732 733 734 735
      /**
       *  @brief  The destructor does nothing.
       *
       *  The file is closed by the filebuf object, not the formatting
       *  stream.
Paolo Carlini committed
736
       */
737 738 739
      ~basic_ofstream()
      { }

740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
#if __cplusplus >= 201103L
      // 27.8.3.2 Assign and swap:

      basic_ofstream&
      operator=(const basic_ofstream&) = delete;

      basic_ofstream&
      operator=(basic_ofstream&& __rhs)
      {
	__ostream_type::operator=(std::move(__rhs));
	_M_filebuf = std::move(__rhs._M_filebuf);
	return *this;
      }

      void
      swap(basic_ofstream& __rhs)
      {
	__ostream_type::swap(__rhs);
	_M_filebuf.swap(__rhs._M_filebuf);
      }
#endif

762
      // Members:
Phil Edwards committed
763
      /**
764 765 766 767
       *  @brief  Accessing the underlying buffer.
       *  @return  The current basic_filebuf buffer.
       *
       *  This hides both signatures of std::basic_ios::rdbuf().
Paolo Carlini committed
768
       */
Phil Edwards committed
769
      __filebuf_type*
770
      rdbuf() const
771
      { return const_cast<__filebuf_type*>(&_M_filebuf); }
Phil Edwards committed
772 773

      /**
774 775
       *  @brief  Wrapper to test for an open file.
       *  @return  @c rdbuf()->is_open()
Paolo Carlini committed
776
       */
Phil Edwards committed
777
      bool
778 779 780 781 782 783 784 785
      is_open()
      { return _M_filebuf.is_open(); }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 365. Lack of const-qualification in clause 27
      bool
      is_open() const
      { return _M_filebuf.is_open(); }
786

Phil Edwards committed
787
      /**
788
       *  @brief  Opens an external file.
789 790
       *  @param  __s  The name of the file.
       *  @param  __mode  The open mode flags.
791
       *
792
       *  Calls @c std::basic_filebuf::open(__s,__mode|out|trunc).  If that
793
       *  function fails, @c failbit is set in the stream's error state.
Phil Edwards committed
794 795 796
       *
       *  Tip:  When using std::string to hold the filename, you must use
       *  .c_str() before passing it to this constructor.
Paolo Carlini committed
797
       */
Phil Edwards committed
798 799
      void
      open(const char* __s,
800
	   ios_base::openmode __mode = ios_base::out | ios_base::trunc)
Phil Edwards committed
801
      {
802
	if (!_M_filebuf.open(__s, __mode | ios_base::out))
Phil Edwards committed
803
	  this->setstate(ios_base::failbit);
804 805 806 807
	else
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 409. Closing an fstream should clear error state
	  this->clear();
808 809
      }

810
#if __cplusplus >= 201103L
Paolo Carlini committed
811 812
      /**
       *  @brief  Opens an external file.
813 814
       *  @param  __s  The name of the file.
       *  @param  __mode  The open mode flags.
Paolo Carlini committed
815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831
       *
       *  Calls @c std::basic_filebuf::open(s,mode|out|trunc).  If that
       *  function fails, @c failbit is set in the stream's error state.
       */
      void
      open(const std::string& __s,
	   ios_base::openmode __mode = ios_base::out | ios_base::trunc)
      {
	if (!_M_filebuf.open(__s, __mode | ios_base::out))
	  this->setstate(ios_base::failbit);
	else
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 409. Closing an fstream should clear error state
	  this->clear();
      }
#endif

832 833 834 835 836
      /**
       *  @brief  Close the file.
       *
       *  Calls @c std::basic_filebuf::close().  If that function
       *  fails, @c failbit is set in the stream's error state.
Paolo Carlini committed
837
       */
Phil Edwards committed
838
      void
839
      close()
Phil Edwards committed
840
      {
841
	if (!_M_filebuf.close())
Phil Edwards committed
842
	  this->setstate(ios_base::failbit);
843 844 845 846
      }
    };


847
  // [27.8.1.11] Template class basic_fstream
Phil Edwards committed
848
  /**
849
   *  @brief  Controlling input and output for files.
Benjamin Kosnik committed
850
   *  @ingroup io
851
   *
852 853 854 855
   *  @tparam _CharT  Type of character stream.
   *  @tparam _Traits  Traits for character type, defaults to
   *                   char_traits<_CharT>.
   *
856 857 858 859
   *  This class supports reading from and writing to named files, using
   *  the inherited functions from std::basic_iostream.  To control the
   *  associated sequence, an instance of std::basic_filebuf is used, which
   *  this page refers to as @c sb.
Paolo Carlini committed
860
   */
861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878
  template<typename _CharT, typename _Traits>
    class basic_fstream : public basic_iostream<_CharT, _Traits>
    {
    public:
      // Types:
      typedef _CharT 					char_type;
      typedef _Traits 					traits_type;
      typedef typename traits_type::int_type 		int_type;
      typedef typename traits_type::pos_type 		pos_type;
      typedef typename traits_type::off_type 		off_type;

      // Non-standard types:
      typedef basic_filebuf<char_type, traits_type> 	__filebuf_type;
      typedef basic_ios<char_type, traits_type>		__ios_type;
      typedef basic_iostream<char_type, traits_type>	__iostream_type;

    private:
      __filebuf_type	_M_filebuf;
Phil Edwards committed
879

880 881
    public:
      // Constructors/destructor:
882 883 884 885 886 887
      /**
       *  @brief  Default constructor.
       *
       *  Initializes @c sb using its default constructor, and passes
       *  @c &sb to the base class initializer.  Does not open any files
       *  (you haven't given it a filename to open).
Paolo Carlini committed
888
       */
889
      basic_fstream()
890
      : __iostream_type(), _M_filebuf()
891 892
      { this->init(&_M_filebuf); }

Phil Edwards committed
893
      /**
894
       *  @brief  Create an input/output file stream.
895 896
       *  @param  __s  Null terminated string specifying the filename.
       *  @param  __mode  Open file in specified mode (see std::ios_base).
Phil Edwards committed
897 898 899
       *
       *  Tip:  When using std::string to hold the filename, you must use
       *  .c_str() before passing it to this constructor.
Paolo Carlini committed
900
       */
Phil Edwards committed
901
      explicit
902 903
      basic_fstream(const char* __s,
		    ios_base::openmode __mode = ios_base::in | ios_base::out)
904
      : __iostream_type(0), _M_filebuf()
Phil Edwards committed
905 906 907
      {
	this->init(&_M_filebuf);
	this->open(__s, __mode);
908
      }
Phil Edwards committed
909

910
#if __cplusplus >= 201103L
Paolo Carlini committed
911 912
      /**
       *  @brief  Create an input/output file stream.
913 914
       *  @param  __s  Null terminated string specifying the filename.
       *  @param  __mode  Open file in specified mode (see std::ios_base).
Paolo Carlini committed
915 916 917 918
       */
      explicit
      basic_fstream(const std::string& __s,
		    ios_base::openmode __mode = ios_base::in | ios_base::out)
919
      : __iostream_type(0), _M_filebuf()
Paolo Carlini committed
920 921 922 923
      {
	this->init(&_M_filebuf);
	this->open(__s, __mode);
      }
924 925 926 927 928 929 930

      basic_fstream(const basic_fstream&) = delete;

      basic_fstream(basic_fstream&& __rhs)
      : __iostream_type(std::move(__rhs)),
      _M_filebuf(std::move(__rhs._M_filebuf))
      { __iostream_type::set_rdbuf(&_M_filebuf); }
Paolo Carlini committed
931 932
#endif

933 934 935 936 937
      /**
       *  @brief  The destructor does nothing.
       *
       *  The file is closed by the filebuf object, not the formatting
       *  stream.
Paolo Carlini committed
938
       */
939 940
      ~basic_fstream()
      { }
Phil Edwards committed
941

942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963
#if __cplusplus >= 201103L
      // 27.8.3.2 Assign and swap:

      basic_fstream&
      operator=(const basic_fstream&) = delete;

      basic_fstream&
      operator=(basic_fstream&& __rhs)
      {
	__iostream_type::operator=(std::move(__rhs));
	_M_filebuf = std::move(__rhs._M_filebuf);
	return *this;
      }

      void
      swap(basic_fstream& __rhs)
      {
	__iostream_type::swap(__rhs);
	_M_filebuf.swap(__rhs._M_filebuf);
      }
#endif

964
      // Members:
Phil Edwards committed
965
      /**
966 967 968 969
       *  @brief  Accessing the underlying buffer.
       *  @return  The current basic_filebuf buffer.
       *
       *  This hides both signatures of std::basic_ios::rdbuf().
Paolo Carlini committed
970
       */
Phil Edwards committed
971
      __filebuf_type*
972
      rdbuf() const
973 974
      { return const_cast<__filebuf_type*>(&_M_filebuf); }

Phil Edwards committed
975
      /**
976 977
       *  @brief  Wrapper to test for an open file.
       *  @return  @c rdbuf()->is_open()
Paolo Carlini committed
978
       */
Phil Edwards committed
979
      bool
980 981 982 983 984 985 986 987
      is_open()
      { return _M_filebuf.is_open(); }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 365. Lack of const-qualification in clause 27
      bool
      is_open() const
      { return _M_filebuf.is_open(); }
988

Phil Edwards committed
989
      /**
990
       *  @brief  Opens an external file.
991 992
       *  @param  __s  The name of the file.
       *  @param  __mode  The open mode flags.
993
       *
994
       *  Calls @c std::basic_filebuf::open(__s,__mode).  If that
995
       *  function fails, @c failbit is set in the stream's error state.
Phil Edwards committed
996 997 998
       *
       *  Tip:  When using std::string to hold the filename, you must use
       *  .c_str() before passing it to this constructor.
Paolo Carlini committed
999
       */
Phil Edwards committed
1000 1001
      void
      open(const char* __s,
1002
	   ios_base::openmode __mode = ios_base::in | ios_base::out)
Phil Edwards committed
1003
      {
1004
	if (!_M_filebuf.open(__s, __mode))
1005
	  this->setstate(ios_base::failbit);
1006 1007 1008 1009
	else
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 409. Closing an fstream should clear error state
	  this->clear();
1010 1011
      }

1012
#if __cplusplus >= 201103L
Paolo Carlini committed
1013 1014
      /**
       *  @brief  Opens an external file.
1015 1016
       *  @param  __s  The name of the file.
       *  @param  __mode  The open mode flags.
Paolo Carlini committed
1017
       *
1018
       *  Calls @c std::basic_filebuf::open(__s,__mode).  If that
Paolo Carlini committed
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033
       *  function fails, @c failbit is set in the stream's error state.
       */
      void
      open(const std::string& __s,
	   ios_base::openmode __mode = ios_base::in | ios_base::out)
      {
	if (!_M_filebuf.open(__s, __mode))
	  this->setstate(ios_base::failbit);
	else
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 409. Closing an fstream should clear error state
	  this->clear();
      }
#endif

1034 1035 1036 1037 1038
      /**
       *  @brief  Close the file.
       *
       *  Calls @c std::basic_filebuf::close().  If that function
       *  fails, @c failbit is set in the stream's error state.
Paolo Carlini committed
1039
       */
Phil Edwards committed
1040
      void
1041
      close()
Phil Edwards committed
1042
      {
1043
	if (!_M_filebuf.close())
1044
	  this->setstate(ios_base::failbit);
1045 1046
      }
    };
1047

1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
#if __cplusplus >= 201103L
  /// Swap specialization for filebufs.
  template <class _CharT, class _Traits>
    inline void
    swap(basic_filebuf<_CharT, _Traits>& __x,
	 basic_filebuf<_CharT, _Traits>& __y)
    { __x.swap(__y); }

  /// Swap specialization for ifstreams.
  template <class _CharT, class _Traits>
    inline void
    swap(basic_ifstream<_CharT, _Traits>& __x,
	 basic_ifstream<_CharT, _Traits>& __y)
    { __x.swap(__y); }

  /// Swap specialization for ofstreams.
  template <class _CharT, class _Traits>
    inline void
    swap(basic_ofstream<_CharT, _Traits>& __x,
	 basic_ofstream<_CharT, _Traits>& __y)
    { __x.swap(__y); }

  /// Swap specialization for fstreams.
  template <class _CharT, class _Traits>
    inline void
    swap(basic_fstream<_CharT, _Traits>& __x,
	 basic_fstream<_CharT, _Traits>& __y)
    { __x.swap(__y); }
#endif

1078 1079
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
1080

1081
#include <bits/fstream.tcc>
1082

1083
#endif /* _GLIBCXX_FSTREAM */