1 | // File based streams -*- C++ -*- |
2 | |
3 | // Copyright (C) 1997-2022 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 | basic_ifstream(const _Path& __s, |
585 | ios_base::openmode __mode = ios_base::in) |
586 | : basic_ifstream(__s.c_str(), __mode) |
587 | { } |
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 | open(const _Path& __s, ios_base::openmode __mode = ios_base::in) |
724 | { 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 | basic_ofstream(const _Path& __s, |
848 | ios_base::openmode __mode = ios_base::out) |
849 | : basic_ofstream(__s.c_str(), __mode) |
850 | { } |
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 | open(const _Path& __s, ios_base::openmode __mode = ios_base::out) |
987 | { 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 */ |
1301 | |