xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/istream.tcc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 // istream classes -*- C++ -*-
2 
3 // Copyright (C) 1997-2022 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file bits/istream.tcc
26  *  This is an internal header file, included by other library headers.
27  *  Do not attempt to use it directly. @headername{istream}
28  */
29 
30 //
31 // ISO C++ 14882: 27.6.1  Input streams
32 //
33 
34 #ifndef _ISTREAM_TCC
35 #define _ISTREAM_TCC 1
36 
37 #pragma GCC system_header
38 
39 #include <bits/cxxabi_forced.h>
40 
41 namespace std _GLIBCXX_VISIBILITY(default)
42 {
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
44 
45   template<typename _CharT, typename _Traits>
46     basic_istream<_CharT, _Traits>::sentry::
sentry(basic_istream<_CharT,_Traits> & __in,bool __noskip)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>::
_M_extract(_ValueT & __v)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>::
operator >>(short & __n)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>::
operator >>(int & __n)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>::
operator >>(__streambuf_type * __sbout)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>::
get(void)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>::
get(char_type & __c)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>::
get(char_type * __s,streamsize __n,char_type __delim)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>::
get(__streambuf_type & __sb,char_type __delim)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>::
getline(char_type * __s,streamsize __n,char_type __delim)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>::
ignore(void)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>::
ignore(streamsize __n)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>::
ignore(streamsize __n,int_type __delim)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>::
peek(void)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>::
read(char_type * __s,streamsize __n)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>::
readsome(char_type * __s,streamsize __n)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(__num, __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>::
putback(char_type __c)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>::
unget(void)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>::
sync(void)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>::
tellg(void)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>::
seekg(pos_type __pos)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>::
seekg(off_type __off,ios_base::seekdir __dir)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>&
operator >>(basic_istream<_CharT,_Traits> & __in,_CharT & __c)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
__istream_extract(basic_istream<_CharT,_Traits> & __in,_CharT * __s,streamsize __num)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>&
ws(basic_istream<_CharT,_Traits> & __in)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