OSDN Git Service

2006-08-10 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, 2005, 2006
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 _GLIBCXX_BEGIN_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     template<typename _ValueT>
114       basic_istream<_CharT, _Traits>&
115       basic_istream<_CharT, _Traits>::
116       _M_extract(_ValueT& __v)
117       {
118         sentry __cerb(*this, false);
119         if (__cerb)
120           {
121             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
122             try
123               {
124                 const __num_get_type& __ng = __check_facet(this->_M_num_get);
125                 __ng.get(*this, 0, *this, __err, __v);
126               }
127             catch(...)
128               { this->_M_setstate(ios_base::badbit); }
129             if (__err)
130               this->setstate(__err);
131           }
132         return *this;
133       }
134
135   template<typename _CharT, typename _Traits>
136     basic_istream<_CharT, _Traits>&
137     basic_istream<_CharT, _Traits>::
138     operator>>(short& __n)
139     {
140       // _GLIBCXX_RESOLVE_LIB_DEFECTS
141       // 118. basic_istream uses nonexistent num_get member functions.
142       long __l;
143       _M_extract(__l);
144       if (!this->fail())
145         {
146           if (numeric_limits<short>::min() <= __l
147               && __l <= numeric_limits<short>::max())
148             __n = __l;
149           else
150             this->setstate(ios_base::failbit);
151         }
152       return *this;
153     }
154     
155   template<typename _CharT, typename _Traits>
156     basic_istream<_CharT, _Traits>&
157     basic_istream<_CharT, _Traits>::
158     operator>>(int& __n)
159     {
160       // _GLIBCXX_RESOLVE_LIB_DEFECTS
161       // 118. basic_istream uses nonexistent num_get member functions.
162       long __l;
163       _M_extract(__l);
164       if (!this->fail())
165         {
166           if (numeric_limits<int>::min() <= __l
167               && __l <= numeric_limits<int>::max())
168             __n = __l;
169           else
170             this->setstate(ios_base::failbit);
171         }
172       return *this;
173     }
174
175   template<typename _CharT, typename _Traits>
176     basic_istream<_CharT, _Traits>&
177     basic_istream<_CharT, _Traits>::
178     operator>>(__streambuf_type* __sbout)
179     {
180       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
181       sentry __cerb(*this, false);
182       if (__cerb && __sbout)
183         {
184           try
185             {
186               bool __ineof;
187               if (!__copy_streambufs_eof(this->rdbuf(), __sbout, __ineof))
188                 __err |= ios_base::failbit;
189               if (__ineof)
190                 __err |= ios_base::eofbit;
191             }
192           catch(...)
193             { this->_M_setstate(ios_base::failbit); }
194         }
195       else if (!__sbout)
196         __err |= ios_base::failbit;
197       if (__err)
198         this->setstate(__err);
199       return *this;
200     }
201
202   template<typename _CharT, typename _Traits>
203     typename basic_istream<_CharT, _Traits>::int_type
204     basic_istream<_CharT, _Traits>::
205     get(void)
206     {
207       const int_type __eof = traits_type::eof();
208       int_type __c = __eof;
209       _M_gcount = 0;
210       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
211       sentry __cerb(*this, true);
212       if (__cerb)
213         {
214           try
215             {
216               __c = this->rdbuf()->sbumpc();
217               // 27.6.1.1 paragraph 3
218               if (!traits_type::eq_int_type(__c, __eof))
219                 _M_gcount = 1;
220               else
221                 __err |= ios_base::eofbit;
222             }
223           catch(...)
224             { this->_M_setstate(ios_base::badbit); }
225         }
226       if (!_M_gcount)
227         __err |= ios_base::failbit;
228       if (__err)
229         this->setstate(__err);
230       return __c;
231     }
232
233   template<typename _CharT, typename _Traits>
234     basic_istream<_CharT, _Traits>&
235     basic_istream<_CharT, _Traits>::
236     get(char_type& __c)
237     {
238       _M_gcount = 0;
239       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
240       sentry __cerb(*this, true);
241       if (__cerb)
242         {
243           try
244             {
245               const int_type __cb = this->rdbuf()->sbumpc();
246               // 27.6.1.1 paragraph 3
247               if (!traits_type::eq_int_type(__cb, traits_type::eof()))
248                 {
249                   _M_gcount = 1;
250                   __c = traits_type::to_char_type(__cb);
251                 }
252               else
253                 __err |= ios_base::eofbit;
254             }
255           catch(...)
256             { this->_M_setstate(ios_base::badbit); }
257         }
258       if (!_M_gcount)
259         __err |= ios_base::failbit;
260       if (__err)
261         this->setstate(__err);
262       return *this;
263     }
264
265   template<typename _CharT, typename _Traits>
266     basic_istream<_CharT, _Traits>&
267     basic_istream<_CharT, _Traits>::
268     get(char_type* __s, streamsize __n, char_type __delim)
269     {
270       _M_gcount = 0;
271       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
272       sentry __cerb(*this, true);
273       if (__cerb)
274         {
275           try
276             {
277               const int_type __idelim = traits_type::to_int_type(__delim);
278               const int_type __eof = traits_type::eof();
279               __streambuf_type* __sb = this->rdbuf();
280               int_type __c = __sb->sgetc();
281
282               while (_M_gcount + 1 < __n
283                      && !traits_type::eq_int_type(__c, __eof)
284                      && !traits_type::eq_int_type(__c, __idelim))
285                 {
286                   *__s++ = traits_type::to_char_type(__c);
287                   ++_M_gcount;
288                   __c = __sb->snextc();
289                 }
290               if (traits_type::eq_int_type(__c, __eof))
291                 __err |= ios_base::eofbit;
292             }
293           catch(...)
294             { this->_M_setstate(ios_base::badbit); }
295         }
296       // _GLIBCXX_RESOLVE_LIB_DEFECTS
297       // 243. get and getline when sentry reports failure.
298       if (__n > 0)
299         *__s = char_type();
300       if (!_M_gcount)
301         __err |= ios_base::failbit;
302       if (__err)
303         this->setstate(__err);
304       return *this;
305     }
306
307   template<typename _CharT, typename _Traits>
308     basic_istream<_CharT, _Traits>&
309     basic_istream<_CharT, _Traits>::
310     get(__streambuf_type& __sb, char_type __delim)
311     {
312       _M_gcount = 0;
313       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
314       sentry __cerb(*this, true);
315       if (__cerb)
316         {
317           try
318             {
319               const int_type __idelim = traits_type::to_int_type(__delim);
320               const int_type __eof = traits_type::eof();
321               __streambuf_type* __this_sb = this->rdbuf();
322               int_type __c = __this_sb->sgetc();
323               char_type __c2 = traits_type::to_char_type(__c);
324
325               while (!traits_type::eq_int_type(__c, __eof)
326                      && !traits_type::eq_int_type(__c, __idelim)
327                      && !traits_type::eq_int_type(__sb.sputc(__c2), __eof))
328                 {
329                   ++_M_gcount;
330                   __c = __this_sb->snextc();
331                   __c2 = traits_type::to_char_type(__c);
332                 }
333               if (traits_type::eq_int_type(__c, __eof))
334                 __err |= ios_base::eofbit;
335             }
336           catch(...)
337             { this->_M_setstate(ios_base::badbit); }
338         }
339       if (!_M_gcount)
340         __err |= ios_base::failbit;
341       if (__err)
342         this->setstate(__err);
343       return *this;
344     }
345
346   template<typename _CharT, typename _Traits>
347     basic_istream<_CharT, _Traits>&
348     basic_istream<_CharT, _Traits>::
349     getline(char_type* __s, streamsize __n, char_type __delim)
350     {
351       _M_gcount = 0;
352       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
353       sentry __cerb(*this, true);
354       if (__cerb)
355         {
356           try
357             {
358               const int_type __idelim = traits_type::to_int_type(__delim);
359               const int_type __eof = traits_type::eof();
360               __streambuf_type* __sb = this->rdbuf();
361               int_type __c = __sb->sgetc();
362
363               while (_M_gcount + 1 < __n
364                      && !traits_type::eq_int_type(__c, __eof)
365                      && !traits_type::eq_int_type(__c, __idelim))
366                 {
367                   *__s++ = traits_type::to_char_type(__c);
368                   __c = __sb->snextc();
369                   ++_M_gcount;
370                 }
371               if (traits_type::eq_int_type(__c, __eof))
372                 __err |= ios_base::eofbit;
373               else
374                 {
375                   if (traits_type::eq_int_type(__c, __idelim))
376                     {
377                       __sb->sbumpc();
378                       ++_M_gcount;
379                     }
380                   else
381                     __err |= ios_base::failbit;
382                 }
383             }
384           catch(...)
385             { this->_M_setstate(ios_base::badbit); }
386         }
387       // _GLIBCXX_RESOLVE_LIB_DEFECTS
388       // 243. get and getline when sentry reports failure.
389       if (__n > 0)
390         *__s = char_type();
391       if (!_M_gcount)
392         __err |= ios_base::failbit;
393       if (__err)
394         this->setstate(__err);
395       return *this;
396     }
397
398   // We provide three overloads, since the first two are much simpler
399   // than the general case. Also, the latter two can thus adopt the
400   // same "batchy" strategy used by getline above.
401   template<typename _CharT, typename _Traits>
402     basic_istream<_CharT, _Traits>&
403     basic_istream<_CharT, _Traits>::
404     ignore(void)
405     {
406       _M_gcount = 0;
407       sentry __cerb(*this, true);
408       if (__cerb)
409         {
410           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
411           try
412             {
413               const int_type __eof = traits_type::eof();
414               __streambuf_type* __sb = this->rdbuf();
415
416               if (traits_type::eq_int_type(__sb->sbumpc(), __eof))
417                 __err |= ios_base::eofbit;
418               else
419                 _M_gcount = 1;
420             }
421           catch(...)
422             { this->_M_setstate(ios_base::badbit); }
423           if (__err)
424             this->setstate(__err);
425         }
426       return *this;
427     }
428
429   template<typename _CharT, typename _Traits>
430     basic_istream<_CharT, _Traits>&
431     basic_istream<_CharT, _Traits>::
432     ignore(streamsize __n)
433     {
434       _M_gcount = 0;
435       sentry __cerb(*this, true);
436       if (__cerb && __n > 0)
437         {
438           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
439           try
440             {
441               const int_type __eof = traits_type::eof();
442               __streambuf_type* __sb = this->rdbuf();
443               int_type __c = __sb->sgetc();
444
445               // N.B. On LFS-enabled platforms streamsize is still 32 bits
446               // wide: if we want to implement the standard mandated behavior
447               // for n == max() (see 27.6.1.3/24) we are at risk of signed
448               // integer overflow: thus these contortions. Also note that,
449               // by definition, when more than 2G chars are actually ignored,
450               // _M_gcount (the return value of gcount, that is) cannot be
451               // really correct, being unavoidably too small.
452               bool __large_ignore = false;
453               while (true)
454                 {
455                   while (_M_gcount < __n
456                          && !traits_type::eq_int_type(__c, __eof))
457                     {
458                       ++_M_gcount;
459                       __c = __sb->snextc();
460                     }
461                   if (__n == numeric_limits<streamsize>::max()
462                       && !traits_type::eq_int_type(__c, __eof))
463                     {
464                       _M_gcount = numeric_limits<streamsize>::min();
465                       __large_ignore = true;
466                     }
467                   else
468                     break;
469                 }
470
471               if (__large_ignore)
472                 _M_gcount = numeric_limits<streamsize>::max();
473
474               if (traits_type::eq_int_type(__c, __eof))
475                 __err |= ios_base::eofbit;
476             }
477           catch(...)
478             { this->_M_setstate(ios_base::badbit); }
479           if (__err)
480             this->setstate(__err);
481         }
482       return *this;
483     }
484
485   template<typename _CharT, typename _Traits>
486     basic_istream<_CharT, _Traits>&
487     basic_istream<_CharT, _Traits>::
488     ignore(streamsize __n, int_type __delim)
489     {
490       _M_gcount = 0;
491       sentry __cerb(*this, true);
492       if (__cerb && __n > 0)
493         {
494           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
495           try
496             {
497               const int_type __eof = traits_type::eof();
498               __streambuf_type* __sb = this->rdbuf();
499               int_type __c = __sb->sgetc();
500
501               // See comment above.
502               bool __large_ignore = false;
503               while (true)
504                 {
505                   while (_M_gcount < __n
506                          && !traits_type::eq_int_type(__c, __eof)
507                          && !traits_type::eq_int_type(__c, __delim))
508                     {
509                       ++_M_gcount;
510                       __c = __sb->snextc();
511                     }
512                   if (__n == numeric_limits<streamsize>::max()
513                       && !traits_type::eq_int_type(__c, __eof)
514                       && !traits_type::eq_int_type(__c, __delim))
515                     {
516                       _M_gcount = numeric_limits<streamsize>::min();
517                       __large_ignore = true;
518                     }
519                   else
520                     break;
521                 }
522
523               if (__large_ignore)
524                 _M_gcount = numeric_limits<streamsize>::max();
525
526               if (traits_type::eq_int_type(__c, __eof))
527                 __err |= ios_base::eofbit;
528               else if (traits_type::eq_int_type(__c, __delim))
529                 {
530                   if (_M_gcount < numeric_limits<streamsize>::max())
531                     ++_M_gcount;
532                   __sb->sbumpc();
533                 }
534             }
535           catch(...)
536             { this->_M_setstate(ios_base::badbit); }
537           if (__err)
538             this->setstate(__err);
539         }
540       return *this;
541     }
542
543   template<typename _CharT, typename _Traits>
544     typename basic_istream<_CharT, _Traits>::int_type
545     basic_istream<_CharT, _Traits>::
546     peek(void)
547     {
548       int_type __c = traits_type::eof();
549       _M_gcount = 0;
550       sentry __cerb(*this, true);
551       if (__cerb)
552         {
553           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
554           try
555             {
556               __c = this->rdbuf()->sgetc();
557               if (traits_type::eq_int_type(__c, traits_type::eof()))
558                 __err |= ios_base::eofbit;
559             }
560           catch(...)
561             { this->_M_setstate(ios_base::badbit); }
562           if (__err)
563             this->setstate(__err);
564         }
565       return __c;
566     }
567
568   template<typename _CharT, typename _Traits>
569     basic_istream<_CharT, _Traits>&
570     basic_istream<_CharT, _Traits>::
571     read(char_type* __s, streamsize __n)
572     {
573       _M_gcount = 0;
574       sentry __cerb(*this, true);
575       if (__cerb)
576         {
577           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
578           try
579             {
580               _M_gcount = this->rdbuf()->sgetn(__s, __n);
581               if (_M_gcount != __n)
582                 __err |= (ios_base::eofbit | ios_base::failbit);
583             }
584           catch(...)
585             { this->_M_setstate(ios_base::badbit); }
586           if (__err)
587             this->setstate(__err);
588         }
589       return *this;
590     }
591
592   template<typename _CharT, typename _Traits>
593     streamsize
594     basic_istream<_CharT, _Traits>::
595     readsome(char_type* __s, streamsize __n)
596     {
597       _M_gcount = 0;
598       sentry __cerb(*this, true);
599       if (__cerb)
600         {
601           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
602           try
603             {
604               // Cannot compare int_type with streamsize generically.
605               const streamsize __num = this->rdbuf()->in_avail();
606               if (__num > 0)
607                 _M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n));
608               else if (__num == -1)
609                 __err |= ios_base::eofbit;
610             }
611           catch(...)
612             { this->_M_setstate(ios_base::badbit); }
613           if (__err)
614             this->setstate(__err);
615         }
616       return _M_gcount;
617     }
618
619   template<typename _CharT, typename _Traits>
620     basic_istream<_CharT, _Traits>&
621     basic_istream<_CharT, _Traits>::
622     putback(char_type __c)
623     {
624       // _GLIBCXX_RESOLVE_LIB_DEFECTS
625       // 60. What is a formatted input function?
626       _M_gcount = 0;
627       sentry __cerb(*this, true);
628       if (__cerb)
629         {
630           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
631           try
632             {
633               const int_type __eof = traits_type::eof();
634               __streambuf_type* __sb = this->rdbuf();
635               if (!__sb
636                   || traits_type::eq_int_type(__sb->sputbackc(__c), __eof))
637                 __err |= ios_base::badbit;
638             }
639           catch(...)
640             { this->_M_setstate(ios_base::badbit); }
641           if (__err)
642             this->setstate(__err);
643         }
644       return *this;
645     }
646
647   template<typename _CharT, typename _Traits>
648     basic_istream<_CharT, _Traits>&
649     basic_istream<_CharT, _Traits>::
650     unget(void)
651     {
652       // _GLIBCXX_RESOLVE_LIB_DEFECTS
653       // 60. What is a formatted input function?
654       _M_gcount = 0;
655       sentry __cerb(*this, true);
656       if (__cerb)
657         {
658           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
659           try
660             {
661               const int_type __eof = traits_type::eof();
662               __streambuf_type* __sb = this->rdbuf();
663               if (!__sb
664                   || traits_type::eq_int_type(__sb->sungetc(), __eof))
665                 __err |= ios_base::badbit;
666             }
667           catch(...)
668             { this->_M_setstate(ios_base::badbit); }
669           if (__err)
670             this->setstate(__err);
671         }
672       return *this;
673     }
674
675   template<typename _CharT, typename _Traits>
676     int
677     basic_istream<_CharT, _Traits>::
678     sync(void)
679     {
680       // _GLIBCXX_RESOLVE_LIB_DEFECTS
681       // DR60.  Do not change _M_gcount.
682       int __ret = -1;
683       sentry __cerb(*this, true);
684       if (__cerb)
685         {
686           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
687           try
688             {
689               __streambuf_type* __sb = this->rdbuf();
690               if (__sb)
691                 {
692                   if (__sb->pubsync() == -1)
693                     __err |= ios_base::badbit;
694                   else
695                     __ret = 0;
696                 }
697             }
698           catch(...)
699             { this->_M_setstate(ios_base::badbit); }
700           if (__err)
701             this->setstate(__err);
702         }
703       return __ret;
704     }
705
706   template<typename _CharT, typename _Traits>
707     typename basic_istream<_CharT, _Traits>::pos_type
708     basic_istream<_CharT, _Traits>::
709     tellg(void)
710     {
711       // _GLIBCXX_RESOLVE_LIB_DEFECTS
712       // DR60.  Do not change _M_gcount.
713       pos_type __ret = pos_type(-1);
714       try
715         {
716           if (!this->fail())
717             __ret = this->rdbuf()->pubseekoff(0, ios_base::cur,
718                                               ios_base::in);
719         }
720       catch(...)
721         { this->_M_setstate(ios_base::badbit); }
722       return __ret;
723     }
724
725   template<typename _CharT, typename _Traits>
726     basic_istream<_CharT, _Traits>&
727     basic_istream<_CharT, _Traits>::
728     seekg(pos_type __pos)
729     {
730       // _GLIBCXX_RESOLVE_LIB_DEFECTS
731       // DR60.  Do not change _M_gcount.
732       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
733       try
734         {
735           if (!this->fail())
736             {
737               // 136.  seekp, seekg setting wrong streams?
738               const pos_type __p = this->rdbuf()->pubseekpos(__pos,
739                                                              ios_base::in);
740               
741               // 129.  Need error indication from seekp() and seekg()
742               if (__p == pos_type(off_type(-1)))
743                 __err |= ios_base::failbit;
744             }
745         }
746       catch(...)
747         { this->_M_setstate(ios_base::badbit); }
748       if (__err)
749         this->setstate(__err);
750       return *this;
751     }
752
753   template<typename _CharT, typename _Traits>
754     basic_istream<_CharT, _Traits>&
755     basic_istream<_CharT, _Traits>::
756     seekg(off_type __off, ios_base::seekdir __dir)
757     {
758       // _GLIBCXX_RESOLVE_LIB_DEFECTS
759       // DR60.  Do not change _M_gcount.
760       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
761       try
762         {
763           if (!this->fail())
764             {
765               // 136.  seekp, seekg setting wrong streams?
766               const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
767                                                              ios_base::in);
768               
769               // 129.  Need error indication from seekp() and seekg()
770               if (__p == pos_type(off_type(-1)))
771                 __err |= ios_base::failbit;
772             }
773         }
774       catch(...)
775         { this->_M_setstate(ios_base::badbit); }
776       if (__err)
777         this->setstate(__err);
778       return *this;
779     }
780
781   // 27.6.1.2.3 Character extraction templates
782   template<typename _CharT, typename _Traits>
783     basic_istream<_CharT, _Traits>&
784     operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c)
785     {
786       typedef basic_istream<_CharT, _Traits>            __istream_type;
787       typedef typename __istream_type::int_type         __int_type;
788
789       typename __istream_type::sentry __cerb(__in, false);
790       if (__cerb)
791         {
792           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
793           try
794             {
795               const __int_type __cb = __in.rdbuf()->sbumpc();
796               if (!_Traits::eq_int_type(__cb, _Traits::eof()))
797                 __c = _Traits::to_char_type(__cb);
798               else
799                 __err |= (ios_base::eofbit | ios_base::failbit);
800             }
801           catch(...)
802             { __in._M_setstate(ios_base::badbit); }
803           if (__err)
804             __in.setstate(__err);
805         }
806       return __in;
807     }
808
809   template<typename _CharT, typename _Traits>
810     basic_istream<_CharT, _Traits>&
811     operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s)
812     {
813       typedef basic_istream<_CharT, _Traits>            __istream_type;
814       typedef typename __istream_type::__streambuf_type __streambuf_type;
815       typedef typename _Traits::int_type                int_type;
816       typedef _CharT                                    char_type;
817       typedef ctype<_CharT>                             __ctype_type;
818
819       streamsize __extracted = 0;
820       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
821       typename __istream_type::sentry __cerb(__in, false);
822       if (__cerb)
823         {
824           try
825             {
826               // Figure out how many characters to extract.
827               streamsize __num = __in.width();
828               if (__num <= 0)
829                 __num = numeric_limits<streamsize>::max();
830
831               const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
832
833               const int_type __eof = _Traits::eof();
834               __streambuf_type* __sb = __in.rdbuf();
835               int_type __c = __sb->sgetc();
836
837               while (__extracted < __num - 1
838                      && !_Traits::eq_int_type(__c, __eof)
839                      && !__ct.is(ctype_base::space,
840                                  _Traits::to_char_type(__c)))
841                 {
842                   *__s++ = _Traits::to_char_type(__c);
843                   ++__extracted;
844                   __c = __sb->snextc();
845                 }
846               if (_Traits::eq_int_type(__c, __eof))
847                 __err |= ios_base::eofbit;
848
849               // _GLIBCXX_RESOLVE_LIB_DEFECTS
850               // 68.  Extractors for char* should store null at end
851               *__s = char_type();
852               __in.width(0);
853             }
854           catch(...)
855             { __in._M_setstate(ios_base::badbit); }
856         }
857       if (!__extracted)
858         __err |= ios_base::failbit;
859       if (__err)
860         __in.setstate(__err);
861       return __in;
862     }
863
864   // 27.6.1.4 Standard basic_istream manipulators
865   template<typename _CharT, typename _Traits>
866     basic_istream<_CharT,_Traits>&
867     ws(basic_istream<_CharT,_Traits>& __in)
868     {
869       typedef basic_istream<_CharT, _Traits>            __istream_type;
870       typedef typename __istream_type::__streambuf_type __streambuf_type;
871       typedef typename __istream_type::__ctype_type     __ctype_type;
872       typedef typename __istream_type::int_type         __int_type;
873
874       const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
875       const __int_type __eof = _Traits::eof();
876       __streambuf_type* __sb = __in.rdbuf();
877       __int_type __c = __sb->sgetc();
878
879       while (!_Traits::eq_int_type(__c, __eof)
880              && __ct.is(ctype_base::space, _Traits::to_char_type(__c)))
881         __c = __sb->snextc();
882
883        if (_Traits::eq_int_type(__c, __eof))
884          __in.setstate(ios_base::eofbit);
885       return __in;
886     }
887
888   // 21.3.7.9 basic_string::getline and operators
889   template<typename _CharT, typename _Traits, typename _Alloc>
890     basic_istream<_CharT, _Traits>&
891     operator>>(basic_istream<_CharT, _Traits>& __in,
892                basic_string<_CharT, _Traits, _Alloc>& __str)
893     {
894       typedef basic_istream<_CharT, _Traits>            __istream_type;
895       typedef typename __istream_type::int_type         __int_type;
896       typedef typename __istream_type::__streambuf_type __streambuf_type;
897       typedef typename __istream_type::__ctype_type     __ctype_type;
898       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
899       typedef typename __string_type::size_type         __size_type;
900
901       __size_type __extracted = 0;
902       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
903       typename __istream_type::sentry __cerb(__in, false);
904       if (__cerb)
905         {
906           try
907             {
908               // Avoid reallocation for common case.
909               __str.erase();
910               _CharT __buf[128];
911               __size_type __len = 0;          
912               const streamsize __w = __in.width();
913               const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
914                                               : __str.max_size();
915               const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
916               const __int_type __eof = _Traits::eof();
917               __streambuf_type* __sb = __in.rdbuf();
918               __int_type __c = __sb->sgetc();
919
920               while (__extracted < __n
921                      && !_Traits::eq_int_type(__c, __eof)
922                      && !__ct.is(ctype_base::space, _Traits::to_char_type(__c)))
923                 {
924                   if (__len == sizeof(__buf) / sizeof(_CharT))
925                     {
926                       __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
927                       __len = 0;
928                     }
929                   __buf[__len++] = _Traits::to_char_type(__c);
930                   ++__extracted;
931                   __c = __sb->snextc();
932                 }
933               __str.append(__buf, __len);
934
935               if (_Traits::eq_int_type(__c, __eof))
936                 __err |= ios_base::eofbit;
937               __in.width(0);
938             }
939           catch(...)
940             {
941               // _GLIBCXX_RESOLVE_LIB_DEFECTS
942               // 91. Description of operator>> and getline() for string<>
943               // might cause endless loop
944               __in._M_setstate(ios_base::badbit);
945             }
946         }
947       // 211.  operator>>(istream&, string&) doesn't set failbit
948       if (!__extracted)
949         __err |= ios_base::failbit;
950       if (__err)
951         __in.setstate(__err);
952       return __in;
953     }
954
955   template<typename _CharT, typename _Traits, typename _Alloc>
956     basic_istream<_CharT, _Traits>&
957     getline(basic_istream<_CharT, _Traits>& __in,
958             basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
959     {
960       typedef basic_istream<_CharT, _Traits>            __istream_type;
961       typedef typename __istream_type::int_type         __int_type;
962       typedef typename __istream_type::__streambuf_type __streambuf_type;
963       typedef typename __istream_type::__ctype_type     __ctype_type;
964       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
965       typedef typename __string_type::size_type         __size_type;
966
967       __size_type __extracted = 0;
968       const __size_type __n = __str.max_size();
969       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
970       typename __istream_type::sentry __cerb(__in, true);
971       if (__cerb)
972         {
973           try
974             {
975               __str.erase();
976               const __int_type __idelim = _Traits::to_int_type(__delim);
977               const __int_type __eof = _Traits::eof();
978               __streambuf_type* __sb = __in.rdbuf();
979               __int_type __c = __sb->sgetc();
980
981               while (__extracted < __n
982                      && !_Traits::eq_int_type(__c, __eof)
983                      && !_Traits::eq_int_type(__c, __idelim))
984                 {
985                   __str += _Traits::to_char_type(__c);
986                   ++__extracted;
987                   __c = __sb->snextc();
988                 }
989
990               if (_Traits::eq_int_type(__c, __eof))
991                 __err |= ios_base::eofbit;
992               else if (_Traits::eq_int_type(__c, __idelim))
993                 {
994                   ++__extracted;                  
995                   __sb->sbumpc();
996                 }
997               else
998                 __err |= ios_base::failbit;
999             }
1000           catch(...)
1001             {
1002               // _GLIBCXX_RESOLVE_LIB_DEFECTS
1003               // 91. Description of operator>> and getline() for string<>
1004               // might cause endless loop
1005               __in._M_setstate(ios_base::badbit);
1006             }
1007         }
1008       if (!__extracted)
1009         __err |= ios_base::failbit;
1010       if (__err)
1011         __in.setstate(__err);
1012       return __in;
1013     }
1014
1015   template<class _CharT, class _Traits, class _Alloc>
1016     inline basic_istream<_CharT,_Traits>&
1017     getline(basic_istream<_CharT, _Traits>& __in,
1018             basic_string<_CharT,_Traits,_Alloc>& __str)
1019     { return getline(__in, __str, __in.widen('\n')); }
1020
1021   // Inhibit implicit instantiations for required instantiations,
1022   // which are defined via explicit instantiations elsewhere.
1023   // NB:  This syntax is a GNU extension.
1024 #if _GLIBCXX_EXTERN_TEMPLATE
1025   extern template class basic_istream<char>;
1026   extern template istream& ws(istream&);
1027   extern template istream& operator>>(istream&, char&);
1028   extern template istream& operator>>(istream&, char*);
1029   extern template istream& operator>>(istream&, unsigned char&);
1030   extern template istream& operator>>(istream&, signed char&);
1031   extern template istream& operator>>(istream&, unsigned char*);
1032   extern template istream& operator>>(istream&, signed char*);
1033
1034   extern template class basic_iostream<char>;
1035
1036 #ifdef _GLIBCXX_USE_WCHAR_T
1037   extern template class basic_istream<wchar_t>;
1038   extern template wistream& ws(wistream&);
1039   extern template wistream& operator>>(wistream&, wchar_t&);
1040   extern template wistream& operator>>(wistream&, wchar_t*);
1041
1042   extern template class basic_iostream<wchar_t>;
1043 #endif
1044 #endif
1045
1046 _GLIBCXX_END_NAMESPACE
1047
1048 #endif