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