OSDN Git Service

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