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