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