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