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