1 // Versatile string -*- C++ -*- 2 3 // Copyright (C) 2005, 2006, 2007 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 2, 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 // You should have received a copy of the GNU General Public License along 17 // with this library; see the file COPYING. If not, write to the Free 18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19 // USA. 20 21 // As a special exception, you may use this file as part of a free software 22 // library without restriction. Specifically, if other files instantiate 23 // templates or use macros or inline functions from this file, or you compile 24 // this file and link it with other files to produce an executable, this 25 // file does not by itself cause the resulting executable to be covered by 26 // the GNU General Public License. This exception does not however 27 // invalidate any other reasons why the executable file might be covered by 28 // the GNU General Public License. 29 30 /** @file ext/vstring.tcc 31 * This file is a GNU extension to the Standard C++ Library. 32 * This is an internal header file, included by other library headers. 33 * You should not attempt to use it directly. 34 */ 35 36 #ifndef _VSTRING_TCC 37 #define _VSTRING_TCC 1 38 39 #pragma GCC system_header 40 41 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 42 43 template<typename _CharT, typename _Traits, typename _Alloc, 44 template <typename, typename, typename> class _Base> 45 const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 46 __versa_string<_CharT, _Traits, _Alloc, _Base>::npos; 47 48 template<typename _CharT, typename _Traits, typename _Alloc, 49 template <typename, typename, typename> class _Base> 50 void 51 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 52 resize(size_type __n, _CharT __c) 53 { 54 const size_type __size = this->size(); 55 if (__size < __n) 56 this->append(__n - __size, __c); 57 else if (__n < __size) 58 this->_M_erase(__n, __size - __n); 59 } 60 61 template<typename _CharT, typename _Traits, typename _Alloc, 62 template <typename, typename, typename> class _Base> 63 __versa_string<_CharT, _Traits, _Alloc, _Base>& 64 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 65 _M_append(const _CharT* __s, size_type __n) 66 { 67 const size_type __len = __n + this->size(); 68 69 if (__len <= this->capacity() && !this->_M_is_shared()) 70 { 71 if (__n) 72 this->_S_copy(this->_M_data() + this->size(), __s, __n); 73 } 74 else 75 this->_M_mutate(this->size(), size_type(0), __s, __n); 76 77 this->_M_set_length(__len); 78 return *this; 79 } 80 81 template<typename _CharT, typename _Traits, typename _Alloc, 82 template <typename, typename, typename> class _Base> 83 template<typename _InputIterator> 84 __versa_string<_CharT, _Traits, _Alloc, _Base>& 85 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 86 _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, 87 _InputIterator __k2, std::__false_type) 88 { 89 const __versa_string __s(__k1, __k2); 90 const size_type __n1 = __i2 - __i1; 91 return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(), 92 __s.size()); 93 } 94 95 template<typename _CharT, typename _Traits, typename _Alloc, 96 template <typename, typename, typename> class _Base> 97 __versa_string<_CharT, _Traits, _Alloc, _Base>& 98 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 99 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, 100 _CharT __c) 101 { 102 _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux"); 103 104 const size_type __old_size = this->size(); 105 const size_type __new_size = __old_size + __n2 - __n1; 106 107 if (__new_size <= this->capacity() && !this->_M_is_shared()) 108 { 109 _CharT* __p = this->_M_data() + __pos1; 110 111 const size_type __how_much = __old_size - __pos1 - __n1; 112 if (__how_much && __n1 != __n2) 113 this->_S_move(__p + __n2, __p + __n1, __how_much); 114 } 115 else 116 this->_M_mutate(__pos1, __n1, 0, __n2); 117 118 if (__n2) 119 this->_S_assign(this->_M_data() + __pos1, __n2, __c); 120 121 this->_M_set_length(__new_size); 122 return *this; 123 } 124 125 template<typename _CharT, typename _Traits, typename _Alloc, 126 template <typename, typename, typename> class _Base> 127 __versa_string<_CharT, _Traits, _Alloc, _Base>& 128 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 129 _M_replace(size_type __pos, size_type __len1, const _CharT* __s, 130 const size_type __len2) 131 { 132 _M_check_length(__len1, __len2, "__versa_string::_M_replace"); 133 134 const size_type __old_size = this->size(); 135 const size_type __new_size = __old_size + __len2 - __len1; 136 137 if (__new_size <= this->capacity() && !this->_M_is_shared()) 138 { 139 _CharT* __p = this->_M_data() + __pos; 140 141 const size_type __how_much = __old_size - __pos - __len1; 142 if (_M_disjunct(__s)) 143 { 144 if (__how_much && __len1 != __len2) 145 this->_S_move(__p + __len2, __p + __len1, __how_much); 146 if (__len2) 147 this->_S_copy(__p, __s, __len2); 148 } 149 else 150 { 151 // Work in-place. 152 if (__len2 && __len2 <= __len1) 153 this->_S_move(__p, __s, __len2); 154 if (__how_much && __len1 != __len2) 155 this->_S_move(__p + __len2, __p + __len1, __how_much); 156 if (__len2 > __len1) 157 { 158 if (__s + __len2 <= __p + __len1) 159 this->_S_move(__p, __s, __len2); 160 else if (__s >= __p + __len1) 161 this->_S_copy(__p, __s + __len2 - __len1, __len2); 162 else 163 { 164 const size_type __nleft = (__p + __len1) - __s; 165 this->_S_move(__p, __s, __nleft); 166 this->_S_copy(__p + __nleft, __p + __len2, 167 __len2 - __nleft); 168 } 169 } 170 } 171 } 172 else 173 this->_M_mutate(__pos, __len1, __s, __len2); 174 175 this->_M_set_length(__new_size); 176 return *this; 177 } 178 179 template<typename _CharT, typename _Traits, typename _Alloc, 180 template <typename, typename, typename> class _Base> 181 __versa_string<_CharT, _Traits, _Alloc, _Base> 182 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, 183 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) 184 { 185 __versa_string<_CharT, _Traits, _Alloc, _Base> __str; 186 __str.reserve(__lhs.size() + __rhs.size()); 187 __str.append(__lhs); 188 __str.append(__rhs); 189 return __str; 190 } 191 192 template<typename _CharT, typename _Traits, typename _Alloc, 193 template <typename, typename, typename> class _Base> 194 __versa_string<_CharT, _Traits, _Alloc, _Base> 195 operator+(const _CharT* __lhs, 196 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) 197 { 198 __glibcxx_requires_string(__lhs); 199 typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; 200 typedef typename __string_type::size_type __size_type; 201 const __size_type __len = _Traits::length(__lhs); 202 __string_type __str; 203 __str.reserve(__len + __rhs.size()); 204 __str.append(__lhs, __len); 205 __str.append(__rhs); 206 return __str; 207 } 208 209 template<typename _CharT, typename _Traits, typename _Alloc, 210 template <typename, typename, typename> class _Base> 211 __versa_string<_CharT, _Traits, _Alloc, _Base> 212 operator+(_CharT __lhs, 213 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) 214 { 215 __versa_string<_CharT, _Traits, _Alloc, _Base> __str; 216 __str.reserve(__rhs.size() + 1); 217 __str.push_back(__lhs); 218 __str.append(__rhs); 219 return __str; 220 } 221 222 template<typename _CharT, typename _Traits, typename _Alloc, 223 template <typename, typename, typename> class _Base> 224 __versa_string<_CharT, _Traits, _Alloc, _Base> 225 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, 226 const _CharT* __rhs) 227 { 228 __glibcxx_requires_string(__rhs); 229 typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; 230 typedef typename __string_type::size_type __size_type; 231 const __size_type __len = _Traits::length(__rhs); 232 __string_type __str; 233 __str.reserve(__lhs.size() + __len); 234 __str.append(__lhs); 235 __str.append(__rhs, __len); 236 return __str; 237 } 238 239 template<typename _CharT, typename _Traits, typename _Alloc, 240 template <typename, typename, typename> class _Base> 241 __versa_string<_CharT, _Traits, _Alloc, _Base> 242 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, 243 _CharT __rhs) 244 { 245 __versa_string<_CharT, _Traits, _Alloc, _Base> __str; 246 __str.reserve(__lhs.size() + 1); 247 __str.append(__lhs); 248 __str.push_back(__rhs); 249 return __str; 250 } 251 252 template<typename _CharT, typename _Traits, typename _Alloc, 253 template <typename, typename, typename> class _Base> 254 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 255 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 256 copy(_CharT* __s, size_type __n, size_type __pos) const 257 { 258 _M_check(__pos, "__versa_string::copy"); 259 __n = _M_limit(__pos, __n); 260 __glibcxx_requires_string_len(__s, __n); 261 if (__n) 262 this->_S_copy(__s, this->_M_data() + __pos, __n); 263 // 21.3.5.7 par 3: do not append null. (good.) 264 return __n; 265 } 266 267 template<typename _CharT, typename _Traits, typename _Alloc, 268 template <typename, typename, typename> class _Base> 269 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 270 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 271 find(const _CharT* __s, size_type __pos, size_type __n) const 272 { 273 __glibcxx_requires_string_len(__s, __n); 274 const size_type __size = this->size(); 275 const _CharT* __data = this->_M_data(); 276 277 if (__n == 0) 278 return __pos <= __size ? __pos : npos; 279 280 if (__n <= __size) 281 { 282 for (; __pos <= __size - __n; ++__pos) 283 if (traits_type::eq(__data[__pos], __s[0]) 284 && traits_type::compare(__data + __pos + 1, 285 __s + 1, __n - 1) == 0) 286 return __pos; 287 } 288 return npos; 289 } 290 291 template<typename _CharT, typename _Traits, typename _Alloc, 292 template <typename, typename, typename> class _Base> 293 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 294 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 295 find(_CharT __c, size_type __pos) const 296 { 297 size_type __ret = npos; 298 const size_type __size = this->size(); 299 if (__pos < __size) 300 { 301 const _CharT* __data = this->_M_data(); 302 const size_type __n = __size - __pos; 303 const _CharT* __p = traits_type::find(__data + __pos, __n, __c); 304 if (__p) 305 __ret = __p - __data; 306 } 307 return __ret; 308 } 309 310 template<typename _CharT, typename _Traits, typename _Alloc, 311 template <typename, typename, typename> class _Base> 312 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 313 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 314 rfind(const _CharT* __s, size_type __pos, size_type __n) const 315 { 316 __glibcxx_requires_string_len(__s, __n); 317 const size_type __size = this->size(); 318 if (__n <= __size) 319 { 320 __pos = std::min(size_type(__size - __n), __pos); 321 const _CharT* __data = this->_M_data(); 322 do 323 { 324 if (traits_type::compare(__data + __pos, __s, __n) == 0) 325 return __pos; 326 } 327 while (__pos-- > 0); 328 } 329 return npos; 330 } 331 332 template<typename _CharT, typename _Traits, typename _Alloc, 333 template <typename, typename, typename> class _Base> 334 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 335 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 336 rfind(_CharT __c, size_type __pos) const 337 { 338 size_type __size = this->size(); 339 if (__size) 340 { 341 if (--__size > __pos) 342 __size = __pos; 343 for (++__size; __size-- > 0; ) 344 if (traits_type::eq(this->_M_data()[__size], __c)) 345 return __size; 346 } 347 return npos; 348 } 349 350 template<typename _CharT, typename _Traits, typename _Alloc, 351 template <typename, typename, typename> class _Base> 352 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 353 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 354 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 355 { 356 __glibcxx_requires_string_len(__s, __n); 357 for (; __n && __pos < this->size(); ++__pos) 358 { 359 const _CharT* __p = traits_type::find(__s, __n, 360 this->_M_data()[__pos]); 361 if (__p) 362 return __pos; 363 } 364 return npos; 365 } 366 367 template<typename _CharT, typename _Traits, typename _Alloc, 368 template <typename, typename, typename> class _Base> 369 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 370 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 371 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 372 { 373 __glibcxx_requires_string_len(__s, __n); 374 size_type __size = this->size(); 375 if (__size && __n) 376 { 377 if (--__size > __pos) 378 __size = __pos; 379 do 380 { 381 if (traits_type::find(__s, __n, this->_M_data()[__size])) 382 return __size; 383 } 384 while (__size-- != 0); 385 } 386 return npos; 387 } 388 389 template<typename _CharT, typename _Traits, typename _Alloc, 390 template <typename, typename, typename> class _Base> 391 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 392 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 393 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 394 { 395 __glibcxx_requires_string_len(__s, __n); 396 for (; __pos < this->size(); ++__pos) 397 if (!traits_type::find(__s, __n, this->_M_data()[__pos])) 398 return __pos; 399 return npos; 400 } 401 402 template<typename _CharT, typename _Traits, typename _Alloc, 403 template <typename, typename, typename> class _Base> 404 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 405 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 406 find_first_not_of(_CharT __c, size_type __pos) const 407 { 408 for (; __pos < this->size(); ++__pos) 409 if (!traits_type::eq(this->_M_data()[__pos], __c)) 410 return __pos; 411 return npos; 412 } 413 414 template<typename _CharT, typename _Traits, typename _Alloc, 415 template <typename, typename, typename> class _Base> 416 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 417 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 418 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 419 { 420 __glibcxx_requires_string_len(__s, __n); 421 size_type __size = this->size(); 422 if (__size) 423 { 424 if (--__size > __pos) 425 __size = __pos; 426 do 427 { 428 if (!traits_type::find(__s, __n, this->_M_data()[__size])) 429 return __size; 430 } 431 while (__size--); 432 } 433 return npos; 434 } 435 436 template<typename _CharT, typename _Traits, typename _Alloc, 437 template <typename, typename, typename> class _Base> 438 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 439 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 440 find_last_not_of(_CharT __c, size_type __pos) const 441 { 442 size_type __size = this->size(); 443 if (__size) 444 { 445 if (--__size > __pos) 446 __size = __pos; 447 do 448 { 449 if (!traits_type::eq(this->_M_data()[__size], __c)) 450 return __size; 451 } 452 while (__size--); 453 } 454 return npos; 455 } 456 457 template<typename _CharT, typename _Traits, typename _Alloc, 458 template <typename, typename, typename> class _Base> 459 int 460 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 461 compare(size_type __pos, size_type __n, const __versa_string& __str) const 462 { 463 _M_check(__pos, "__versa_string::compare"); 464 __n = _M_limit(__pos, __n); 465 const size_type __osize = __str.size(); 466 const size_type __len = std::min(__n, __osize); 467 int __r = traits_type::compare(this->_M_data() + __pos, 468 __str.data(), __len); 469 if (!__r) 470 __r = __n - __osize; 471 return __r; 472 } 473 474 template<typename _CharT, typename _Traits, typename _Alloc, 475 template <typename, typename, typename> class _Base> 476 int 477 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 478 compare(size_type __pos1, size_type __n1, const __versa_string& __str, 479 size_type __pos2, size_type __n2) const 480 { 481 _M_check(__pos1, "__versa_string::compare"); 482 __str._M_check(__pos2, "__versa_string::compare"); 483 __n1 = _M_limit(__pos1, __n1); 484 __n2 = __str._M_limit(__pos2, __n2); 485 const size_type __len = std::min(__n1, __n2); 486 int __r = traits_type::compare(this->_M_data() + __pos1, 487 __str.data() + __pos2, __len); 488 if (!__r) 489 __r = __n1 - __n2; 490 return __r; 491 } 492 493 template<typename _CharT, typename _Traits, typename _Alloc, 494 template <typename, typename, typename> class _Base> 495 int 496 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 497 compare(const _CharT* __s) const 498 { 499 __glibcxx_requires_string(__s); 500 const size_type __size = this->size(); 501 const size_type __osize = traits_type::length(__s); 502 const size_type __len = std::min(__size, __osize); 503 int __r = traits_type::compare(this->_M_data(), __s, __len); 504 if (!__r) 505 __r = __size - __osize; 506 return __r; 507 } 508 509 template<typename _CharT, typename _Traits, typename _Alloc, 510 template <typename, typename, typename> class _Base> 511 int 512 __versa_string <_CharT, _Traits, _Alloc, _Base>:: 513 compare(size_type __pos, size_type __n1, const _CharT* __s) const 514 { 515 __glibcxx_requires_string(__s); 516 _M_check(__pos, "__versa_string::compare"); 517 __n1 = _M_limit(__pos, __n1); 518 const size_type __osize = traits_type::length(__s); 519 const size_type __len = std::min(__n1, __osize); 520 int __r = traits_type::compare(this->_M_data() + __pos, __s, __len); 521 if (!__r) 522 __r = __n1 - __osize; 523 return __r; 524 } 525 526 template<typename _CharT, typename _Traits, typename _Alloc, 527 template <typename, typename, typename> class _Base> 528 int 529 __versa_string <_CharT, _Traits, _Alloc, _Base>:: 530 compare(size_type __pos, size_type __n1, const _CharT* __s, 531 size_type __n2) const 532 { 533 __glibcxx_requires_string_len(__s, __n2); 534 _M_check(__pos, "__versa_string::compare"); 535 __n1 = _M_limit(__pos, __n1); 536 const size_type __len = std::min(__n1, __n2); 537 int __r = traits_type::compare(this->_M_data() + __pos, __s, __len); 538 if (!__r) 539 __r = __n1 - __n2; 540 return __r; 541 } 542 543 _GLIBCXX_END_NAMESPACE 544 545 _GLIBCXX_BEGIN_NAMESPACE(std) 546 547 template<typename _CharT, typename _Traits, typename _Alloc, 548 template <typename, typename, typename> class _Base> 549 basic_istream<_CharT, _Traits>& 550 operator>>(basic_istream<_CharT, _Traits>& __in, 551 __gnu_cxx::__versa_string<_CharT, _Traits, 552 _Alloc, _Base>& __str) 553 { 554 typedef basic_istream<_CharT, _Traits> __istream_type; 555 typedef typename __istream_type::int_type __int_type; 556 typedef typename __istream_type::__streambuf_type __streambuf_type; 557 typedef typename __istream_type::__ctype_type __ctype_type; 558 typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base> 559 __string_type; 560 typedef typename __string_type::size_type __size_type; 561 562 __size_type __extracted = 0; 563 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 564 typename __istream_type::sentry __cerb(__in, false); 565 if (__cerb) 566 { 567 try 568 { 569 // Avoid reallocation for common case. 570 __str.erase(); 571 _CharT __buf[128]; 572 __size_type __len = 0; 573 const streamsize __w = __in.width(); 574 const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) 575 : __str.max_size(); 576 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); 577 const __int_type __eof = _Traits::eof(); 578 __streambuf_type* __sb = __in.rdbuf(); 579 __int_type __c = __sb->sgetc(); 580 581 while (__extracted < __n 582 && !_Traits::eq_int_type(__c, __eof) 583 && !__ct.is(ctype_base::space, _Traits::to_char_type(__c))) 584 { 585 if (__len == sizeof(__buf) / sizeof(_CharT)) 586 { 587 __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); 588 __len = 0; 589 } 590 __buf[__len++] = _Traits::to_char_type(__c); 591 ++__extracted; 592 __c = __sb->snextc(); 593 } 594 __str.append(__buf, __len); 595 596 if (_Traits::eq_int_type(__c, __eof)) 597 __err |= ios_base::eofbit; 598 __in.width(0); 599 } 600 catch(...) 601 { 602 // _GLIBCXX_RESOLVE_LIB_DEFECTS 603 // 91. Description of operator>> and getline() for string<> 604 // might cause endless loop 605 __in._M_setstate(ios_base::badbit); 606 } 607 } 608 // 211. operator>>(istream&, string&) doesn't set failbit 609 if (!__extracted) 610 __err |= ios_base::failbit; 611 if (__err) 612 __in.setstate(__err); 613 return __in; 614 } 615 616 template<typename _CharT, typename _Traits, typename _Alloc, 617 template <typename, typename, typename> class _Base> 618 basic_istream<_CharT, _Traits>& 619 getline(basic_istream<_CharT, _Traits>& __in, 620 __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str, 621 _CharT __delim) 622 { 623 typedef basic_istream<_CharT, _Traits> __istream_type; 624 typedef typename __istream_type::int_type __int_type; 625 typedef typename __istream_type::__streambuf_type __streambuf_type; 626 typedef typename __istream_type::__ctype_type __ctype_type; 627 typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base> 628 __string_type; 629 typedef typename __string_type::size_type __size_type; 630 631 __size_type __extracted = 0; 632 const __size_type __n = __str.max_size(); 633 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 634 typename __istream_type::sentry __cerb(__in, true); 635 if (__cerb) 636 { 637 try 638 { 639 // Avoid reallocation for common case. 640 __str.erase(); 641 _CharT __buf[128]; 642 __size_type __len = 0; 643 const __int_type __idelim = _Traits::to_int_type(__delim); 644 const __int_type __eof = _Traits::eof(); 645 __streambuf_type* __sb = __in.rdbuf(); 646 __int_type __c = __sb->sgetc(); 647 648 while (__extracted < __n 649 && !_Traits::eq_int_type(__c, __eof) 650 && !_Traits::eq_int_type(__c, __idelim)) 651 { 652 if (__len == sizeof(__buf) / sizeof(_CharT)) 653 { 654 __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); 655 __len = 0; 656 } 657 __buf[__len++] = _Traits::to_char_type(__c); 658 ++__extracted; 659 __c = __sb->snextc(); 660 } 661 __str.append(__buf, __len); 662 663 if (_Traits::eq_int_type(__c, __eof)) 664 __err |= ios_base::eofbit; 665 else if (_Traits::eq_int_type(__c, __idelim)) 666 { 667 ++__extracted; 668 __sb->sbumpc(); 669 } 670 else 671 __err |= ios_base::failbit; 672 } 673 catch(...) 674 { 675 // _GLIBCXX_RESOLVE_LIB_DEFECTS 676 // 91. Description of operator>> and getline() for string<> 677 // might cause endless loop 678 __in._M_setstate(ios_base::badbit); 679 } 680 } 681 if (!__extracted) 682 __err |= ios_base::failbit; 683 if (__err) 684 __in.setstate(__err); 685 return __in; 686 } 687 688 _GLIBCXX_END_NAMESPACE 689 690 #endif // _VSTRING_TCC 691