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