Whole document tree basic_string.tccGo to the documentation of this file.00001 // Components for manipulating sequences of characters -*- C++ -*- 00002 00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001 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 2, 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 // You should have received a copy of the GNU General Public License along 00017 // with this library; see the file COPYING. If not, write to the Free 00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00019 // USA. 00020 00021 // As a special exception, you may use this file as part of a free software 00022 // library without restriction. Specifically, if other files instantiate 00023 // templates or use macros or inline functions from this file, or you compile 00024 // this file and link it with other files to produce an executable, this 00025 // file does not by itself cause the resulting executable to be covered by 00026 // the GNU General Public License. This exception does not however 00027 // invalidate any other reasons why the executable file might be covered by 00028 // the GNU General Public License. 00029 00030 // 00031 // ISO C++ 14882: 21 Strings library 00032 // 00033 00034 // This file is included by <string>. It is not meant to be included 00035 // separately. 00036 00037 // Written by Jason Merrill based upon the specification by Takanori Adachi 00038 // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. 00039 00040 #ifndef _CPP_BITS_STRING_TCC 00041 #define _CPP_BITS_STRING_TCC 1 00042 00043 namespace std 00044 { 00045 template<typename _CharT, typename _Traits, typename _Alloc> 00046 const _CharT 00047 basic_string<_CharT, _Traits, _Alloc>:: 00048 _Rep::_S_terminal = _CharT(); 00049 00050 template<typename _CharT, typename _Traits, typename _Alloc> 00051 const typename basic_string<_CharT, _Traits, _Alloc>::size_type 00052 basic_string<_CharT, _Traits, _Alloc>:: 00053 _Rep::_S_max_size = (((npos - sizeof(_Rep))/sizeof(_CharT)) - 1) / 4; 00054 00055 template<typename _CharT, typename _Traits, typename _Alloc> 00056 const typename basic_string<_CharT, _Traits, _Alloc>::size_type 00057 basic_string<_CharT, _Traits, _Alloc>::npos; 00058 00059 // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string) 00060 // at static init time (before static ctors are run). 00061 template<typename _CharT, typename _Traits, typename _Alloc> 00062 typename basic_string<_CharT, _Traits, _Alloc>::size_type 00063 basic_string<_CharT, _Traits, _Alloc>::_S_empty_rep_storage[ 00064 (sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)]; 00065 00066 // NB: This is the special case for Input Iterators, used in 00067 // istreambuf_iterators, etc. 00068 // Input Iterators have a cost structure very different from 00069 // pointers, calling for a different coding style. 00070 template<typename _CharT, typename _Traits, typename _Alloc> 00071 template<typename _InIter> 00072 _CharT* 00073 basic_string<_CharT, _Traits, _Alloc>:: 00074 _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, 00075 input_iterator_tag) 00076 { 00077 if (__beg == __end && __a == _Alloc()) 00078 return _S_empty_rep()._M_refcopy(); 00079 // Avoid reallocation for common case. 00080 _CharT __buf[100]; 00081 size_type __i = 0; 00082 while (__beg != __end && __i < sizeof(__buf) / sizeof(_CharT)) 00083 { 00084 __buf[__i++] = *__beg; 00085 ++__beg; 00086 } 00087 _Rep* __r = _Rep::_S_create(__i, __a); 00088 traits_type::copy(__r->_M_refdata(), __buf, __i); 00089 __r->_M_length = __i; 00090 try 00091 { 00092 // NB: this loop looks precisely this way because 00093 // it avoids comparing __beg != __end any more 00094 // than strictly necessary; != might be expensive! 00095 for (;;) 00096 { 00097 _CharT* __p = __r->_M_refdata() + __r->_M_length; 00098 _CharT* __last = __r->_M_refdata() + __r->_M_capacity; 00099 for (;;) 00100 { 00101 if (__beg == __end) 00102 { 00103 __r->_M_length = __p - __r->_M_refdata(); 00104 *__p = _Rep::_S_terminal; // grrr. 00105 return __r->_M_refdata(); 00106 } 00107 if (__p == __last) 00108 break; 00109 *__p++ = *__beg; 00110 ++__beg; 00111 } 00112 // Allocate more space. 00113 size_type __len = __p - __r->_M_refdata(); 00114 _Rep* __another = _Rep::_S_create(__len + 1, __a); 00115 traits_type::copy(__another->_M_refdata(), 00116 __r->_M_refdata(), __len); 00117 __r->_M_destroy(__a); 00118 __r = __another; 00119 __r->_M_length = __len; 00120 } 00121 } 00122 catch(...) 00123 { 00124 __r->_M_destroy(__a); 00125 __throw_exception_again; 00126 } 00127 return 0; 00128 } 00129 00130 template<typename _CharT, typename _Traits, typename _Alloc> 00131 template <class _InIter> 00132 _CharT* 00133 basic_string<_CharT,_Traits,_Alloc>:: 00134 _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, 00135 forward_iterator_tag) 00136 { 00137 size_type __dnew = static_cast<size_type>(distance(__beg, __end)); 00138 00139 if (__beg == __end && __a == _Alloc()) 00140 return _S_empty_rep()._M_refcopy(); 00141 00142 // Check for out_of_range and length_error exceptions. 00143 _Rep* __r = _Rep::_S_create(__dnew, __a); 00144 try 00145 { _S_copy_chars(__r->_M_refdata(), __beg, __end); } 00146 catch(...) 00147 { 00148 __r->_M_destroy(__a); 00149 __throw_exception_again; 00150 } 00151 __r->_M_length = __dnew; 00152 00153 __r->_M_refdata()[__dnew] = _Rep::_S_terminal; // grrr. 00154 return __r->_M_refdata(); 00155 } 00156 00157 template<typename _CharT, typename _Traits, typename _Alloc> 00158 _CharT* 00159 basic_string<_CharT,_Traits, _Alloc>:: 00160 _S_construct(size_type __n, _CharT __c, const _Alloc& __a) 00161 { 00162 if (__n == 0 && __a == _Alloc()) 00163 return _S_empty_rep()._M_refcopy(); 00164 00165 // Check for out_of_range and length_error exceptions. 00166 _Rep* __r = _Rep::_S_create(__n, __a); 00167 try 00168 { 00169 if (__n) 00170 traits_type::assign(__r->_M_refdata(), __n, __c); 00171 } 00172 catch(...) 00173 { 00174 __r->_M_destroy(__a); 00175 __throw_exception_again; 00176 } 00177 __r->_M_length = __n; 00178 __r->_M_refdata()[__n] = _Rep::_S_terminal; // grrr 00179 return __r->_M_refdata(); 00180 } 00181 00182 template<typename _CharT, typename _Traits, typename _Alloc> 00183 basic_string<_CharT, _Traits, _Alloc>:: 00184 basic_string(const basic_string& __str) 00185 : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(), __str.get_allocator()), 00186 __str.get_allocator()) 00187 { } 00188 00189 template<typename _CharT, typename _Traits, typename _Alloc> 00190 basic_string<_CharT, _Traits, _Alloc>:: 00191 basic_string(const _Alloc& __a) 00192 : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) 00193 { } 00194 00195 template<typename _CharT, typename _Traits, typename _Alloc> 00196 basic_string<_CharT, _Traits, _Alloc>:: 00197 basic_string(const basic_string& __str, size_type __pos, size_type __n) 00198 : _M_dataplus(_S_construct(__str._M_check(__pos), 00199 __str._M_fold(__pos, __n), _Alloc()), _Alloc()) 00200 { } 00201 00202 template<typename _CharT, typename _Traits, typename _Alloc> 00203 basic_string<_CharT, _Traits, _Alloc>:: 00204 basic_string(const basic_string& __str, size_type __pos, 00205 size_type __n, const _Alloc& __a) 00206 : _M_dataplus(_S_construct(__str._M_check(__pos), 00207 __str._M_fold(__pos, __n), __a), __a) 00208 { } 00209 00210 template<typename _CharT, typename _Traits, typename _Alloc> 00211 basic_string<_CharT, _Traits, _Alloc>:: 00212 basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) 00213 : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) 00214 { } 00215 00216 template<typename _CharT, typename _Traits, typename _Alloc> 00217 basic_string<_CharT, _Traits, _Alloc>:: 00218 basic_string(const _CharT* __s, const _Alloc& __a) 00219 : _M_dataplus(_S_construct(__s, __s + traits_type::length(__s), __a), __a) 00220 { } 00221 00222 template<typename _CharT, typename _Traits, typename _Alloc> 00223 basic_string<_CharT, _Traits, _Alloc>:: 00224 basic_string(size_type __n, _CharT __c, const _Alloc& __a) 00225 : _M_dataplus(_S_construct(__n, __c, __a), __a) 00226 { } 00227 00228 template<typename _CharT, typename _Traits, typename _Alloc> 00229 template<typename _InputIter> 00230 basic_string<_CharT, _Traits, _Alloc>:: 00231 basic_string(_InputIter __beg, _InputIter __end, const _Alloc& __a) 00232 : _M_dataplus(_S_construct(__beg, __end, __a), __a) 00233 { } 00234 00235 template<typename _CharT, typename _Traits, typename _Alloc> 00236 basic_string<_CharT, _Traits, _Alloc>& 00237 basic_string<_CharT, _Traits, _Alloc>::assign(const basic_string& __str) 00238 { 00239 if (_M_rep() != __str._M_rep()) 00240 { 00241 // XXX MT 00242 allocator_type __a = this->get_allocator(); 00243 _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); 00244 _M_rep()->_M_dispose(__a); 00245 _M_data(__tmp); 00246 } 00247 return *this; 00248 } 00249 00250 template<typename _CharT, typename _Traits, typename _Alloc> 00251 void 00252 basic_string<_CharT, _Traits, _Alloc>::_Rep:: 00253 _M_destroy(const _Alloc& __a) throw () 00254 { 00255 size_type __size = sizeof(_Rep) + (_M_capacity + 1) * sizeof(_CharT); 00256 _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size); 00257 } 00258 00259 template<typename _CharT, typename _Traits, typename _Alloc> 00260 void 00261 basic_string<_CharT, _Traits, _Alloc>::_M_leak_hard() 00262 { 00263 if (_M_rep()->_M_is_shared()) 00264 _M_mutate(0, 0, 0); 00265 _M_rep()->_M_set_leaked(); 00266 } 00267 00268 template<typename _CharT, typename _Traits, typename _Alloc> 00269 void 00270 basic_string<_CharT, _Traits, _Alloc>:: 00271 _M_mutate(size_type __pos, size_type __len1, size_type __len2) 00272 { 00273 size_type __old_size = this->size(); 00274 const size_type __new_size = __old_size + __len2 - __len1; 00275 const _CharT* __src = _M_data() + __pos + __len1; 00276 const size_type __how_much = __old_size - __pos - __len1; 00277 00278 if (_M_rep()->_M_is_shared() || __new_size > capacity()) 00279 { 00280 // Must reallocate. 00281 allocator_type __a = get_allocator(); 00282 _Rep* __r = _Rep::_S_create(__new_size, __a); 00283 try 00284 { 00285 if (__pos) 00286 traits_type::copy(__r->_M_refdata(), _M_data(), __pos); 00287 if (__how_much) 00288 traits_type::copy(__r->_M_refdata() + __pos + __len2, 00289 __src, __how_much); 00290 } 00291 catch(...) 00292 { 00293 __r->_M_dispose(get_allocator()); 00294 __throw_exception_again; 00295 } 00296 _M_rep()->_M_dispose(__a); 00297 _M_data(__r->_M_refdata()); 00298 } 00299 else if (__how_much && __len1 != __len2) 00300 { 00301 // Work in-place 00302 traits_type::move(_M_data() + __pos + __len2, __src, __how_much); 00303 } 00304 _M_rep()->_M_set_sharable(); 00305 _M_rep()->_M_length = __new_size; 00306 _M_data()[__new_size] = _Rep::_S_terminal; // grrr. (per 21.3.4) 00307 // You cannot leave those LWG people alone for a second. 00308 } 00309 00310 template<typename _CharT, typename _Traits, typename _Alloc> 00311 void 00312 basic_string<_CharT, _Traits, _Alloc>::reserve(size_type __res) 00313 { 00314 if (__res > this->capacity() || _M_rep()->_M_is_shared()) 00315 { 00316 if (__res > this->max_size()) 00317 __throw_length_error("basic_string::reserve"); 00318 // Make sure we don't shrink below the current size 00319 if (__res < this->size()) 00320 __res = this->size(); 00321 allocator_type __a = get_allocator(); 00322 _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); 00323 _M_rep()->_M_dispose(__a); 00324 _M_data(__tmp); 00325 } 00326 } 00327 00328 template<typename _CharT, typename _Traits, typename _Alloc> 00329 void basic_string<_CharT, _Traits, _Alloc>::swap(basic_string& __s) 00330 { 00331 if (_M_rep()->_M_is_leaked()) 00332 _M_rep()->_M_set_sharable(); 00333 if (__s._M_rep()->_M_is_leaked()) 00334 __s._M_rep()->_M_set_sharable(); 00335 if (this->get_allocator() == __s.get_allocator()) 00336 { 00337 _CharT* __tmp = _M_data(); 00338 _M_data(__s._M_data()); 00339 __s._M_data(__tmp); 00340 } 00341 // The code below can usually be optimized away. 00342 else 00343 { 00344 basic_string __tmp1(_M_ibegin(), _M_iend(), __s.get_allocator()); 00345 basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), 00346 this->get_allocator()); 00347 *this = __tmp2; 00348 __s = __tmp1; 00349 } 00350 } 00351 00352 #ifdef _GLIBCPP_ALLOC_CONTROL 00353 template<typename _CharT, typename _Traits, typename _Alloc> 00354 bool (*basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_excess_slop) 00355 (size_t, size_t) = 00356 basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_default_excess; 00357 #endif 00358 00359 template<typename _CharT, typename _Traits, typename _Alloc> 00360 typename basic_string<_CharT, _Traits, _Alloc>::_Rep* 00361 basic_string<_CharT, _Traits, _Alloc>::_Rep:: 00362 _S_create(size_t __capacity, const _Alloc& __alloc) 00363 { 00364 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 00365 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 00366 // 83. String::npos vs. string::max_size() 00367 if (__capacity > _S_max_size) 00368 #else 00369 if (__capacity == npos) 00370 #endif 00371 __throw_length_error("basic_string::_S_create"); 00372 00373 // NB: Need an array of char_type[__capacity], plus a 00374 // terminating null char_type() element, plus enough for the 00375 // _Rep data structure. Whew. Seemingly so needy, yet so elemental. 00376 size_t __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); 00377 // NB: Might throw, but no worries about a leak, mate: _Rep() 00378 // does not throw. 00379 void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); 00380 _Rep *__p = new (__place) _Rep; 00381 __p->_M_capacity = __capacity; 00382 __p->_M_set_sharable(); // one reference 00383 __p->_M_length = 0; 00384 return __p; 00385 } 00386 00387 template<typename _CharT, typename _Traits, typename _Alloc> 00388 _CharT* 00389 basic_string<_CharT, _Traits, _Alloc>::_Rep:: 00390 _M_clone(const _Alloc& __alloc, size_type __res) 00391 { 00392 _Rep* __r = _Rep::_S_create(_M_length + __res, __alloc); 00393 if (_M_length) 00394 { 00395 try 00396 { traits_type::copy(__r->_M_refdata(), _M_refdata(), _M_length); } 00397 catch(...) 00398 { 00399 __r->_M_destroy(__alloc); 00400 __throw_exception_again; 00401 } 00402 } 00403 __r->_M_length = _M_length; 00404 return __r->_M_refdata(); 00405 } 00406 00407 template<typename _CharT, typename _Traits, typename _Alloc> 00408 inline bool 00409 #ifdef _GLIBCPP_ALLOC_CONTROL 00410 basic_string<_CharT, _Traits, _Alloc>::_Rep:: 00411 _S_default_excess(size_t __s, size_t __r) 00412 #else 00413 basic_string<_CharT, _Traits, _Alloc>::_Rep:: 00414 _S_excess_slop(size_t __s, size_t __r) 00415 #endif 00416 { 00417 return 2 * (__s <= 16 ? 16 : __s) < __r; 00418 } 00419 00420 template<typename _CharT, typename _Traits, typename _Alloc> 00421 void 00422 basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c) 00423 { 00424 if (__n > max_size()) 00425 __throw_length_error("basic_string::resize"); 00426 size_type __size = this->size(); 00427 if (__size < __n) 00428 this->append(__n - __size, __c); 00429 else if (__n < __size) 00430 this->erase(__n); 00431 // else nothing (in particular, avoid calling _M_mutate() unnecessarily.) 00432 } 00433 00434 template<typename _CharT, typename _Traits, typename _Alloc> 00435 template<typename _InputIter> 00436 basic_string<_CharT, _Traits, _Alloc>& 00437 basic_string<_CharT, _Traits, _Alloc>:: 00438 _M_replace(iterator __i1, iterator __i2, _InputIter __k1, 00439 _InputIter __k2, input_iterator_tag) 00440 { 00441 basic_string __s(__k1, __k2); 00442 return this->replace(__i1, __i2, __s._M_ibegin(), __s._M_iend()); 00443 } 00444 00445 template<typename _CharT, typename _Traits, typename _Alloc> 00446 template<typename _ForwardIter> 00447 basic_string<_CharT, _Traits, _Alloc>& 00448 basic_string<_CharT, _Traits, _Alloc>:: 00449 _M_replace(iterator __i1, iterator __i2, _ForwardIter __k1, 00450 _ForwardIter __k2, forward_iterator_tag) 00451 { 00452 size_type __dold = __i2 - __i1; 00453 size_type __dmax = this->max_size(); 00454 size_type __dnew = static_cast<size_type>(distance(__k1, __k2)); 00455 00456 if (__dmax <= __dnew) 00457 __throw_length_error("basic_string::_M_replace"); 00458 size_type __off = __i1 - _M_ibegin(); 00459 _M_mutate(__off, __dold, __dnew); 00460 // Invalidated __i1, __i2 00461 if (__dnew) 00462 _S_copy_chars(_M_data() + __off, __k1, __k2); 00463 00464 return *this; 00465 } 00466 00467 template<typename _CharT, typename _Traits, typename _Alloc> 00468 basic_string<_CharT, _Traits, _Alloc>& 00469 basic_string<_CharT, _Traits, _Alloc>:: 00470 replace(size_type __pos1, size_type __n1, const basic_string& __str, 00471 size_type __pos2, size_type __n2) 00472 { 00473 return this->replace(_M_check(__pos1), _M_fold(__pos1, __n1), 00474 __str._M_check(__pos2), 00475 __str._M_fold(__pos2, __n2)); 00476 } 00477 00478 template<typename _CharT, typename _Traits, typename _Alloc> 00479 basic_string<_CharT,_Traits,_Alloc>& 00480 basic_string<_CharT,_Traits,_Alloc>:: 00481 append(const basic_string& __str) 00482 { 00483 // Iff appending itself, string needs to pre-reserve the 00484 // correct size so that _M_mutate does not clobber the 00485 // iterators formed here. 00486 size_type __size = __str.size(); 00487 size_type __len = __size + this->size(); 00488 if (__len > this->capacity()) 00489 this->reserve(__len); 00490 return this->replace(_M_iend(), _M_iend(), __str._M_ibegin(), 00491 __str._M_iend()); 00492 } 00493 00494 template<typename _CharT, typename _Traits, typename _Alloc> 00495 basic_string<_CharT,_Traits,_Alloc>& 00496 basic_string<_CharT,_Traits,_Alloc>:: 00497 append(const basic_string& __str, size_type __pos, size_type __n) 00498 { 00499 // Iff appending itself, string needs to pre-reserve the 00500 // correct size so that _M_mutate does not clobber the 00501 // iterators formed here. 00502 size_type __len = min(__str.size() - __pos, __n) + this->size(); 00503 if (__len > this->capacity()) 00504 this->reserve(__len); 00505 return this->replace(_M_iend(), _M_iend(), __str._M_check(__pos), 00506 __str._M_fold(__pos, __n)); 00507 } 00508 00509 template<typename _CharT, typename _Traits, typename _Alloc> 00510 basic_string<_CharT,_Traits,_Alloc>& 00511 basic_string<_CharT,_Traits,_Alloc>:: 00512 append(const _CharT* __s, size_type __n) 00513 { 00514 size_type __len = __n + this->size(); 00515 if (__len > this->capacity()) 00516 this->reserve(__len); 00517 return this->replace(_M_iend(), _M_iend(), __s, __s + __n); 00518 } 00519 00520 template<typename _CharT, typename _Traits, typename _Alloc> 00521 basic_string<_CharT,_Traits,_Alloc>& 00522 basic_string<_CharT,_Traits,_Alloc>:: 00523 append(size_type __n, _CharT __c) 00524 { 00525 size_type __len = __n + this->size(); 00526 if (__len > this->capacity()) 00527 this->reserve(__len); 00528 return this->replace(_M_iend(), _M_iend(), __n, __c); 00529 } 00530 00531 template<typename _CharT, typename _Traits, typename _Alloc> 00532 basic_string<_CharT,_Traits,_Alloc> 00533 operator+(const _CharT* __lhs, 00534 const basic_string<_CharT,_Traits,_Alloc>& __rhs) 00535 { 00536 typedef basic_string<_CharT,_Traits,_Alloc> __string_type; 00537 typedef typename __string_type::size_type __size_type; 00538 __size_type __len = _Traits::length(__lhs); 00539 __string_type __str; 00540 __str.reserve(__len + __rhs.size()); 00541 __str.append(__lhs, __lhs + __len); 00542 __str.append(__rhs); 00543 return __str; 00544 } 00545 00546 template<typename _CharT, typename _Traits, typename _Alloc> 00547 basic_string<_CharT,_Traits,_Alloc> 00548 operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs) 00549 { 00550 typedef basic_string<_CharT,_Traits,_Alloc> __string_type; 00551 typedef typename __string_type::size_type __size_type; 00552 __string_type __str; 00553 __size_type __len = __rhs.size(); 00554 __str.reserve(__len + 1); 00555 __str.append(__size_type(1), __lhs); 00556 __str.append(__rhs); 00557 return __str; 00558 } 00559 00560 template<typename _CharT, typename _Traits, typename _Alloc> 00561 basic_string<_CharT, _Traits, _Alloc>& 00562 basic_string<_CharT, _Traits, _Alloc>:: 00563 replace(iterator __i1, iterator __i2, size_type __n2, _CharT __c) 00564 { 00565 size_type __n1 = __i2 - __i1; 00566 size_type __off1 = __i1 - _M_ibegin(); 00567 if (max_size() - (this->size() - __n1) <= __n2) 00568 __throw_length_error("basic_string::replace"); 00569 _M_mutate (__off1, __n1, __n2); 00570 // Invalidated __i1, __i2 00571 if (__n2) 00572 traits_type::assign(_M_data() + __off1, __n2, __c); 00573 return *this; 00574 } 00575 00576 template<typename _CharT, typename _Traits, typename _Alloc> 00577 typename basic_string<_CharT, _Traits, _Alloc>::size_type 00578 basic_string<_CharT, _Traits, _Alloc>:: 00579 copy(_CharT* __s, size_type __n, size_type __pos) const 00580 { 00581 if (__pos > this->size()) 00582 __throw_out_of_range("basic_string::copy"); 00583 00584 if (__n > this->size() - __pos) 00585 __n = this->size() - __pos; 00586 00587 traits_type::copy(__s, _M_data() + __pos, __n); 00588 // 21.3.5.7 par 3: do not append null. (good.) 00589 return __n; 00590 } 00591 00592 template<typename _CharT, typename _Traits, typename _Alloc> 00593 typename basic_string<_CharT, _Traits, _Alloc>::size_type 00594 basic_string<_CharT, _Traits, _Alloc>:: 00595 find(const _CharT* __s, size_type __pos, size_type __n) const 00596 { 00597 size_type __size = this->size(); 00598 size_t __xpos = __pos; 00599 const _CharT* __data = _M_data(); 00600 for (; __xpos + __n <= __size; ++__xpos) 00601 if (traits_type::compare(__data + __xpos, __s, __n) == 0) 00602 return __xpos; 00603 return npos; 00604 } 00605 00606 template<typename _CharT, typename _Traits, typename _Alloc> 00607 typename basic_string<_CharT, _Traits, _Alloc>::size_type 00608 basic_string<_CharT, _Traits, _Alloc>:: 00609 find(_CharT __c, size_type __pos) const 00610 { 00611 size_type __size = this->size(); 00612 size_type __ret = npos; 00613 if (__pos < __size) 00614 { 00615 const _CharT* __data = _M_data(); 00616 size_type __n = __size - __pos; 00617 const _CharT* __p = traits_type::find(__data + __pos, __n, __c); 00618 if (__p) 00619 __ret = __p - __data; 00620 } 00621 return __ret; 00622 } 00623 00624 00625 template<typename _CharT, typename _Traits, typename _Alloc> 00626 typename basic_string<_CharT, _Traits, _Alloc>::size_type 00627 basic_string<_CharT, _Traits, _Alloc>:: 00628 rfind(const _CharT* __s, size_type __pos, size_type __n) const 00629 { 00630 size_type __size = this->size(); 00631 if (__n <= __size) 00632 { 00633 __pos = std::min(__size - __n ,__pos); 00634 const _CharT* __data = _M_data(); 00635 do 00636 { 00637 if (traits_type::compare(__data + __pos, __s, __n) == 0) 00638 return __pos; 00639 } 00640 while (__pos-- > 0); 00641 } 00642 return npos; 00643 } 00644 00645 template<typename _CharT, typename _Traits, typename _Alloc> 00646 typename basic_string<_CharT, _Traits, _Alloc>::size_type 00647 basic_string<_CharT, _Traits, _Alloc>:: 00648 rfind(_CharT __c, size_type __pos) const 00649 { 00650 size_type __size = this->size(); 00651 if (__size) 00652 { 00653 size_t __xpos = __size - 1; 00654 if (__xpos > __pos) 00655 __xpos = __pos; 00656 00657 for (++__xpos; __xpos-- > 0; ) 00658 if (traits_type::eq(_M_data()[__xpos], __c)) 00659 return __xpos; 00660 } 00661 return npos; 00662 } 00663 00664 template<typename _CharT, typename _Traits, typename _Alloc> 00665 typename basic_string<_CharT, _Traits, _Alloc>::size_type 00666 basic_string<_CharT, _Traits, _Alloc>:: 00667 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const 00668 { 00669 for (; __n && __pos < this->size(); ++__pos) 00670 { 00671 const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); 00672 if (__p) 00673 return __pos; 00674 } 00675 return npos; 00676 } 00677 00678 template<typename _CharT, typename _Traits, typename _Alloc> 00679 typename basic_string<_CharT, _Traits, _Alloc>::size_type 00680 basic_string<_CharT, _Traits, _Alloc>:: 00681 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const 00682 { 00683 size_type __size = this->size(); 00684 if (__size && __n) 00685 { 00686 if (--__size > __pos) 00687 __size = __pos; 00688 do 00689 { 00690 if (traits_type::find(__s, __n, _M_data()[__size])) 00691 return __size; 00692 } 00693 while (__size-- != 0); 00694 } 00695 return npos; 00696 } 00697 00698 template<typename _CharT, typename _Traits, typename _Alloc> 00699 typename basic_string<_CharT, _Traits, _Alloc>::size_type 00700 basic_string<_CharT, _Traits, _Alloc>:: 00701 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const 00702 { 00703 size_t __xpos = __pos; 00704 for (; __n && __xpos < this->size(); ++__xpos) 00705 if (!traits_type::find(__s, __n, _M_data()[__xpos])) 00706 return __xpos; 00707 return npos; 00708 } 00709 00710 template<typename _CharT, typename _Traits, typename _Alloc> 00711 typename basic_string<_CharT, _Traits, _Alloc>::size_type 00712 basic_string<_CharT, _Traits, _Alloc>:: 00713 find_first_not_of(_CharT __c, size_type __pos) const 00714 { 00715 size_t __xpos = __pos; 00716 for (; __xpos < this->size(); ++__xpos) 00717 if (!traits_type::eq(_M_data()[__xpos], __c)) 00718 return __xpos; 00719 return npos; 00720 } 00721 00722 template<typename _CharT, typename _Traits, typename _Alloc> 00723 typename basic_string<_CharT, _Traits, _Alloc>::size_type 00724 basic_string<_CharT, _Traits, _Alloc>:: 00725 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 00726 { 00727 size_type __size = this->size(); 00728 if (__size && __n) 00729 { 00730 if (--__size > __pos) 00731 __size = __pos; 00732 do 00733 { 00734 if (!traits_type::find(__s, __n, _M_data()[__size])) 00735 return __size; 00736 } 00737 while (__size--); 00738 } 00739 return npos; 00740 } 00741 00742 template<typename _CharT, typename _Traits, typename _Alloc> 00743 typename basic_string<_CharT, _Traits, _Alloc>::size_type 00744 basic_string<_CharT, _Traits, _Alloc>:: 00745 find_last_not_of(_CharT __c, size_type __pos) const 00746 { 00747 size_type __size = this->size(); 00748 if (__size) 00749 { 00750 if (--__size > __pos) 00751 __size = __pos; 00752 do 00753 { 00754 if (!traits_type::eq(_M_data()[__size], __c)) 00755 return __size; 00756 } 00757 while (__size--); 00758 } 00759 return npos; 00760 } 00761 00762 template<typename _CharT, typename _Traits, typename _Alloc> 00763 int 00764 basic_string<_CharT, _Traits, _Alloc>:: 00765 compare(size_type __pos, size_type __n, const basic_string& __str) const 00766 { 00767 size_type __size = this->size(); 00768 size_type __osize = __str.size(); 00769 if (__pos > __size) 00770 __throw_out_of_range("basic_string::compare"); 00771 00772 size_type __rsize= min(__size - __pos, __n); 00773 size_type __len = min(__rsize, __osize); 00774 int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); 00775 if (!__r) 00776 __r = __rsize - __osize; 00777 return __r; 00778 } 00779 00780 template<typename _CharT, typename _Traits, typename _Alloc> 00781 int 00782 basic_string<_CharT, _Traits, _Alloc>:: 00783 compare(size_type __pos1, size_type __n1, const basic_string& __str, 00784 size_type __pos2, size_type __n2) const 00785 { 00786 size_type __size = this->size(); 00787 size_type __osize = __str.size(); 00788 if (__pos1 > __size || __pos2 > __osize) 00789 __throw_out_of_range("basic_string::compare"); 00790 00791 size_type __rsize = min(__size - __pos1, __n1); 00792 size_type __rosize = min(__osize - __pos2, __n2); 00793 size_type __len = min(__rsize, __rosize); 00794 int __r = traits_type::compare(_M_data() + __pos1, 00795 __str.data() + __pos2, __len); 00796 if (!__r) 00797 __r = __rsize - __rosize; 00798 return __r; 00799 } 00800 00801 00802 template<typename _CharT, typename _Traits, typename _Alloc> 00803 int 00804 basic_string<_CharT, _Traits, _Alloc>:: 00805 compare(const _CharT* __s) const 00806 { 00807 size_type __size = this->size(); 00808 int __r = traits_type::compare(_M_data(), __s, __size); 00809 if (!__r) 00810 __r = __size - traits_type::length(__s); 00811 return __r; 00812 } 00813 00814 00815 template<typename _CharT, typename _Traits, typename _Alloc> 00816 int 00817 basic_string <_CharT,_Traits,_Alloc>:: 00818 compare(size_type __pos, size_type __n1, const _CharT* __s) const 00819 { 00820 size_type __size = this->size(); 00821 if (__pos > __size) 00822 __throw_out_of_range("basic_string::compare"); 00823 00824 size_type __osize = traits_type::length(__s); 00825 size_type __rsize = min(__size - __pos, __n1); 00826 size_type __len = min(__rsize, __osize); 00827 int __r = traits_type::compare(_M_data() + __pos, __s, __len); 00828 if (!__r) 00829 __r = __rsize - __osize; 00830 return __r; 00831 } 00832 00833 template<typename _CharT, typename _Traits, typename _Alloc> 00834 int 00835 basic_string <_CharT,_Traits,_Alloc>:: 00836 compare(size_type __pos, size_type __n1, const _CharT* __s, 00837 size_type __n2) const 00838 { 00839 size_type __size = this->size(); 00840 if (__pos > __size) 00841 __throw_out_of_range("basic_string::compare"); 00842 00843 size_type __osize = min(traits_type::length(__s), __n2); 00844 size_type __rsize = min(__size - __pos, __n1); 00845 size_type __len = min(__rsize, __osize); 00846 int __r = traits_type::compare(_M_data() + __pos, __s, __len); 00847 if (!__r) 00848 __r = __rsize - __osize; 00849 return __r; 00850 } 00851 00852 template <class _CharT, class _Traits, class _Alloc> 00853 void 00854 _S_string_copy(const basic_string<_CharT, _Traits, _Alloc>& __str, 00855 _CharT* __buf, typename _Alloc::size_type __bufsiz) 00856 { 00857 typedef typename _Alloc::size_type size_type; 00858 size_type __strsize = __str.size(); 00859 size_type __bytes = min(__strsize, __bufsiz - 1); 00860 _Traits::copy(__buf, __str.data(), __bytes); 00861 __buf[__bytes] = _CharT(); 00862 } 00863 } // namespace std 00864 00865 #endif Generated on Mon Apr 8 03:11:22 2002 for libstdc++-v3 Source by ![]() |