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