OSDN Git Service

2003-04-12 Paolo Carlini <pcarlini@unitus.it>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / std_fstream.h
1 // File based streams -*- C++ -*-
2
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 // USA.
21
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 //
32 // ISO C++ 14882: 27.8  File-based streams
33 //
34
35 /** @file fstream
36  *  This is a Standard C++ Library header.  You should @c #include this header
37  *  in your programs, rather than any of the "st[dl]_*.h" implementation files.
38  */
39
40 #ifndef _CPP_FSTREAM
41 #define _CPP_FSTREAM    1
42
43 #pragma GCC system_header
44
45 #include <istream>
46 #include <ostream>
47 #include <locale>       // For codecvt
48 #include <bits/basic_file.h>
49 #include <bits/gthr.h>
50
51 namespace std
52 {
53   // [27.8.1.1] template class basic_filebuf
54   /**
55    *  @brief  The actual work of input and output (for files).
56    *
57    *  This class associates both its input and output sequence with an
58    *  external disk file, and maintains a joint file position for both
59    *  sequences.  Many of its sematics are described in terms of similar
60    *  behavior in the Standard C Library's @c FILE streams.
61   */
62   template<typename _CharT, typename _Traits>
63     class basic_filebuf : public basic_streambuf<_CharT, _Traits>
64     {
65     public:
66       // Types:
67       typedef _CharT                                    char_type;
68       typedef _Traits                                   traits_type;
69       typedef typename traits_type::int_type            int_type;
70       typedef typename traits_type::pos_type            pos_type;
71       typedef typename traits_type::off_type            off_type;
72
73       //@{
74       /**
75        *  @if maint
76        *  @doctodo
77        *  @endif
78       */
79       typedef basic_streambuf<char_type, traits_type>   __streambuf_type;
80       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
81       typedef __basic_file<char>                        __file_type;
82       typedef typename traits_type::state_type          __state_type;
83       typedef codecvt<char_type, char, __state_type>    __codecvt_type;
84       typedef typename __codecvt_type::result           __res_type;
85       typedef ctype<char_type>                          __ctype_type;
86       //@}
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       /**
94        *  @if maint
95        *  @doctodo
96        *  @endif
97       */
98       __c_lock                  _M_lock;
99
100       // External buffer.
101       /**
102        *  @if maint
103        *  @doctodo
104        *  @endif
105       */
106       __file_type               _M_file;
107
108       // Current and beginning state type for codecvt.
109       /**
110        *  @if maint
111        *  @doctodo
112        *  @endif
113       */
114       __state_type              _M_state_cur;
115       __state_type              _M_state_beg;
116
117       // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.
118       /**
119        *  @if maint
120        *  @doctodo
121        *  @endif
122       */
123       bool                      _M_buf_allocated;
124       
125       // XXX Needed?
126       bool                      _M_last_overflowed;
127
128       // The position in the buffer corresponding to the external file
129       // pointer.
130       /**
131        *  @if maint
132        *  @doctodo
133        *  @endif
134       */
135       char_type*                _M_filepos;
136
137     public:
138       // Constructors/destructor:
139       /**
140        *  @brief  Does not open any files.
141        *
142        *  The default constructor initializes the parent class using its
143        *  own default ctor.
144       */
145       basic_filebuf();
146
147       /**
148        *  @brief  The destructor closes the file first.
149       */
150       virtual
151       ~basic_filebuf()
152       {
153         this->close();
154         _M_last_overflowed = false;
155       }
156
157       // Members:
158       /**
159        *  @brief  Returns true if the external file is open.
160       */
161       bool
162       is_open() const { return _M_file.is_open(); }
163
164       /**
165        *  @brief  Opens an external file.
166        *  @param  s  The name of the file.
167        *  @param  mode  The open mode flags.
168        *  @return  @c this on success, NULL on failure
169        *
170        *  If a file is already open, this function immediately fails.
171        *  Otherwise it tries to open the file named @a s using the flags
172        *  given in @a mode.
173        *
174        *  [Table 92 gives the relation between openmode combinations and the
175        *  equivalent fopen() flags, but the table has not been copied yet.]
176       */
177       __filebuf_type*
178       open(const char* __s, ios_base::openmode __mode);
179
180       /**
181        *  @brief  Closes the currently associated file.
182        *  @return  @c this on success, NULL on failure
183        *
184        *  If no file is currently open, this function immediately fails.
185        *
186        *  If a "put buffer area" exists, @c overflow(eof) is called to flush
187        *  all the characters.  The file is then closed.
188        *
189        *  If any operations fail, this function also fails.
190       */
191       __filebuf_type*
192       close();
193
194     protected:
195       /**
196        *  @if maint
197        *  @doctodo
198        *  @endif
199       */
200       void
201       _M_allocate_internal_buffer();
202
203       /**
204        *  @if maint
205        *  @doctodo
206        *  @endif
207       */
208       void
209       _M_destroy_internal_buffer();
210
211       // [27.8.1.4] overridden virtual functions
212       // [documentation is inherited]
213       virtual streamsize
214       showmanyc();
215
216       // Stroustrup, 1998, p. 628
217       // underflow() and uflow() functions are called to get the next
218       // charater from the real input source when the buffer is empty.
219       // Buffered input uses underflow()
220
221       // The only difference between underflow() and uflow() is that the
222       // latter bumps _M_in_cur after the read.  In the sync_with_stdio
223       // case, this is important, as we need to unget the read character in
224       // the underflow() case in order to maintain synchronization.  So
225       // instead of calling underflow() from uflow(), we create a common
226       // subroutine to do the real work.
227       /**
228        *  @if maint
229        *  @doctodo
230        *  @endif
231       */
232       int_type
233       _M_underflow_common(bool __bump);
234
235       // [documentation is inherited]
236       virtual int_type
237       underflow();
238
239       // [documentation is inherited]
240       virtual int_type
241       uflow();
242
243       // [documentation is inherited]
244       virtual int_type
245       pbackfail(int_type __c = _Traits::eof());
246
247       // NB: For what the standard expects of the overflow function,
248       // see _M_really_overflow(), below. Because basic_streambuf's
249       // sputc/sputn call overflow directly, and the complications of
250       // this implementation's setting of the initial pointers all
251       // equal to _M_buf when initializing, it seems essential to have
252       // this in actuality be a helper function that checks for the
253       // eccentricities of this implementation, and then call
254       // overflow() if indeed the buffer is full.
255
256       // [documentation is inherited]
257       virtual int_type
258       overflow(int_type __c = _Traits::eof());
259
260       // Stroustrup, 1998, p 648
261       // The overflow() function is called to transfer characters to the
262       // real output destination when the buffer is full. A call to
263       // overflow(c) outputs the contents of the buffer plus the
264       // character c.
265       // 27.5.2.4.5
266       // Consume some sequence of the characters in the pending sequence.
267       /**
268        *  @if maint
269        *  @doctodo
270        *  @endif
271       */
272       int_type
273       _M_really_overflow(int_type __c = _Traits::eof());
274
275       // Convert internal byte sequence to external, char-based
276       // sequence via codecvt.
277       /**
278        *  @if maint
279        *  @doctodo
280        *  @endif
281       */
282       void
283       _M_convert_to_external(char_type*, streamsize, streamsize&, streamsize&);
284
285       /**
286        *  @brief  Manipulates the buffer.
287        *  @param  s  Pointer to a buffer area.
288        *  @param  n  Size of @a s.
289        *  @return  @c this
290        *
291        *  If no file has been opened, and both @a s and @a n are zero, then
292        *  the stream becomes unbuffered.  Otherwise, @c s is used as a
293        *  buffer; see
294        *  http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2
295        *  for more.
296       */
297       virtual __streambuf_type*
298       setbuf(char_type* __s, streamsize __n);
299
300       // [documentation is inherited]
301       virtual pos_type
302       seekoff(off_type __off, ios_base::seekdir __way,
303               ios_base::openmode __mode = ios_base::in | ios_base::out);
304
305       // [documentation is inherited]
306       virtual pos_type
307       seekpos(pos_type __pos,
308               ios_base::openmode __mode = ios_base::in | ios_base::out);
309
310       // [documentation is inherited]
311       virtual int
312       sync()
313       {
314         int __ret = 0;
315         bool __testput = this->_M_out_cur
316           && this->_M_out_beg < this->_M_out_lim;
317         // Sync with stdio.
318         bool __sync = this->_M_buf_size <= 1;
319
320         // Make sure that the internal buffer resyncs its idea of
321         // the file position with the external file.
322         if (__testput)
323           {
324             // Need to restore current position after the write.
325             off_type __off = this->_M_out_cur - this->_M_out_lim;
326
327             // _M_file.sync() will be called within
328             if (traits_type::eq_int_type(_M_really_overflow(),
329                                          traits_type::eof()))
330               __ret = -1;
331             else if (__off)
332               _M_file.seekoff(__off, ios_base::cur, __sync);
333           }
334         else
335           _M_file.sync();
336
337         _M_last_overflowed = false;
338         return __ret;
339       }
340
341       // [documentation is inherited]
342       virtual void
343       imbue(const locale& __loc);
344
345       // [documentation is inherited]
346       virtual streamsize
347       xsgetn(char_type* __s, streamsize __n)
348       {
349         streamsize __ret = 0;
350         // Clear out pback buffer before going on to the real deal...
351         if (this->_M_pback_init)
352           {
353             while (__ret < __n && this->_M_in_cur < this->_M_in_end)
354               {
355                 *__s = *this->_M_in_cur;
356                 ++__ret;
357                 ++__s;
358                 ++this->_M_in_cur;
359               }
360             _M_pback_destroy();
361           }
362         if (__ret < __n)
363           __ret += __streambuf_type::xsgetn(__s, __n - __ret);
364         return __ret;
365       }
366
367       // [documentation is inherited]
368       virtual streamsize
369       xsputn(const char_type* __s, streamsize __n)
370       {
371         _M_pback_destroy();
372         return __streambuf_type::xsputn(__s, __n);
373       }
374
375       /**
376        *  @if maint
377        *  @doctodo
378        *  @endif
379       */
380       void
381       _M_output_unshift();
382
383       // These three functions are used to clarify internal buffer
384       // maintenance. After an overflow, or after a seekoff call that
385       // started at beg or end, or possibly when the stream becomes
386       // unbuffered, and a myrid other obscure corner cases, the
387       // internal buffer does not truly reflect the contents of the
388       // external buffer. At this point, for whatever reason, it is in
389       // an indeterminate state.
390       /**
391        *  @if maint
392        *  @doctodo
393        *  @endif
394       */
395       void
396       _M_set_indeterminate(void)
397       { _M_set_determinate(off_type(0)); }
398
399       /**
400        *  @if maint
401        *  @doctodo
402        *  @endif
403       */
404       void
405       _M_set_determinate(off_type __off)
406       {
407         bool __testin = this->_M_mode & ios_base::in;
408         bool __testout = this->_M_mode & ios_base::out;
409         if (__testin)
410           this->setg(this->_M_buf, this->_M_buf, this->_M_buf + __off);
411         if (__testout)
412           {
413             this->setp(this->_M_buf, this->_M_buf + this->_M_buf_size);
414             this->_M_out_lim = this->_M_buf + __off;
415           }
416         _M_filepos = this->_M_buf + __off;
417       }
418
419       /**
420        *  @if maint
421        *  @doctodo
422        *  @endif
423       */
424       bool
425       _M_is_indeterminate(void)
426       { 
427         bool __testin = this->_M_mode & ios_base::in;
428         bool __testout = this->_M_mode & ios_base::out;
429         bool __ret = false;
430         // Don't return true if unbuffered.
431         if (this->_M_buf)
432           {
433             if (__testin)
434               __ret = this->_M_in_beg == this->_M_in_cur
435                 && this->_M_in_cur == this->_M_in_end;
436             if (__testout)
437               __ret = this->_M_out_beg == this->_M_out_cur
438                 && this->_M_out_cur == this->_M_out_lim;
439           }
440         return __ret;
441       }
442     };
443
444   // Explicit specialization declarations, defined in src/fstream.cc.
445   template<> 
446     basic_filebuf<char>::int_type 
447     basic_filebuf<char>::_M_underflow_common(bool __bump);
448
449   template<>
450     basic_filebuf<char>::int_type
451     basic_filebuf<char>::underflow(); 
452
453   template<>
454     basic_filebuf<char>::int_type
455     basic_filebuf<char>::uflow(); 
456
457  #ifdef _GLIBCPP_USE_WCHAR_T
458   template<> 
459     basic_filebuf<wchar_t>::int_type 
460     basic_filebuf<wchar_t>::_M_underflow_common(bool __bump);
461
462   template<>
463     basic_filebuf<wchar_t>::int_type
464     basic_filebuf<wchar_t>::underflow(); 
465
466   template<>
467     basic_filebuf<wchar_t>::int_type
468     basic_filebuf<wchar_t>::uflow(); 
469  #endif
470
471   // Generic definitions do nothing.
472   template <typename _CharT, typename _Traits>
473     typename basic_filebuf<_CharT, _Traits>::int_type
474     basic_filebuf<_CharT, _Traits>::underflow() 
475     { return int_type(); }
476
477   template <typename _CharT, typename _Traits>
478     typename basic_filebuf<_CharT, _Traits>::int_type
479     basic_filebuf<_CharT, _Traits>::uflow() 
480     { return int_type(); }
481
482   // [27.8.1.5] Template class basic_ifstream
483   /**
484    *  @brief  Controlling input for files.
485    *
486    *  This class supports reading from named files, using the inherited
487    *  functions from std::basic_istream.  To control the associated
488    *  sequence, an instance of std::basic_filebuf is used, which this page
489    *  refers to as @c sb.
490   */
491   template<typename _CharT, typename _Traits>
492     class basic_ifstream : public basic_istream<_CharT, _Traits>
493     {
494     public:
495       // Types:
496       typedef _CharT                                    char_type;
497       typedef _Traits                                   traits_type;
498       typedef typename traits_type::int_type            int_type;
499       typedef typename traits_type::pos_type            pos_type;
500       typedef typename traits_type::off_type            off_type;
501
502       // Non-standard types:
503       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
504       typedef basic_istream<char_type, traits_type>     __istream_type;
505
506     private:
507       /**
508        *  @if maint
509        *  @doctodo
510        *  @endif
511       */
512       __filebuf_type    _M_filebuf;
513
514     public:
515       // Constructors/Destructors:
516       /**
517        *  @brief  Default constructor.
518        *
519        *  Initializes @c sb using its default constructor, and passes
520        *  @c &sb to the base class initializer.  Does not open any files
521        *  (you haven't given it a filename to open).
522       */
523       basic_ifstream() : __istream_type(), _M_filebuf()
524       { this->init(&_M_filebuf); }
525
526       /**
527        *  @brief  Create an input file stream.
528        *  @param  s  Null terminated string specifying the filename.
529        *  @param  mode  Open file in specified mode (see std::ios_base).
530        *
531        *  @c ios_base::in is automatically included in @a mode.
532        *
533        *  Tip:  When using std::string to hold the filename, you must use
534        *  .c_str() before passing it to this constructor.
535       */
536       explicit
537       basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
538       : __istream_type(), _M_filebuf()
539       {
540         this->init(&_M_filebuf);
541         this->open(__s, __mode);
542       }
543
544       /**
545        *  @brief  The destructor does nothing.
546        *
547        *  The file is closed by the filebuf object, not the formatting
548        *  stream.
549       */
550       ~basic_ifstream()
551       { }
552
553       // Members:
554       /**
555        *  @brief  Accessing the underlying buffer.
556        *  @return  The current basic_filebuf buffer.
557        *
558        *  This hides both signatures of std::basic_ios::rdbuf().
559       */
560       __filebuf_type*
561       rdbuf() const
562       { return const_cast<__filebuf_type*>(&_M_filebuf); }
563
564       /**
565        *  @brief  Wrapper to test for an open file.
566        *  @return  @c rdbuf()->is_open()
567       */
568       bool
569       is_open() { return _M_filebuf.is_open(); }
570
571       /**
572        *  @brief  Opens an external file.
573        *  @param  s  The name of the file.
574        *  @param  mode  The open mode flags.
575        *
576        *  Calls @c std::basic_filebuf::open(s,mode|in).  If that function
577        *  fails, @c failbit is set in the stream's error state.
578        *
579        *  Tip:  When using std::string to hold the filename, you must use
580        *  .c_str() before passing it to this constructor.
581       */
582       void
583       open(const char* __s, ios_base::openmode __mode = ios_base::in)
584       {
585         if (!_M_filebuf.open(__s, __mode | ios_base::in))
586           this->setstate(ios_base::failbit);
587       }
588
589       /**
590        *  @brief  Close the file.
591        *
592        *  Calls @c std::basic_filebuf::close().  If that function
593        *  fails, @c failbit is set in the stream's error state.
594       */
595       void
596       close()
597       {
598         if (!_M_filebuf.close())
599           this->setstate(ios_base::failbit);
600       }
601     };
602
603
604   // [27.8.1.8] Template class basic_ofstream
605   /**
606    *  @brief  Controlling output for files.
607    *
608    *  This class supports reading from named files, using the inherited
609    *  functions from std::basic_ostream.  To control the associated
610    *  sequence, an instance of std::basic_filebuf is used, which this page
611    *  refers to as @c sb.
612   */
613   template<typename _CharT, typename _Traits>
614     class basic_ofstream : public basic_ostream<_CharT,_Traits>
615     {
616     public:
617       // Types:
618       typedef _CharT                                    char_type;
619       typedef _Traits                                   traits_type;
620       typedef typename traits_type::int_type            int_type;
621       typedef typename traits_type::pos_type            pos_type;
622       typedef typename traits_type::off_type            off_type;
623
624       // Non-standard types:
625       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
626       typedef basic_ostream<char_type, traits_type>     __ostream_type;
627
628     private:
629       /**
630        *  @if maint
631        *  @doctodo
632        *  @endif
633       */
634       __filebuf_type    _M_filebuf;
635
636     public:
637       // Constructors:
638       /**
639        *  @brief  Default constructor.
640        *
641        *  Initializes @c sb using its default constructor, and passes
642        *  @c &sb to the base class initializer.  Does not open any files
643        *  (you haven't given it a filename to open).
644       */
645       basic_ofstream(): __ostream_type(), _M_filebuf()
646       { this->init(&_M_filebuf); }
647
648       /**
649        *  @brief  Create an output file stream.
650        *  @param  s  Null terminated string specifying the filename.
651        *  @param  mode  Open file in specified mode (see std::ios_base).
652        *
653        *  @c ios_base::out|ios_base::trunc is automatically included in
654        *  @a mode.
655        *
656        *  Tip:  When using std::string to hold the filename, you must use
657        *  .c_str() before passing it to this constructor.
658       */
659       explicit
660       basic_ofstream(const char* __s,
661                      ios_base::openmode __mode = ios_base::out|ios_base::trunc)
662       : __ostream_type(), _M_filebuf()
663       {
664         this->init(&_M_filebuf);
665         this->open(__s, __mode);
666       }
667
668       /**
669        *  @brief  The destructor does nothing.
670        *
671        *  The file is closed by the filebuf object, not the formatting
672        *  stream.
673       */
674       ~basic_ofstream()
675       { }
676
677       // Members:
678       /**
679        *  @brief  Accessing the underlying buffer.
680        *  @return  The current basic_filebuf buffer.
681        *
682        *  This hides both signatures of std::basic_ios::rdbuf().
683       */
684       __filebuf_type*
685       rdbuf() const
686       { return const_cast<__filebuf_type*>(&_M_filebuf); }
687
688       /**
689        *  @brief  Wrapper to test for an open file.
690        *  @return  @c rdbuf()->is_open()
691       */
692       bool
693       is_open() { return _M_filebuf.is_open(); }
694
695       /**
696        *  @brief  Opens an external file.
697        *  @param  s  The name of the file.
698        *  @param  mode  The open mode flags.
699        *
700        *  Calls @c std::basic_filebuf::open(s,mode|out|trunc).  If that
701        *  function fails, @c failbit is set in the stream's error state.
702        *
703        *  Tip:  When using std::string to hold the filename, you must use
704        *  .c_str() before passing it to this constructor.
705       */
706       void
707       open(const char* __s,
708            ios_base::openmode __mode = ios_base::out | ios_base::trunc)
709       {
710         if (!_M_filebuf.open(__s, __mode | ios_base::out))
711           this->setstate(ios_base::failbit);
712       }
713
714       /**
715        *  @brief  Close the file.
716        *
717        *  Calls @c std::basic_filebuf::close().  If that function
718        *  fails, @c failbit is set in the stream's error state.
719       */
720       void
721       close()
722       {
723         if (!_M_filebuf.close())
724           this->setstate(ios_base::failbit);
725       }
726     };
727
728
729   // [27.8.1.11] Template class basic_fstream
730   /**
731    *  @brief  Controlling intput and output for files.
732    *
733    *  This class supports reading from and writing to named files, using
734    *  the inherited functions from std::basic_iostream.  To control the
735    *  associated sequence, an instance of std::basic_filebuf is used, which
736    *  this page refers to as @c sb.
737   */
738   template<typename _CharT, typename _Traits>
739     class basic_fstream : public basic_iostream<_CharT, _Traits>
740     {
741     public:
742       // Types:
743       typedef _CharT                                    char_type;
744       typedef _Traits                                   traits_type;
745       typedef typename traits_type::int_type            int_type;
746       typedef typename traits_type::pos_type            pos_type;
747       typedef typename traits_type::off_type            off_type;
748
749       // Non-standard types:
750       typedef basic_filebuf<char_type, traits_type>     __filebuf_type;
751       typedef basic_ios<char_type, traits_type>         __ios_type;
752       typedef basic_iostream<char_type, traits_type>    __iostream_type;
753
754     private:
755       /**
756        *  @if maint
757        *  @doctodo
758        *  @endif
759       */
760       __filebuf_type    _M_filebuf;
761
762     public:
763       // Constructors/destructor:
764       /**
765        *  @brief  Default constructor.
766        *
767        *  Initializes @c sb using its default constructor, and passes
768        *  @c &sb to the base class initializer.  Does not open any files
769        *  (you haven't given it a filename to open).
770       */
771       basic_fstream()
772       : __iostream_type(), _M_filebuf()
773       { this->init(&_M_filebuf); }
774
775       /**
776        *  @brief  Create an input/output file stream.
777        *  @param  s  Null terminated string specifying the filename.
778        *  @param  mode  Open file in specified mode (see std::ios_base).
779        *
780        *  Tip:  When using std::string to hold the filename, you must use
781        *  .c_str() before passing it to this constructor.
782       */
783       explicit
784       basic_fstream(const char* __s,
785                     ios_base::openmode __mode = ios_base::in | ios_base::out)
786       : __iostream_type(NULL), _M_filebuf()
787       {
788         this->init(&_M_filebuf);
789         this->open(__s, __mode);
790       }
791
792       /**
793        *  @brief  The destructor does nothing.
794        *
795        *  The file is closed by the filebuf object, not the formatting
796        *  stream.
797       */
798       ~basic_fstream()
799       { }
800
801       // Members:
802       /**
803        *  @brief  Accessing the underlying buffer.
804        *  @return  The current basic_filebuf buffer.
805        *
806        *  This hides both signatures of std::basic_ios::rdbuf().
807       */
808       __filebuf_type*
809       rdbuf() const
810       { return const_cast<__filebuf_type*>(&_M_filebuf); }
811
812       /**
813        *  @brief  Wrapper to test for an open file.
814        *  @return  @c rdbuf()->is_open()
815       */
816       bool
817       is_open() { return _M_filebuf.is_open(); }
818
819       /**
820        *  @brief  Opens an external file.
821        *  @param  s  The name of the file.
822        *  @param  mode  The open mode flags.
823        *
824        *  Calls @c std::basic_filebuf::open(s,mode).  If that
825        *  function fails, @c failbit is set in the stream's error state.
826        *
827        *  Tip:  When using std::string to hold the filename, you must use
828        *  .c_str() before passing it to this constructor.
829       */
830       void
831       open(const char* __s,
832            ios_base::openmode __mode = ios_base::in | ios_base::out)
833       {
834         if (!_M_filebuf.open(__s, __mode))
835           this->setstate(ios_base::failbit);
836       }
837
838       /**
839        *  @brief  Close the file.
840        *
841        *  Calls @c std::basic_filebuf::close().  If that function
842        *  fails, @c failbit is set in the stream's error state.
843       */
844       void
845       close()
846       {
847         if (!_M_filebuf.close())
848           this->setstate(ios_base::failbit);
849       }
850     };
851 } // namespace std
852
853 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
854 # define export
855 #endif
856 #ifdef  _GLIBCPP_FULLY_COMPLIANT_HEADERS
857 # include <bits/fstream.tcc>
858 #endif
859
860 #endif