00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef _CPP_BITS_STRING_TCC
00042 #define _CPP_BITS_STRING_TCC 1
00043
00044 #pragma GCC system_header
00045
00046 namespace std
00047 {
00048 template<typename _CharT, typename _Traits, typename _Alloc>
00049 const typename basic_string<_CharT, _Traits, _Alloc>::size_type
00050 basic_string<_CharT, _Traits, _Alloc>::
00051 _Rep::_S_max_size = (((npos - sizeof(_Rep))/sizeof(_CharT)) - 1) / 4;
00052
00053 template<typename _CharT, typename _Traits, typename _Alloc>
00054 const _CharT
00055 basic_string<_CharT, _Traits, _Alloc>::
00056 _Rep::_S_terminal = _CharT();
00057
00058 template<typename _CharT, typename _Traits, typename _Alloc>
00059 const typename basic_string<_CharT, _Traits, _Alloc>::size_type
00060 basic_string<_CharT, _Traits, _Alloc>::npos;
00061
00062
00063
00064 template<typename _CharT, typename _Traits, typename _Alloc>
00065 typename basic_string<_CharT, _Traits, _Alloc>::size_type
00066 basic_string<_CharT, _Traits, _Alloc>::_S_empty_rep_storage[
00067 (sizeof(_Rep) + sizeof(_CharT) + sizeof(size_type) - 1)/sizeof(size_type)];
00068
00069
00070
00071
00072
00073 template<typename _CharT, typename _Traits, typename _Alloc>
00074 template<typename _InIter>
00075 _CharT*
00076 basic_string<_CharT, _Traits, _Alloc>::
00077 _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
00078 input_iterator_tag)
00079 {
00080 if (__beg == __end && __a == _Alloc())
00081 return _S_empty_rep()._M_refcopy();
00082
00083 _CharT __buf[100];
00084 size_type __i = 0;
00085 while (__beg != __end && __i < sizeof(__buf) / sizeof(_CharT))
00086 {
00087 __buf[__i++] = *__beg;
00088 ++__beg;
00089 }
00090 _Rep* __r = _Rep::_S_create(__i, __a);
00091 traits_type::copy(__r->_M_refdata(), __buf, __i);
00092 __r->_M_length = __i;
00093 try
00094 {
00095
00096
00097
00098 for (;;)
00099 {
00100 _CharT* __p = __r->_M_refdata() + __r->_M_length;
00101 _CharT* __last = __r->_M_refdata() + __r->_M_capacity;
00102 for (;;)
00103 {
00104 if (__beg == __end)
00105 {
00106 __r->_M_length = __p - __r->_M_refdata();
00107 *__p = _Rep::_S_terminal;
00108 return __r->_M_refdata();
00109 }
00110 if (__p == __last)
00111 break;
00112 *__p++ = *__beg;
00113 ++__beg;
00114 }
00115
00116 size_type __len = __p - __r->_M_refdata();
00117 _Rep* __another = _Rep::_S_create(__len + 1, __a);
00118 traits_type::copy(__another->_M_refdata(),
00119 __r->_M_refdata(), __len);
00120 __r->_M_destroy(__a);
00121 __r = __another;
00122 __r->_M_length = __len;
00123 }
00124 }
00125 catch(...)
00126 {
00127 __r->_M_destroy(__a);
00128 __throw_exception_again;
00129 }
00130 return 0;
00131 }
00132
00133 template<typename _CharT, typename _Traits, typename _Alloc>
00134 template <class _InIter>
00135 _CharT*
00136 basic_string<_CharT, _Traits, _Alloc>::
00137 _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a,
00138 forward_iterator_tag)
00139 {
00140 if (__beg == __end && __a == _Alloc())
00141 return _S_empty_rep()._M_refcopy();
00142
00143
00144 if (__builtin_expect(__beg == _InIter(), 0))
00145 __throw_logic_error("attempt to create string with null pointer");
00146
00147 size_type __dnew = static_cast<size_type>(std::distance(__beg, __end));
00148
00149
00150 _Rep* __r = _Rep::_S_create(__dnew, __a);
00151 try
00152 { _S_copy_chars(__r->_M_refdata(), __beg, __end); }
00153 catch(...)
00154 {
00155 __r->_M_destroy(__a);
00156 __throw_exception_again;
00157 }
00158 __r->_M_length = __dnew;
00159
00160 __r->_M_refdata()[__dnew] = _Rep::_S_terminal;
00161 return __r->_M_refdata();
00162 }
00163
00164 template<typename _CharT, typename _Traits, typename _Alloc>
00165 _CharT*
00166 basic_string<_CharT, _Traits, _Alloc>::
00167 _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
00168 {
00169 if (__n == 0 && __a == _Alloc())
00170 return _S_empty_rep()._M_refcopy();
00171
00172
00173 _Rep* __r = _Rep::_S_create(__n, __a);
00174 try
00175 {
00176 if (__n)
00177 traits_type::assign(__r->_M_refdata(), __n, __c);
00178 }
00179 catch(...)
00180 {
00181 __r->_M_destroy(__a);
00182 __throw_exception_again;
00183 }
00184 __r->_M_length = __n;
00185 __r->_M_refdata()[__n] = _Rep::_S_terminal;
00186 return __r->_M_refdata();
00187 }
00188
00189 template<typename _CharT, typename _Traits, typename _Alloc>
00190 basic_string<_CharT, _Traits, _Alloc>::
00191 basic_string(const basic_string& __str)
00192 : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()),
00193 __str.get_allocator()),
00194 __str.get_allocator())
00195 { }
00196
00197 template<typename _CharT, typename _Traits, typename _Alloc>
00198 basic_string<_CharT, _Traits, _Alloc>::
00199 basic_string(const _Alloc& __a)
00200 : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a)
00201 { }
00202
00203 template<typename _CharT, typename _Traits, typename _Alloc>
00204 basic_string<_CharT, _Traits, _Alloc>::
00205 basic_string(const basic_string& __str, size_type __pos, size_type __n)
00206 : _M_dataplus(_S_construct(__str._M_check(__pos),
00207 __str._M_fold(__pos, __n), _Alloc()), _Alloc())
00208 { }
00209
00210 template<typename _CharT, typename _Traits, typename _Alloc>
00211 basic_string<_CharT, _Traits, _Alloc>::
00212 basic_string(const basic_string& __str, size_type __pos,
00213 size_type __n, const _Alloc& __a)
00214 : _M_dataplus(_S_construct(__str._M_check(__pos),
00215 __str._M_fold(__pos, __n), __a), __a)
00216 { }
00217
00218 template<typename _CharT, typename _Traits, typename _Alloc>
00219 basic_string<_CharT, _Traits, _Alloc>::
00220 basic_string(const _CharT* __s, size_type __n, const _Alloc& __a)
00221 : _M_dataplus(_S_construct(__s, __s + __n, __a), __a)
00222 { }
00223
00224 template<typename _CharT, typename _Traits, typename _Alloc>
00225 basic_string<_CharT, _Traits, _Alloc>::
00226 basic_string(const _CharT* __s, const _Alloc& __a)
00227 : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) :
00228 __s + npos, __a), __a)
00229 { }
00230
00231 template<typename _CharT, typename _Traits, typename _Alloc>
00232 basic_string<_CharT, _Traits, _Alloc>::
00233 basic_string(size_type __n, _CharT __c, const _Alloc& __a)
00234 : _M_dataplus(_S_construct(__n, __c, __a), __a)
00235 { }
00236
00237 template<typename _CharT, typename _Traits, typename _Alloc>
00238 template<typename _InputIter>
00239 basic_string<_CharT, _Traits, _Alloc>::
00240 basic_string(_InputIter __beg, _InputIter __end, const _Alloc& __a)
00241 : _M_dataplus(_S_construct(__beg, __end, __a), __a)
00242 { }
00243
00244 template<typename _CharT, typename _Traits, typename _Alloc>
00245 basic_string<_CharT, _Traits, _Alloc>&
00246 basic_string<_CharT, _Traits, _Alloc>::assign(const basic_string& __str)
00247 {
00248 if (_M_rep() != __str._M_rep())
00249 {
00250
00251 allocator_type __a = this->get_allocator();
00252 _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator());
00253 _M_rep()->_M_dispose(__a);
00254 _M_data(__tmp);
00255 }
00256 return *this;
00257 }
00258
00259 template<typename _CharT, typename _Traits, typename _Alloc>
00260 basic_string<_CharT, _Traits, _Alloc>&
00261 basic_string<_CharT, _Traits, _Alloc>::
00262 assign(const basic_string& __str, size_type __pos, size_type __n)
00263 {
00264 const size_type __strsize = __str.size();
00265 if (__pos > __strsize)
00266 __throw_out_of_range("basic_string::assign");
00267 const bool __testn = __n < __strsize - __pos;
00268 const size_type __newsize = __testn ? __n : __strsize - __pos;
00269 return this->assign(__str._M_data() + __pos, __newsize);
00270 }
00271
00272 template<typename _CharT, typename _Traits, typename _Alloc>
00273 basic_string<_CharT, _Traits, _Alloc>&
00274 basic_string<_CharT, _Traits, _Alloc>::
00275 assign(const _CharT* __s, size_type __n)
00276 {
00277 if (__n > this->max_size())
00278 __throw_length_error("basic_string::assign");
00279 if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
00280 || less<const _CharT*>()(_M_data() + this->size(), __s))
00281 return _M_replace_safe(_M_ibegin(), _M_iend(), __s, __s + __n);
00282 else
00283 {
00284
00285 const size_type __pos = __s - _M_data();
00286 if (__pos >= __n)
00287 traits_type::copy(_M_data(), __s, __n);
00288 else if (__pos)
00289 traits_type::move(_M_data(), __s, __n);
00290 _M_rep()->_M_length = __n;
00291 _M_data()[__n] = _Rep::_S_terminal;
00292 return *this;
00293 }
00294 }
00295
00296 template<typename _CharT, typename _Traits, typename _Alloc>
00297 basic_string<_CharT, _Traits, _Alloc>&
00298 basic_string<_CharT, _Traits, _Alloc>::
00299 insert(size_type __pos1, const basic_string& __str,
00300 size_type __pos2, size_type __n)
00301 {
00302 const size_type __strsize = __str.size();
00303 if (__pos2 > __strsize)
00304 __throw_out_of_range("basic_string::insert");
00305 const bool __testn = __n < __strsize - __pos2;
00306 const size_type __newsize = __testn ? __n : __strsize - __pos2;
00307 return this->insert(__pos1, __str._M_data() + __pos2, __newsize);
00308 }
00309
00310 template<typename _CharT, typename _Traits, typename _Alloc>
00311 basic_string<_CharT, _Traits, _Alloc>&
00312 basic_string<_CharT, _Traits, _Alloc>::
00313 insert(size_type __pos, const _CharT* __s, size_type __n)
00314 {
00315 const size_type __size = this->size();
00316 if (__pos > __size)
00317 __throw_out_of_range("basic_string::insert");
00318 if (__size > this->max_size() - __n)
00319 __throw_length_error("basic_string::insert");
00320 if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
00321 || less<const _CharT*>()(_M_data() + __size, __s))
00322 return _M_replace_safe(_M_ibegin() + __pos, _M_ibegin() + __pos,
00323 __s, __s + __n);
00324 else
00325 {
00326
00327
00328
00329 const size_type __off = __s - _M_data();
00330 _M_mutate(__pos, 0, __n);
00331 __s = _M_data() + __off;
00332 _CharT* __p = _M_data() + __pos;
00333 if (__s + __n <= __p)
00334 traits_type::copy(__p, __s, __n);
00335 else if (__s >= __p)
00336 traits_type::copy(__p, __s + __n, __n);
00337 else
00338 {
00339 traits_type::copy(__p, __s, __p - __s);
00340 traits_type::copy(__p + (__p-__s), __p + __n, __n - (__p-__s));
00341 }
00342 return *this;
00343 }
00344 }
00345
00346 template<typename _CharT, typename _Traits, typename _Alloc>
00347 basic_string<_CharT, _Traits, _Alloc>&
00348 basic_string<_CharT, _Traits, _Alloc>::
00349 replace(size_type __pos, size_type __n1, const _CharT* __s,
00350 size_type __n2)
00351 {
00352 const size_type __size = this->size();
00353 if (__pos > __size)
00354 __throw_out_of_range("basic_string::replace");
00355 const bool __testn1 = __n1 < __size - __pos;
00356 const size_type __foldn1 = __testn1 ? __n1 : __size - __pos;
00357 if (__size - __foldn1 > this->max_size() - __n2)
00358 __throw_length_error("basic_string::replace");
00359 if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
00360 || less<const _CharT*>()(_M_data() + __size, __s))
00361 return _M_replace_safe(_M_ibegin() + __pos,
00362 _M_ibegin() + __pos + __foldn1, __s, __s + __n2);
00363
00364 else
00365 return _M_replace(_M_ibegin() + __pos, _M_ibegin() + __pos + __foldn1,
00366 __s, __s + __n2,
00367 typename iterator_traits<const _CharT*>::iterator_category());
00368 }
00369
00370 template<typename _CharT, typename _Traits, typename _Alloc>
00371 void
00372 basic_string<_CharT, _Traits, _Alloc>::_Rep::
00373 _M_destroy(const _Alloc& __a) throw ()
00374 {
00375 size_type __size = sizeof(_Rep) + (_M_capacity + 1) * sizeof(_CharT);
00376 _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
00377 }
00378
00379 template<typename _CharT, typename _Traits, typename _Alloc>
00380 void
00381 basic_string<_CharT, _Traits, _Alloc>::_M_leak_hard()
00382 {
00383 if (_M_rep()->_M_is_shared())
00384 _M_mutate(0, 0, 0);
00385 _M_rep()->_M_set_leaked();
00386 }
00387
00388
00389
00390
00391
00392
00393
00394 template<typename _CharT, typename _Traits, typename _Alloc>
00395 void
00396 basic_string<_CharT, _Traits, _Alloc>::
00397 _M_mutate(size_type __pos, size_type __len1, size_type __len2)
00398 {
00399 size_type __old_size = this->size();
00400 const size_type __new_size = __old_size + __len2 - __len1;
00401 const _CharT* __src = _M_data() + __pos + __len1;
00402 const size_type __how_much = __old_size - __pos - __len1;
00403
00404 if (_M_rep()->_M_is_shared() || __new_size > capacity())
00405 {
00406
00407 allocator_type __a = get_allocator();
00408
00409
00410 const size_type __pagesize = 4096;
00411 const size_type __malloc_header_size = 4 * sizeof (void*);
00412
00413 const size_type __page_capacity = (__pagesize - __malloc_header_size
00414 - sizeof(_Rep) - sizeof(_CharT))
00415 / sizeof(_CharT);
00416 _Rep* __r;
00417 if (__new_size > capacity() && __new_size > __page_capacity)
00418
00419 __r = _Rep::_S_create(__new_size > 2*capacity() ?
00420 __new_size : 2*capacity(), __a);
00421 else
00422 __r = _Rep::_S_create(__new_size, __a);
00423 try
00424 {
00425 if (__pos)
00426 traits_type::copy(__r->_M_refdata(), _M_data(), __pos);
00427 if (__how_much)
00428 traits_type::copy(__r->_M_refdata() + __pos + __len2,
00429 __src, __how_much);
00430 }
00431 catch(...)
00432 {
00433 __r->_M_dispose(get_allocator());
00434 __throw_exception_again;
00435 }
00436 _M_rep()->_M_dispose(__a);
00437 _M_data(__r->_M_refdata());
00438 }
00439 else if (__how_much && __len1 != __len2)
00440 {
00441
00442 traits_type::move(_M_data() + __pos + __len2, __src, __how_much);
00443 }
00444 _M_rep()->_M_set_sharable();
00445 _M_rep()->_M_length = __new_size;
00446 _M_data()[__new_size] = _Rep::_S_terminal;
00447
00448 }
00449
00450 template<typename _CharT, typename _Traits, typename _Alloc>
00451 void
00452 basic_string<_CharT, _Traits, _Alloc>::reserve(size_type __res)
00453 {
00454 if (__res != this->capacity() || _M_rep()->_M_is_shared())
00455 {
00456 if (__res > this->max_size())
00457 __throw_length_error("basic_string::reserve");
00458
00459 if (__res < this->size())
00460 __res = this->size();
00461 allocator_type __a = get_allocator();
00462 _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());
00463 _M_rep()->_M_dispose(__a);
00464 _M_data(__tmp);
00465 }
00466 }
00467
00468 template<typename _CharT, typename _Traits, typename _Alloc>
00469 void basic_string<_CharT, _Traits, _Alloc>::swap(basic_string& __s)
00470 {
00471 if (_M_rep()->_M_is_leaked())
00472 _M_rep()->_M_set_sharable();
00473 if (__s._M_rep()->_M_is_leaked())
00474 __s._M_rep()->_M_set_sharable();
00475 if (this->get_allocator() == __s.get_allocator())
00476 {
00477 _CharT* __tmp = _M_data();
00478 _M_data(__s._M_data());
00479 __s._M_data(__tmp);
00480 }
00481
00482 else
00483 {
00484 basic_string __tmp1(_M_ibegin(), _M_iend(), __s.get_allocator());
00485 basic_string __tmp2(__s._M_ibegin(), __s._M_iend(),
00486 this->get_allocator());
00487 *this = __tmp2;
00488 __s = __tmp1;
00489 }
00490 }
00491
00492 template<typename _CharT, typename _Traits, typename _Alloc>
00493 typename basic_string<_CharT, _Traits, _Alloc>::_Rep*
00494 basic_string<_CharT, _Traits, _Alloc>::_Rep::
00495 _S_create(size_t __capacity, const _Alloc& __alloc)
00496 {
00497 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
00498 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
00499
00500 if (__capacity > _S_max_size)
00501 #else
00502 if (__capacity == npos)
00503 #endif
00504 __throw_length_error("basic_string::_S_create");
00505
00506
00507
00508
00509 size_t __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 const size_t __pagesize = 4096;
00534 const size_t __subpagesize = 128;
00535 const size_t __malloc_header_size = 4 * sizeof (void*);
00536 if ((__size + __malloc_header_size) > __pagesize)
00537 {
00538 size_t __extra =
00539 (__pagesize - ((__size + __malloc_header_size) % __pagesize))
00540 % __pagesize;
00541 __capacity += __extra / sizeof(_CharT);
00542 __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
00543 }
00544 else if (__size > __subpagesize)
00545 {
00546 size_t __extra =
00547 (__subpagesize - ((__size + __malloc_header_size) % __subpagesize))
00548 % __subpagesize;
00549 __capacity += __extra / sizeof(_CharT);
00550 __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
00551 }
00552
00553
00554
00555 void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
00556 _Rep *__p = new (__place) _Rep;
00557 __p->_M_capacity = __capacity;
00558 __p->_M_set_sharable();
00559 __p->_M_length = 0;
00560 return __p;
00561 }
00562
00563 template<typename _CharT, typename _Traits, typename _Alloc>
00564 _CharT*
00565 basic_string<_CharT, _Traits, _Alloc>::_Rep::
00566 _M_clone(const _Alloc& __alloc, size_type __res)
00567 {
00568
00569 const size_type __requested_cap = _M_length + __res;
00570
00571 const size_type __pagesize = 4096;
00572 const size_type __malloc_header_size = 4 * sizeof (void*);
00573
00574 const size_type __page_capacity =
00575 (__pagesize - __malloc_header_size - sizeof(_Rep) - sizeof(_CharT))
00576 / sizeof(_CharT);
00577 _Rep* __r;
00578 if (__requested_cap > _M_capacity && __requested_cap > __page_capacity)
00579
00580 __r = _Rep::_S_create(__requested_cap > 2*_M_capacity ?
00581 __requested_cap : 2*_M_capacity, __alloc);
00582 else
00583 __r = _Rep::_S_create(__requested_cap, __alloc);
00584
00585 if (_M_length)
00586 {
00587 try
00588 { traits_type::copy(__r->_M_refdata(), _M_refdata(), _M_length); }
00589 catch(...)
00590 {
00591 __r->_M_destroy(__alloc);
00592 __throw_exception_again;
00593 }
00594 }
00595 __r->_M_length = _M_length;
00596 __r->_M_refdata()[_M_length] = _Rep::_S_terminal;
00597 return __r->_M_refdata();
00598 }
00599
00600 template<typename _CharT, typename _Traits, typename _Alloc>
00601 void
00602 basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c)
00603 {
00604 if (__n > max_size())
00605 __throw_length_error("basic_string::resize");
00606 size_type __size = this->size();
00607 if (__size < __n)
00608 this->append(__n - __size, __c);
00609 else if (__n < __size)
00610 this->erase(__n);
00611
00612 }
00613
00614
00615
00616
00617 template<typename _CharT, typename _Traits, typename _Alloc>
00618 template<typename _InputIter>
00619 basic_string<_CharT, _Traits, _Alloc>&
00620 basic_string<_CharT, _Traits, _Alloc>::
00621 _M_replace(iterator __i1, iterator __i2, _InputIter __k1,
00622 _InputIter __k2, input_iterator_tag)
00623 {
00624
00625 basic_string __s(__k1, __k2);
00626 return _M_replace_safe(__i1, __i2, __s._M_ibegin(), __s._M_iend());
00627 }
00628
00629
00630
00631
00632 template<typename _CharT, typename _Traits, typename _Alloc>
00633 template<typename _ForwardIter>
00634 basic_string<_CharT, _Traits, _Alloc>&
00635 basic_string<_CharT, _Traits, _Alloc>::
00636 _M_replace_safe(iterator __i1, iterator __i2, _ForwardIter __k1,
00637 _ForwardIter __k2)
00638 {
00639 size_type __dnew = static_cast<size_type>(std::distance(__k1, __k2));
00640 size_type __dold = __i2 - __i1;
00641 size_type __dmax = this->max_size();
00642
00643 if (__dmax <= __dnew)
00644 __throw_length_error("basic_string::_M_replace");
00645 size_type __off = __i1 - _M_ibegin();
00646 _M_mutate(__off, __dold, __dnew);
00647
00648
00649 if (__dnew == 1)
00650 _M_data()[__off] = *__k1;
00651 else if (__dnew)
00652 _S_copy_chars(_M_data() + __off, __k1, __k2);
00653
00654 return *this;
00655 }
00656
00657 template<typename _CharT, typename _Traits, typename _Alloc>
00658 basic_string<_CharT, _Traits, _Alloc>&
00659 basic_string<_CharT, _Traits, _Alloc>::
00660 replace(size_type __pos1, size_type __n1, const basic_string& __str,
00661 size_type __pos2, size_type __n2)
00662 {
00663 const size_type __strsize = __str.size();
00664 if (__pos2 > __strsize)
00665 __throw_out_of_range("basic_string::replace");
00666 const bool __testn2 = __n2 < __strsize - __pos2;
00667 const size_type __foldn2 = __testn2 ? __n2 : __strsize - __pos2;
00668 return this->replace(__pos1, __n1,
00669 __str._M_data() + __pos2, __foldn2);
00670 }
00671
00672 template<typename _CharT, typename _Traits, typename _Alloc>
00673 basic_string<_CharT, _Traits, _Alloc>&
00674 basic_string<_CharT, _Traits, _Alloc>::
00675 append(const basic_string& __str)
00676 {
00677
00678
00679
00680 size_type __size = __str.size();
00681 size_type __len = __size + this->size();
00682 if (__len > this->capacity())
00683 this->reserve(__len);
00684 return _M_replace_safe(_M_iend(), _M_iend(), __str._M_ibegin(),
00685 __str._M_iend());
00686 }
00687
00688 template<typename _CharT, typename _Traits, typename _Alloc>
00689 basic_string<_CharT, _Traits, _Alloc>&
00690 basic_string<_CharT, _Traits, _Alloc>::
00691 append(const basic_string& __str, size_type __pos, size_type __n)
00692 {
00693
00694
00695
00696 size_type __len = std::min(size_type(__str.size() - __pos),
00697 __n) + this->size();
00698 if (__len > this->capacity())
00699 this->reserve(__len);
00700 return _M_replace_safe(_M_iend(), _M_iend(), __str._M_check(__pos),
00701 __str._M_fold(__pos, __n));
00702 }
00703
00704 template<typename _CharT, typename _Traits, typename _Alloc>
00705 basic_string<_CharT, _Traits, _Alloc>&
00706 basic_string<_CharT, _Traits, _Alloc>::
00707 append(const _CharT* __s, size_type __n)
00708 {
00709 size_type __len = __n + this->size();
00710 if (__len > this->capacity())
00711 this->reserve(__len);
00712 return _M_replace_safe(_M_iend(), _M_iend(), __s, __s + __n);
00713 }
00714
00715 template<typename _CharT, typename _Traits, typename _Alloc>
00716 basic_string<_CharT, _Traits, _Alloc>&
00717 basic_string<_CharT, _Traits, _Alloc>::
00718 append(size_type __n, _CharT __c)
00719 {
00720 size_type __len = __n + this->size();
00721 if (__len > this->capacity())
00722 this->reserve(__len);
00723 return this->replace(_M_iend(), _M_iend(), __n, __c);
00724 }
00725
00726 template<typename _CharT, typename _Traits, typename _Alloc>
00727 basic_string<_CharT, _Traits, _Alloc>
00728 operator+(const _CharT* __lhs,
00729 const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00730 {
00731 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
00732 typedef typename __string_type::size_type __size_type;
00733 __size_type __len = _Traits::length(__lhs);
00734 __string_type __str;
00735 __str.reserve(__len + __rhs.size());
00736 __str.append(__lhs, __lhs + __len);
00737 __str.append(__rhs);
00738 return __str;
00739 }
00740
00741 template<typename _CharT, typename _Traits, typename _Alloc>
00742 basic_string<_CharT, _Traits, _Alloc>
00743 operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs)
00744 {
00745 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
00746 typedef typename __string_type::size_type __size_type;
00747 __string_type __str;
00748 __size_type __len = __rhs.size();
00749 __str.reserve(__len + 1);
00750 __str.append(__size_type(1), __lhs);
00751 __str.append(__rhs);
00752 return __str;
00753 }
00754
00755 template<typename _CharT, typename _Traits, typename _Alloc>
00756 basic_string<_CharT, _Traits, _Alloc>&
00757 basic_string<_CharT, _Traits, _Alloc>::
00758 replace(iterator __i1, iterator __i2, size_type __n2, _CharT __c)
00759 {
00760 size_type __n1 = __i2 - __i1;
00761 size_type __off1 = __i1 - _M_ibegin();
00762 if (max_size() - (this->size() - __n1) <= __n2)
00763 __throw_length_error("basic_string::replace");
00764 _M_mutate (__off1, __n1, __n2);
00765
00766 if (__n2 == 1)
00767 _M_data()[__off1] = __c;
00768 else if (__n2)
00769 traits_type::assign(_M_data() + __off1, __n2, __c);
00770 return *this;
00771 }
00772
00773 template<typename _CharT, typename _Traits, typename _Alloc>
00774 typename basic_string<_CharT, _Traits, _Alloc>::size_type
00775 basic_string<_CharT, _Traits, _Alloc>::
00776 copy(_CharT* __s, size_type __n, size_type __pos) const
00777 {
00778 if (__pos > this->size())
00779 __throw_out_of_range("basic_string::copy");
00780
00781 if (__n > this->size() - __pos)
00782 __n = this->size() - __pos;
00783
00784 traits_type::copy(__s, _M_data() + __pos, __n);
00785
00786 return __n;
00787 }
00788
00789 template<typename _CharT, typename _Traits, typename _Alloc>
00790 typename basic_string<_CharT, _Traits, _Alloc>::size_type
00791 basic_string<_CharT, _Traits, _Alloc>::
00792 find(const _CharT* __s, size_type __pos, size_type __n) const
00793 {
00794 size_type __size = this->size();
00795 size_t __xpos = __pos;
00796 const _CharT* __data = _M_data();
00797 for (; __xpos + __n <= __size; ++__xpos)
00798 if (traits_type::compare(__data + __xpos, __s, __n) == 0)
00799 return __xpos;
00800 return npos;
00801 }
00802
00803 template<typename _CharT, typename _Traits, typename _Alloc>
00804 typename basic_string<_CharT, _Traits, _Alloc>::size_type
00805 basic_string<_CharT, _Traits, _Alloc>::
00806 find(_CharT __c, size_type __pos) const
00807 {
00808 size_type __size = this->size();
00809 size_type __ret = npos;
00810 if (__pos < __size)
00811 {
00812 const _CharT* __data = _M_data();
00813 size_type __n = __size - __pos;
00814 const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
00815 if (__p)
00816 __ret = __p - __data;
00817 }
00818 return __ret;
00819 }
00820
00821
00822 template<typename _CharT, typename _Traits, typename _Alloc>
00823 typename basic_string<_CharT, _Traits, _Alloc>::size_type
00824 basic_string<_CharT, _Traits, _Alloc>::
00825 rfind(const _CharT* __s, size_type __pos, size_type __n) const
00826 {
00827 size_type __size = this->size();
00828 if (__n <= __size)
00829 {
00830 __pos = std::min(size_type(__size - __n), __pos);
00831 const _CharT* __data = _M_data();
00832 do
00833 {
00834 if (traits_type::compare(__data + __pos, __s, __n) == 0)
00835 return __pos;
00836 }
00837 while (__pos-- > 0);
00838 }
00839 return npos;
00840 }
00841
00842 template<typename _CharT, typename _Traits, typename _Alloc>
00843 typename basic_string<_CharT, _Traits, _Alloc>::size_type
00844 basic_string<_CharT, _Traits, _Alloc>::
00845 rfind(_CharT __c, size_type __pos) const
00846 {
00847 size_type __size = this->size();
00848 if (__size)
00849 {
00850 size_t __xpos = __size - 1;
00851 if (__xpos > __pos)
00852 __xpos = __pos;
00853
00854 for (++__xpos; __xpos-- > 0; )
00855 if (traits_type::eq(_M_data()[__xpos], __c))
00856 return __xpos;
00857 }
00858 return npos;
00859 }
00860
00861 template<typename _CharT, typename _Traits, typename _Alloc>
00862 typename basic_string<_CharT, _Traits, _Alloc>::size_type
00863 basic_string<_CharT, _Traits, _Alloc>::
00864 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
00865 {
00866 for (; __n && __pos < this->size(); ++__pos)
00867 {
00868 const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]);
00869 if (__p)
00870 return __pos;
00871 }
00872 return npos;
00873 }
00874
00875 template<typename _CharT, typename _Traits, typename _Alloc>
00876 typename basic_string<_CharT, _Traits, _Alloc>::size_type
00877 basic_string<_CharT, _Traits, _Alloc>::
00878 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
00879 {
00880 size_type __size = this->size();
00881 if (__size && __n)
00882 {
00883 if (--__size > __pos)
00884 __size = __pos;
00885 do
00886 {
00887 if (traits_type::find(__s, __n, _M_data()[__size]))
00888 return __size;
00889 }
00890 while (__size-- != 0);
00891 }
00892 return npos;
00893 }
00894
00895 template<typename _CharT, typename _Traits, typename _Alloc>
00896 typename basic_string<_CharT, _Traits, _Alloc>::size_type
00897 basic_string<_CharT, _Traits, _Alloc>::
00898 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00899 {
00900 size_t __xpos = __pos;
00901 for (; __xpos < this->size(); ++__xpos)
00902 if (!traits_type::find(__s, __n, _M_data()[__xpos]))
00903 return __xpos;
00904 return npos;
00905 }
00906
00907 template<typename _CharT, typename _Traits, typename _Alloc>
00908 typename basic_string<_CharT, _Traits, _Alloc>::size_type
00909 basic_string<_CharT, _Traits, _Alloc>::
00910 find_first_not_of(_CharT __c, size_type __pos) const
00911 {
00912 size_t __xpos = __pos;
00913 for (; __xpos < this->size(); ++__xpos)
00914 if (!traits_type::eq(_M_data()[__xpos], __c))
00915 return __xpos;
00916 return npos;
00917 }
00918
00919 template<typename _CharT, typename _Traits, typename _Alloc>
00920 typename basic_string<_CharT, _Traits, _Alloc>::size_type
00921 basic_string<_CharT, _Traits, _Alloc>::
00922 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00923 {
00924 size_type __size = this->size();
00925 if (__size)
00926 {
00927 if (--__size > __pos)
00928 __size = __pos;
00929 do
00930 {
00931 if (!traits_type::find(__s, __n, _M_data()[__size]))
00932 return __size;
00933 }
00934 while (__size--);
00935 }
00936 return npos;
00937 }
00938
00939 template<typename _CharT, typename _Traits, typename _Alloc>
00940 typename basic_string<_CharT, _Traits, _Alloc>::size_type
00941 basic_string<_CharT, _Traits, _Alloc>::
00942 find_last_not_of(_CharT __c, size_type __pos) const
00943 {
00944 size_type __size = this->size();
00945 if (__size)
00946 {
00947 if (--__size > __pos)
00948 __size = __pos;
00949 do
00950 {
00951 if (!traits_type::eq(_M_data()[__size], __c))
00952 return __size;
00953 }
00954 while (__size--);
00955 }
00956 return npos;
00957 }
00958
00959 template<typename _CharT, typename _Traits, typename _Alloc>
00960 int
00961 basic_string<_CharT, _Traits, _Alloc>::
00962 compare(size_type __pos, size_type __n, const basic_string& __str) const
00963 {
00964 size_type __size = this->size();
00965 size_type __osize = __str.size();
00966 if (__pos > __size)
00967 __throw_out_of_range("basic_string::compare");
00968
00969 size_type __rsize= std::min(size_type(__size - __pos), __n);
00970 size_type __len = std::min(__rsize, __osize);
00971 int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
00972 if (!__r)
00973 __r = __rsize - __osize;
00974 return __r;
00975 }
00976
00977 template<typename _CharT, typename _Traits, typename _Alloc>
00978 int
00979 basic_string<_CharT, _Traits, _Alloc>::
00980 compare(size_type __pos1, size_type __n1, const basic_string& __str,
00981 size_type __pos2, size_type __n2) const
00982 {
00983 size_type __size = this->size();
00984 size_type __osize = __str.size();
00985 if (__pos1 > __size || __pos2 > __osize)
00986 __throw_out_of_range("basic_string::compare");
00987
00988 size_type __rsize = std::min(size_type(__size - __pos1), __n1);
00989 size_type __rosize = std::min(size_type(__osize - __pos2), __n2);
00990 size_type __len = std::min(__rsize, __rosize);
00991 int __r = traits_type::compare(_M_data() + __pos1,
00992 __str.data() + __pos2, __len);
00993 if (!__r)
00994 __r = __rsize - __rosize;
00995 return __r;
00996 }
00997
00998
00999 template<typename _CharT, typename _Traits, typename _Alloc>
01000 int
01001 basic_string<_CharT, _Traits, _Alloc>::
01002 compare(const _CharT* __s) const
01003 {
01004 size_type __size = this->size();
01005 size_type __osize = traits_type::length(__s);
01006 size_type __len = std::min(__size, __osize);
01007 int __r = traits_type::compare(_M_data(), __s, __len);
01008 if (!__r)
01009 __r = __size - __osize;
01010 return __r;
01011 }
01012
01013
01014 template<typename _CharT, typename _Traits, typename _Alloc>
01015 int
01016 basic_string <_CharT, _Traits, _Alloc>::
01017 compare(size_type __pos, size_type __n1, const _CharT* __s) const
01018 {
01019 size_type __size = this->size();
01020 if (__pos > __size)
01021 __throw_out_of_range("basic_string::compare");
01022
01023 size_type __osize = traits_type::length(__s);
01024 size_type __rsize = std::min(size_type(__size - __pos), __n1);
01025 size_type __len = std::min(__rsize, __osize);
01026 int __r = traits_type::compare(_M_data() + __pos, __s, __len);
01027 if (!__r)
01028 __r = __rsize - __osize;
01029 return __r;
01030 }
01031
01032 template<typename _CharT, typename _Traits, typename _Alloc>
01033 int
01034 basic_string <_CharT, _Traits, _Alloc>::
01035 compare(size_type __pos, size_type __n1, const _CharT* __s,
01036 size_type __n2) const
01037 {
01038 size_type __size = this->size();
01039 if (__pos > __size)
01040 __throw_out_of_range("basic_string::compare");
01041
01042 size_type __rsize = std::min(size_type(__size - __pos), __n1);
01043 size_type __len = std::min(__rsize, __n2);
01044 int __r = traits_type::compare(_M_data() + __pos, __s, __len);
01045 if (!__r)
01046 __r = __rsize - __n2;
01047 return __r;
01048 }
01049
01050 template <class _CharT, class _Traits, class _Alloc>
01051 void
01052 _S_string_copy(const basic_string<_CharT, _Traits, _Alloc>& __str,
01053 _CharT* __buf, typename _Alloc::size_type __bufsiz)
01054 {
01055 typedef typename _Alloc::size_type size_type;
01056 size_type __strsize = __str.size();
01057 size_type __bytes = std::min(__strsize, __bufsiz - 1);
01058 _Traits::copy(__buf, __str.data(), __bytes);
01059 __buf[__bytes] = _CharT();
01060 }
01061
01062
01063
01064
01065 #if _GLIBCPP_EXTERN_TEMPLATE
01066 extern template class basic_string<char>;
01067 extern template
01068 basic_istream<char>&
01069 operator>>(basic_istream<char>&, string&);
01070 extern template
01071 basic_ostream<char>&
01072 operator<<(basic_ostream<char>&, const string&);
01073 extern template
01074 basic_istream<char>&
01075 getline(basic_istream<char>&, string&, char);
01076 extern template
01077 basic_istream<char>&
01078 getline(basic_istream<char>&, string&);
01079
01080 #ifdef _GLIBCPP_USE_WCHAR_T
01081 extern template class basic_string<wchar_t>;
01082 extern template
01083 basic_istream<wchar_t>&
01084 operator>>(basic_istream<wchar_t>&, wstring&);
01085 extern template
01086 basic_ostream<wchar_t>&
01087 operator<<(basic_ostream<wchar_t>&, const wstring&);
01088 extern template
01089 basic_istream<wchar_t>&
01090 getline(basic_istream<wchar_t>&, wstring&, wchar_t);
01091 extern template
01092 basic_istream<wchar_t>&
01093 getline(basic_istream<wchar_t>&, wstring&);
01094 #endif
01095 #endif
01096 }
01097
01098 #endif