libstdc++
fstream
Go to the documentation of this file.
1 // File based streams -*- C++ -*-
2 
3 // Copyright (C) 1997-2022 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 
52 namespace 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 */