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