OSDN Git Service

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