]>
Commit | Line | Data |
---|---|---|
54c1bf78 | 1 | // File based streams -*- C++ -*- |
de96ac46 | 2 | |
85ec4feb | 3 | // Copyright (C) 1997-2018 Free Software Foundation, Inc. |
de96ac46 BK |
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 | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
de96ac46 BK |
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 | ||
748086b7 JJ |
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/>. | |
de96ac46 | 24 | |
f910786b | 25 | /** @file include/fstream |
0aa06b18 | 26 | * This is a Standard C++ Library header. |
2f9d51b8 PE |
27 | */ |
28 | ||
143c27b0 BK |
29 | // |
30 | // ISO C++ 14882: 27.8 File-based streams | |
31 | // | |
32 | ||
1143680e SE |
33 | #ifndef _GLIBCXX_FSTREAM |
34 | #define _GLIBCXX_FSTREAM 1 | |
54c1bf78 BK |
35 | |
36 | #pragma GCC system_header | |
37 | ||
38 | #include <istream> | |
39 | #include <ostream> | |
84b31797 | 40 | #include <bits/codecvt.h> |
13c4b877 | 41 | #include <cstdio> // For BUFSIZ |
bd91a8c4 | 42 | #include <bits/basic_file.h> // For __basic_file, __c_lock |
734f5023 | 43 | #if __cplusplus >= 201103L |
13c4b877 PC |
44 | #include <string> // For std::string overloads. |
45 | #endif | |
54c1bf78 | 46 | |
12ffa228 BK |
47 | namespace std _GLIBCXX_VISIBILITY(default) |
48 | { | |
49 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
3cbc7af0 | 50 | |
96e0367e JW |
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 | ||
840ceb34 PE |
59 | // [27.8.1.1] template class basic_filebuf |
60 | /** | |
61 | * @brief The actual work of input and output (for files). | |
5b9daa7e | 62 | * @ingroup io |
840ceb34 | 63 | * |
d632488a BK |
64 | * @tparam _CharT Type of character stream. |
65 | * @tparam _Traits Traits for character type, defaults to | |
66 | * char_traits<_CharT>. | |
67 | * | |
840ceb34 PE |
68 | * This class associates both its input and output sequence with an |
69 | * external disk file, and maintains a joint file position for both | |
28dac70a | 70 | * sequences. Many of its semantics are described in terms of similar |
840ceb34 | 71 | * behavior in the Standard C Library's @c FILE streams. |
d632488a BK |
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. | |
13c4b877 | 78 | */ |
54c1bf78 BK |
79 | template<typename _CharT, typename _Traits> |
80 | class basic_filebuf : public basic_streambuf<_CharT, _Traits> | |
81 | { | |
2735097a JW |
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 | |
54c1bf78 BK |
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; | |
fd58f127 | 103 | |
54c1bf78 BK |
104 | typedef basic_streambuf<char_type, traits_type> __streambuf_type; |
105 | typedef basic_filebuf<char_type, traits_type> __filebuf_type; | |
07814743 | 106 | typedef __basic_file<char> __file_type; |
54c1bf78 BK |
107 | typedef typename traits_type::state_type __state_type; |
108 | typedef codecvt<char_type, char, __state_type> __codecvt_type; | |
54c1bf78 BK |
109 | |
110 | friend class ios_base; // For sync_with_stdio. | |
111 | ||
6f48900c | 112 | protected: |
54c1bf78 | 113 | // Data Members: |
d3a193e3 BK |
114 | // MT lock inherited from libio or other low-level io library. |
115 | __c_lock _M_lock; | |
116 | ||
54c1bf78 | 117 | // External buffer. |
d3a193e3 | 118 | __file_type _M_file; |
54c1bf78 | 119 | |
4312e020 | 120 | /// Place to stash in || out || in | out settings for current filebuf. |
cd16e04b PC |
121 | ios_base::openmode _M_mode; |
122 | ||
5e93f39f | 123 | // Beginning state type for codecvt. |
fd58f127 | 124 | __state_type _M_state_beg; |
54c1bf78 | 125 | |
5e93f39f PR |
126 | // During output, the state that corresponds to pptr(), |
127 | // during input, the state that corresponds to egptr() and | |
128 | // _M_ext_next. | |
5e93f39f PR |
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. | |
5e93f39f PR |
133 | __state_type _M_state_last; |
134 | ||
4312e020 | 135 | /// Pointer to the beginning of internal buffer. |
9b817548 | 136 | char_type* _M_buf; |
479a1811 | 137 | |
f10eea7b | 138 | /** |
f10eea7b PC |
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. | |
13c4b877 | 142 | */ |
f10eea7b PC |
143 | size_t _M_buf_size; |
144 | ||
5cdd50a5 | 145 | // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. |
54c1bf78 | 146 | bool _M_buf_allocated; |
71b46021 | 147 | |
a8cad3e1 | 148 | /** |
2a60a9f6 BK |
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; | |
a8cad3e1 PC |
152 | * |
153 | * NB: _M_reading == true && _M_writing == true is unused. | |
13c4b877 | 154 | */ |
71b46021 PC |
155 | bool _M_reading; |
156 | bool _M_writing; | |
157 | ||
45aca21f PC |
158 | //@{ |
159 | /** | |
45aca21f PC |
160 | * Necessary bits for putback buffer management. |
161 | * | |
162 | * @note pbacks of over one character are not currently supported. | |
13c4b877 PC |
163 | */ |
164 | char_type _M_pback; | |
45aca21f PC |
165 | char_type* _M_pback_cur_save; |
166 | char_type* _M_pback_end_save; | |
13c4b877 | 167 | bool _M_pback_init; |
45aca21f PC |
168 | //@} |
169 | ||
0cd1de6f BK |
170 | // Cached codecvt facet. |
171 | const __codecvt_type* _M_codecvt; | |
172 | ||
f1813b69 | 173 | /** |
f1813b69 PR |
174 | * Buffer for external characters. Used for input when |
175 | * codecvt::always_noconv() == false. When valid, this corresponds | |
176 | * to eback(). | |
13c4b877 | 177 | */ |
f1813b69 PR |
178 | char* _M_ext_buf; |
179 | ||
180 | /** | |
f1813b69 | 181 | * Size of buffer held by _M_ext_buf. |
13c4b877 | 182 | */ |
f1813b69 PR |
183 | streamsize _M_ext_buf_size; |
184 | ||
185 | /** | |
f1813b69 PR |
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(). | |
13c4b877 | 189 | */ |
f1813b69 PR |
190 | const char* _M_ext_next; |
191 | char* _M_ext_end; | |
192 | ||
6623b2f2 | 193 | /** |
6623b2f2 PC |
194 | * Initializes pback buffers, and moves normal buffers to safety. |
195 | * Assumptions: | |
196 | * _M_in_cur has already been moved back | |
13c4b877 | 197 | */ |
45aca21f | 198 | void |
aa438e8f | 199 | _M_create_pback() |
45aca21f PC |
200 | { |
201 | if (!_M_pback_init) | |
202 | { | |
71b46021 PC |
203 | _M_pback_cur_save = this->gptr(); |
204 | _M_pback_end_save = this->egptr(); | |
002bd606 | 205 | this->setg(&_M_pback, &_M_pback, &_M_pback + 1); |
45aca21f PC |
206 | _M_pback_init = true; |
207 | } | |
208 | } | |
209 | ||
6623b2f2 | 210 | /** |
6623b2f2 PC |
211 | * Deactivates pback buffer contents, and restores normal buffer. |
212 | * Assumptions: | |
213 | * The pback buffer has only moved forward. | |
13c4b877 | 214 | */ |
45aca21f | 215 | void |
aa438e8f | 216 | _M_destroy_pback() throw() |
45aca21f PC |
217 | { |
218 | if (_M_pback_init) | |
219 | { | |
220 | // Length _M_in_cur moved in the pback buffer. | |
71b46021 | 221 | _M_pback_cur_save += this->gptr() != this->eback(); |
a8e3a00f | 222 | this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save); |
45aca21f PC |
223 | _M_pback_init = false; |
224 | } | |
225 | } | |
226 | ||
54c1bf78 BK |
227 | public: |
228 | // Constructors/destructor: | |
840ceb34 PE |
229 | /** |
230 | * @brief Does not open any files. | |
231 | * | |
232 | * The default constructor initializes the parent class using its | |
233 | * own default ctor. | |
13c4b877 | 234 | */ |
54c1bf78 BK |
235 | basic_filebuf(); |
236 | ||
9b817548 JW |
237 | #if __cplusplus >= 201103L |
238 | basic_filebuf(const basic_filebuf&) = delete; | |
239 | basic_filebuf(basic_filebuf&&); | |
240 | #endif | |
241 | ||
840ceb34 PE |
242 | /** |
243 | * @brief The destructor closes the file first. | |
13c4b877 | 244 | */ |
fd58f127 PE |
245 | virtual |
246 | ~basic_filebuf() | |
e77497ab JW |
247 | { |
248 | __try | |
249 | { this->close(); } | |
250 | __catch(...) | |
251 | { } | |
252 | } | |
54c1bf78 | 253 | |
9b817548 JW |
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 | ||
54c1bf78 | 260 | // Members: |
840ceb34 PE |
261 | /** |
262 | * @brief Returns true if the external file is open. | |
13c4b877 | 263 | */ |
fd58f127 | 264 | bool |
85a5f64e PC |
265 | is_open() const throw() |
266 | { return _M_file.is_open(); } | |
fd58f127 | 267 | |
840ceb34 PE |
268 | /** |
269 | * @brief Opens an external file. | |
93c66bc6 BK |
270 | * @param __s The name of the file. |
271 | * @param __mode The open mode flags. | |
840ceb34 PE |
272 | * @return @c this on success, NULL on failure |
273 | * | |
274 | * If a file is already open, this function immediately fails. | |
93c66bc6 | 275 | * Otherwise it tries to open the file named @a __s using the flags |
d8dd52a9 | 276 | * given in @a __mode. |
840ceb34 | 277 | * |
9735f6ba | 278 | * Table 92, adapted here, gives the relation between openmode |
a566cb5e | 279 | * combinations and the equivalent @c fopen() flags. |
ec01f292 PC |
280 | * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app, |
281 | * and binary|in|app per DR 596) | |
a566cb5e | 282 | * <pre> |
9735f6ba FP |
283 | * +---------------------------------------------------------+ |
284 | * | ios_base Flag combination stdio equivalent | | |
285 | * |binary in out trunc app | | |
286 | * +---------------------------------------------------------+ | |
2a60a9f6 BK |
287 | * | + w | |
288 | * | + + a | | |
289 | * | + a | | |
290 | * | + + w | | |
291 | * | + r | | |
292 | * | + + r+ | | |
293 | * | + + + w+ | | |
294 | * | + + + a+ | | |
295 | * | + + a+ | | |
9735f6ba | 296 | * +---------------------------------------------------------+ |
2a60a9f6 BK |
297 | * | + + wb | |
298 | * | + + + ab | | |
299 | * | + + ab | | |
300 | * | + + + wb | | |
301 | * | + + rb | | |
302 | * | + + + r+b | | |
303 | * | + + + + w+b | | |
304 | * | + + + + a+b | | |
305 | * | + + + a+b | | |
9735f6ba | 306 | * +---------------------------------------------------------+ |
a566cb5e | 307 | * </pre> |
9735f6ba | 308 | */ |
fd58f127 | 309 | __filebuf_type* |
54c1bf78 | 310 | open(const char* __s, ios_base::openmode __mode); |
fd58f127 | 311 | |
b0292359 JW |
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 | ||
734f5023 | 323 | #if __cplusplus >= 201103L |
13c4b877 PC |
324 | /** |
325 | * @brief Opens an external file. | |
93c66bc6 BK |
326 | * @param __s The name of the file. |
327 | * @param __mode The open mode flags. | |
13c4b877 PC |
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); } | |
d49f254a JW |
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> | |
96e0367e | 342 | _If_fs_path<_Path, __filebuf_type*> |
d49f254a JW |
343 | open(const _Path& __s, ios_base::openmode __mode) |
344 | { return open(__s.c_str(), __mode); } | |
345 | #endif // C++17 | |
346 | #endif // C++11 | |
13c4b877 | 347 | |
840ceb34 PE |
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 | * | |
2a60a9f6 BK |
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. | |
840ceb34 PE |
357 | * |
358 | * If any operations fail, this function also fails. | |
13c4b877 | 359 | */ |
fd58f127 | 360 | __filebuf_type* |
d05f74f1 | 361 | close(); |
54c1bf78 BK |
362 | |
363 | protected: | |
fd58f127 | 364 | void |
54c1bf78 BK |
365 | _M_allocate_internal_buffer(); |
366 | ||
fd58f127 | 367 | void |
a1796d12 | 368 | _M_destroy_internal_buffer() throw(); |
54c1bf78 | 369 | |
840ceb34 | 370 | // [27.8.1.4] overridden virtual functions |
fd58f127 | 371 | virtual streamsize |
07814743 | 372 | showmanyc(); |
fd58f127 PE |
373 | |
374 | // Stroustrup, 1998, p. 628 | |
54c1bf78 | 375 | // underflow() and uflow() functions are called to get the next |
28dac70a | 376 | // character from the real input source when the buffer is empty. |
54c1bf78 | 377 | // Buffered input uses underflow() |
5066927d | 378 | |
fd58f127 | 379 | virtual int_type |
cd16e04b | 380 | underflow(); |
54c1bf78 | 381 | |
fd58f127 | 382 | virtual int_type |
54c1bf78 BK |
383 | pbackfail(int_type __c = _Traits::eof()); |
384 | ||
54c1bf78 BK |
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. | |
fd58f127 | 390 | // 27.5.2.4.5 |
54c1bf78 | 391 | // Consume some sequence of the characters in the pending sequence. |
002bd606 BK |
392 | virtual int_type |
393 | overflow(int_type __c = _Traits::eof()); | |
fd58f127 | 394 | |
07814743 BK |
395 | // Convert internal byte sequence to external, char-based |
396 | // sequence via codecvt. | |
6e81c6f4 BK |
397 | bool |
398 | _M_convert_to_external(char_type*, streamsize); | |
07814743 | 399 | |
840ceb34 PE |
400 | /** |
401 | * @brief Manipulates the buffer. | |
93c66bc6 BK |
402 | * @param __s Pointer to a buffer area. |
403 | * @param __n Size of @a __s. | |
840ceb34 PE |
404 | * @return @c this |
405 | * | |
93c66bc6 BK |
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 | |
840ceb34 | 408 | * buffer; see |
10d43d2f | 409 | * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering |
840ceb34 | 410 | * for more. |
13c4b877 | 411 | */ |
fd58f127 | 412 | virtual __streambuf_type* |
54c1bf78 | 413 | setbuf(char_type* __s, streamsize __n); |
fd58f127 PE |
414 | |
415 | virtual pos_type | |
54c1bf78 BK |
416 | seekoff(off_type __off, ios_base::seekdir __way, |
417 | ios_base::openmode __mode = ios_base::in | ios_base::out); | |
418 | ||
fd58f127 | 419 | virtual pos_type |
54c1bf78 BK |
420 | seekpos(pos_type __pos, |
421 | ios_base::openmode __mode = ios_base::in | ios_base::out); | |
422 | ||
3531cf5e | 423 | // Common code for seekoff, seekpos, and overflow |
1a139c59 | 424 | pos_type |
5e93f39f | 425 | _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); |
33ac58d5 | 426 | |
3531cf5e DK |
427 | int |
428 | _M_get_ext_pos(__state_type &__state); | |
1a139c59 | 429 | |
fd58f127 | 430 | virtual int |
5e93f39f | 431 | sync(); |
fd58f127 PE |
432 | |
433 | virtual void | |
54c1bf78 BK |
434 | imbue(const locale& __loc); |
435 | ||
fd58f127 | 436 | virtual streamsize |
c56e3d82 | 437 | xsgetn(char_type* __s, streamsize __n); |
fd58f127 PE |
438 | |
439 | virtual streamsize | |
bda243ec | 440 | xsputn(const char_type* __s, streamsize __n); |
fd58f127 | 441 | |
5e93f39f | 442 | // Flushes output buffer, then writes unshift sequence. |
5e93f39f PR |
443 | bool |
444 | _M_terminate_output(); | |
5066927d | 445 | |
6623b2f2 | 446 | /** |
6623b2f2 PC |
447 | * This function sets the pointers of the internal buffer, both get |
448 | * and put areas. Typically: | |
449 | * | |
2a60a9f6 BK |
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). | |
13c4b877 | 453 | * |
6623b2f2 PC |
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. | |
13c4b877 | 457 | */ |
98ce9d06 PC |
458 | void |
459 | _M_set_buffer(streamsize __off) | |
460 | { | |
a0d026d9 PC |
461 | const bool __testin = _M_mode & ios_base::in; |
462 | const bool __testout = (_M_mode & ios_base::out | |
03fd2f60 PC |
463 | || _M_mode & ios_base::app); |
464 | ||
71b46021 | 465 | if (__testin && __off > 0) |
a8e3a00f | 466 | this->setg(_M_buf, _M_buf, _M_buf + __off); |
71b46021 | 467 | else |
a8e3a00f | 468 | this->setg(_M_buf, _M_buf, _M_buf); |
71b46021 | 469 | |
a8e3a00f BK |
470 | if (__testout && __off == 0 && _M_buf_size > 1 ) |
471 | this->setp(_M_buf, _M_buf + _M_buf_size - 1); | |
71b46021 | 472 | else |
8fc81078 | 473 | this->setp(0, 0); |
98ce9d06 | 474 | } |
54c1bf78 BK |
475 | }; |
476 | ||
840ceb34 | 477 | // [27.8.1.5] Template class basic_ifstream |
fd58f127 | 478 | /** |
840ceb34 | 479 | * @brief Controlling input for files. |
5b9daa7e | 480 | * @ingroup io |
840ceb34 | 481 | * |
d632488a BK |
482 | * @tparam _CharT Type of character stream. |
483 | * @tparam _Traits Traits for character type, defaults to | |
484 | * char_traits<_CharT>. | |
485 | * | |
840ceb34 PE |
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. | |
13c4b877 | 490 | */ |
54c1bf78 BK |
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; | |
fd58f127 | 505 | |
54c1bf78 BK |
506 | private: |
507 | __filebuf_type _M_filebuf; | |
508 | ||
509 | public: | |
840ceb34 PE |
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). | |
13c4b877 | 517 | */ |
d29cc32f | 518 | basic_ifstream() : __istream_type(), _M_filebuf() |
54c1bf78 BK |
519 | { this->init(&_M_filebuf); } |
520 | ||
fd58f127 | 521 | /** |
840ceb34 | 522 | * @brief Create an input file stream. |
93c66bc6 BK |
523 | * @param __s Null terminated string specifying the filename. |
524 | * @param __mode Open file in specified mode (see std::ios_base). | |
fd58f127 | 525 | * |
93c66bc6 | 526 | * @c ios_base::in is automatically included in @a __mode. |
13c4b877 | 527 | */ |
fd58f127 | 528 | explicit |
54c1bf78 | 529 | basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) |
d29cc32f | 530 | : __istream_type(), _M_filebuf() |
fd58f127 PE |
531 | { |
532 | this->init(&_M_filebuf); | |
533 | this->open(__s, __mode); | |
54c1bf78 | 534 | } |
fd58f127 | 535 | |
b0292359 JW |
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 | ||
734f5023 | 553 | #if __cplusplus >= 201103L |
13c4b877 PC |
554 | /** |
555 | * @brief Create an input file stream. | |
93c66bc6 BK |
556 | * @param __s std::string specifying the filename. |
557 | * @param __mode Open file in specified mode (see std::ios_base). | |
13c4b877 | 558 | * |
93c66bc6 | 559 | * @c ios_base::in is automatically included in @a __mode. |
13c4b877 PC |
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 | } | |
9b817548 | 569 | |
d49f254a JW |
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 | */ | |
96e0367e | 578 | template<typename _Path, typename _Require = _If_fs_path<_Path>> |
d49f254a JW |
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 | ||
9b817548 JW |
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); } | |
d49f254a | 591 | #endif // C++11 |
13c4b877 | 592 | |
840ceb34 PE |
593 | /** |
594 | * @brief The destructor does nothing. | |
595 | * | |
596 | * The file is closed by the filebuf object, not the formatting | |
597 | * stream. | |
13c4b877 | 598 | */ |
54c1bf78 BK |
599 | ~basic_ifstream() |
600 | { } | |
601 | ||
9b817548 JW |
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 | ||
54c1bf78 | 624 | // Members: |
fd58f127 | 625 | /** |
840ceb34 PE |
626 | * @brief Accessing the underlying buffer. |
627 | * @return The current basic_filebuf buffer. | |
628 | * | |
629 | * This hides both signatures of std::basic_ios::rdbuf(). | |
13c4b877 | 630 | */ |
fd58f127 PE |
631 | __filebuf_type* |
632 | rdbuf() const | |
54c1bf78 BK |
633 | { return const_cast<__filebuf_type*>(&_M_filebuf); } |
634 | ||
840ceb34 PE |
635 | /** |
636 | * @brief Wrapper to test for an open file. | |
637 | * @return @c rdbuf()->is_open() | |
13c4b877 | 638 | */ |
fd58f127 | 639 | bool |
85a5f64e PC |
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(); } | |
54c1bf78 | 648 | |
840ceb34 PE |
649 | /** |
650 | * @brief Opens an external file. | |
93c66bc6 BK |
651 | * @param __s The name of the file. |
652 | * @param __mode The open mode flags. | |
840ceb34 | 653 | * |
93c66bc6 | 654 | * Calls @c std::basic_filebuf::open(s,__mode|in). If that function |
840ceb34 | 655 | * fails, @c failbit is set in the stream's error state. |
13c4b877 | 656 | */ |
fd58f127 | 657 | void |
54c1bf78 | 658 | open(const char* __s, ios_base::openmode __mode = ios_base::in) |
fd58f127 | 659 | { |
b988dfc5 | 660 | if (!_M_filebuf.open(__s, __mode | ios_base::in)) |
fd58f127 | 661 | this->setstate(ios_base::failbit); |
7a59efae PC |
662 | else |
663 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
664 | // 409. Closing an fstream should clear error state | |
665 | this->clear(); | |
54c1bf78 BK |
666 | } |
667 | ||
b0292359 JW |
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 | ||
734f5023 | 687 | #if __cplusplus >= 201103L |
13c4b877 PC |
688 | /** |
689 | * @brief Opens an external file. | |
93c66bc6 BK |
690 | * @param __s The name of the file. |
691 | * @param __mode The open mode flags. | |
13c4b877 | 692 | * |
93c66bc6 | 693 | * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function |
13c4b877 PC |
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 | } | |
d49f254a JW |
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> | |
96e0367e | 717 | _If_fs_path<_Path, void> |
d49f254a | 718 | open(const _Path& __s, ios_base::openmode __mode = ios_base::in) |
d49f254a JW |
719 | { open(__s.c_str(), __mode); } |
720 | #endif // C++17 | |
721 | #endif // C++11 | |
13c4b877 | 722 | |
840ceb34 PE |
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. | |
13c4b877 | 728 | */ |
fd58f127 | 729 | void |
07814743 | 730 | close() |
fd58f127 | 731 | { |
54c1bf78 | 732 | if (!_M_filebuf.close()) |
fd58f127 | 733 | this->setstate(ios_base::failbit); |
54c1bf78 BK |
734 | } |
735 | }; | |
736 | ||
fd58f127 | 737 | |
840ceb34 | 738 | // [27.8.1.8] Template class basic_ofstream |
fd58f127 | 739 | /** |
840ceb34 | 740 | * @brief Controlling output for files. |
5b9daa7e | 741 | * @ingroup io |
840ceb34 | 742 | * |
d632488a BK |
743 | * @tparam _CharT Type of character stream. |
744 | * @tparam _Traits Traits for character type, defaults to | |
745 | * char_traits<_CharT>. | |
746 | * | |
840ceb34 PE |
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. | |
13c4b877 | 751 | */ |
54c1bf78 BK |
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; | |
fd58f127 | 766 | |
54c1bf78 BK |
767 | private: |
768 | __filebuf_type _M_filebuf; | |
769 | ||
770 | public: | |
771 | // Constructors: | |
840ceb34 PE |
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). | |
13c4b877 | 778 | */ |
d29cc32f | 779 | basic_ofstream(): __ostream_type(), _M_filebuf() |
54c1bf78 | 780 | { this->init(&_M_filebuf); } |
fd58f127 PE |
781 | |
782 | /** | |
840ceb34 | 783 | * @brief Create an output file stream. |
93c66bc6 BK |
784 | * @param __s Null terminated string specifying the filename. |
785 | * @param __mode Open file in specified mode (see std::ios_base). | |
fd58f127 | 786 | * |
0a6e98b7 | 787 | * @c ios_base::out is automatically included in @a __mode. |
13c4b877 | 788 | */ |
fd58f127 PE |
789 | explicit |
790 | basic_ofstream(const char* __s, | |
0a6e98b7 | 791 | ios_base::openmode __mode = ios_base::out) |
d29cc32f | 792 | : __ostream_type(), _M_filebuf() |
fd58f127 PE |
793 | { |
794 | this->init(&_M_filebuf); | |
795 | this->open(__s, __mode); | |
54c1bf78 BK |
796 | } |
797 | ||
b0292359 JW |
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 | ||
734f5023 | 816 | #if __cplusplus >= 201103L |
13c4b877 PC |
817 | /** |
818 | * @brief Create an output file stream. | |
93c66bc6 BK |
819 | * @param __s std::string specifying the filename. |
820 | * @param __mode Open file in specified mode (see std::ios_base). | |
13c4b877 | 821 | * |
0a6e98b7 | 822 | * @c ios_base::out is automatically included in @a __mode. |
13c4b877 PC |
823 | */ |
824 | explicit | |
825 | basic_ofstream(const std::string& __s, | |
0a6e98b7 | 826 | ios_base::openmode __mode = ios_base::out) |
13c4b877 PC |
827 | : __ostream_type(), _M_filebuf() |
828 | { | |
829 | this->init(&_M_filebuf); | |
830 | this->open(__s, __mode); | |
831 | } | |
9b817548 | 832 | |
d49f254a JW |
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 | * | |
0a6e98b7 | 839 | * @c ios_base::out is automatically included in @a __mode. |
d49f254a | 840 | */ |
96e0367e | 841 | template<typename _Path, typename _Require = _If_fs_path<_Path>> |
0a6e98b7 JW |
842 | basic_ofstream(const _Path& __s, |
843 | ios_base::openmode __mode = ios_base::out) | |
d49f254a JW |
844 | : basic_ofstream(__s.c_str(), __mode) |
845 | { } | |
846 | #endif // C++17 | |
847 | ||
9b817548 JW |
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); } | |
13c4b877 PC |
854 | #endif |
855 | ||
840ceb34 PE |
856 | /** |
857 | * @brief The destructor does nothing. | |
858 | * | |
859 | * The file is closed by the filebuf object, not the formatting | |
860 | * stream. | |
13c4b877 | 861 | */ |
54c1bf78 BK |
862 | ~basic_ofstream() |
863 | { } | |
864 | ||
9b817548 JW |
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 | ||
54c1bf78 | 887 | // Members: |
fd58f127 | 888 | /** |
840ceb34 PE |
889 | * @brief Accessing the underlying buffer. |
890 | * @return The current basic_filebuf buffer. | |
891 | * | |
892 | * This hides both signatures of std::basic_ios::rdbuf(). | |
13c4b877 | 893 | */ |
fd58f127 | 894 | __filebuf_type* |
07814743 | 895 | rdbuf() const |
54c1bf78 | 896 | { return const_cast<__filebuf_type*>(&_M_filebuf); } |
fd58f127 PE |
897 | |
898 | /** | |
840ceb34 PE |
899 | * @brief Wrapper to test for an open file. |
900 | * @return @c rdbuf()->is_open() | |
13c4b877 | 901 | */ |
fd58f127 | 902 | bool |
85a5f64e PC |
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(); } | |
54c1bf78 | 911 | |
fd58f127 | 912 | /** |
840ceb34 | 913 | * @brief Opens an external file. |
93c66bc6 BK |
914 | * @param __s The name of the file. |
915 | * @param __mode The open mode flags. | |
840ceb34 | 916 | * |
0a6e98b7 | 917 | * Calls @c std::basic_filebuf::open(__s,__mode|out). If that |
840ceb34 | 918 | * function fails, @c failbit is set in the stream's error state. |
13c4b877 | 919 | */ |
fd58f127 | 920 | void |
0a6e98b7 | 921 | open(const char* __s, ios_base::openmode __mode = ios_base::out) |
fd58f127 | 922 | { |
54c1bf78 | 923 | if (!_M_filebuf.open(__s, __mode | ios_base::out)) |
fd58f127 | 924 | this->setstate(ios_base::failbit); |
7a59efae PC |
925 | else |
926 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
927 | // 409. Closing an fstream should clear error state | |
928 | this->clear(); | |
54c1bf78 BK |
929 | } |
930 | ||
b0292359 JW |
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 | ||
734f5023 | 950 | #if __cplusplus >= 201103L |
13c4b877 PC |
951 | /** |
952 | * @brief Opens an external file. | |
93c66bc6 BK |
953 | * @param __s The name of the file. |
954 | * @param __mode The open mode flags. | |
13c4b877 | 955 | * |
0a6e98b7 | 956 | * Calls @c std::basic_filebuf::open(s,mode|out). If that |
13c4b877 PC |
957 | * function fails, @c failbit is set in the stream's error state. |
958 | */ | |
959 | void | |
0a6e98b7 | 960 | open(const std::string& __s, ios_base::openmode __mode = ios_base::out) |
13c4b877 PC |
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 | } | |
d49f254a JW |
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> | |
96e0367e | 980 | _If_fs_path<_Path, void> |
d49f254a | 981 | open(const _Path& __s, ios_base::openmode __mode = ios_base::out) |
d49f254a JW |
982 | { open(__s.c_str(), __mode); } |
983 | #endif // C++17 | |
984 | #endif // C++11 | |
13c4b877 | 985 | |
840ceb34 PE |
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. | |
13c4b877 | 991 | */ |
fd58f127 | 992 | void |
07814743 | 993 | close() |
fd58f127 | 994 | { |
54c1bf78 | 995 | if (!_M_filebuf.close()) |
fd58f127 | 996 | this->setstate(ios_base::failbit); |
54c1bf78 BK |
997 | } |
998 | }; | |
999 | ||
1000 | ||
840ceb34 | 1001 | // [27.8.1.11] Template class basic_fstream |
fd58f127 | 1002 | /** |
28dac70a | 1003 | * @brief Controlling input and output for files. |
5b9daa7e | 1004 | * @ingroup io |
840ceb34 | 1005 | * |
d632488a BK |
1006 | * @tparam _CharT Type of character stream. |
1007 | * @tparam _Traits Traits for character type, defaults to | |
1008 | * char_traits<_CharT>. | |
1009 | * | |
840ceb34 PE |
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. | |
13c4b877 | 1014 | */ |
54c1bf78 BK |
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; | |
fd58f127 | 1033 | |
54c1bf78 BK |
1034 | public: |
1035 | // Constructors/destructor: | |
840ceb34 PE |
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). | |
13c4b877 | 1042 | */ |
54c1bf78 | 1043 | basic_fstream() |
d29cc32f | 1044 | : __iostream_type(), _M_filebuf() |
54c1bf78 BK |
1045 | { this->init(&_M_filebuf); } |
1046 | ||
fd58f127 | 1047 | /** |
840ceb34 | 1048 | * @brief Create an input/output file stream. |
93c66bc6 BK |
1049 | * @param __s Null terminated string specifying the filename. |
1050 | * @param __mode Open file in specified mode (see std::ios_base). | |
13c4b877 | 1051 | */ |
fd58f127 | 1052 | explicit |
54c1bf78 BK |
1053 | basic_fstream(const char* __s, |
1054 | ios_base::openmode __mode = ios_base::in | ios_base::out) | |
8fc81078 | 1055 | : __iostream_type(0), _M_filebuf() |
fd58f127 PE |
1056 | { |
1057 | this->init(&_M_filebuf); | |
1058 | this->open(__s, __mode); | |
54c1bf78 | 1059 | } |
fd58f127 | 1060 | |
b0292359 JW |
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 | ||
734f5023 | 1076 | #if __cplusplus >= 201103L |
13c4b877 PC |
1077 | /** |
1078 | * @brief Create an input/output file stream. | |
93c66bc6 BK |
1079 | * @param __s Null terminated string specifying the filename. |
1080 | * @param __mode Open file in specified mode (see std::ios_base). | |
13c4b877 PC |
1081 | */ |
1082 | explicit | |
1083 | basic_fstream(const std::string& __s, | |
1084 | ios_base::openmode __mode = ios_base::in | ios_base::out) | |
8fc81078 | 1085 | : __iostream_type(0), _M_filebuf() |
13c4b877 PC |
1086 | { |
1087 | this->init(&_M_filebuf); | |
1088 | this->open(__s, __mode); | |
1089 | } | |
9b817548 | 1090 | |
d49f254a JW |
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 | */ | |
96e0367e | 1097 | template<typename _Path, typename _Require = _If_fs_path<_Path>> |
d49f254a JW |
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 | ||
9b817548 JW |
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); } | |
13c4b877 PC |
1110 | #endif |
1111 | ||
840ceb34 PE |
1112 | /** |
1113 | * @brief The destructor does nothing. | |
1114 | * | |
1115 | * The file is closed by the filebuf object, not the formatting | |
1116 | * stream. | |
13c4b877 | 1117 | */ |
54c1bf78 BK |
1118 | ~basic_fstream() |
1119 | { } | |
fd58f127 | 1120 | |
9b817548 JW |
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 | ||
54c1bf78 | 1143 | // Members: |
fd58f127 | 1144 | /** |
840ceb34 PE |
1145 | * @brief Accessing the underlying buffer. |
1146 | * @return The current basic_filebuf buffer. | |
1147 | * | |
1148 | * This hides both signatures of std::basic_ios::rdbuf(). | |
13c4b877 | 1149 | */ |
fd58f127 | 1150 | __filebuf_type* |
07814743 | 1151 | rdbuf() const |
54c1bf78 BK |
1152 | { return const_cast<__filebuf_type*>(&_M_filebuf); } |
1153 | ||
fd58f127 | 1154 | /** |
840ceb34 PE |
1155 | * @brief Wrapper to test for an open file. |
1156 | * @return @c rdbuf()->is_open() | |
13c4b877 | 1157 | */ |
fd58f127 | 1158 | bool |
85a5f64e PC |
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(); } | |
54c1bf78 | 1167 | |
fd58f127 | 1168 | /** |
840ceb34 | 1169 | * @brief Opens an external file. |
93c66bc6 BK |
1170 | * @param __s The name of the file. |
1171 | * @param __mode The open mode flags. | |
840ceb34 | 1172 | * |
93c66bc6 | 1173 | * Calls @c std::basic_filebuf::open(__s,__mode). If that |
840ceb34 | 1174 | * function fails, @c failbit is set in the stream's error state. |
13c4b877 | 1175 | */ |
fd58f127 PE |
1176 | void |
1177 | open(const char* __s, | |
54c1bf78 | 1178 | ios_base::openmode __mode = ios_base::in | ios_base::out) |
fd58f127 | 1179 | { |
54c1bf78 | 1180 | if (!_M_filebuf.open(__s, __mode)) |
43be7fe7 | 1181 | this->setstate(ios_base::failbit); |
7a59efae PC |
1182 | else |
1183 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
1184 | // 409. Closing an fstream should clear error state | |
1185 | this->clear(); | |
54c1bf78 BK |
1186 | } |
1187 | ||
b0292359 JW |
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 | ||
734f5023 | 1208 | #if __cplusplus >= 201103L |
13c4b877 PC |
1209 | /** |
1210 | * @brief Opens an external file. | |
93c66bc6 BK |
1211 | * @param __s The name of the file. |
1212 | * @param __mode The open mode flags. | |
13c4b877 | 1213 | * |
93c66bc6 | 1214 | * Calls @c std::basic_filebuf::open(__s,__mode). If that |
13c4b877 PC |
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 | } | |
d49f254a JW |
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> | |
96e0367e | 1239 | _If_fs_path<_Path, void> |
d49f254a JW |
1240 | open(const _Path& __s, |
1241 | ios_base::openmode __mode = ios_base::in | ios_base::out) | |
d49f254a JW |
1242 | { open(__s.c_str(), __mode); } |
1243 | #endif // C++17 | |
1244 | #endif // C++11 | |
13c4b877 | 1245 | |
840ceb34 PE |
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. | |
13c4b877 | 1251 | */ |
fd58f127 | 1252 | void |
07814743 | 1253 | close() |
fd58f127 | 1254 | { |
54c1bf78 | 1255 | if (!_M_filebuf.close()) |
43be7fe7 | 1256 | this->setstate(ios_base::failbit); |
54c1bf78 BK |
1257 | } |
1258 | }; | |
3cbc7af0 | 1259 | |
9b817548 JW |
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 | ||
12ffa228 BK |
1290 | _GLIBCXX_END_NAMESPACE_VERSION |
1291 | } // namespace | |
54c1bf78 | 1292 | |
ee3ee948 | 1293 | #include <bits/fstream.tcc> |
54c1bf78 | 1294 | |
1143680e | 1295 | #endif /* _GLIBCXX_FSTREAM */ |