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

source code of include/c++/11/bits/istream.tcc