OSDN Git Service

2004-05-24 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / istream.tcc
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
43 namespace std
44 {
45   template<typename _CharT, typename _Traits>
46     basic_istream<_CharT, _Traits>::sentry::
47     sentry(basic_istream<_CharT, _Traits>& __in, bool __noskip) : _M_ok(false)
48     {
49       ios_base::iostate __err = ios_base::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 #ifdef _GLIBCXX_USE_WCHAR_T
1180   extern template class basic_istream<wchar_t>;
1181   extern template wistream& ws(wistream&);
1182   extern template wistream& operator>>(wistream&, wchar_t&);
1183   extern template wistream& operator>>(wistream&, wchar_t*);
1184 #endif
1185 #endif
1186 } // namespace std
1187
1188 #endif