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