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