]>
Commit | Line | Data |
---|---|---|
725dc051 BK |
1 | // File based streams -*- C++ -*- |
2 | ||
8fbc5ae7 | 3 | // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 |
e6705174 | 4 | // Free Software Foundation, Inc. |
725dc051 BK |
5 | // |
6 | // This file is part of the GNU ISO C++ Library. This library is free | |
7 | // software; you can redistribute it and/or modify it under the | |
8 | // terms of the GNU General Public License as published by the | |
9 | // Free Software Foundation; either version 2, or (at your option) | |
10 | // any later version. | |
11 | ||
12 | // This library is distributed in the hope that it will be useful, | |
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | // GNU General Public License for more details. | |
16 | ||
17 | // You should have received a copy of the GNU General Public License along | |
18 | // with this library; see the file COPYING. If not, write to the Free | |
19 | // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
20 | // USA. | |
21 | ||
22 | // As a special exception, you may use this file as part of a free software | |
23 | // library without restriction. Specifically, if other files instantiate | |
24 | // templates or use macros or inline functions from this file, or you compile | |
25 | // this file and link it with other files to produce an executable, this | |
26 | // file does not by itself cause the resulting executable to be covered by | |
27 | // the GNU General Public License. This exception does not however | |
28 | // invalidate any other reasons why the executable file might be covered by | |
29 | // the GNU General Public License. | |
30 | ||
31 | // | |
32 | // ISO C++ 14882: 27.8 File-based streams | |
33 | // | |
34 | ||
35 | #ifndef _CPP_BITS_FSTREAM_TCC | |
36 | #define _CPP_BITS_FSTREAM_TCC 1 | |
37 | ||
3b794528 BK |
38 | #pragma GCC system_header |
39 | ||
725dc051 BK |
40 | namespace std |
41 | { | |
725dc051 BK |
42 | template<typename _CharT, typename _Traits> |
43 | void | |
44 | basic_filebuf<_CharT, _Traits>:: | |
990101f9 | 45 | _M_allocate_internal_buffer() |
725dc051 | 46 | { |
8fbc5ae7 | 47 | if (!this->_M_buf && this->_M_buf_size_opt) |
13187a45 | 48 | { |
8fbc5ae7 | 49 | this->_M_buf_size = this->_M_buf_size_opt; |
990101f9 | 50 | |
391cd095 PC |
51 | // Allocate internal buffer... |
52 | this->_M_buf = new char_type[this->_M_buf_size]; | |
53 | // ... and consistently set the end of buffer pointer. | |
54 | this->_M_out_end = this->_M_buf + this->_M_buf_size; | |
5cdd50a5 | 55 | _M_buf_allocated = true; |
990101f9 BK |
56 | } |
57 | } | |
58 | ||
59 | // Both close and setbuf need to deallocate internal buffers, if it exists. | |
60 | template<typename _CharT, typename _Traits> | |
61 | void | |
62 | basic_filebuf<_CharT, _Traits>:: | |
63 | _M_destroy_internal_buffer() | |
64 | { | |
65 | if (_M_buf_allocated) | |
66 | { | |
8fbc5ae7 MM |
67 | delete [] this->_M_buf; |
68 | this->_M_buf = NULL; | |
990101f9 BK |
69 | _M_buf_allocated = false; |
70 | this->setg(NULL, NULL, NULL); | |
71 | this->setp(NULL, NULL); | |
72 | } | |
725dc051 BK |
73 | } |
74 | ||
75 | template<typename _CharT, typename _Traits> | |
76 | basic_filebuf<_CharT, _Traits>:: | |
5cdd50a5 BK |
77 | basic_filebuf() : __streambuf_type(), _M_file(&_M_lock), |
78 | _M_state_cur(__state_type()), _M_state_beg(__state_type()), | |
79 | _M_buf_allocated(false), _M_last_overflowed(false) | |
8fbc5ae7 | 80 | { this->_M_buf_unified = true; } |
725dc051 | 81 | |
725dc051 | 82 | template<typename _CharT, typename _Traits> |
31bfa177 | 83 | typename basic_filebuf<_CharT, _Traits>::__filebuf_type* |
725dc051 BK |
84 | basic_filebuf<_CharT, _Traits>:: |
85 | open(const char* __s, ios_base::openmode __mode) | |
86 | { | |
87 | __filebuf_type *__ret = NULL; | |
88 | if (!this->is_open()) | |
89 | { | |
d3a193e3 | 90 | _M_file.open(__s, __mode); |
13187a45 | 91 | if (this->is_open()) |
725dc051 | 92 | { |
990101f9 | 93 | _M_allocate_internal_buffer(); |
8fbc5ae7 | 94 | this->_M_mode = __mode; |
6eeb7d7a BK |
95 | |
96 | // Setup initial position of buffer. | |
725dc051 | 97 | _M_set_indeterminate(); |
6e52332e | 98 | |
6eeb7d7a BK |
99 | // Set input buffer to something real. |
100 | // NB: Must open in non-blocking way to do this, or must | |
101 | // set the initial position in a different manner than | |
102 | // using underflow. | |
103 | if (__mode & ios_base::in && _M_buf_allocated) | |
104 | this->underflow(); | |
105 | ||
b7737230 | 106 | if ((__mode & ios_base::ate) |
725dc051 | 107 | && this->seekoff(0, ios_base::end, __mode) < 0) |
7cd3907b PC |
108 | { |
109 | // 27.8.1.3,4 | |
110 | this->close(); | |
111 | return __ret; | |
112 | } | |
6eeb7d7a | 113 | |
725dc051 BK |
114 | __ret = this; |
115 | } | |
116 | } | |
117 | return __ret; | |
118 | } | |
119 | ||
120 | template<typename _CharT, typename _Traits> | |
31bfa177 | 121 | typename basic_filebuf<_CharT, _Traits>::__filebuf_type* |
725dc051 BK |
122 | basic_filebuf<_CharT, _Traits>:: |
123 | close() | |
124 | { | |
125 | __filebuf_type *__ret = NULL; | |
126 | if (this->is_open()) | |
127 | { | |
e6705174 | 128 | const int_type __eof = traits_type::eof(); |
8fbc5ae7 | 129 | bool __testput = this->_M_out_cur |
391cd095 | 130 | && this->_M_out_beg < this->_M_out_lim; |
f13a69ec BK |
131 | if (__testput |
132 | && traits_type::eq_int_type(_M_really_overflow(__eof), __eof)) | |
e6705174 | 133 | return __ret; |
725dc051 | 134 | |
e6705174 | 135 | // NB: Do this here so that re-opened filebufs will be cool... |
8fbc5ae7 | 136 | this->_M_mode = ios_base::openmode(0); |
e6705174 | 137 | _M_destroy_internal_buffer(); |
e6705174 | 138 | _M_pback_destroy(); |
e6705174 | 139 | |
725dc051 BK |
140 | #if 0 |
141 | // XXX not done | |
142 | if (_M_last_overflowed) | |
143 | { | |
144 | _M_output_unshift(); | |
e6705174 | 145 | _M_really_overflow(__eof); |
725dc051 BK |
146 | } |
147 | #endif | |
725dc051 | 148 | |
d3a193e3 BK |
149 | if (_M_file.close()) |
150 | __ret = this; | |
725dc051 | 151 | } |
d3a193e3 | 152 | |
725dc051 BK |
153 | _M_last_overflowed = false; |
154 | return __ret; | |
155 | } | |
156 | ||
157 | template<typename _CharT, typename _Traits> | |
158 | streamsize | |
159 | basic_filebuf<_CharT, _Traits>:: | |
160 | showmanyc() | |
161 | { | |
162 | streamsize __ret = -1; | |
8fbc5ae7 | 163 | bool __testin = this->_M_mode & ios_base::in; |
725dc051 | 164 | |
9fbcb61a | 165 | if (__testin && this->is_open()) |
8fbc5ae7 | 166 | __ret = this->_M_in_end - this->_M_in_cur; |
725dc051 BK |
167 | _M_last_overflowed = false; |
168 | return __ret; | |
169 | } | |
725dc051 BK |
170 | |
171 | template<typename _CharT, typename _Traits> | |
31bfa177 | 172 | typename basic_filebuf<_CharT, _Traits>::int_type |
725dc051 BK |
173 | basic_filebuf<_CharT, _Traits>:: |
174 | pbackfail(int_type __i) | |
175 | { | |
176 | int_type __ret = traits_type::eof(); | |
8fbc5ae7 | 177 | bool __testin = this->_M_mode & ios_base::in; |
725dc051 BK |
178 | |
179 | if (__testin) | |
180 | { | |
8fbc5ae7 | 181 | bool __testpb = this->_M_in_beg < this->_M_in_cur; |
725dc051 BK |
182 | char_type __c = traits_type::to_char_type(__i); |
183 | bool __testeof = traits_type::eq_int_type(__i, __ret); | |
184 | ||
185 | if (__testpb) | |
186 | { | |
8fbc5ae7 | 187 | bool __testout = this->_M_mode & ios_base::out; |
725dc051 BK |
188 | bool __testeq = traits_type::eq(__c, this->gptr()[-1]); |
189 | ||
190 | // Try to put back __c into input sequence in one of three ways. | |
191 | // Order these tests done in is unspecified by the standard. | |
192 | if (!__testeof && __testeq) | |
193 | { | |
8fbc5ae7 | 194 | --this->_M_in_cur; |
725dc051 | 195 | if (__testout) |
8fbc5ae7 | 196 | --this->_M_out_cur; |
725dc051 BK |
197 | __ret = __i; |
198 | } | |
199 | else if (__testeof) | |
200 | { | |
8fbc5ae7 | 201 | --this->_M_in_cur; |
725dc051 | 202 | if (__testout) |
8fbc5ae7 | 203 | --this->_M_out_cur; |
725dc051 BK |
204 | __ret = traits_type::not_eof(__i); |
205 | } | |
206 | else if (!__testeof) | |
207 | { | |
8fbc5ae7 | 208 | --this->_M_in_cur; |
725dc051 | 209 | if (__testout) |
8fbc5ae7 | 210 | --this->_M_out_cur; |
725dc051 | 211 | _M_pback_create(); |
8fbc5ae7 | 212 | *this->_M_in_cur = __c; |
725dc051 BK |
213 | __ret = __i; |
214 | } | |
215 | } | |
216 | else | |
217 | { | |
218 | // At the beginning of the buffer, need to make a | |
219 | // putback position available. | |
52b62c0e PC |
220 | // But the seek may fail (f.i., at the beginning of |
221 | // a file, see libstdc++/9439) and in that case | |
222 | // we return traits_type::eof() | |
223 | if (this->seekoff(-1, ios_base::cur) >= 0) | |
224 | { | |
225 | this->underflow(); | |
226 | if (!__testeof) | |
725dc051 | 227 | { |
52b62c0e PC |
228 | if (!traits_type::eq(__c, *this->_M_in_cur)) |
229 | { | |
230 | _M_pback_create(); | |
231 | *this->_M_in_cur = __c; | |
232 | } | |
233 | __ret = __i; | |
725dc051 | 234 | } |
52b62c0e PC |
235 | else |
236 | __ret = traits_type::not_eof(__i); | |
237 | } | |
725dc051 BK |
238 | } |
239 | } | |
240 | _M_last_overflowed = false; | |
241 | return __ret; | |
242 | } | |
243 | ||
244 | template<typename _CharT, typename _Traits> | |
31bfa177 | 245 | typename basic_filebuf<_CharT, _Traits>::int_type |
725dc051 BK |
246 | basic_filebuf<_CharT, _Traits>:: |
247 | overflow(int_type __c) | |
248 | { | |
249 | int_type __ret = traits_type::eof(); | |
391cd095 | 250 | bool __testput = _M_out_buf_size(); |
8fbc5ae7 | 251 | bool __testout = this->_M_mode & ios_base::out; |
725dc051 BK |
252 | |
253 | if (__testout) | |
254 | { | |
5fa9abc3 | 255 | if (__testput) |
725dc051 | 256 | { |
8fbc5ae7 | 257 | *this->_M_out_cur = traits_type::to_char_type(__c); |
725dc051 BK |
258 | _M_out_cur_move(1); |
259 | __ret = traits_type::not_eof(__c); | |
260 | } | |
261 | else | |
262 | __ret = this->_M_really_overflow(__c); | |
263 | } | |
264 | ||
265 | _M_last_overflowed = false; // Set in _M_really_overflow, below. | |
266 | return __ret; | |
267 | } | |
268 | ||
07814743 BK |
269 | template<typename _CharT, typename _Traits> |
270 | void | |
271 | basic_filebuf<_CharT, _Traits>:: | |
272 | _M_convert_to_external(_CharT* __ibuf, streamsize __ilen, | |
273 | streamsize& __elen, streamsize& __plen) | |
274 | { | |
07814743 BK |
275 | const locale __loc = this->getloc(); |
276 | const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc); | |
277 | ||
278 | if (__cvt.always_noconv() && __ilen) | |
279 | { | |
d3a193e3 | 280 | __elen += _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen); |
07814743 BK |
281 | __plen += __ilen; |
282 | } | |
283 | else | |
284 | { | |
285 | // Worst-case number of external bytes needed. | |
286 | int __ext_multiplier = __cvt.encoding(); | |
287 | if (__ext_multiplier == -1 || __ext_multiplier == 0) | |
288 | __ext_multiplier = sizeof(char_type); | |
289 | streamsize __blen = __ilen * __ext_multiplier; | |
290 | char* __buf = static_cast<char*>(__builtin_alloca(__blen)); | |
291 | char* __bend; | |
292 | const char_type* __iend; | |
293 | __res_type __r = __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen, | |
294 | __iend, __buf, __buf + __blen, __bend); | |
130cd3e1 PC |
295 | |
296 | if (__r == codecvt_base::ok || __r == codecvt_base::partial) | |
07814743 | 297 | __blen = __bend - __buf; |
130cd3e1 PC |
298 | // Similarly to the always_noconv case above. |
299 | else if (__r == codecvt_base::noconv) | |
300 | { | |
301 | __buf = reinterpret_cast<char*>(__ibuf); | |
302 | __blen = __ilen; | |
303 | } | |
07814743 BK |
304 | // Result == error |
305 | else | |
306 | __blen = 0; | |
307 | ||
308 | if (__blen) | |
309 | { | |
d3a193e3 | 310 | __elen += _M_file.xsputn(__buf, __blen); |
07814743 BK |
311 | __plen += __blen; |
312 | } | |
313 | ||
314 | // Try once more for partial conversions. | |
315 | if (__r == codecvt_base::partial) | |
316 | { | |
317 | const char_type* __iresume = __iend; | |
391cd095 | 318 | streamsize __rlen = this->_M_out_lim - __iend; |
07814743 BK |
319 | __r = __cvt.out(_M_state_cur, __iresume, __iresume + __rlen, |
320 | __iend, __buf, __buf + __blen, __bend); | |
321 | if (__r != codecvt_base::error) | |
322 | __rlen = __bend - __buf; | |
323 | else | |
324 | __rlen = 0; | |
325 | if (__rlen) | |
326 | { | |
d3a193e3 | 327 | __elen += _M_file.xsputn(__buf, __rlen); |
07814743 BK |
328 | __plen += __rlen; |
329 | } | |
330 | } | |
331 | } | |
332 | } | |
333 | ||
725dc051 | 334 | template<typename _CharT, typename _Traits> |
31bfa177 | 335 | typename basic_filebuf<_CharT, _Traits>::int_type |
725dc051 BK |
336 | basic_filebuf<_CharT, _Traits>:: |
337 | _M_really_overflow(int_type __c) | |
338 | { | |
339 | int_type __ret = traits_type::eof(); | |
391cd095 | 340 | bool __testput = this->_M_out_cur && this->_M_out_beg < this->_M_out_lim; |
8fbc5ae7 | 341 | bool __testunbuffered = _M_file.is_open() && !this->_M_buf_size_opt; |
5fa9abc3 BK |
342 | |
343 | if (__testput || __testunbuffered) | |
725dc051 | 344 | { |
07814743 BK |
345 | // Sizes of external and pending output. |
346 | streamsize __elen = 0; | |
347 | streamsize __plen = 0; | |
348 | ||
5066927d JM |
349 | // Need to restore current position. The position of the external |
350 | // byte sequence (_M_file) corresponds to _M_filepos, and we need | |
351 | // to move it to _M_out_beg for the write. | |
8fbc5ae7 | 352 | if (_M_filepos && _M_filepos != this->_M_out_beg) |
5066927d | 353 | { |
8fbc5ae7 | 354 | off_type __off = this->_M_out_beg - _M_filepos; |
5066927d JM |
355 | _M_file.seekoff(__off, ios_base::cur); |
356 | } | |
357 | ||
07814743 BK |
358 | // Convert internal buffer to external representation, output. |
359 | // NB: In the unbuffered case, no internal buffer exists. | |
360 | if (!__testunbuffered) | |
8fbc5ae7 | 361 | _M_convert_to_external(this->_M_out_beg, |
391cd095 | 362 | this->_M_out_lim - this->_M_out_beg, |
07814743 BK |
363 | __elen, __plen); |
364 | ||
365 | // Convert pending sequence to external representation, output. | |
9385d9cb | 366 | // If eof, then just attempt sync. |
07814743 | 367 | if (!traits_type::eq_int_type(__c, traits_type::eof())) |
725dc051 | 368 | { |
07814743 BK |
369 | char_type __pending = traits_type::to_char_type(__c); |
370 | _M_convert_to_external(&__pending, 1, __elen, __plen); | |
5fa9abc3 | 371 | |
9385d9cb LR |
372 | // User code must flush when switching modes (thus don't sync). |
373 | if (__elen == __plen) | |
374 | { | |
375 | _M_set_indeterminate(); | |
376 | __ret = traits_type::not_eof(__c); | |
377 | } | |
378 | } | |
379 | else if (!_M_file.sync()) | |
e6705174 BK |
380 | { |
381 | _M_set_indeterminate(); | |
382 | __ret = traits_type::not_eof(__c); | |
383 | } | |
725dc051 BK |
384 | } |
385 | _M_last_overflowed = true; | |
386 | return __ret; | |
387 | } | |
388 | ||
990101f9 | 389 | template<typename _CharT, typename _Traits> |
31bfa177 | 390 | typename basic_filebuf<_CharT, _Traits>::__streambuf_type* |
990101f9 BK |
391 | basic_filebuf<_CharT, _Traits>:: |
392 | setbuf(char_type* __s, streamsize __n) | |
393 | { | |
394 | if (!this->is_open() && __s == 0 && __n == 0) | |
8fbc5ae7 | 395 | this->_M_buf_size_opt = 0; |
990101f9 BK |
396 | else if (__s && __n) |
397 | { | |
398 | // This is implementation-defined behavior, and assumes | |
399 | // that an external char_type array of length (__s + __n) | |
400 | // exists and has been pre-allocated. If this is not the | |
401 | // case, things will quickly blow up. | |
391cd095 | 402 | |
990101f9 BK |
403 | // Step 1: Destroy the current internal array. |
404 | _M_destroy_internal_buffer(); | |
405 | ||
406 | // Step 2: Use the external array. | |
8fbc5ae7 MM |
407 | this->_M_buf = __s; |
408 | this->_M_buf_size_opt = this->_M_buf_size = __n; | |
391cd095 PC |
409 | // Consistently set the end of buffer pointer. |
410 | this->_M_out_end = this->_M_buf + this->_M_buf_size; | |
990101f9 | 411 | _M_set_indeterminate(); |
990101f9 BK |
412 | } |
413 | _M_last_overflowed = false; | |
414 | return this; | |
415 | } | |
416 | ||
725dc051 | 417 | template<typename _CharT, typename _Traits> |
31bfa177 | 418 | typename basic_filebuf<_CharT, _Traits>::pos_type |
725dc051 BK |
419 | basic_filebuf<_CharT, _Traits>:: |
420 | seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) | |
421 | { | |
422 | pos_type __ret = pos_type(off_type(-1)); | |
8fbc5ae7 MM |
423 | bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; |
424 | bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; | |
69302d8b BK |
425 | |
426 | // Should probably do has_facet checks here. | |
8fbc5ae7 | 427 | int __width = use_facet<__codecvt_type>(this->_M_buf_locale).encoding(); |
725dc051 BK |
428 | if (__width < 0) |
429 | __width = 0; | |
b988dfc5 | 430 | bool __testfail = __off != 0 && __width <= 0; |
725dc051 | 431 | |
dcf5a5de | 432 | if (this->is_open() && !__testfail && (__testin || __testout)) |
725dc051 BK |
433 | { |
434 | // Ditch any pback buffers to avoid confusion. | |
435 | _M_pback_destroy(); | |
436 | ||
437 | if (__way != ios_base::cur || __off != 0) | |
438 | { | |
439 | off_type __computed_off = __width * __off; | |
440 | ||
8fbc5ae7 MM |
441 | bool __testget = this->_M_in_cur |
442 | && this->_M_in_beg < this->_M_in_end; | |
443 | bool __testput = this->_M_out_cur | |
391cd095 | 444 | && this->_M_out_beg < this->_M_out_lim; |
725dc051 BK |
445 | // Sync the internal and external streams. |
446 | // out | |
447 | if (__testput || _M_last_overflowed) | |
448 | { | |
449 | // Part one: update the output sequence. | |
450 | this->sync(); | |
451 | // Part two: output unshift sequence. | |
452 | _M_output_unshift(); | |
453 | } | |
454 | //in | |
725dc051 | 455 | else if (__testget && __way == ios_base::cur) |
8fbc5ae7 | 456 | __computed_off += this->_M_in_cur - _M_filepos; |
52b62c0e PC |
457 | |
458 | // Return pos_type(off_type(-1)) in case of failure. | |
d3a193e3 | 459 | __ret = _M_file.seekoff(__computed_off, __way, __mode); |
725dc051 BK |
460 | _M_set_indeterminate(); |
461 | } | |
462 | // NB: Need to do this in case _M_file in indeterminate | |
d3a193e3 | 463 | // state, ie _M_file._offset == -1 |
725dc051 BK |
464 | else |
465 | { | |
52b62c0e PC |
466 | pos_type __tmp = |
467 | _M_file.seekoff(__off, ios_base::cur, __mode); | |
468 | if (__tmp >= 0) | |
74db1461 SS |
469 | { |
470 | // Seek successful. | |
471 | __ret = __tmp; | |
472 | __ret += | |
473 | std::max(this->_M_out_cur, this->_M_in_cur) - _M_filepos; | |
474 | } | |
725dc051 BK |
475 | } |
476 | } | |
477 | _M_last_overflowed = false; | |
478 | return __ret; | |
479 | } | |
480 | ||
481 | template<typename _CharT, typename _Traits> | |
31bfa177 | 482 | typename basic_filebuf<_CharT, _Traits>::pos_type |
725dc051 BK |
483 | basic_filebuf<_CharT, _Traits>:: |
484 | seekpos(pos_type __pos, ios_base::openmode __mode) | |
485 | { | |
b988dfc5 BK |
486 | #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS |
487 | // 171. Strange seekpos() semantics due to joint position | |
488 | return this->seekoff(off_type(__pos), ios_base::beg, __mode); | |
489 | #endif | |
725dc051 BK |
490 | } |
491 | ||
492 | template<typename _CharT, typename _Traits> | |
493 | void | |
494 | basic_filebuf<_CharT, _Traits>:: | |
495 | _M_output_unshift() | |
496 | { } | |
497 | ||
498 | template<typename _CharT, typename _Traits> | |
499 | void | |
500 | basic_filebuf<_CharT, _Traits>:: | |
501 | imbue(const locale& __loc) | |
502 | { | |
503 | bool __testbeg = gptr() == eback() && pptr() == pbase(); | |
69302d8b | 504 | |
8fbc5ae7 | 505 | if (__testbeg && this->_M_buf_locale != __loc) |
1ceb90cf | 506 | this->_M_buf_locale = __loc; |
69302d8b | 507 | |
725dc051 BK |
508 | // NB this may require the reconversion of previously |
509 | // converted chars. This in turn may cause the reconstruction | |
510 | // of the original file. YIKES!! | |
511 | // XXX The part in the above comment is not done. | |
512 | _M_last_overflowed = false; | |
513 | } | |
a32e3c09 BK |
514 | |
515 | // Inhibit implicit instantiations for required instantiations, | |
516 | // which are defined via explicit instantiations elsewhere. | |
517 | // NB: This syntax is a GNU extension. | |
1bc8b0ad | 518 | #if _GLIBCPP_EXTERN_TEMPLATE |
a32e3c09 | 519 | extern template class basic_filebuf<char>; |
a32e3c09 | 520 | extern template class basic_ifstream<char>; |
a32e3c09 | 521 | extern template class basic_ofstream<char>; |
a32e3c09 | 522 | extern template class basic_fstream<char>; |
5112ae3a BK |
523 | |
524 | #ifdef _GLIBCPP_USE_WCHAR_T | |
525 | extern template class basic_filebuf<wchar_t>; | |
526 | extern template class basic_ifstream<wchar_t>; | |
527 | extern template class basic_ofstream<wchar_t>; | |
a32e3c09 | 528 | extern template class basic_fstream<wchar_t>; |
5112ae3a | 529 | #endif |
1bc8b0ad | 530 | #endif |
725dc051 BK |
531 | } // namespace std |
532 | ||
6f48900c | 533 | #endif |