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