istream.tcc revision 146897
1// istream classes -*- C++ -*-
2
3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
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.1  Input streams
33//
34
35#ifndef _ISTREAM_TCC
36#define _ISTREAM_TCC 1
37
38#pragma GCC system_header
39
40#include <locale>
41#include <ostream> // For flush()
42
43namespace 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::iostate(ios_base::goodbit);
50      if (__in.good())
51	{
52	  if (__in.tie())
53	    __in.tie()->flush();
54	  if (!__noskip && (__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    basic_istream<_CharT, _Traits>&
85    basic_istream<_CharT, _Traits>::
86    operator>>(__istream_type& (*__pf)(__istream_type&))
87    { return __pf(*this); }
88
89  template<typename _CharT, typename _Traits>
90    basic_istream<_CharT, _Traits>&
91    basic_istream<_CharT, _Traits>::
92    operator>>(__ios_type& (*__pf)(__ios_type&))
93    {
94      __pf(*this);
95      return *this;
96    }
97
98  template<typename _CharT, typename _Traits>
99    basic_istream<_CharT, _Traits>&
100    basic_istream<_CharT, _Traits>::
101    operator>>(ios_base& (*__pf)(ios_base&))
102    {
103      __pf(*this);
104      return *this;
105    }
106
107  template<typename _CharT, typename _Traits>
108    basic_istream<_CharT, _Traits>&
109    basic_istream<_CharT, _Traits>::
110    operator>>(bool& __n)
111    {
112      sentry __cerb(*this, false);
113      if (__cerb)
114	{
115	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
116	  try
117	    {
118	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
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>::
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	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
142	      __ng.get(*this, 0, *this, __err, __l);
143	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
144	      // 118. basic_istream uses nonexistent num_get member functions.
145	      if (!(__err & ios_base::failbit)
146		  && (numeric_limits<short>::min() <= __l
147		      && __l <= numeric_limits<short>::max()))
148		__n = __l;
149	      else
150                __err |= ios_base::failbit;
151	    }
152	  catch(...)
153	    { this->_M_setstate(ios_base::badbit); }
154	  if (__err)
155	    this->setstate(__err);
156	}
157      return *this;
158    }
159
160  template<typename _CharT, typename _Traits>
161    basic_istream<_CharT, _Traits>&
162    basic_istream<_CharT, _Traits>::
163    operator>>(unsigned short& __n)
164    {
165      sentry __cerb(*this, false);
166      if (__cerb)
167	{
168	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
169	  try
170	    {
171	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
172	      __ng.get(*this, 0, *this, __err, __n);
173	    }
174	  catch(...)
175	    { this->_M_setstate(ios_base::badbit); }
176	  if (__err)
177	    this->setstate(__err);
178	}
179      return *this;
180    }
181
182  template<typename _CharT, typename _Traits>
183    basic_istream<_CharT, _Traits>&
184    basic_istream<_CharT, _Traits>::
185    operator>>(int& __n)
186    {
187      sentry __cerb(*this, false);
188      if (__cerb)
189	{
190	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
191	  try
192	    {
193	      long __l;
194	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
195	      __ng.get(*this, 0, *this, __err, __l);
196	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
197	      // 118. basic_istream uses nonexistent num_get member functions.
198	      if (!(__err & ios_base::failbit)
199		  && (numeric_limits<int>::min() <= __l
200		      && __l <= numeric_limits<int>::max()))
201		__n = __l;
202	      else
203                __err |= ios_base::failbit;
204	    }
205	  catch(...)
206	    { this->_M_setstate(ios_base::badbit); }
207	  if (__err)
208	    this->setstate(__err);
209	}
210      return *this;
211    }
212
213  template<typename _CharT, typename _Traits>
214    basic_istream<_CharT, _Traits>&
215    basic_istream<_CharT, _Traits>::
216    operator>>(unsigned int& __n)
217    {
218      sentry __cerb(*this, false);
219      if (__cerb)
220	{
221	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
222	  try
223	    {
224	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
225	      __ng.get(*this, 0, *this, __err, __n);
226	    }
227	  catch(...)
228	    { this->_M_setstate(ios_base::badbit); }
229	  if (__err)
230	    this->setstate(__err);
231	}
232      return *this;
233    }
234
235  template<typename _CharT, typename _Traits>
236    basic_istream<_CharT, _Traits>&
237    basic_istream<_CharT, _Traits>::
238    operator>>(long& __n)
239    {
240      sentry __cerb(*this, false);
241      if (__cerb)
242	{
243	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
244	  try
245	    {
246	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
247	      __ng.get(*this, 0, *this, __err, __n);
248	    }
249	  catch(...)
250	    { this->_M_setstate(ios_base::badbit); }
251	  if (__err)
252	    this->setstate(__err);
253	}
254      return *this;
255    }
256
257  template<typename _CharT, typename _Traits>
258    basic_istream<_CharT, _Traits>&
259    basic_istream<_CharT, _Traits>::
260    operator>>(unsigned long& __n)
261    {
262      sentry __cerb(*this, false);
263      if (__cerb)
264	{
265	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
266	  try
267	    {
268	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
269	      __ng.get(*this, 0, *this, __err, __n);
270	    }
271	  catch(...)
272	    { this->_M_setstate(ios_base::badbit); }
273	  if (__err)
274	    this->setstate(__err);
275	}
276      return *this;
277    }
278
279#ifdef _GLIBCXX_USE_LONG_LONG
280  template<typename _CharT, typename _Traits>
281    basic_istream<_CharT, _Traits>&
282    basic_istream<_CharT, _Traits>::
283    operator>>(long long& __n)
284    {
285      sentry __cerb(*this, false);
286      if (__cerb)
287	{
288	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
289	  try
290	    {
291	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
292	      __ng.get(*this, 0, *this, __err, __n);
293	    }
294	  catch(...)
295	    { this->_M_setstate(ios_base::badbit); }
296	  if (__err)
297	    this->setstate(__err);
298	}
299      return *this;
300    }
301
302  template<typename _CharT, typename _Traits>
303    basic_istream<_CharT, _Traits>&
304    basic_istream<_CharT, _Traits>::
305    operator>>(unsigned long long& __n)
306    {
307      sentry __cerb(*this, false);
308      if (__cerb)
309	{
310	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
311	  try
312	    {
313	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
314	      __ng.get(*this, 0, *this, __err, __n);
315	    }
316	  catch(...)
317	    { this->_M_setstate(ios_base::badbit); }
318	  if (__err)
319	    this->setstate(__err);
320	}
321      return *this;
322    }
323#endif
324
325  template<typename _CharT, typename _Traits>
326    basic_istream<_CharT, _Traits>&
327    basic_istream<_CharT, _Traits>::
328    operator>>(float& __n)
329    {
330      sentry __cerb(*this, false);
331      if (__cerb)
332	{
333	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
334	  try
335	    {
336	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
337	      __ng.get(*this, 0, *this, __err, __n);
338	    }
339	  catch(...)
340	    { this->_M_setstate(ios_base::badbit); }
341	  if (__err)
342	    this->setstate(__err);
343	}
344      return *this;
345    }
346
347  template<typename _CharT, typename _Traits>
348    basic_istream<_CharT, _Traits>&
349    basic_istream<_CharT, _Traits>::
350    operator>>(double& __n)
351    {
352      sentry __cerb(*this, false);
353      if (__cerb)
354	{
355	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
356	  try
357	    {
358	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
359	      __ng.get(*this, 0, *this, __err, __n);
360	    }
361	  catch(...)
362	    { this->_M_setstate(ios_base::badbit); }
363	  if (__err)
364	    this->setstate(__err);
365	}
366      return *this;
367    }
368
369  template<typename _CharT, typename _Traits>
370    basic_istream<_CharT, _Traits>&
371    basic_istream<_CharT, _Traits>::
372    operator>>(long double& __n)
373    {
374      sentry __cerb(*this, false);
375      if (__cerb)
376	{
377	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
378	  try
379	    {
380	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
381	      __ng.get(*this, 0, *this, __err, __n);
382	    }
383	  catch(...)
384	    { this->_M_setstate(ios_base::badbit); }
385	  if (__err)
386	    this->setstate(__err);
387	}
388      return *this;
389    }
390
391  template<typename _CharT, typename _Traits>
392    basic_istream<_CharT, _Traits>&
393    basic_istream<_CharT, _Traits>::
394    operator>>(void*& __n)
395    {
396      sentry __cerb(*this, false);
397      if (__cerb)
398	{
399	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
400	  try
401	    {
402	      const __num_get_type& __ng = __check_facet(this->_M_num_get);
403	      __ng.get(*this, 0, *this, __err, __n);
404	    }
405	  catch(...)
406	    { this->_M_setstate(ios_base::badbit); }
407	  if (__err)
408	    this->setstate(__err);
409	}
410      return *this;
411    }
412
413  template<typename _CharT, typename _Traits>
414    basic_istream<_CharT, _Traits>&
415    basic_istream<_CharT, _Traits>::
416    operator>>(__streambuf_type* __sbout)
417    {
418      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
419      sentry __cerb(*this, false);
420      if (__cerb && __sbout)
421	{
422	  try
423	    {
424	      if (!__copy_streambufs(this->rdbuf(), __sbout))
425		__err |= ios_base::failbit;
426	    }
427	  catch(...)
428	    { this->_M_setstate(ios_base::failbit); }
429	}
430      else if (!__sbout)
431	__err |= ios_base::failbit;
432      if (__err)
433	this->setstate(__err);
434      return *this;
435    }
436
437  template<typename _CharT, typename _Traits>
438    typename basic_istream<_CharT, _Traits>::int_type
439    basic_istream<_CharT, _Traits>::
440    get(void)
441    {
442      const int_type __eof = traits_type::eof();
443      int_type __c = __eof;
444      _M_gcount = 0;
445      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
446      sentry __cerb(*this, true);
447      if (__cerb)
448	{
449	  try
450	    {
451	      __c = this->rdbuf()->sbumpc();
452	      // 27.6.1.1 paragraph 3
453	      if (!traits_type::eq_int_type(__c, __eof))
454		_M_gcount = 1;
455	      else
456		__err |= ios_base::eofbit;
457	    }
458	  catch(...)
459	    { this->_M_setstate(ios_base::badbit); }
460	}
461      if (!_M_gcount)
462	__err |= ios_base::failbit;
463      if (__err)
464	this->setstate(__err);
465      return __c;
466    }
467
468  template<typename _CharT, typename _Traits>
469    basic_istream<_CharT, _Traits>&
470    basic_istream<_CharT, _Traits>::
471    get(char_type& __c)
472    {
473      _M_gcount = 0;
474      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
475      sentry __cerb(*this, true);
476      if (__cerb)
477	{
478	  try
479	    {
480	      const int_type __cb = this->rdbuf()->sbumpc();
481	      // 27.6.1.1 paragraph 3
482	      if (!traits_type::eq_int_type(__cb, traits_type::eof()))
483		{
484		  _M_gcount = 1;
485		  __c = traits_type::to_char_type(__cb);
486		}
487	      else
488		__err |= ios_base::eofbit;
489	    }
490	  catch(...)
491	    { this->_M_setstate(ios_base::badbit); }
492	}
493      if (!_M_gcount)
494	__err |= ios_base::failbit;
495      if (__err)
496	this->setstate(__err);
497      return *this;
498    }
499
500  template<typename _CharT, typename _Traits>
501    basic_istream<_CharT, _Traits>&
502    basic_istream<_CharT, _Traits>::
503    get(char_type* __s, streamsize __n, char_type __delim)
504    {
505      _M_gcount = 0;
506      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
507      sentry __cerb(*this, true);
508      if (__cerb)
509	{
510	  try
511	    {
512	      const int_type __idelim = traits_type::to_int_type(__delim);
513	      const int_type __eof = traits_type::eof();
514	      __streambuf_type* __sb = this->rdbuf();
515	      int_type __c = __sb->sgetc();
516
517	      while (_M_gcount + 1 < __n
518		     && !traits_type::eq_int_type(__c, __eof)
519		     && !traits_type::eq_int_type(__c, __idelim))
520		{
521		  *__s++ = traits_type::to_char_type(__c);
522		  ++_M_gcount;
523		  __c = __sb->snextc();
524		}
525	      if (traits_type::eq_int_type(__c, __eof))
526		__err |= ios_base::eofbit;
527	    }
528	  catch(...)
529	    { this->_M_setstate(ios_base::badbit); }
530	}
531      *__s = char_type();
532      if (!_M_gcount)
533	__err |= ios_base::failbit;
534      if (__err)
535	this->setstate(__err);
536      return *this;
537    }
538
539  template<typename _CharT, typename _Traits>
540    basic_istream<_CharT, _Traits>&
541    basic_istream<_CharT, _Traits>::
542    get(__streambuf_type& __sb, char_type __delim)
543    {
544      _M_gcount = 0;
545      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
546      sentry __cerb(*this, true);
547      if (__cerb)
548	{
549	  try
550	    {
551	      const int_type __idelim = traits_type::to_int_type(__delim);
552	      const int_type __eof = traits_type::eof();
553	      __streambuf_type* __this_sb = this->rdbuf();
554	      int_type __c = __this_sb->sgetc();
555	      char_type __c2 = traits_type::to_char_type(__c);
556
557	      while (!traits_type::eq_int_type(__c, __eof)
558		     && !traits_type::eq_int_type(__c, __idelim)
559		     && !traits_type::eq_int_type(__sb.sputc(__c2), __eof))
560		{
561		  ++_M_gcount;
562		  __c = __this_sb->snextc();
563		  __c2 = traits_type::to_char_type(__c);
564		}
565	      if (traits_type::eq_int_type(__c, __eof))
566		__err |= ios_base::eofbit;
567	    }
568	  catch(...)
569	    { this->_M_setstate(ios_base::badbit); }
570	}
571      if (!_M_gcount)
572	__err |= ios_base::failbit;
573      if (__err)
574	this->setstate(__err);
575      return *this;
576    }
577
578  template<typename _CharT, typename _Traits>
579    basic_istream<_CharT, _Traits>&
580    basic_istream<_CharT, _Traits>::
581    getline(char_type* __s, streamsize __n, char_type __delim)
582    {
583      _M_gcount = 0;
584      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
585      sentry __cerb(*this, true);
586      if (__cerb)
587	{
588          try
589	    {
590	      const int_type __idelim = traits_type::to_int_type(__delim);
591	      const int_type __eof = traits_type::eof();
592	      __streambuf_type* __sb = this->rdbuf();
593	      int_type __c = __sb->sgetc();
594	      
595	      while (_M_gcount + 1 < __n
596		     && !traits_type::eq_int_type(__c, __eof)
597		     && !traits_type::eq_int_type(__c, __idelim))
598		{
599		  streamsize __size = std::min(streamsize(__sb->egptr()
600							  - __sb->gptr()),
601					       __n - _M_gcount - 1);
602		  if (__size > 1)
603		    {
604		      const char_type* __p = traits_type::find(__sb->gptr(),
605							       __size,
606							       __delim);
607		      if (__p)
608			__size = __p - __sb->gptr();
609		      traits_type::copy(__s, __sb->gptr(), __size);
610		      __s += __size;
611		      __sb->gbump(__size);
612		      _M_gcount += __size;
613		      __c = __sb->sgetc();
614		    }
615		  else
616		    {
617		      *__s++ = traits_type::to_char_type(__c);
618		      ++_M_gcount;
619		      __c = __sb->snextc();
620		    }
621		}
622
623	      if (traits_type::eq_int_type(__c, __eof))
624		__err |= ios_base::eofbit;
625	      else if (traits_type::eq_int_type(__c, __idelim))
626		{
627		  ++_M_gcount;		  
628		  __sb->sbumpc();
629		}
630	      else
631		__err |= ios_base::failbit;
632	    }
633	  catch(...)
634	    { this->_M_setstate(ios_base::badbit); }
635	}
636      *__s = char_type();
637      if (!_M_gcount)
638	__err |= ios_base::failbit;
639      if (__err)
640	this->setstate(__err);
641      return *this;
642    }
643
644  template<typename _CharT, typename _Traits>
645    basic_istream<_CharT, _Traits>&
646    basic_istream<_CharT, _Traits>::
647    ignore(streamsize __n, int_type __delim)
648    {
649      _M_gcount = 0;
650      sentry __cerb(*this, true);
651      if (__cerb && __n > 0)
652	{
653	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
654	  try
655	    {
656	      const int_type __eof = traits_type::eof();
657	      __streambuf_type* __sb = this->rdbuf();
658	      int_type __c;
659
660	      if (__n != numeric_limits<streamsize>::max())
661		--__n;
662	      while (_M_gcount <= __n
663		     && !traits_type::eq_int_type(__c = __sb->sbumpc(), __eof))
664		{
665		  ++_M_gcount;
666		  if (traits_type::eq_int_type(__c, __delim))
667		    break;
668		}
669	      if (traits_type::eq_int_type(__c, __eof))
670		__err |= ios_base::eofbit;
671	    }
672	  catch(...)
673	    { this->_M_setstate(ios_base::badbit); }
674	  if (__err)
675	    this->setstate(__err);
676	}
677      return *this;
678    }
679
680  template<typename _CharT, typename _Traits>
681    typename basic_istream<_CharT, _Traits>::int_type
682    basic_istream<_CharT, _Traits>::
683    peek(void)
684    {
685      int_type __c = traits_type::eof();
686      _M_gcount = 0;
687      sentry __cerb(*this, true);
688      if (__cerb)
689	{
690	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
691	  try
692	    {
693	      __c = this->rdbuf()->sgetc();
694	      if (traits_type::eq_int_type(__c, traits_type::eof()))
695		__err |= ios_base::eofbit;
696	    }
697	  catch(...)
698	    { this->_M_setstate(ios_base::badbit); }
699	  if (__err)
700	    this->setstate(__err);
701	}
702      return __c;
703    }
704
705  template<typename _CharT, typename _Traits>
706    basic_istream<_CharT, _Traits>&
707    basic_istream<_CharT, _Traits>::
708    read(char_type* __s, streamsize __n)
709    {
710      _M_gcount = 0;
711      sentry __cerb(*this, true);
712      if (__cerb)
713	{
714	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
715	  try
716	    {
717	      _M_gcount = this->rdbuf()->sgetn(__s, __n);
718	      if (_M_gcount != __n)
719		__err |= (ios_base::eofbit | ios_base::failbit);
720	    }
721	  catch(...)
722	    { this->_M_setstate(ios_base::badbit); }
723	  if (__err)
724	    this->setstate(__err);
725	}
726      return *this;
727    }
728
729  template<typename _CharT, typename _Traits>
730    streamsize
731    basic_istream<_CharT, _Traits>::
732    readsome(char_type* __s, streamsize __n)
733    {
734      _M_gcount = 0;
735      sentry __cerb(*this, true);
736      if (__cerb)
737	{
738	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
739	  try
740	    {
741	      // Cannot compare int_type with streamsize generically.
742	      const streamsize __num = this->rdbuf()->in_avail();
743	      if (__num > 0)
744		_M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n));
745	      else if (__num == -1)
746		__err |= ios_base::eofbit;
747	    }
748	  catch(...)
749	    { this->_M_setstate(ios_base::badbit); }
750	  if (__err)
751	    this->setstate(__err);
752	}
753      return _M_gcount;
754    }
755
756  template<typename _CharT, typename _Traits>
757    basic_istream<_CharT, _Traits>&
758    basic_istream<_CharT, _Traits>::
759    putback(char_type __c)
760    {
761      // _GLIBCXX_RESOLVE_LIB_DEFECTS
762      // 60. What is a formatted input function?
763      _M_gcount = 0;
764      sentry __cerb(*this, true);
765      if (__cerb)
766	{
767	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
768	  try
769	    {
770	      const int_type __eof = traits_type::eof();
771	      __streambuf_type* __sb = this->rdbuf();
772	      if (!__sb
773		  || traits_type::eq_int_type(__sb->sputbackc(__c), __eof))
774		__err |= ios_base::badbit;
775	    }
776	  catch(...)
777	    { this->_M_setstate(ios_base::badbit); }
778	  if (__err)
779	    this->setstate(__err);
780	}
781      return *this;
782    }
783
784  template<typename _CharT, typename _Traits>
785    basic_istream<_CharT, _Traits>&
786    basic_istream<_CharT, _Traits>::
787    unget(void)
788    {
789      // _GLIBCXX_RESOLVE_LIB_DEFECTS
790      // 60. What is a formatted input function?
791      _M_gcount = 0;
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>::
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>::
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  template<typename _CharT, typename _Traits>
862    basic_istream<_CharT, _Traits>&
863    basic_istream<_CharT, _Traits>::
864    seekg(pos_type __pos)
865    {
866      // _GLIBCXX_RESOLVE_LIB_DEFECTS
867      // DR60.  Do not change _M_gcount.
868      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
869      try
870	{
871	  if (!this->fail())
872	    {
873	      // 136.  seekp, seekg setting wrong streams?
874	      const pos_type __p = this->rdbuf()->pubseekpos(__pos,
875							     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>::
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	      const 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>&
920    operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c)
921    {
922      typedef basic_istream<_CharT, _Traits>		__istream_type;
923      typedef typename __istream_type::int_type         __int_type;
924
925      typename __istream_type::sentry __cerb(__in, false);
926      if (__cerb)
927	{
928	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
929	  try
930	    {
931	      const __int_type __cb = __in.rdbuf()->sbumpc();
932	      if (!_Traits::eq_int_type(__cb, _Traits::eof()))
933		__c = _Traits::to_char_type(__cb);
934	      else
935		__err |= (ios_base::eofbit | ios_base::failbit);
936	    }
937	  catch(...)
938	    { __in._M_setstate(ios_base::badbit); }
939	  if (__err)
940	    __in.setstate(__err);
941	}
942      return __in;
943    }
944
945  template<typename _CharT, typename _Traits>
946    basic_istream<_CharT, _Traits>&
947    operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s)
948    {
949      typedef basic_istream<_CharT, _Traits>		__istream_type;
950      typedef typename __istream_type::__streambuf_type __streambuf_type;
951      typedef typename _Traits::int_type		int_type;
952      typedef _CharT					char_type;
953      typedef ctype<_CharT>				__ctype_type;
954
955      streamsize __extracted = 0;
956      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
957      typename __istream_type::sentry __cerb(__in, false);
958      if (__cerb)
959	{
960	  try
961	    {
962	      // Figure out how many characters to extract.
963	      streamsize __num = __in.width();
964	      if (__num <= 0)
965		__num = numeric_limits<streamsize>::max();
966
967	      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
968
969	      const int_type __eof = _Traits::eof();
970	      __streambuf_type* __sb = __in.rdbuf();
971	      int_type __c = __sb->sgetc();
972
973	      while (__extracted < __num - 1
974		     && !_Traits::eq_int_type(__c, __eof)
975		     && !__ct.is(ctype_base::space,
976				 _Traits::to_char_type(__c)))
977		{
978		  *__s++ = _Traits::to_char_type(__c);
979		  ++__extracted;
980		  __c = __sb->snextc();
981		}
982	      if (_Traits::eq_int_type(__c, __eof))
983		__err |= ios_base::eofbit;
984
985	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
986	      // 68.  Extractors for char* should store null at end
987	      *__s = char_type();
988	      __in.width(0);
989	    }
990	  catch(...)
991	    { __in._M_setstate(ios_base::badbit); }
992	}
993      if (!__extracted)
994	__err |= ios_base::failbit;
995      if (__err)
996	__in.setstate(__err);
997      return __in;
998    }
999
1000  // 27.6.1.4 Standard basic_istream manipulators
1001  template<typename _CharT, typename _Traits>
1002    basic_istream<_CharT,_Traits>&
1003    ws(basic_istream<_CharT,_Traits>& __in)
1004    {
1005      typedef basic_istream<_CharT, _Traits>		__istream_type;
1006      typedef typename __istream_type::__streambuf_type __streambuf_type;
1007      typedef typename __istream_type::__ctype_type	__ctype_type;
1008      typedef typename __istream_type::int_type		__int_type;
1009
1010      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
1011      const __int_type __eof = _Traits::eof();
1012      __streambuf_type* __sb = __in.rdbuf();
1013      __int_type __c = __sb->sgetc();
1014
1015      while (!_Traits::eq_int_type(__c, __eof)
1016	     && __ct.is(ctype_base::space, _Traits::to_char_type(__c)))
1017	__c = __sb->snextc();
1018
1019       if (_Traits::eq_int_type(__c, __eof))
1020	 __in.setstate(ios_base::eofbit);
1021      return __in;
1022    }
1023
1024  // 21.3.7.9 basic_string::getline and operators
1025  template<typename _CharT, typename _Traits, typename _Alloc>
1026    basic_istream<_CharT, _Traits>&
1027    operator>>(basic_istream<_CharT, _Traits>& __in,
1028	       basic_string<_CharT, _Traits, _Alloc>& __str)
1029    {
1030      typedef basic_istream<_CharT, _Traits>		__istream_type;
1031      typedef typename __istream_type::int_type		__int_type;
1032      typedef typename __istream_type::__streambuf_type __streambuf_type;
1033      typedef typename __istream_type::__ctype_type	__ctype_type;
1034      typedef basic_string<_CharT, _Traits, _Alloc>	__string_type;
1035      typedef typename __string_type::size_type		__size_type;
1036
1037      __size_type __extracted = 0;
1038      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
1039      typename __istream_type::sentry __cerb(__in, false);
1040      if (__cerb)
1041	{
1042	  try
1043	    {
1044	      // Avoid reallocation for common case.
1045	      __str.erase();
1046	      _CharT __buf[128];
1047	      __size_type __len = 0;	      
1048	      const streamsize __w = __in.width();
1049	      const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
1050		                              : __str.max_size();
1051	      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
1052	      const __int_type __eof = _Traits::eof();
1053	      __streambuf_type* __sb = __in.rdbuf();
1054	      __int_type __c = __sb->sgetc();
1055
1056	      while (__extracted < __n
1057		     && !_Traits::eq_int_type(__c, __eof)
1058		     && !__ct.is(ctype_base::space, _Traits::to_char_type(__c)))
1059		{
1060		  if (__len == sizeof(__buf) / sizeof(_CharT))
1061		    {
1062		      __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
1063		      __len = 0;
1064		    }
1065		  __buf[__len++] = _Traits::to_char_type(__c);
1066		  ++__extracted;
1067		  __c = __sb->snextc();
1068		}
1069	      __str.append(__buf, __len);
1070
1071	      if (_Traits::eq_int_type(__c, __eof))
1072		__err |= ios_base::eofbit;
1073	      __in.width(0);
1074	    }
1075	  catch(...)
1076	    {
1077	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1078	      // 91. Description of operator>> and getline() for string<>
1079	      // might cause endless loop
1080	      __in._M_setstate(ios_base::badbit);
1081	    }
1082	}
1083      // 211.  operator>>(istream&, string&) doesn't set failbit
1084      if (!__extracted)
1085	__err |= ios_base::failbit;
1086      if (__err)
1087	__in.setstate(__err);
1088      return __in;
1089    }
1090
1091  template<typename _CharT, typename _Traits, typename _Alloc>
1092    basic_istream<_CharT, _Traits>&
1093    getline(basic_istream<_CharT, _Traits>& __in,
1094	    basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
1095    {
1096      typedef basic_istream<_CharT, _Traits>		__istream_type;
1097      typedef typename __istream_type::int_type		__int_type;
1098      typedef typename __istream_type::__streambuf_type __streambuf_type;
1099      typedef typename __istream_type::__ctype_type	__ctype_type;
1100      typedef basic_string<_CharT, _Traits, _Alloc>	__string_type;
1101      typedef typename __string_type::size_type		__size_type;
1102
1103      __size_type __extracted = 0;
1104      const __size_type __n = __str.max_size();
1105      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
1106      typename __istream_type::sentry __cerb(__in, true);
1107      if (__cerb)
1108	{
1109	  try
1110	    {
1111	      // Avoid reallocation for common case.
1112	      __str.erase();
1113	      _CharT __buf[128];
1114	      __size_type __len = 0;
1115	      const __int_type __idelim = _Traits::to_int_type(__delim);
1116	      const __int_type __eof = _Traits::eof();
1117	      __streambuf_type* __sb = __in.rdbuf();
1118	      __int_type __c = __sb->sgetc();
1119
1120	      while (__extracted < __n
1121		     && !_Traits::eq_int_type(__c, __eof)
1122		     && !_Traits::eq_int_type(__c, __idelim))
1123		{
1124		  if (__len == sizeof(__buf) / sizeof(_CharT))
1125		    {
1126		      __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
1127		      __len = 0;
1128		    }
1129		  __buf[__len++] = _Traits::to_char_type(__c);
1130		  ++__extracted;
1131		  __c = __sb->snextc();
1132		}
1133	      __str.append(__buf, __len);
1134
1135	      if (_Traits::eq_int_type(__c, __eof))
1136		__err |= ios_base::eofbit;
1137	      else if (_Traits::eq_int_type(__c, __idelim))
1138		{
1139		  ++__extracted;		  
1140		  __sb->sbumpc();
1141		}
1142	      else
1143		__err |= ios_base::failbit;
1144	    }
1145	  catch(...)
1146	    {
1147	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1148	      // 91. Description of operator>> and getline() for string<>
1149	      // might cause endless loop
1150	      __in._M_setstate(ios_base::badbit);
1151	    }
1152	}
1153      if (!__extracted)
1154	__err |= ios_base::failbit;
1155      if (__err)
1156	__in.setstate(__err);
1157      return __in;
1158    }
1159
1160  template<class _CharT, class _Traits, class _Alloc>
1161    inline basic_istream<_CharT,_Traits>&
1162    getline(basic_istream<_CharT, _Traits>& __in,
1163	    basic_string<_CharT,_Traits,_Alloc>& __str)
1164    { return getline(__in, __str, __in.widen('\n')); }
1165
1166  // Inhibit implicit instantiations for required instantiations,
1167  // which are defined via explicit instantiations elsewhere.
1168  // NB:  This syntax is a GNU extension.
1169#if _GLIBCXX_EXTERN_TEMPLATE
1170  extern template class basic_istream<char>;
1171  extern template istream& ws(istream&);
1172  extern template istream& operator>>(istream&, char&);
1173  extern template istream& operator>>(istream&, char*);
1174  extern template istream& operator>>(istream&, unsigned char&);
1175  extern template istream& operator>>(istream&, signed char&);
1176  extern template istream& operator>>(istream&, unsigned char*);
1177  extern template istream& operator>>(istream&, signed char*);
1178
1179  extern template class basic_iostream<char>;
1180
1181#ifdef _GLIBCXX_USE_WCHAR_T
1182  extern template class basic_istream<wchar_t>;
1183  extern template wistream& ws(wistream&);
1184  extern template wistream& operator>>(wistream&, wchar_t&);
1185  extern template wistream& operator>>(wistream&, wchar_t*);
1186
1187  extern template class basic_iostream<wchar_t>;
1188#endif
1189#endif
1190} // namespace std
1191
1192#endif
1193