Merge from mainline
[official-gcc.git] / libstdc++-v3 / include / bits / istream.tcc
blobdb3e96e00e11043c9f9ca60c4a51961df9615a7c
1 // istream classes -*- C++ -*-
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.
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.
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.
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.
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  */
37 // ISO C++ 14882: 27.6.1  Input streams
40 #ifndef _ISTREAM_TCC
41 #define _ISTREAM_TCC 1
43 #pragma GCC system_header
45 #include <locale>
46 #include <ostream> // For flush()
48 _GLIBCXX_BEGIN_NAMESPACE(std)
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();
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();
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         }
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     }
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); }
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     }
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     }
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       }
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     }
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     }
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     }
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     }
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();
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     }
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);
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     }
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();
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     }
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();
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     }
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();
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                 }
471               if (__large_ignore)
472                 _M_gcount = numeric_limits<streamsize>::max();
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     }
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();
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                 }
523               if (__large_ignore)
524                 _M_gcount = numeric_limits<streamsize>::max();
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     }
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     }
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     }
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     }
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     }
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     }
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     }
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       sentry __cerb(*this, true);
715       if (__cerb)
716         {
717           try
718             {
719               if (!this->fail())
720                 __ret = this->rdbuf()->pubseekoff(0, ios_base::cur,
721                                                   ios_base::in);
722             }
723           catch(...)
724             { this->_M_setstate(ios_base::badbit); }
725         }
726       return __ret;
727     }
729   template<typename _CharT, typename _Traits>
730     basic_istream<_CharT, _Traits>&
731     basic_istream<_CharT, _Traits>::
732     seekg(pos_type __pos)
733     {
734       // _GLIBCXX_RESOLVE_LIB_DEFECTS
735       // DR60.  Do not change _M_gcount.
736       sentry __cerb(*this, true);
737       if (__cerb)
738         {
739           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
740           try
741             {
742               if (!this->fail())
743                 {
744                   // 136.  seekp, seekg setting wrong streams?
745                   const pos_type __p = this->rdbuf()->pubseekpos(__pos,
746                                                                  ios_base::in);
748                   // 129. Need error indication from seekp() and seekg()
749                   if (__p == pos_type(off_type(-1)))
750                     __err |= ios_base::failbit;
751                 }
752             }
753           catch(...)
754             { this->_M_setstate(ios_base::badbit); }
755           if (__err)
756             this->setstate(__err);
757         }
758       return *this;
759     }
761   template<typename _CharT, typename _Traits>
762     basic_istream<_CharT, _Traits>&
763     basic_istream<_CharT, _Traits>::
764     seekg(off_type __off, ios_base::seekdir __dir)
765     {
766       // _GLIBCXX_RESOLVE_LIB_DEFECTS
767       // DR60.  Do not change _M_gcount.
768       sentry __cerb(*this, true);
769       if (__cerb)
770         {
771           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
772           try
773             {
774               if (!this->fail())
775                 {
776                   // 136.  seekp, seekg setting wrong streams?
777                   const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
778                                                                  ios_base::in);
780                   // 129. Need error indication from seekp() and seekg()
781                   if (__p == pos_type(off_type(-1)))
782                     __err |= ios_base::failbit;
783                 }
784             }
785           catch(...)
786             { this->_M_setstate(ios_base::badbit); }
787           if (__err)
788             this->setstate(__err);
789         }
790       return *this;
791     }
793   // 27.6.1.2.3 Character extraction templates
794   template<typename _CharT, typename _Traits>
795     basic_istream<_CharT, _Traits>&
796     operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c)
797     {
798       typedef basic_istream<_CharT, _Traits>            __istream_type;
799       typedef typename __istream_type::int_type         __int_type;
801       typename __istream_type::sentry __cerb(__in, false);
802       if (__cerb)
803         {
804           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
805           try
806             {
807               const __int_type __cb = __in.rdbuf()->sbumpc();
808               if (!_Traits::eq_int_type(__cb, _Traits::eof()))
809                 __c = _Traits::to_char_type(__cb);
810               else
811                 __err |= (ios_base::eofbit | ios_base::failbit);
812             }
813           catch(...)
814             { __in._M_setstate(ios_base::badbit); }
815           if (__err)
816             __in.setstate(__err);
817         }
818       return __in;
819     }
821   template<typename _CharT, typename _Traits>
822     basic_istream<_CharT, _Traits>&
823     operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s)
824     {
825       typedef basic_istream<_CharT, _Traits>            __istream_type;
826       typedef typename __istream_type::__streambuf_type __streambuf_type;
827       typedef typename _Traits::int_type                int_type;
828       typedef _CharT                                    char_type;
829       typedef ctype<_CharT>                             __ctype_type;
831       streamsize __extracted = 0;
832       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
833       typename __istream_type::sentry __cerb(__in, false);
834       if (__cerb)
835         {
836           try
837             {
838               // Figure out how many characters to extract.
839               streamsize __num = __in.width();
840               if (__num <= 0)
841                 __num = numeric_limits<streamsize>::max();
843               const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
845               const int_type __eof = _Traits::eof();
846               __streambuf_type* __sb = __in.rdbuf();
847               int_type __c = __sb->sgetc();
849               while (__extracted < __num - 1
850                      && !_Traits::eq_int_type(__c, __eof)
851                      && !__ct.is(ctype_base::space,
852                                  _Traits::to_char_type(__c)))
853                 {
854                   *__s++ = _Traits::to_char_type(__c);
855                   ++__extracted;
856                   __c = __sb->snextc();
857                 }
858               if (_Traits::eq_int_type(__c, __eof))
859                 __err |= ios_base::eofbit;
861               // _GLIBCXX_RESOLVE_LIB_DEFECTS
862               // 68.  Extractors for char* should store null at end
863               *__s = char_type();
864               __in.width(0);
865             }
866           catch(...)
867             { __in._M_setstate(ios_base::badbit); }
868         }
869       if (!__extracted)
870         __err |= ios_base::failbit;
871       if (__err)
872         __in.setstate(__err);
873       return __in;
874     }
876   // 27.6.1.4 Standard basic_istream manipulators
877   template<typename _CharT, typename _Traits>
878     basic_istream<_CharT,_Traits>&
879     ws(basic_istream<_CharT,_Traits>& __in)
880     {
881       typedef basic_istream<_CharT, _Traits>            __istream_type;
882       typedef typename __istream_type::__streambuf_type __streambuf_type;
883       typedef typename __istream_type::__ctype_type     __ctype_type;
884       typedef typename __istream_type::int_type         __int_type;
886       const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
887       const __int_type __eof = _Traits::eof();
888       __streambuf_type* __sb = __in.rdbuf();
889       __int_type __c = __sb->sgetc();
891       while (!_Traits::eq_int_type(__c, __eof)
892              && __ct.is(ctype_base::space, _Traits::to_char_type(__c)))
893         __c = __sb->snextc();
895        if (_Traits::eq_int_type(__c, __eof))
896          __in.setstate(ios_base::eofbit);
897       return __in;
898     }
900   // 21.3.7.9 basic_string::getline and operators
901   template<typename _CharT, typename _Traits, typename _Alloc>
902     basic_istream<_CharT, _Traits>&
903     operator>>(basic_istream<_CharT, _Traits>& __in,
904                basic_string<_CharT, _Traits, _Alloc>& __str)
905     {
906       typedef basic_istream<_CharT, _Traits>            __istream_type;
907       typedef typename __istream_type::int_type         __int_type;
908       typedef typename __istream_type::__streambuf_type __streambuf_type;
909       typedef typename __istream_type::__ctype_type     __ctype_type;
910       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
911       typedef typename __string_type::size_type         __size_type;
913       __size_type __extracted = 0;
914       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
915       typename __istream_type::sentry __cerb(__in, false);
916       if (__cerb)
917         {
918           try
919             {
920               // Avoid reallocation for common case.
921               __str.erase();
922               _CharT __buf[128];
923               __size_type __len = 0;          
924               const streamsize __w = __in.width();
925               const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
926                                               : __str.max_size();
927               const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
928               const __int_type __eof = _Traits::eof();
929               __streambuf_type* __sb = __in.rdbuf();
930               __int_type __c = __sb->sgetc();
932               while (__extracted < __n
933                      && !_Traits::eq_int_type(__c, __eof)
934                      && !__ct.is(ctype_base::space, _Traits::to_char_type(__c)))
935                 {
936                   if (__len == sizeof(__buf) / sizeof(_CharT))
937                     {
938                       __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
939                       __len = 0;
940                     }
941                   __buf[__len++] = _Traits::to_char_type(__c);
942                   ++__extracted;
943                   __c = __sb->snextc();
944                 }
945               __str.append(__buf, __len);
947               if (_Traits::eq_int_type(__c, __eof))
948                 __err |= ios_base::eofbit;
949               __in.width(0);
950             }
951           catch(...)
952             {
953               // _GLIBCXX_RESOLVE_LIB_DEFECTS
954               // 91. Description of operator>> and getline() for string<>
955               // might cause endless loop
956               __in._M_setstate(ios_base::badbit);
957             }
958         }
959       // 211.  operator>>(istream&, string&) doesn't set failbit
960       if (!__extracted)
961         __err |= ios_base::failbit;
962       if (__err)
963         __in.setstate(__err);
964       return __in;
965     }
967   template<typename _CharT, typename _Traits, typename _Alloc>
968     basic_istream<_CharT, _Traits>&
969     getline(basic_istream<_CharT, _Traits>& __in,
970             basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
971     {
972       typedef basic_istream<_CharT, _Traits>            __istream_type;
973       typedef typename __istream_type::int_type         __int_type;
974       typedef typename __istream_type::__streambuf_type __streambuf_type;
975       typedef typename __istream_type::__ctype_type     __ctype_type;
976       typedef basic_string<_CharT, _Traits, _Alloc>     __string_type;
977       typedef typename __string_type::size_type         __size_type;
979       __size_type __extracted = 0;
980       const __size_type __n = __str.max_size();
981       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
982       typename __istream_type::sentry __cerb(__in, true);
983       if (__cerb)
984         {
985           try
986             {
987               __str.erase();
988               const __int_type __idelim = _Traits::to_int_type(__delim);
989               const __int_type __eof = _Traits::eof();
990               __streambuf_type* __sb = __in.rdbuf();
991               __int_type __c = __sb->sgetc();
993               while (__extracted < __n
994                      && !_Traits::eq_int_type(__c, __eof)
995                      && !_Traits::eq_int_type(__c, __idelim))
996                 {
997                   __str += _Traits::to_char_type(__c);
998                   ++__extracted;
999                   __c = __sb->snextc();
1000                 }
1002               if (_Traits::eq_int_type(__c, __eof))
1003                 __err |= ios_base::eofbit;
1004               else if (_Traits::eq_int_type(__c, __idelim))
1005                 {
1006                   ++__extracted;                  
1007                   __sb->sbumpc();
1008                 }
1009               else
1010                 __err |= ios_base::failbit;
1011             }
1012           catch(...)
1013             {
1014               // _GLIBCXX_RESOLVE_LIB_DEFECTS
1015               // 91. Description of operator>> and getline() for string<>
1016               // might cause endless loop
1017               __in._M_setstate(ios_base::badbit);
1018             }
1019         }
1020       if (!__extracted)
1021         __err |= ios_base::failbit;
1022       if (__err)
1023         __in.setstate(__err);
1024       return __in;
1025     }
1027   template<class _CharT, class _Traits, class _Alloc>
1028     inline basic_istream<_CharT,_Traits>&
1029     getline(basic_istream<_CharT, _Traits>& __in,
1030             basic_string<_CharT,_Traits,_Alloc>& __str)
1031     { return getline(__in, __str, __in.widen('\n')); }
1033   // Inhibit implicit instantiations for required instantiations,
1034   // which are defined via explicit instantiations elsewhere.
1035   // NB:  This syntax is a GNU extension.
1036 #if _GLIBCXX_EXTERN_TEMPLATE
1037   extern template class basic_istream<char>;
1038   extern template istream& ws(istream&);
1039   extern template istream& operator>>(istream&, char&);
1040   extern template istream& operator>>(istream&, char*);
1041   extern template istream& operator>>(istream&, unsigned char&);
1042   extern template istream& operator>>(istream&, signed char&);
1043   extern template istream& operator>>(istream&, unsigned char*);
1044   extern template istream& operator>>(istream&, signed char*);
1046   extern template class basic_iostream<char>;
1048 #ifdef _GLIBCXX_USE_WCHAR_T
1049   extern template class basic_istream<wchar_t>;
1050   extern template wistream& ws(wistream&);
1051   extern template wistream& operator>>(wistream&, wchar_t&);
1052   extern template wistream& operator>>(wistream&, wchar_t*);
1054   extern template class basic_iostream<wchar_t>;
1055 #endif
1056 #endif
1058 _GLIBCXX_END_NAMESPACE
1060 #endif