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