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