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