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