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