OSDN Git Service

2004-05-21 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 __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               const 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               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       bool __testdelim = false;
1106       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
1107       typename __istream_type::sentry __cerb(__in, true);
1108       if (__cerb)
1109         {
1110           try
1111             {
1112               // Avoid reallocation for common case.
1113               __str.erase();
1114               _CharT __buf[128];
1115               __size_type __len = 0;
1116               const __int_type __idelim = _Traits::to_int_type(__delim);
1117               const __int_type __eof = _Traits::eof();
1118               __streambuf_type* __sb = __in.rdbuf();
1119               __int_type __c = __sb->sgetc();
1120
1121               while (__extracted < __n
1122                      && !_Traits::eq_int_type(__c, __eof)
1123                      && !_Traits::eq_int_type(__c, __idelim))
1124                 {
1125                   if (__len == sizeof(__buf) / sizeof(_CharT))
1126                     {
1127                       __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
1128                       __len = 0;
1129                     }
1130                   __buf[__len++] = _Traits::to_char_type(__c);
1131                   ++__extracted;
1132                   __c = __sb->snextc();
1133                 }
1134               __str.append(__buf, __len);
1135
1136               if (_Traits::eq_int_type(__c, __eof))
1137                 __err |= ios_base::eofbit;
1138               else if (_Traits::eq_int_type(__c, __idelim))
1139                 {
1140                   __sb->sbumpc();
1141                   ++__extracted;
1142                 }
1143               else
1144                 __err |= ios_base::failbit;
1145             }
1146           catch(...)
1147             {
1148               // _GLIBCXX_RESOLVE_LIB_DEFECTS
1149               // 91. Description of operator>> and getline() for string<>
1150               // might cause endless loop
1151               __in._M_setstate(ios_base::badbit);
1152             }
1153         }
1154       if (!__extracted)
1155         __err |= ios_base::failbit;
1156       if (__err)
1157         __in.setstate(__err);
1158       return __in;
1159     }
1160
1161   template<class _CharT, class _Traits, class _Alloc>
1162     inline basic_istream<_CharT,_Traits>&
1163     getline(basic_istream<_CharT, _Traits>& __in,
1164             basic_string<_CharT,_Traits,_Alloc>& __str)
1165     { return getline(__in, __str, __in.widen('\n')); }
1166
1167   // Inhibit implicit instantiations for required instantiations,
1168   // which are defined via explicit instantiations elsewhere.
1169   // NB:  This syntax is a GNU extension.
1170 #if _GLIBCXX_EXTERN_TEMPLATE
1171   extern template class basic_istream<char>;
1172   extern template istream& ws(istream&);
1173   extern template istream& operator>>(istream&, char&);
1174   extern template istream& operator>>(istream&, char*);
1175   extern template istream& operator>>(istream&, unsigned char&);
1176   extern template istream& operator>>(istream&, signed char&);
1177   extern template istream& operator>>(istream&, unsigned char*);
1178   extern template istream& operator>>(istream&, signed char*);
1179
1180 #ifdef _GLIBCXX_USE_WCHAR_T
1181   extern template class basic_istream<wchar_t>;
1182   extern template wistream& ws(wistream&);
1183   extern template wistream& operator>>(wistream&, wchar_t&);
1184   extern template wistream& operator>>(wistream&, wchar_t*);
1185 #endif
1186 #endif
1187 } // namespace std
1188
1189 #endif