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