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