libstdc++
|
00001 // Versatile string -*- C++ -*- 00002 00003 // Copyright (C) 2005-2013 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file ext/vstring.tcc 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{ext/vstring.h} 00028 */ 00029 00030 #ifndef _VSTRING_TCC 00031 #define _VSTRING_TCC 1 00032 00033 #pragma GCC system_header 00034 00035 #include <bits/cxxabi_forced.h> 00036 00037 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 00038 { 00039 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00040 00041 template<typename _CharT, typename _Traits, typename _Alloc, 00042 template <typename, typename, typename> class _Base> 00043 const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 00044 __versa_string<_CharT, _Traits, _Alloc, _Base>::npos; 00045 00046 template<typename _CharT, typename _Traits, typename _Alloc, 00047 template <typename, typename, typename> class _Base> 00048 void 00049 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00050 resize(size_type __n, _CharT __c) 00051 { 00052 const size_type __size = this->size(); 00053 if (__size < __n) 00054 this->append(__n - __size, __c); 00055 else if (__n < __size) 00056 this->_M_erase(__n, __size - __n); 00057 } 00058 00059 template<typename _CharT, typename _Traits, typename _Alloc, 00060 template <typename, typename, typename> class _Base> 00061 __versa_string<_CharT, _Traits, _Alloc, _Base>& 00062 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00063 _M_append(const _CharT* __s, size_type __n) 00064 { 00065 const size_type __len = __n + this->size(); 00066 00067 if (__len <= this->capacity() && !this->_M_is_shared()) 00068 { 00069 if (__n) 00070 this->_S_copy(this->_M_data() + this->size(), __s, __n); 00071 } 00072 else 00073 this->_M_mutate(this->size(), size_type(0), __s, __n); 00074 00075 this->_M_set_length(__len); 00076 return *this; 00077 } 00078 00079 template<typename _CharT, typename _Traits, typename _Alloc, 00080 template <typename, typename, typename> class _Base> 00081 template<typename _InputIterator> 00082 __versa_string<_CharT, _Traits, _Alloc, _Base>& 00083 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00084 _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, 00085 _InputIterator __k2, std::__false_type) 00086 { 00087 const __versa_string __s(__k1, __k2); 00088 const size_type __n1 = __i2 - __i1; 00089 return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(), 00090 __s.size()); 00091 } 00092 00093 template<typename _CharT, typename _Traits, typename _Alloc, 00094 template <typename, typename, typename> class _Base> 00095 __versa_string<_CharT, _Traits, _Alloc, _Base>& 00096 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00097 _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, 00098 _CharT __c) 00099 { 00100 _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux"); 00101 00102 const size_type __old_size = this->size(); 00103 const size_type __new_size = __old_size + __n2 - __n1; 00104 00105 if (__new_size <= this->capacity() && !this->_M_is_shared()) 00106 { 00107 _CharT* __p = this->_M_data() + __pos1; 00108 00109 const size_type __how_much = __old_size - __pos1 - __n1; 00110 if (__how_much && __n1 != __n2) 00111 this->_S_move(__p + __n2, __p + __n1, __how_much); 00112 } 00113 else 00114 this->_M_mutate(__pos1, __n1, 0, __n2); 00115 00116 if (__n2) 00117 this->_S_assign(this->_M_data() + __pos1, __n2, __c); 00118 00119 this->_M_set_length(__new_size); 00120 return *this; 00121 } 00122 00123 template<typename _CharT, typename _Traits, typename _Alloc, 00124 template <typename, typename, typename> class _Base> 00125 __versa_string<_CharT, _Traits, _Alloc, _Base>& 00126 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00127 _M_replace(size_type __pos, size_type __len1, const _CharT* __s, 00128 const size_type __len2) 00129 { 00130 _M_check_length(__len1, __len2, "__versa_string::_M_replace"); 00131 00132 const size_type __old_size = this->size(); 00133 const size_type __new_size = __old_size + __len2 - __len1; 00134 00135 if (__new_size <= this->capacity() && !this->_M_is_shared()) 00136 { 00137 _CharT* __p = this->_M_data() + __pos; 00138 00139 const size_type __how_much = __old_size - __pos - __len1; 00140 if (_M_disjunct(__s)) 00141 { 00142 if (__how_much && __len1 != __len2) 00143 this->_S_move(__p + __len2, __p + __len1, __how_much); 00144 if (__len2) 00145 this->_S_copy(__p, __s, __len2); 00146 } 00147 else 00148 { 00149 // Work in-place. 00150 if (__len2 && __len2 <= __len1) 00151 this->_S_move(__p, __s, __len2); 00152 if (__how_much && __len1 != __len2) 00153 this->_S_move(__p + __len2, __p + __len1, __how_much); 00154 if (__len2 > __len1) 00155 { 00156 if (__s + __len2 <= __p + __len1) 00157 this->_S_move(__p, __s, __len2); 00158 else if (__s >= __p + __len1) 00159 this->_S_copy(__p, __s + __len2 - __len1, __len2); 00160 else 00161 { 00162 const size_type __nleft = (__p + __len1) - __s; 00163 this->_S_move(__p, __s, __nleft); 00164 this->_S_copy(__p + __nleft, __p + __len2, 00165 __len2 - __nleft); 00166 } 00167 } 00168 } 00169 } 00170 else 00171 this->_M_mutate(__pos, __len1, __s, __len2); 00172 00173 this->_M_set_length(__new_size); 00174 return *this; 00175 } 00176 00177 template<typename _CharT, typename _Traits, typename _Alloc, 00178 template <typename, typename, typename> class _Base> 00179 __versa_string<_CharT, _Traits, _Alloc, _Base> 00180 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, 00181 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) 00182 { 00183 __versa_string<_CharT, _Traits, _Alloc, _Base> __str; 00184 __str.reserve(__lhs.size() + __rhs.size()); 00185 __str.append(__lhs); 00186 __str.append(__rhs); 00187 return __str; 00188 } 00189 00190 template<typename _CharT, typename _Traits, typename _Alloc, 00191 template <typename, typename, typename> class _Base> 00192 __versa_string<_CharT, _Traits, _Alloc, _Base> 00193 operator+(const _CharT* __lhs, 00194 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) 00195 { 00196 __glibcxx_requires_string(__lhs); 00197 typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; 00198 typedef typename __string_type::size_type __size_type; 00199 const __size_type __len = _Traits::length(__lhs); 00200 __string_type __str; 00201 __str.reserve(__len + __rhs.size()); 00202 __str.append(__lhs, __len); 00203 __str.append(__rhs); 00204 return __str; 00205 } 00206 00207 template<typename _CharT, typename _Traits, typename _Alloc, 00208 template <typename, typename, typename> class _Base> 00209 __versa_string<_CharT, _Traits, _Alloc, _Base> 00210 operator+(_CharT __lhs, 00211 const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) 00212 { 00213 __versa_string<_CharT, _Traits, _Alloc, _Base> __str; 00214 __str.reserve(__rhs.size() + 1); 00215 __str.push_back(__lhs); 00216 __str.append(__rhs); 00217 return __str; 00218 } 00219 00220 template<typename _CharT, typename _Traits, typename _Alloc, 00221 template <typename, typename, typename> class _Base> 00222 __versa_string<_CharT, _Traits, _Alloc, _Base> 00223 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, 00224 const _CharT* __rhs) 00225 { 00226 __glibcxx_requires_string(__rhs); 00227 typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; 00228 typedef typename __string_type::size_type __size_type; 00229 const __size_type __len = _Traits::length(__rhs); 00230 __string_type __str; 00231 __str.reserve(__lhs.size() + __len); 00232 __str.append(__lhs); 00233 __str.append(__rhs, __len); 00234 return __str; 00235 } 00236 00237 template<typename _CharT, typename _Traits, typename _Alloc, 00238 template <typename, typename, typename> class _Base> 00239 __versa_string<_CharT, _Traits, _Alloc, _Base> 00240 operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, 00241 _CharT __rhs) 00242 { 00243 __versa_string<_CharT, _Traits, _Alloc, _Base> __str; 00244 __str.reserve(__lhs.size() + 1); 00245 __str.append(__lhs); 00246 __str.push_back(__rhs); 00247 return __str; 00248 } 00249 00250 template<typename _CharT, typename _Traits, typename _Alloc, 00251 template <typename, typename, typename> class _Base> 00252 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 00253 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00254 copy(_CharT* __s, size_type __n, size_type __pos) const 00255 { 00256 _M_check(__pos, "__versa_string::copy"); 00257 __n = _M_limit(__pos, __n); 00258 __glibcxx_requires_string_len(__s, __n); 00259 if (__n) 00260 this->_S_copy(__s, this->_M_data() + __pos, __n); 00261 // 21.3.5.7 par 3: do not append null. (good.) 00262 return __n; 00263 } 00264 00265 template<typename _CharT, typename _Traits, typename _Alloc, 00266 template <typename, typename, typename> class _Base> 00267 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 00268 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00269 find(const _CharT* __s, size_type __pos, size_type __n) const 00270 { 00271 __glibcxx_requires_string_len(__s, __n); 00272 const size_type __size = this->size(); 00273 const _CharT* __data = this->_M_data(); 00274 00275 if (__n == 0) 00276 return __pos <= __size ? __pos : npos; 00277 00278 if (__n <= __size) 00279 { 00280 for (; __pos <= __size - __n; ++__pos) 00281 if (traits_type::eq(__data[__pos], __s[0]) 00282 && traits_type::compare(__data + __pos + 1, 00283 __s + 1, __n - 1) == 0) 00284 return __pos; 00285 } 00286 return npos; 00287 } 00288 00289 template<typename _CharT, typename _Traits, typename _Alloc, 00290 template <typename, typename, typename> class _Base> 00291 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 00292 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00293 find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 00294 { 00295 size_type __ret = npos; 00296 const size_type __size = this->size(); 00297 if (__pos < __size) 00298 { 00299 const _CharT* __data = this->_M_data(); 00300 const size_type __n = __size - __pos; 00301 const _CharT* __p = traits_type::find(__data + __pos, __n, __c); 00302 if (__p) 00303 __ret = __p - __data; 00304 } 00305 return __ret; 00306 } 00307 00308 template<typename _CharT, typename _Traits, typename _Alloc, 00309 template <typename, typename, typename> class _Base> 00310 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 00311 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00312 rfind(const _CharT* __s, size_type __pos, size_type __n) const 00313 { 00314 __glibcxx_requires_string_len(__s, __n); 00315 const size_type __size = this->size(); 00316 if (__n <= __size) 00317 { 00318 __pos = std::min(size_type(__size - __n), __pos); 00319 const _CharT* __data = this->_M_data(); 00320 do 00321 { 00322 if (traits_type::compare(__data + __pos, __s, __n) == 0) 00323 return __pos; 00324 } 00325 while (__pos-- > 0); 00326 } 00327 return npos; 00328 } 00329 00330 template<typename _CharT, typename _Traits, typename _Alloc, 00331 template <typename, typename, typename> class _Base> 00332 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 00333 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00334 rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 00335 { 00336 size_type __size = this->size(); 00337 if (__size) 00338 { 00339 if (--__size > __pos) 00340 __size = __pos; 00341 for (++__size; __size-- > 0; ) 00342 if (traits_type::eq(this->_M_data()[__size], __c)) 00343 return __size; 00344 } 00345 return npos; 00346 } 00347 00348 template<typename _CharT, typename _Traits, typename _Alloc, 00349 template <typename, typename, typename> class _Base> 00350 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 00351 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00352 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 00353 { 00354 __glibcxx_requires_string_len(__s, __n); 00355 for (; __n && __pos < this->size(); ++__pos) 00356 { 00357 const _CharT* __p = traits_type::find(__s, __n, 00358 this->_M_data()[__pos]); 00359 if (__p) 00360 return __pos; 00361 } 00362 return npos; 00363 } 00364 00365 template<typename _CharT, typename _Traits, typename _Alloc, 00366 template <typename, typename, typename> class _Base> 00367 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 00368 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00369 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 00370 { 00371 __glibcxx_requires_string_len(__s, __n); 00372 size_type __size = this->size(); 00373 if (__size && __n) 00374 { 00375 if (--__size > __pos) 00376 __size = __pos; 00377 do 00378 { 00379 if (traits_type::find(__s, __n, this->_M_data()[__size])) 00380 return __size; 00381 } 00382 while (__size-- != 0); 00383 } 00384 return npos; 00385 } 00386 00387 template<typename _CharT, typename _Traits, typename _Alloc, 00388 template <typename, typename, typename> class _Base> 00389 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 00390 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00391 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 00392 { 00393 __glibcxx_requires_string_len(__s, __n); 00394 for (; __pos < this->size(); ++__pos) 00395 if (!traits_type::find(__s, __n, this->_M_data()[__pos])) 00396 return __pos; 00397 return npos; 00398 } 00399 00400 template<typename _CharT, typename _Traits, typename _Alloc, 00401 template <typename, typename, typename> class _Base> 00402 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 00403 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00404 find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 00405 { 00406 for (; __pos < this->size(); ++__pos) 00407 if (!traits_type::eq(this->_M_data()[__pos], __c)) 00408 return __pos; 00409 return npos; 00410 } 00411 00412 template<typename _CharT, typename _Traits, typename _Alloc, 00413 template <typename, typename, typename> class _Base> 00414 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 00415 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00416 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 00417 { 00418 __glibcxx_requires_string_len(__s, __n); 00419 size_type __size = this->size(); 00420 if (__size) 00421 { 00422 if (--__size > __pos) 00423 __size = __pos; 00424 do 00425 { 00426 if (!traits_type::find(__s, __n, this->_M_data()[__size])) 00427 return __size; 00428 } 00429 while (__size--); 00430 } 00431 return npos; 00432 } 00433 00434 template<typename _CharT, typename _Traits, typename _Alloc, 00435 template <typename, typename, typename> class _Base> 00436 typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type 00437 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00438 find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT 00439 { 00440 size_type __size = this->size(); 00441 if (__size) 00442 { 00443 if (--__size > __pos) 00444 __size = __pos; 00445 do 00446 { 00447 if (!traits_type::eq(this->_M_data()[__size], __c)) 00448 return __size; 00449 } 00450 while (__size--); 00451 } 00452 return npos; 00453 } 00454 00455 template<typename _CharT, typename _Traits, typename _Alloc, 00456 template <typename, typename, typename> class _Base> 00457 int 00458 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00459 compare(size_type __pos, size_type __n, const __versa_string& __str) const 00460 { 00461 _M_check(__pos, "__versa_string::compare"); 00462 __n = _M_limit(__pos, __n); 00463 const size_type __osize = __str.size(); 00464 const size_type __len = std::min(__n, __osize); 00465 int __r = traits_type::compare(this->_M_data() + __pos, 00466 __str.data(), __len); 00467 if (!__r) 00468 __r = this->_S_compare(__n, __osize); 00469 return __r; 00470 } 00471 00472 template<typename _CharT, typename _Traits, typename _Alloc, 00473 template <typename, typename, typename> class _Base> 00474 int 00475 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00476 compare(size_type __pos1, size_type __n1, const __versa_string& __str, 00477 size_type __pos2, size_type __n2) const 00478 { 00479 _M_check(__pos1, "__versa_string::compare"); 00480 __str._M_check(__pos2, "__versa_string::compare"); 00481 __n1 = _M_limit(__pos1, __n1); 00482 __n2 = __str._M_limit(__pos2, __n2); 00483 const size_type __len = std::min(__n1, __n2); 00484 int __r = traits_type::compare(this->_M_data() + __pos1, 00485 __str.data() + __pos2, __len); 00486 if (!__r) 00487 __r = this->_S_compare(__n1, __n2); 00488 return __r; 00489 } 00490 00491 template<typename _CharT, typename _Traits, typename _Alloc, 00492 template <typename, typename, typename> class _Base> 00493 int 00494 __versa_string<_CharT, _Traits, _Alloc, _Base>:: 00495 compare(const _CharT* __s) const 00496 { 00497 __glibcxx_requires_string(__s); 00498 const size_type __size = this->size(); 00499 const size_type __osize = traits_type::length(__s); 00500 const size_type __len = std::min(__size, __osize); 00501 int __r = traits_type::compare(this->_M_data(), __s, __len); 00502 if (!__r) 00503 __r = this->_S_compare(__size, __osize); 00504 return __r; 00505 } 00506 00507 template<typename _CharT, typename _Traits, typename _Alloc, 00508 template <typename, typename, typename> class _Base> 00509 int 00510 __versa_string <_CharT, _Traits, _Alloc, _Base>:: 00511 compare(size_type __pos, size_type __n1, const _CharT* __s) const 00512 { 00513 __glibcxx_requires_string(__s); 00514 _M_check(__pos, "__versa_string::compare"); 00515 __n1 = _M_limit(__pos, __n1); 00516 const size_type __osize = traits_type::length(__s); 00517 const size_type __len = std::min(__n1, __osize); 00518 int __r = traits_type::compare(this->_M_data() + __pos, __s, __len); 00519 if (!__r) 00520 __r = this->_S_compare(__n1, __osize); 00521 return __r; 00522 } 00523 00524 template<typename _CharT, typename _Traits, typename _Alloc, 00525 template <typename, typename, typename> class _Base> 00526 int 00527 __versa_string <_CharT, _Traits, _Alloc, _Base>:: 00528 compare(size_type __pos, size_type __n1, const _CharT* __s, 00529 size_type __n2) const 00530 { 00531 __glibcxx_requires_string_len(__s, __n2); 00532 _M_check(__pos, "__versa_string::compare"); 00533 __n1 = _M_limit(__pos, __n1); 00534 const size_type __len = std::min(__n1, __n2); 00535 int __r = traits_type::compare(this->_M_data() + __pos, __s, __len); 00536 if (!__r) 00537 __r = this->_S_compare(__n1, __n2); 00538 return __r; 00539 } 00540 00541 _GLIBCXX_END_NAMESPACE_VERSION 00542 } // namespace 00543 00544 namespace std _GLIBCXX_VISIBILITY(default) 00545 { 00546 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00547 00548 template<typename _CharT, typename _Traits, typename _Alloc, 00549 template <typename, typename, typename> class _Base> 00550 basic_istream<_CharT, _Traits>& 00551 operator>>(basic_istream<_CharT, _Traits>& __in, 00552 __gnu_cxx::__versa_string<_CharT, _Traits, 00553 _Alloc, _Base>& __str) 00554 { 00555 typedef basic_istream<_CharT, _Traits> __istream_type; 00556 typedef typename __istream_type::ios_base __ios_base; 00557 typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base> 00558 __string_type; 00559 typedef typename __istream_type::int_type __int_type; 00560 typedef typename __string_type::size_type __size_type; 00561 typedef ctype<_CharT> __ctype_type; 00562 typedef typename __ctype_type::ctype_base __ctype_base; 00563 00564 __size_type __extracted = 0; 00565 typename __ios_base::iostate __err = __ios_base::goodbit; 00566 typename __istream_type::sentry __cerb(__in, false); 00567 if (__cerb) 00568 { 00569 __try 00570 { 00571 // Avoid reallocation for common case. 00572 __str.erase(); 00573 _CharT __buf[128]; 00574 __size_type __len = 0; 00575 const streamsize __w = __in.width(); 00576 const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) 00577 : __str.max_size(); 00578 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); 00579 const __int_type __eof = _Traits::eof(); 00580 __int_type __c = __in.rdbuf()->sgetc(); 00581 00582 while (__extracted < __n 00583 && !_Traits::eq_int_type(__c, __eof) 00584 && !__ct.is(__ctype_base::space, 00585 _Traits::to_char_type(__c))) 00586 { 00587 if (__len == sizeof(__buf) / sizeof(_CharT)) 00588 { 00589 __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); 00590 __len = 0; 00591 } 00592 __buf[__len++] = _Traits::to_char_type(__c); 00593 ++__extracted; 00594 __c = __in.rdbuf()->snextc(); 00595 } 00596 __str.append(__buf, __len); 00597 00598 if (_Traits::eq_int_type(__c, __eof)) 00599 __err |= __ios_base::eofbit; 00600 __in.width(0); 00601 } 00602 __catch(__cxxabiv1::__forced_unwind&) 00603 { 00604 __in._M_setstate(__ios_base::badbit); 00605 __throw_exception_again; 00606 } 00607 __catch(...) 00608 { 00609 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00610 // 91. Description of operator>> and getline() for string<> 00611 // might cause endless loop 00612 __in._M_setstate(__ios_base::badbit); 00613 } 00614 } 00615 // 211. operator>>(istream&, string&) doesn't set failbit 00616 if (!__extracted) 00617 __err |= __ios_base::failbit; 00618 if (__err) 00619 __in.setstate(__err); 00620 return __in; 00621 } 00622 00623 template<typename _CharT, typename _Traits, typename _Alloc, 00624 template <typename, typename, typename> class _Base> 00625 basic_istream<_CharT, _Traits>& 00626 getline(basic_istream<_CharT, _Traits>& __in, 00627 __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str, 00628 _CharT __delim) 00629 { 00630 typedef basic_istream<_CharT, _Traits> __istream_type; 00631 typedef typename __istream_type::ios_base __ios_base; 00632 typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base> 00633 __string_type; 00634 typedef typename __istream_type::int_type __int_type; 00635 typedef typename __string_type::size_type __size_type; 00636 00637 __size_type __extracted = 0; 00638 const __size_type __n = __str.max_size(); 00639 typename __ios_base::iostate __err = __ios_base::goodbit; 00640 typename __istream_type::sentry __cerb(__in, true); 00641 if (__cerb) 00642 { 00643 __try 00644 { 00645 // Avoid reallocation for common case. 00646 __str.erase(); 00647 _CharT __buf[128]; 00648 __size_type __len = 0; 00649 const __int_type __idelim = _Traits::to_int_type(__delim); 00650 const __int_type __eof = _Traits::eof(); 00651 __int_type __c = __in.rdbuf()->sgetc(); 00652 00653 while (__extracted < __n 00654 && !_Traits::eq_int_type(__c, __eof) 00655 && !_Traits::eq_int_type(__c, __idelim)) 00656 { 00657 if (__len == sizeof(__buf) / sizeof(_CharT)) 00658 { 00659 __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); 00660 __len = 0; 00661 } 00662 __buf[__len++] = _Traits::to_char_type(__c); 00663 ++__extracted; 00664 __c = __in.rdbuf()->snextc(); 00665 } 00666 __str.append(__buf, __len); 00667 00668 if (_Traits::eq_int_type(__c, __eof)) 00669 __err |= __ios_base::eofbit; 00670 else if (_Traits::eq_int_type(__c, __idelim)) 00671 { 00672 ++__extracted; 00673 __in.rdbuf()->sbumpc(); 00674 } 00675 else 00676 __err |= __ios_base::failbit; 00677 } 00678 __catch(__cxxabiv1::__forced_unwind&) 00679 { 00680 __in._M_setstate(__ios_base::badbit); 00681 __throw_exception_again; 00682 } 00683 __catch(...) 00684 { 00685 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00686 // 91. Description of operator>> and getline() for string<> 00687 // might cause endless loop 00688 __in._M_setstate(__ios_base::badbit); 00689 } 00690 } 00691 if (!__extracted) 00692 __err |= __ios_base::failbit; 00693 if (__err) 00694 __in.setstate(__err); 00695 return __in; 00696 } 00697 00698 _GLIBCXX_END_NAMESPACE_VERSION 00699 } // namespace 00700 00701 #endif // _VSTRING_TCC