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