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