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 */ |
1363 | |