1 | // istream classes -*- 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 bits/istream.tcc |
26 | * This is an internal header file, included by other library headers. |
27 | * Do not attempt to use it directly. @headername{istream} |
28 | */ |
29 | |
30 | // |
31 | // ISO C++ 14882: 27.6.1 Input streams |
32 | // |
33 | |
34 | #ifndef _ISTREAM_TCC |
35 | #define _ISTREAM_TCC 1 |
36 | |
37 | #pragma GCC system_header |
38 | |
39 | #include <bits/cxxabi_forced.h> |
40 | |
41 | namespace std _GLIBCXX_VISIBILITY(default) |
42 | { |
43 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
44 | |
45 | template<typename _CharT, typename _Traits> |
46 | basic_istream<_CharT, _Traits>::sentry:: |
47 | sentry(basic_istream<_CharT, _Traits>& __in, bool __noskip) : _M_ok(false) |
48 | { |
49 | ios_base::iostate __err = ios_base::goodbit; |
50 | if (__in.good()) |
51 | { |
52 | __try |
53 | { |
54 | if (__in.tie()) |
55 | __in.tie()->flush(); |
56 | if (!__noskip && bool(__in.flags() & ios_base::skipws)) |
57 | { |
58 | const __int_type __eof = traits_type::eof(); |
59 | __streambuf_type* __sb = __in.rdbuf(); |
60 | __int_type __c = __sb->sgetc(); |
61 | |
62 | const __ctype_type& __ct = __check_facet(__in._M_ctype); |
63 | while (!traits_type::eq_int_type(__c, __eof) |
64 | && __ct.is(ctype_base::space, |
65 | traits_type::to_char_type(__c))) |
66 | __c = __sb->snextc(); |
67 | |
68 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
69 | // 195. Should basic_istream::sentry's constructor ever |
70 | // set eofbit? |
71 | if (traits_type::eq_int_type(__c, __eof)) |
72 | __err |= ios_base::eofbit; |
73 | } |
74 | } |
75 | __catch(__cxxabiv1::__forced_unwind&) |
76 | { |
77 | __in._M_setstate(ios_base::badbit); |
78 | __throw_exception_again; |
79 | } |
80 | __catch(...) |
81 | { __in._M_setstate(ios_base::badbit); } |
82 | } |
83 | |
84 | if (__in.good() && __err == ios_base::goodbit) |
85 | _M_ok = true; |
86 | else |
87 | { |
88 | __err |= ios_base::failbit; |
89 | __in.setstate(__err); |
90 | } |
91 | } |
92 | |
93 | template<typename _CharT, typename _Traits> |
94 | template<typename _ValueT> |
95 | basic_istream<_CharT, _Traits>& |
96 | basic_istream<_CharT, _Traits>:: |
97 | (_ValueT& __v) |
98 | { |
99 | sentry __cerb(*this, false); |
100 | if (__cerb) |
101 | { |
102 | ios_base::iostate __err = ios_base::goodbit; |
103 | __try |
104 | { |
105 | const __num_get_type& __ng = __check_facet(this->_M_num_get); |
106 | __ng.get(*this, 0, *this, __err, __v); |
107 | } |
108 | __catch(__cxxabiv1::__forced_unwind&) |
109 | { |
110 | this->_M_setstate(ios_base::badbit); |
111 | __throw_exception_again; |
112 | } |
113 | __catch(...) |
114 | { this->_M_setstate(ios_base::badbit); } |
115 | if (__err) |
116 | this->setstate(__err); |
117 | } |
118 | return *this; |
119 | } |
120 | |
121 | template<typename _CharT, typename _Traits> |
122 | basic_istream<_CharT, _Traits>& |
123 | basic_istream<_CharT, _Traits>:: |
124 | operator>>(short& __n) |
125 | { |
126 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
127 | // 118. basic_istream uses nonexistent num_get member functions. |
128 | sentry __cerb(*this, false); |
129 | if (__cerb) |
130 | { |
131 | ios_base::iostate __err = ios_base::goodbit; |
132 | __try |
133 | { |
134 | long __l; |
135 | const __num_get_type& __ng = __check_facet(this->_M_num_get); |
136 | __ng.get(*this, 0, *this, __err, __l); |
137 | |
138 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
139 | // 696. istream::operator>>(int&) broken. |
140 | if (__l < __gnu_cxx::__numeric_traits<short>::__min) |
141 | { |
142 | __err |= ios_base::failbit; |
143 | __n = __gnu_cxx::__numeric_traits<short>::__min; |
144 | } |
145 | else if (__l > __gnu_cxx::__numeric_traits<short>::__max) |
146 | { |
147 | __err |= ios_base::failbit; |
148 | __n = __gnu_cxx::__numeric_traits<short>::__max; |
149 | } |
150 | else |
151 | __n = short(__l); |
152 | } |
153 | __catch(__cxxabiv1::__forced_unwind&) |
154 | { |
155 | this->_M_setstate(ios_base::badbit); |
156 | __throw_exception_again; |
157 | } |
158 | __catch(...) |
159 | { this->_M_setstate(ios_base::badbit); } |
160 | if (__err) |
161 | this->setstate(__err); |
162 | } |
163 | return *this; |
164 | } |
165 | |
166 | template<typename _CharT, typename _Traits> |
167 | basic_istream<_CharT, _Traits>& |
168 | basic_istream<_CharT, _Traits>:: |
169 | operator>>(int& __n) |
170 | { |
171 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
172 | // 118. basic_istream uses nonexistent num_get member functions. |
173 | sentry __cerb(*this, false); |
174 | if (__cerb) |
175 | { |
176 | ios_base::iostate __err = ios_base::goodbit; |
177 | __try |
178 | { |
179 | long __l; |
180 | const __num_get_type& __ng = __check_facet(this->_M_num_get); |
181 | __ng.get(*this, 0, *this, __err, __l); |
182 | |
183 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
184 | // 696. istream::operator>>(int&) broken. |
185 | if (__l < __gnu_cxx::__numeric_traits<int>::__min) |
186 | { |
187 | __err |= ios_base::failbit; |
188 | __n = __gnu_cxx::__numeric_traits<int>::__min; |
189 | } |
190 | else if (__l > __gnu_cxx::__numeric_traits<int>::__max) |
191 | { |
192 | __err |= ios_base::failbit; |
193 | __n = __gnu_cxx::__numeric_traits<int>::__max; |
194 | } |
195 | else |
196 | __n = int(__l); |
197 | } |
198 | __catch(__cxxabiv1::__forced_unwind&) |
199 | { |
200 | this->_M_setstate(ios_base::badbit); |
201 | __throw_exception_again; |
202 | } |
203 | __catch(...) |
204 | { this->_M_setstate(ios_base::badbit); } |
205 | if (__err) |
206 | this->setstate(__err); |
207 | } |
208 | return *this; |
209 | } |
210 | |
211 | template<typename _CharT, typename _Traits> |
212 | basic_istream<_CharT, _Traits>& |
213 | basic_istream<_CharT, _Traits>:: |
214 | operator>>(__streambuf_type* __sbout) |
215 | { |
216 | ios_base::iostate __err = ios_base::goodbit; |
217 | sentry __cerb(*this, false); |
218 | if (__cerb && __sbout) |
219 | { |
220 | __try |
221 | { |
222 | bool __ineof; |
223 | if (!__copy_streambufs_eof(this->rdbuf(), __sbout, __ineof)) |
224 | __err |= ios_base::failbit; |
225 | if (__ineof) |
226 | __err |= ios_base::eofbit; |
227 | } |
228 | __catch(__cxxabiv1::__forced_unwind&) |
229 | { |
230 | this->_M_setstate(ios_base::failbit); |
231 | __throw_exception_again; |
232 | } |
233 | __catch(...) |
234 | { this->_M_setstate(ios_base::failbit); } |
235 | } |
236 | else if (!__sbout) |
237 | __err |= ios_base::failbit; |
238 | if (__err) |
239 | this->setstate(__err); |
240 | return *this; |
241 | } |
242 | |
243 | template<typename _CharT, typename _Traits> |
244 | typename basic_istream<_CharT, _Traits>::int_type |
245 | basic_istream<_CharT, _Traits>:: |
246 | get(void) |
247 | { |
248 | const int_type __eof = traits_type::eof(); |
249 | int_type __c = __eof; |
250 | _M_gcount = 0; |
251 | ios_base::iostate __err = ios_base::goodbit; |
252 | sentry __cerb(*this, true); |
253 | if (__cerb) |
254 | { |
255 | __try |
256 | { |
257 | __c = this->rdbuf()->sbumpc(); |
258 | // 27.6.1.1 paragraph 3 |
259 | if (!traits_type::eq_int_type(__c, __eof)) |
260 | _M_gcount = 1; |
261 | else |
262 | __err |= ios_base::eofbit; |
263 | } |
264 | __catch(__cxxabiv1::__forced_unwind&) |
265 | { |
266 | this->_M_setstate(ios_base::badbit); |
267 | __throw_exception_again; |
268 | } |
269 | __catch(...) |
270 | { this->_M_setstate(ios_base::badbit); } |
271 | } |
272 | if (!_M_gcount) |
273 | __err |= ios_base::failbit; |
274 | if (__err) |
275 | this->setstate(__err); |
276 | return __c; |
277 | } |
278 | |
279 | template<typename _CharT, typename _Traits> |
280 | basic_istream<_CharT, _Traits>& |
281 | basic_istream<_CharT, _Traits>:: |
282 | get(char_type& __c) |
283 | { |
284 | _M_gcount = 0; |
285 | ios_base::iostate __err = ios_base::goodbit; |
286 | sentry __cerb(*this, true); |
287 | if (__cerb) |
288 | { |
289 | __try |
290 | { |
291 | const int_type __cb = this->rdbuf()->sbumpc(); |
292 | // 27.6.1.1 paragraph 3 |
293 | if (!traits_type::eq_int_type(__cb, traits_type::eof())) |
294 | { |
295 | _M_gcount = 1; |
296 | __c = traits_type::to_char_type(__cb); |
297 | } |
298 | else |
299 | __err |= ios_base::eofbit; |
300 | } |
301 | __catch(__cxxabiv1::__forced_unwind&) |
302 | { |
303 | this->_M_setstate(ios_base::badbit); |
304 | __throw_exception_again; |
305 | } |
306 | __catch(...) |
307 | { this->_M_setstate(ios_base::badbit); } |
308 | } |
309 | if (!_M_gcount) |
310 | __err |= ios_base::failbit; |
311 | if (__err) |
312 | this->setstate(__err); |
313 | return *this; |
314 | } |
315 | |
316 | template<typename _CharT, typename _Traits> |
317 | basic_istream<_CharT, _Traits>& |
318 | basic_istream<_CharT, _Traits>:: |
319 | get(char_type* __s, streamsize __n, char_type __delim) |
320 | { |
321 | _M_gcount = 0; |
322 | ios_base::iostate __err = ios_base::goodbit; |
323 | sentry __cerb(*this, true); |
324 | if (__cerb) |
325 | { |
326 | __try |
327 | { |
328 | const int_type __idelim = traits_type::to_int_type(__delim); |
329 | const int_type __eof = traits_type::eof(); |
330 | __streambuf_type* __sb = this->rdbuf(); |
331 | int_type __c = __sb->sgetc(); |
332 | |
333 | while (_M_gcount + 1 < __n |
334 | && !traits_type::eq_int_type(__c, __eof) |
335 | && !traits_type::eq_int_type(__c, __idelim)) |
336 | { |
337 | *__s++ = traits_type::to_char_type(__c); |
338 | ++_M_gcount; |
339 | __c = __sb->snextc(); |
340 | } |
341 | if (traits_type::eq_int_type(__c, __eof)) |
342 | __err |= ios_base::eofbit; |
343 | } |
344 | __catch(__cxxabiv1::__forced_unwind&) |
345 | { |
346 | this->_M_setstate(ios_base::badbit); |
347 | __throw_exception_again; |
348 | } |
349 | __catch(...) |
350 | { this->_M_setstate(ios_base::badbit); } |
351 | } |
352 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
353 | // 243. get and getline when sentry reports failure. |
354 | if (__n > 0) |
355 | *__s = char_type(); |
356 | if (!_M_gcount) |
357 | __err |= ios_base::failbit; |
358 | if (__err) |
359 | this->setstate(__err); |
360 | return *this; |
361 | } |
362 | |
363 | template<typename _CharT, typename _Traits> |
364 | basic_istream<_CharT, _Traits>& |
365 | basic_istream<_CharT, _Traits>:: |
366 | get(__streambuf_type& __sb, char_type __delim) |
367 | { |
368 | _M_gcount = 0; |
369 | ios_base::iostate __err = ios_base::goodbit; |
370 | sentry __cerb(*this, true); |
371 | if (__cerb) |
372 | { |
373 | __try |
374 | { |
375 | const int_type __idelim = traits_type::to_int_type(__delim); |
376 | const int_type __eof = traits_type::eof(); |
377 | __streambuf_type* __this_sb = this->rdbuf(); |
378 | int_type __c = __this_sb->sgetc(); |
379 | char_type __c2 = traits_type::to_char_type(__c); |
380 | unsigned long long __gcount = 0; |
381 | |
382 | while (!traits_type::eq_int_type(__c, __eof) |
383 | && !traits_type::eq_int_type(__c, __idelim) |
384 | && !traits_type::eq_int_type(__sb.sputc(__c2), __eof)) |
385 | { |
386 | ++__gcount; |
387 | __c = __this_sb->snextc(); |
388 | __c2 = traits_type::to_char_type(__c); |
389 | } |
390 | if (traits_type::eq_int_type(__c, __eof)) |
391 | __err |= ios_base::eofbit; |
392 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
393 | // 3464. istream::gcount() can overflow |
394 | if (__gcount <= __gnu_cxx::__numeric_traits<streamsize>::__max) |
395 | _M_gcount = __gcount; |
396 | else |
397 | _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; |
398 | } |
399 | __catch(__cxxabiv1::__forced_unwind&) |
400 | { |
401 | this->_M_setstate(ios_base::badbit); |
402 | __throw_exception_again; |
403 | } |
404 | __catch(...) |
405 | { this->_M_setstate(ios_base::badbit); } |
406 | } |
407 | if (!_M_gcount) |
408 | __err |= ios_base::failbit; |
409 | if (__err) |
410 | this->setstate(__err); |
411 | return *this; |
412 | } |
413 | |
414 | template<typename _CharT, typename _Traits> |
415 | basic_istream<_CharT, _Traits>& |
416 | basic_istream<_CharT, _Traits>:: |
417 | getline(char_type* __s, streamsize __n, char_type __delim) |
418 | { |
419 | _M_gcount = 0; |
420 | ios_base::iostate __err = ios_base::goodbit; |
421 | sentry __cerb(*this, true); |
422 | if (__cerb) |
423 | { |
424 | __try |
425 | { |
426 | const int_type __idelim = traits_type::to_int_type(__delim); |
427 | const int_type __eof = traits_type::eof(); |
428 | __streambuf_type* __sb = this->rdbuf(); |
429 | int_type __c = __sb->sgetc(); |
430 | |
431 | while (_M_gcount + 1 < __n |
432 | && !traits_type::eq_int_type(__c, __eof) |
433 | && !traits_type::eq_int_type(__c, __idelim)) |
434 | { |
435 | *__s++ = traits_type::to_char_type(__c); |
436 | __c = __sb->snextc(); |
437 | ++_M_gcount; |
438 | } |
439 | if (traits_type::eq_int_type(__c, __eof)) |
440 | __err |= ios_base::eofbit; |
441 | else |
442 | { |
443 | if (traits_type::eq_int_type(__c, __idelim)) |
444 | { |
445 | __sb->sbumpc(); |
446 | ++_M_gcount; |
447 | } |
448 | else |
449 | __err |= ios_base::failbit; |
450 | } |
451 | } |
452 | __catch(__cxxabiv1::__forced_unwind&) |
453 | { |
454 | this->_M_setstate(ios_base::badbit); |
455 | __throw_exception_again; |
456 | } |
457 | __catch(...) |
458 | { this->_M_setstate(ios_base::badbit); } |
459 | } |
460 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
461 | // 243. get and getline when sentry reports failure. |
462 | if (__n > 0) |
463 | *__s = char_type(); |
464 | if (!_M_gcount) |
465 | __err |= ios_base::failbit; |
466 | if (__err) |
467 | this->setstate(__err); |
468 | return *this; |
469 | } |
470 | |
471 | // We provide three overloads, since the first two are much simpler |
472 | // than the general case. Also, the latter two can thus adopt the |
473 | // same "batchy" strategy used by getline above. |
474 | template<typename _CharT, typename _Traits> |
475 | basic_istream<_CharT, _Traits>& |
476 | basic_istream<_CharT, _Traits>:: |
477 | ignore(void) |
478 | { |
479 | _M_gcount = 0; |
480 | sentry __cerb(*this, true); |
481 | if (__cerb) |
482 | { |
483 | ios_base::iostate __err = ios_base::goodbit; |
484 | __try |
485 | { |
486 | const int_type __eof = traits_type::eof(); |
487 | __streambuf_type* __sb = this->rdbuf(); |
488 | |
489 | if (traits_type::eq_int_type(__sb->sbumpc(), __eof)) |
490 | __err |= ios_base::eofbit; |
491 | else |
492 | _M_gcount = 1; |
493 | } |
494 | __catch(__cxxabiv1::__forced_unwind&) |
495 | { |
496 | this->_M_setstate(ios_base::badbit); |
497 | __throw_exception_again; |
498 | } |
499 | __catch(...) |
500 | { this->_M_setstate(ios_base::badbit); } |
501 | if (__err) |
502 | this->setstate(__err); |
503 | } |
504 | return *this; |
505 | } |
506 | |
507 | template<typename _CharT, typename _Traits> |
508 | basic_istream<_CharT, _Traits>& |
509 | basic_istream<_CharT, _Traits>:: |
510 | ignore(streamsize __n) |
511 | { |
512 | _M_gcount = 0; |
513 | sentry __cerb(*this, true); |
514 | if (__cerb && __n > 0) |
515 | { |
516 | ios_base::iostate __err = ios_base::goodbit; |
517 | __try |
518 | { |
519 | const int_type __eof = traits_type::eof(); |
520 | __streambuf_type* __sb = this->rdbuf(); |
521 | int_type __c = __sb->sgetc(); |
522 | |
523 | // N.B. On LFS-enabled platforms streamsize is still 32 bits |
524 | // wide: if we want to implement the standard mandated behavior |
525 | // for n == max() (see 27.6.1.3/24) we are at risk of signed |
526 | // integer overflow: thus these contortions. Also note that, |
527 | // by definition, when more than 2G chars are actually ignored, |
528 | // _M_gcount (the return value of gcount, that is) cannot be |
529 | // really correct, being unavoidably too small. |
530 | bool __large_ignore = false; |
531 | while (true) |
532 | { |
533 | while (_M_gcount < __n |
534 | && !traits_type::eq_int_type(__c, __eof)) |
535 | { |
536 | ++_M_gcount; |
537 | __c = __sb->snextc(); |
538 | } |
539 | if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max |
540 | && !traits_type::eq_int_type(__c, __eof)) |
541 | { |
542 | _M_gcount = |
543 | __gnu_cxx::__numeric_traits<streamsize>::__min; |
544 | __large_ignore = true; |
545 | } |
546 | else |
547 | break; |
548 | } |
549 | |
550 | if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max) |
551 | { |
552 | if (__large_ignore) |
553 | _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; |
554 | |
555 | if (traits_type::eq_int_type(__c, __eof)) |
556 | __err |= ios_base::eofbit; |
557 | } |
558 | else if (_M_gcount < __n) |
559 | { |
560 | if (traits_type::eq_int_type(__c, __eof)) |
561 | __err |= ios_base::eofbit; |
562 | } |
563 | } |
564 | __catch(__cxxabiv1::__forced_unwind&) |
565 | { |
566 | this->_M_setstate(ios_base::badbit); |
567 | __throw_exception_again; |
568 | } |
569 | __catch(...) |
570 | { this->_M_setstate(ios_base::badbit); } |
571 | if (__err) |
572 | this->setstate(__err); |
573 | } |
574 | return *this; |
575 | } |
576 | |
577 | template<typename _CharT, typename _Traits> |
578 | basic_istream<_CharT, _Traits>& |
579 | basic_istream<_CharT, _Traits>:: |
580 | ignore(streamsize __n, int_type __delim) |
581 | { |
582 | _M_gcount = 0; |
583 | sentry __cerb(*this, true); |
584 | if (__cerb && __n > 0) |
585 | { |
586 | ios_base::iostate __err = ios_base::goodbit; |
587 | __try |
588 | { |
589 | const int_type __eof = traits_type::eof(); |
590 | __streambuf_type* __sb = this->rdbuf(); |
591 | int_type __c = __sb->sgetc(); |
592 | |
593 | // See comment above. |
594 | bool __large_ignore = false; |
595 | while (true) |
596 | { |
597 | while (_M_gcount < __n |
598 | && !traits_type::eq_int_type(__c, __eof) |
599 | && !traits_type::eq_int_type(__c, __delim)) |
600 | { |
601 | ++_M_gcount; |
602 | __c = __sb->snextc(); |
603 | } |
604 | if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max |
605 | && !traits_type::eq_int_type(__c, __eof) |
606 | && !traits_type::eq_int_type(__c, __delim)) |
607 | { |
608 | _M_gcount = |
609 | __gnu_cxx::__numeric_traits<streamsize>::__min; |
610 | __large_ignore = true; |
611 | } |
612 | else |
613 | break; |
614 | } |
615 | |
616 | if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max) |
617 | { |
618 | if (__large_ignore) |
619 | _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; |
620 | |
621 | if (traits_type::eq_int_type(__c, __eof)) |
622 | __err |= ios_base::eofbit; |
623 | else |
624 | { |
625 | if (_M_gcount != __n) |
626 | ++_M_gcount; |
627 | __sb->sbumpc(); |
628 | } |
629 | } |
630 | else if (_M_gcount < __n) // implies __c == __delim or EOF |
631 | { |
632 | if (traits_type::eq_int_type(__c, __eof)) |
633 | __err |= ios_base::eofbit; |
634 | else |
635 | { |
636 | ++_M_gcount; |
637 | __sb->sbumpc(); |
638 | } |
639 | } |
640 | } |
641 | __catch(__cxxabiv1::__forced_unwind&) |
642 | { |
643 | this->_M_setstate(ios_base::badbit); |
644 | __throw_exception_again; |
645 | } |
646 | __catch(...) |
647 | { this->_M_setstate(ios_base::badbit); } |
648 | if (__err) |
649 | this->setstate(__err); |
650 | } |
651 | return *this; |
652 | } |
653 | |
654 | template<typename _CharT, typename _Traits> |
655 | typename basic_istream<_CharT, _Traits>::int_type |
656 | basic_istream<_CharT, _Traits>:: |
657 | peek(void) |
658 | { |
659 | int_type __c = traits_type::eof(); |
660 | _M_gcount = 0; |
661 | sentry __cerb(*this, true); |
662 | if (__cerb) |
663 | { |
664 | ios_base::iostate __err = ios_base::goodbit; |
665 | __try |
666 | { |
667 | __c = this->rdbuf()->sgetc(); |
668 | if (traits_type::eq_int_type(__c, traits_type::eof())) |
669 | __err |= ios_base::eofbit; |
670 | } |
671 | __catch(__cxxabiv1::__forced_unwind&) |
672 | { |
673 | this->_M_setstate(ios_base::badbit); |
674 | __throw_exception_again; |
675 | } |
676 | __catch(...) |
677 | { this->_M_setstate(ios_base::badbit); } |
678 | if (__err) |
679 | this->setstate(__err); |
680 | } |
681 | return __c; |
682 | } |
683 | |
684 | template<typename _CharT, typename _Traits> |
685 | basic_istream<_CharT, _Traits>& |
686 | basic_istream<_CharT, _Traits>:: |
687 | read(char_type* __s, streamsize __n) |
688 | { |
689 | _M_gcount = 0; |
690 | sentry __cerb(*this, true); |
691 | if (__cerb) |
692 | { |
693 | ios_base::iostate __err = ios_base::goodbit; |
694 | __try |
695 | { |
696 | _M_gcount = this->rdbuf()->sgetn(__s, __n); |
697 | if (_M_gcount != __n) |
698 | __err |= (ios_base::eofbit | ios_base::failbit); |
699 | } |
700 | __catch(__cxxabiv1::__forced_unwind&) |
701 | { |
702 | this->_M_setstate(ios_base::badbit); |
703 | __throw_exception_again; |
704 | } |
705 | __catch(...) |
706 | { this->_M_setstate(ios_base::badbit); } |
707 | if (__err) |
708 | this->setstate(__err); |
709 | } |
710 | return *this; |
711 | } |
712 | |
713 | template<typename _CharT, typename _Traits> |
714 | streamsize |
715 | basic_istream<_CharT, _Traits>:: |
716 | readsome(char_type* __s, streamsize __n) |
717 | { |
718 | _M_gcount = 0; |
719 | sentry __cerb(*this, true); |
720 | if (__cerb) |
721 | { |
722 | ios_base::iostate __err = ios_base::goodbit; |
723 | __try |
724 | { |
725 | // Cannot compare int_type with streamsize generically. |
726 | const streamsize __num = this->rdbuf()->in_avail(); |
727 | if (__num > 0) |
728 | _M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n)); |
729 | else if (__num == -1) |
730 | __err |= ios_base::eofbit; |
731 | } |
732 | __catch(__cxxabiv1::__forced_unwind&) |
733 | { |
734 | this->_M_setstate(ios_base::badbit); |
735 | __throw_exception_again; |
736 | } |
737 | __catch(...) |
738 | { this->_M_setstate(ios_base::badbit); } |
739 | if (__err) |
740 | this->setstate(__err); |
741 | } |
742 | return _M_gcount; |
743 | } |
744 | |
745 | template<typename _CharT, typename _Traits> |
746 | basic_istream<_CharT, _Traits>& |
747 | basic_istream<_CharT, _Traits>:: |
748 | putback(char_type __c) |
749 | { |
750 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
751 | // 60. What is a formatted input function? |
752 | _M_gcount = 0; |
753 | // Clear eofbit per N3168. |
754 | this->clear(this->rdstate() & ~ios_base::eofbit); |
755 | sentry __cerb(*this, true); |
756 | if (__cerb) |
757 | { |
758 | ios_base::iostate __err = ios_base::goodbit; |
759 | __try |
760 | { |
761 | const int_type __eof = traits_type::eof(); |
762 | __streambuf_type* __sb = this->rdbuf(); |
763 | if (!__sb |
764 | || traits_type::eq_int_type(__sb->sputbackc(__c), __eof)) |
765 | __err |= ios_base::badbit; |
766 | } |
767 | __catch(__cxxabiv1::__forced_unwind&) |
768 | { |
769 | this->_M_setstate(ios_base::badbit); |
770 | __throw_exception_again; |
771 | } |
772 | __catch(...) |
773 | { this->_M_setstate(ios_base::badbit); } |
774 | if (__err) |
775 | this->setstate(__err); |
776 | } |
777 | return *this; |
778 | } |
779 | |
780 | template<typename _CharT, typename _Traits> |
781 | basic_istream<_CharT, _Traits>& |
782 | basic_istream<_CharT, _Traits>:: |
783 | unget(void) |
784 | { |
785 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
786 | // 60. What is a formatted input function? |
787 | _M_gcount = 0; |
788 | // Clear eofbit per N3168. |
789 | this->clear(this->rdstate() & ~ios_base::eofbit); |
790 | sentry __cerb(*this, true); |
791 | if (__cerb) |
792 | { |
793 | ios_base::iostate __err = ios_base::goodbit; |
794 | __try |
795 | { |
796 | const int_type __eof = traits_type::eof(); |
797 | __streambuf_type* __sb = this->rdbuf(); |
798 | if (!__sb |
799 | || traits_type::eq_int_type(__sb->sungetc(), __eof)) |
800 | __err |= ios_base::badbit; |
801 | } |
802 | __catch(__cxxabiv1::__forced_unwind&) |
803 | { |
804 | this->_M_setstate(ios_base::badbit); |
805 | __throw_exception_again; |
806 | } |
807 | __catch(...) |
808 | { this->_M_setstate(ios_base::badbit); } |
809 | if (__err) |
810 | this->setstate(__err); |
811 | } |
812 | return *this; |
813 | } |
814 | |
815 | template<typename _CharT, typename _Traits> |
816 | int |
817 | basic_istream<_CharT, _Traits>:: |
818 | sync(void) |
819 | { |
820 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
821 | // DR60. Do not change _M_gcount. |
822 | int __ret = -1; |
823 | sentry __cerb(*this, true); |
824 | if (__cerb) |
825 | { |
826 | ios_base::iostate __err = ios_base::goodbit; |
827 | __try |
828 | { |
829 | __streambuf_type* __sb = this->rdbuf(); |
830 | if (__sb) |
831 | { |
832 | if (__sb->pubsync() == -1) |
833 | __err |= ios_base::badbit; |
834 | else |
835 | __ret = 0; |
836 | } |
837 | } |
838 | __catch(__cxxabiv1::__forced_unwind&) |
839 | { |
840 | this->_M_setstate(ios_base::badbit); |
841 | __throw_exception_again; |
842 | } |
843 | __catch(...) |
844 | { this->_M_setstate(ios_base::badbit); } |
845 | if (__err) |
846 | this->setstate(__err); |
847 | } |
848 | return __ret; |
849 | } |
850 | |
851 | template<typename _CharT, typename _Traits> |
852 | typename basic_istream<_CharT, _Traits>::pos_type |
853 | basic_istream<_CharT, _Traits>:: |
854 | tellg(void) |
855 | { |
856 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
857 | // DR60. Do not change _M_gcount. |
858 | pos_type __ret = pos_type(-1); |
859 | sentry __cerb(*this, true); |
860 | if (__cerb) |
861 | { |
862 | __try |
863 | { |
864 | if (!this->fail()) |
865 | __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, |
866 | ios_base::in); |
867 | } |
868 | __catch(__cxxabiv1::__forced_unwind&) |
869 | { |
870 | this->_M_setstate(ios_base::badbit); |
871 | __throw_exception_again; |
872 | } |
873 | __catch(...) |
874 | { this->_M_setstate(ios_base::badbit); } |
875 | } |
876 | return __ret; |
877 | } |
878 | |
879 | template<typename _CharT, typename _Traits> |
880 | basic_istream<_CharT, _Traits>& |
881 | basic_istream<_CharT, _Traits>:: |
882 | seekg(pos_type __pos) |
883 | { |
884 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
885 | // DR60. Do not change _M_gcount. |
886 | // Clear eofbit per N3168. |
887 | this->clear(this->rdstate() & ~ios_base::eofbit); |
888 | sentry __cerb(*this, true); |
889 | if (__cerb) |
890 | { |
891 | ios_base::iostate __err = ios_base::goodbit; |
892 | __try |
893 | { |
894 | if (!this->fail()) |
895 | { |
896 | // 136. seekp, seekg setting wrong streams? |
897 | const pos_type __p = this->rdbuf()->pubseekpos(__pos, |
898 | ios_base::in); |
899 | |
900 | // 129. Need error indication from seekp() and seekg() |
901 | if (__p == pos_type(off_type(-1))) |
902 | __err |= ios_base::failbit; |
903 | } |
904 | } |
905 | __catch(__cxxabiv1::__forced_unwind&) |
906 | { |
907 | this->_M_setstate(ios_base::badbit); |
908 | __throw_exception_again; |
909 | } |
910 | __catch(...) |
911 | { this->_M_setstate(ios_base::badbit); } |
912 | if (__err) |
913 | this->setstate(__err); |
914 | } |
915 | return *this; |
916 | } |
917 | |
918 | template<typename _CharT, typename _Traits> |
919 | basic_istream<_CharT, _Traits>& |
920 | basic_istream<_CharT, _Traits>:: |
921 | seekg(off_type __off, ios_base::seekdir __dir) |
922 | { |
923 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
924 | // DR60. Do not change _M_gcount. |
925 | // Clear eofbit per N3168. |
926 | this->clear(this->rdstate() & ~ios_base::eofbit); |
927 | sentry __cerb(*this, true); |
928 | if (__cerb) |
929 | { |
930 | ios_base::iostate __err = ios_base::goodbit; |
931 | __try |
932 | { |
933 | if (!this->fail()) |
934 | { |
935 | // 136. seekp, seekg setting wrong streams? |
936 | const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, |
937 | ios_base::in); |
938 | |
939 | // 129. Need error indication from seekp() and seekg() |
940 | if (__p == pos_type(off_type(-1))) |
941 | __err |= ios_base::failbit; |
942 | } |
943 | } |
944 | __catch(__cxxabiv1::__forced_unwind&) |
945 | { |
946 | this->_M_setstate(ios_base::badbit); |
947 | __throw_exception_again; |
948 | } |
949 | __catch(...) |
950 | { this->_M_setstate(ios_base::badbit); } |
951 | if (__err) |
952 | this->setstate(__err); |
953 | } |
954 | return *this; |
955 | } |
956 | |
957 | // 27.6.1.2.3 Character extraction templates |
958 | template<typename _CharT, typename _Traits> |
959 | basic_istream<_CharT, _Traits>& |
960 | operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c) |
961 | { |
962 | typedef basic_istream<_CharT, _Traits> __istream_type; |
963 | typedef typename __istream_type::int_type __int_type; |
964 | |
965 | typename __istream_type::sentry __cerb(__in, false); |
966 | if (__cerb) |
967 | { |
968 | ios_base::iostate __err = ios_base::goodbit; |
969 | __try |
970 | { |
971 | const __int_type __cb = __in.rdbuf()->sbumpc(); |
972 | if (!_Traits::eq_int_type(__cb, _Traits::eof())) |
973 | __c = _Traits::to_char_type(__cb); |
974 | else |
975 | __err |= (ios_base::eofbit | ios_base::failbit); |
976 | } |
977 | __catch(__cxxabiv1::__forced_unwind&) |
978 | { |
979 | __in._M_setstate(ios_base::badbit); |
980 | __throw_exception_again; |
981 | } |
982 | __catch(...) |
983 | { __in._M_setstate(ios_base::badbit); } |
984 | if (__err) |
985 | __in.setstate(__err); |
986 | } |
987 | return __in; |
988 | } |
989 | |
990 | template<typename _CharT, typename _Traits> |
991 | void |
992 | (basic_istream<_CharT, _Traits>& __in, _CharT* __s, |
993 | streamsize __num) |
994 | { |
995 | typedef basic_istream<_CharT, _Traits> __istream_type; |
996 | typedef basic_streambuf<_CharT, _Traits> __streambuf_type; |
997 | typedef typename _Traits::int_type int_type; |
998 | typedef _CharT char_type; |
999 | typedef ctype<_CharT> __ctype_type; |
1000 | |
1001 | streamsize = 0; |
1002 | ios_base::iostate __err = ios_base::goodbit; |
1003 | typename __istream_type::sentry __cerb(__in, false); |
1004 | if (__cerb) |
1005 | { |
1006 | __try |
1007 | { |
1008 | // Figure out how many characters to extract. |
1009 | streamsize __width = __in.width(); |
1010 | if (0 < __width && __width < __num) |
1011 | __num = __width; |
1012 | |
1013 | const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); |
1014 | |
1015 | const int_type __eof = _Traits::eof(); |
1016 | __streambuf_type* __sb = __in.rdbuf(); |
1017 | int_type __c = __sb->sgetc(); |
1018 | |
1019 | while (__extracted < __num - 1 |
1020 | && !_Traits::eq_int_type(__c, __eof) |
1021 | && !__ct.is(ctype_base::space, |
1022 | _Traits::to_char_type(__c))) |
1023 | { |
1024 | *__s++ = _Traits::to_char_type(__c); |
1025 | ++__extracted; |
1026 | __c = __sb->snextc(); |
1027 | } |
1028 | |
1029 | if (__extracted < __num - 1 |
1030 | && _Traits::eq_int_type(__c, __eof)) |
1031 | __err |= ios_base::eofbit; |
1032 | |
1033 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1034 | // 68. Extractors for char* should store null at end |
1035 | *__s = char_type(); |
1036 | __in.width(0); |
1037 | } |
1038 | __catch(__cxxabiv1::__forced_unwind&) |
1039 | { |
1040 | __in._M_setstate(ios_base::badbit); |
1041 | __throw_exception_again; |
1042 | } |
1043 | __catch(...) |
1044 | { __in._M_setstate(ios_base::badbit); } |
1045 | } |
1046 | if (!__extracted) |
1047 | __err |= ios_base::failbit; |
1048 | if (__err) |
1049 | __in.setstate(__err); |
1050 | } |
1051 | |
1052 | // 27.6.1.4 Standard basic_istream manipulators |
1053 | template<typename _CharT, typename _Traits> |
1054 | basic_istream<_CharT, _Traits>& |
1055 | ws(basic_istream<_CharT, _Traits>& __in) |
1056 | { |
1057 | typedef basic_istream<_CharT, _Traits> __istream_type; |
1058 | typedef basic_streambuf<_CharT, _Traits> __streambuf_type; |
1059 | typedef typename __istream_type::int_type __int_type; |
1060 | typedef ctype<_CharT> __ctype_type; |
1061 | |
1062 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
1063 | // 451. behavior of std::ws |
1064 | typename __istream_type::sentry __cerb(__in, true); |
1065 | if (__cerb) |
1066 | { |
1067 | ios_base::iostate __err = ios_base::goodbit; |
1068 | __try |
1069 | { |
1070 | const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); |
1071 | const __int_type __eof = _Traits::eof(); |
1072 | __streambuf_type* __sb = __in.rdbuf(); |
1073 | __int_type __c = __sb->sgetc(); |
1074 | |
1075 | while (true) |
1076 | { |
1077 | if (_Traits::eq_int_type(__c, __eof)) |
1078 | { |
1079 | __err = ios_base::eofbit; |
1080 | break; |
1081 | } |
1082 | if (!__ct.is(ctype_base::space, _Traits::to_char_type(__c))) |
1083 | break; |
1084 | __c = __sb->snextc(); |
1085 | } |
1086 | } |
1087 | __catch (const __cxxabiv1::__forced_unwind&) |
1088 | { |
1089 | __in._M_setstate(ios_base::badbit); |
1090 | __throw_exception_again; |
1091 | } |
1092 | __catch (...) |
1093 | { |
1094 | __in._M_setstate(ios_base::badbit); |
1095 | } |
1096 | if (__err) |
1097 | __in.setstate(__err); |
1098 | } |
1099 | return __in; |
1100 | } |
1101 | |
1102 | // Inhibit implicit instantiations for required instantiations, |
1103 | // which are defined via explicit instantiations elsewhere. |
1104 | #if _GLIBCXX_EXTERN_TEMPLATE |
1105 | extern template class basic_istream<char>; |
1106 | extern template istream& ws(istream&); |
1107 | extern template istream& operator>>(istream&, char&); |
1108 | extern template istream& operator>>(istream&, unsigned char&); |
1109 | extern template istream& operator>>(istream&, signed char&); |
1110 | |
1111 | extern template istream& istream::_M_extract(unsigned short&); |
1112 | extern template istream& istream::_M_extract(unsigned int&); |
1113 | extern template istream& istream::_M_extract(long&); |
1114 | extern template istream& istream::_M_extract(unsigned long&); |
1115 | extern template istream& istream::_M_extract(bool&); |
1116 | #ifdef _GLIBCXX_USE_LONG_LONG |
1117 | extern template istream& istream::_M_extract(long long&); |
1118 | extern template istream& istream::_M_extract(unsigned long long&); |
1119 | #endif |
1120 | extern template istream& istream::_M_extract(float&); |
1121 | extern template istream& istream::_M_extract(double&); |
1122 | extern template istream& istream::_M_extract(long double&); |
1123 | extern template istream& istream::_M_extract(void*&); |
1124 | |
1125 | extern template class basic_iostream<char>; |
1126 | |
1127 | #ifdef _GLIBCXX_USE_WCHAR_T |
1128 | extern template class basic_istream<wchar_t>; |
1129 | extern template wistream& ws(wistream&); |
1130 | extern template wistream& operator>>(wistream&, wchar_t&); |
1131 | extern template void __istream_extract(wistream&, wchar_t*, streamsize); |
1132 | |
1133 | extern template wistream& wistream::_M_extract(unsigned short&); |
1134 | extern template wistream& wistream::_M_extract(unsigned int&); |
1135 | extern template wistream& wistream::_M_extract(long&); |
1136 | extern template wistream& wistream::_M_extract(unsigned long&); |
1137 | extern template wistream& wistream::_M_extract(bool&); |
1138 | #ifdef _GLIBCXX_USE_LONG_LONG |
1139 | extern template wistream& wistream::_M_extract(long long&); |
1140 | extern template wistream& wistream::_M_extract(unsigned long long&); |
1141 | #endif |
1142 | extern template wistream& wistream::_M_extract(float&); |
1143 | extern template wistream& wistream::_M_extract(double&); |
1144 | extern template wistream& wistream::_M_extract(long double&); |
1145 | extern template wistream& wistream::_M_extract(void*&); |
1146 | |
1147 | extern template class basic_iostream<wchar_t>; |
1148 | #endif |
1149 | #endif |
1150 | |
1151 | _GLIBCXX_END_NAMESPACE_VERSION |
1152 | } // namespace std |
1153 | |
1154 | #endif |
1155 | |