OSDN Git Service

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