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