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