_string.h revision 9720d5f59b9c1f5d1b9ecbc9173dbcb71bd557be
1/* 2 * Copyright (c) 1997-1999 3 * Silicon Graphics Computer Systems, Inc. 4 * 5 * Copyright (c) 1999 6 * Boris Fomitchev 7 * 8 * This material is provided "as is", with absolutely no warranty expressed 9 * or implied. Any use is at your own risk. 10 * 11 * Permission to use or copy this software for any purpose is hereby granted 12 * without fee, provided the above notices are retained on all copies. 13 * Permission to modify the code and to distribute modified code is granted, 14 * provided the above notices are retained, and a notice that the code was 15 * modified is included with the above copyright notice. 16 * 17 */ 18 19#ifndef _STLP_INTERNAL_STRING_H 20#define _STLP_INTERNAL_STRING_H 21 22#ifndef _STLP_INTERNAL_ALLOC_H 23# include <stl/_alloc.h> 24#endif 25 26#ifndef _STLP_STRING_FWD_H 27# include <stl/_string_fwd.h> 28#endif 29 30#ifndef _STLP_INTERNAL_FUNCTION_BASE_H 31# include <stl/_function_base.h> 32#endif 33 34#ifndef _STLP_INTERNAL_ALGOBASE_H 35# include <stl/_algobase.h> 36#endif 37 38#ifndef _STLP_INTERNAL_ITERATOR_H 39# include <stl/_iterator.h> 40#endif 41 42#ifndef _STLP_INTERNAL_UNINITIALIZED_H 43# include <stl/_uninitialized.h> 44#endif 45 46#if defined (_STLP_USE_TEMPLATE_EXPRESSION) 47# include <stl/_string_sum.h> 48#endif /* _STLP_USE_TEMPLATE_EXPRESSION */ 49 50#if defined (__MWERKS__) && ! defined (_STLP_USE_OWN_NAMESPACE) 51 52// MSL implementation classes expect to see the definition of streampos 53// when this header is included. We expect this to be fixed in later MSL 54// implementations 55# if !defined( __MSL_CPP__ ) || __MSL_CPP__ < 0x4105 56# include <stl/msl_string.h> 57# endif 58#endif // __MWERKS__ 59 60/* 61 * Standard C++ string class. This class has performance 62 * characteristics very much like vector<>, meaning, for example, that 63 * it does not perform reference-count or copy-on-write, and that 64 * concatenation of two strings is an O(N) operation. 65 66 * There are three reasons why basic_string is not identical to 67 * vector. 68 * First, basic_string can always stores a null character 69 * at the end (macro dependent); this makes it possible for c_str to 70 * be a fast operation. 71 * Second, the C++ standard requires basic_string to copy elements 72 * using char_traits<>::assign, char_traits<>::copy, and 73 * char_traits<>::move. This means that all of vector<>'s low-level 74 * operations must be rewritten. Third, basic_string<> has a lot of 75 * extra functions in its interface that are convenient but, strictly 76 * speaking, redundant. 77 78 * Additionally, the C++ standard imposes a major restriction: according 79 * to the standard, the character type _CharT must be a POD type. This 80 * implementation weakens that restriction, and allows _CharT to be a 81 * a user-defined non-POD type. However, _CharT must still have a 82 * default constructor. 83 */ 84 85#include <stl/_string_base.h> 86 87_STLP_BEGIN_NAMESPACE 88 89// ------------------------------------------------------------ 90// Class basic_string. 91 92// Class invariants: 93// (1) [start, finish) is a valid range. 94// (2) Each iterator in [start, finish) points to a valid object 95// of type value_type. 96// (3) *finish is a valid object of type value_type; when 97// value_type is not a POD it is value_type(). 98// (4) [finish + 1, end_of_storage) is a valid range. 99// (5) Each iterator in [finish + 1, end_of_storage) points to 100// unininitialized memory. 101 102// Note one important consequence: a string of length n must manage 103// a block of memory whose size is at least n + 1. 104 105struct _String_reserve_t {}; 106 107#if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 108# define basic_string _STLP_NO_MEM_T_NAME(str) 109#elif defined (_STLP_DEBUG) 110# define basic_string _STLP_NON_DBG_NAME(str) 111#endif 112 113#if defined (basic_string) 114_STLP_MOVE_TO_PRIV_NAMESPACE 115#endif 116 117template <class _CharT, class _Traits, class _Alloc> 118class basic_string : protected _STLP_PRIV _String_base<_CharT,_Alloc> 119#if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (basic_string) 120 , public __stlport_class<basic_string<_CharT, _Traits, _Alloc> > 121#endif 122{ 123protected: // Protected members inherited from base. 124 typedef _STLP_PRIV _String_base<_CharT,_Alloc> _Base; 125 typedef basic_string<_CharT, _Traits, _Alloc> _Self; 126 // fbp : used to optimize char/wchar_t cases, and to simplify 127 // _STLP_DEF_CONST_PLCT_NEW_BUG problem workaround 128 typedef typename _IsIntegral<_CharT>::_Ret _Char_Is_Integral; 129 typedef typename _IsPOD<_CharT>::_Type _Char_Is_POD; 130 typedef random_access_iterator_tag r_a_i_t; 131 132public: 133 typedef _CharT value_type; 134 typedef _Traits traits_type; 135 136 typedef value_type* pointer; 137 typedef const value_type* const_pointer; 138 typedef value_type& reference; 139 typedef const value_type& const_reference; 140 typedef typename _Base::size_type size_type; 141 typedef ptrdiff_t difference_type; 142 typedef random_access_iterator_tag _Iterator_category; 143 144 typedef const value_type* const_iterator; 145 typedef value_type* iterator; 146 147 _STLP_DECLARE_RANDOM_ACCESS_REVERSE_ITERATORS; 148 149#include <stl/_string_npos.h> 150 151 typedef _String_reserve_t _Reserve_t; 152 153public: // Constructor, destructor, assignment. 154 typedef typename _Base::allocator_type allocator_type; 155 156 allocator_type get_allocator() const 157 { return _STLP_CONVERT_ALLOCATOR((const allocator_type&)this->_M_end_of_storage, _CharT); } 158 159#if !defined (_STLP_DONT_SUP_DFLT_PARAM) 160 explicit basic_string(const allocator_type& __a = allocator_type()) 161#else 162 basic_string() 163 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type(), _Base::_DEFAULT_SIZE) 164 { _M_terminate_string(); } 165 explicit basic_string(const allocator_type& __a) 166#endif 167 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a, _Base::_DEFAULT_SIZE) 168 { _M_terminate_string(); } 169 170#if !defined (_STLP_DONT_SUP_DFLT_PARAM) 171 basic_string(_Reserve_t, size_t __n, 172 const allocator_type& __a = allocator_type()) 173#else 174 basic_string(_Reserve_t, size_t __n) 175 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type(), __n + 1) 176 { _M_terminate_string(); } 177 basic_string(_Reserve_t, size_t __n, const allocator_type& __a) 178#endif 179 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a, __n + 1) 180 { _M_terminate_string(); } 181 182 basic_string(const _Self&); 183 184#if !defined (_STLP_DONT_SUP_DFLT_PARAM) 185 basic_string(const _Self& __s, size_type __pos, size_type __n = npos, 186 const allocator_type& __a = allocator_type()) 187#else 188 basic_string(const _Self& __s, size_type __pos) 189 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 190 if (__pos > __s.size()) 191 this->_M_throw_out_of_range(); 192 else 193 _M_range_initialize(__s._M_Start() + __pos, __s._M_Finish()); 194 } 195 basic_string(const _Self& __s, size_type __pos, size_type __n) 196 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 197 if (__pos > __s.size()) 198 this->_M_throw_out_of_range(); 199 else 200 _M_range_initialize(__s._M_Start() + __pos, 201 __s._M_Start() + __pos + (min) (__n, __s.size() - __pos)); 202 } 203 basic_string(const _Self& __s, size_type __pos, size_type __n, 204 const allocator_type& __a) 205#endif 206 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a) { 207 if (__pos > __s.size()) 208 this->_M_throw_out_of_range(); 209 else 210 _M_range_initialize(__s._M_Start() + __pos, 211 __s._M_Start() + __pos + (min) (__n, __s.size() - __pos)); 212 } 213 214#if !defined (_STLP_DONT_SUP_DFLT_PARAM) 215 basic_string(const _CharT* __s, size_type __n, 216 const allocator_type& __a = allocator_type()) 217#else 218 basic_string(const _CharT* __s, size_type __n) 219 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 220 _STLP_FIX_LITERAL_BUG(__s) 221 _M_range_initialize(__s, __s + __n); 222 } 223 basic_string(const _CharT* __s, size_type __n, const allocator_type& __a) 224#endif 225 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a) { 226 _STLP_FIX_LITERAL_BUG(__s) 227 _M_range_initialize(__s, __s + __n); 228 } 229 230#if !defined (_STLP_DONT_SUP_DFLT_PARAM) 231 basic_string(const _CharT* __s, 232 const allocator_type& __a = allocator_type()); 233#else 234 basic_string(const _CharT* __s); 235 basic_string(const _CharT* __s, const allocator_type& __a); 236#endif 237 238#if !defined (_STLP_DONT_SUP_DFLT_PARAM) 239 basic_string(size_type __n, _CharT __c, 240 const allocator_type& __a = allocator_type()) 241#else 242 basic_string(size_type __n, _CharT __c) 243 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type(), __n + 1) { 244# if defined (_STLP_USE_SHORT_STRING_OPTIM) 245 if (this->_M_using_static_buf()) { 246 _Traits::assign(this->_M_Start(), __n, __c); 247 this->_M_finish = this->_M_Start() + __n; 248 } 249 else 250# endif 251 this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_Start(), __n, __c); 252 _M_terminate_string(); 253 } 254 basic_string(size_type __n, _CharT __c, const allocator_type& __a) 255#endif 256 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a, __n + 1) { 257#if defined (_STLP_USE_SHORT_STRING_OPTIM) 258 if (this->_M_using_static_buf()) { 259 _Traits::assign(this->_M_Start(), __n, __c); 260 this->_M_finish = this->_M_Start() + __n; 261 } 262 else 263#endif 264 this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_Start(), __n, __c); 265 _M_terminate_string(); 266 } 267 268 basic_string(__move_source<_Self> src) 269 : _STLP_PRIV _String_base<_CharT,_Alloc>(__move_source<_Base>(src.get())) {} 270 271 // Check to see if _InputIterator is an integer type. If so, then 272 // it can't be an iterator. 273#if defined (_STLP_MEMBER_TEMPLATES) && !(defined (__MRC__) || (defined(__SC__) && !defined(__DMC__))) //*ty 04/30/2001 - mpw compilers choke on this ctor 274# if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 275 template <class _InputIterator> 276 basic_string(_InputIterator __f, _InputIterator __l, 277 const allocator_type & __a _STLP_ALLOCATOR_TYPE_DFL) 278 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a) { 279 typedef typename _IsIntegral<_InputIterator>::_Ret _Integral; 280 _M_initialize_dispatch(__f, __l, _Integral()); 281 } 282# if defined (_STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS) 283 template <class _InputIterator> 284 basic_string(_InputIterator __f, _InputIterator __l) 285 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 286 typedef typename _IsIntegral<_InputIterator>::_Ret _Integral; 287 _M_initialize_dispatch(__f, __l, _Integral()); 288 } 289# endif 290# else 291 /* We need an additionnal constructor to build an empty string without 292 * any allocation or termination char*/ 293protected: 294 struct _CalledFromWorkaround_t {}; 295 basic_string(_CalledFromWorkaround_t, const allocator_type &__a) 296 : _String_base<_CharT,_Alloc>(__a) {} 297public: 298# endif /* _STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND */ 299#endif /* !__MRC__ || (__SC__ && !__DMC__) */ 300 301#if !(defined (_STLP_MEMBER_TEMPLATES) && !(defined (__MRC__) || (defined (__SC__) && !defined (__DMC__)))) || \ 302 !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS) || \ 303 defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 304 basic_string(const _CharT* __f, const _CharT* __l, 305 const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL) 306 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a) { 307 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 308 _M_range_initialize(__f, __l); 309 } 310# if defined (_STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS) 311 basic_string(const _CharT* __f, const _CharT* __l) 312 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 313 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 314 _M_range_initialize(__f, __l); 315 } 316# endif 317#endif /* _STLP_MEMBER_TEMPLATES */ 318 319private: 320 template <class _InputIter> 321 void _M_range_initialize(_InputIter __f, _InputIter __l, 322 const input_iterator_tag &__tag) { 323 this->_M_allocate_block(); 324 _M_construct_null(this->_M_Finish()); 325 _STLP_TRY { 326 _M_appendT(__f, __l, __tag); 327 } 328 _STLP_UNWIND(this->_M_destroy_range()) 329 } 330 331 template <class _ForwardIter> 332 void _M_range_initialize(_ForwardIter __f, _ForwardIter __l, 333 const forward_iterator_tag &) { 334 difference_type __n = distance(__f, __l); 335 this->_M_allocate_block(__n + 1); 336#if defined (_STLP_USE_SHORT_STRING_OPTIM) 337 if (this->_M_using_static_buf()) { 338 _M_copyT(__f, __l, this->_M_Start()); 339 this->_M_finish = this->_M_Start() + __n; 340 } 341 else 342#endif /* _STLP_USE_SHORT_STRING_OPTIM */ 343 this->_M_finish = uninitialized_copy(__f, __l, this->_M_Start()); 344 this->_M_terminate_string(); 345 } 346 347 template <class _InputIter> 348 void _M_range_initializeT(_InputIter __f, _InputIter __l) { 349 _M_range_initialize(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter)); 350 } 351 352 template <class _Integer> 353 void _M_initialize_dispatch(_Integer __n, _Integer __x, const __true_type& /*_Integral*/) { 354 this->_M_allocate_block(__n + 1); 355#if defined (_STLP_USE_SHORT_STRING_OPTIM) 356 if (this->_M_using_static_buf()) { 357 _Traits::assign(this->_M_Start(), __n, __x); 358 this->_M_finish = this->_M_Start() + __n; 359 } 360 else 361#endif /* _STLP_USE_SHORT_STRING_OPTIM */ 362 this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_Start(), __n, __x); 363 this->_M_terminate_string(); 364 } 365 366 template <class _InputIter> 367 void _M_initialize_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*_Integral*/) { 368 _M_range_initializeT(__f, __l); 369 } 370 371public: 372 ~basic_string() 373 { this->_M_destroy_range(); } 374 375 _Self& operator=(const _Self& __s) { 376 if (&__s != this) 377 _M_assign(__s._M_Start(), __s._M_Finish()); 378 return *this; 379 } 380 381 _Self& operator=(const _CharT* __s) { 382 _STLP_FIX_LITERAL_BUG(__s) 383 return _M_assign(__s, __s + traits_type::length(__s)); 384 } 385 386 _Self& operator=(_CharT __c) 387 { return assign(__STATIC_CAST(size_type,1), __c); } 388 389protected: 390 391 static _CharT _STLP_CALL _M_null() 392 { return _STLP_DEFAULT_CONSTRUCTED(_CharT); } 393 394protected: // Helper functions used by constructors 395 // and elsewhere. 396 // fbp : simplify integer types (char, wchar) 397 void _M_construct_null_aux(_CharT* __p, const __false_type& /*_Is_Integral*/) const { 398#if defined (_STLP_USE_SHORT_STRING_OPTIM) 399 if (this->_M_using_static_buf()) 400 _Traits::assign(*__p, _M_null()); 401 else 402#endif /*_STLP_USE_SHORT_STRING_OPTIM*/ 403 _STLP_STD::_Construct(__p); 404 } 405 void _M_construct_null_aux(_CharT* __p, const __true_type& /*_Is_Integral*/) const 406 { *__p = 0; } 407 408 void _M_force_construct_null(_CharT*, const __true_type& /* _Is_POD */) const 409 { /*Nothing to do*/ } 410 void _M_force_construct_null(_CharT* __p, const __false_type& /* _Is_POD */) const 411 { _M_construct_null_aux(__p, _Char_Is_Integral()); } 412 413 void _M_construct_null(_CharT* __p) const { 414 typedef __false_type _Answer; 415 416 _M_force_construct_null(__p, _Answer()); 417 } 418 419protected: 420 // Helper functions used by constructors. It is a severe error for 421 // any of them to be called anywhere except from within constructors. 422 void _M_terminate_string_aux(const __false_type& __is_integral) { 423 _STLP_TRY { 424 _M_construct_null_aux(this->_M_Finish(), __is_integral); 425 } 426 _STLP_UNWIND(this->_M_destroy_range(0,0)) 427 } 428 429 void _M_terminate_string_aux(const __true_type& __is_integral) 430 { _M_construct_null_aux(this->_M_Finish(), __is_integral); } 431 432 void _M_force_terminate_string(const __true_type& /* _Is_POD */) 433 { /*Nothing to do*/ } 434 void _M_force_terminate_string(const __false_type& /* _Is_POD */) 435 { _M_terminate_string_aux(_Char_Is_Integral()); } 436 437 void _M_terminate_string() { 438 typedef __false_type _Answer; 439 440 _M_force_terminate_string(_Answer()); 441 } 442 443 bool _M_inside(const _CharT* __s) const { 444 _STLP_FIX_LITERAL_BUG(__s) 445 return (__s >= this->_M_Start()) && (__s < this->_M_Finish()); 446 } 447 448 void _M_range_initialize(const _CharT* __f, const _CharT* __l) { 449 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 450 ptrdiff_t __n = __l - __f; 451 this->_M_allocate_block(__n + 1); 452#if defined (_STLP_USE_SHORT_STRING_OPTIM) 453 if (this->_M_using_static_buf()) { 454 _M_copy(__f, __l, this->_M_Start()); 455 this->_M_finish = this->_M_Start() + __n; 456 } 457 else 458#endif /* _STLP_USE_SHORT_STRING_OPTIM */ 459 this->_M_finish = uninitialized_copy(__f, __l, this->_M_Start()); 460 _M_terminate_string(); 461 } 462 463public: // Iterators. 464 iterator begin() { return this->_M_Start(); } 465 iterator end() { return this->_M_Finish(); } 466 const_iterator begin() const { return this->_M_Start(); } 467 const_iterator end() const { return this->_M_Finish(); } 468 469 reverse_iterator rbegin() 470 { return reverse_iterator(this->_M_Finish()); } 471 reverse_iterator rend() 472 { return reverse_iterator(this->_M_Start()); } 473 const_reverse_iterator rbegin() const 474 { return const_reverse_iterator(this->_M_Finish()); } 475 const_reverse_iterator rend() const 476 { return const_reverse_iterator(this->_M_Start()); } 477 478public: // Size, capacity, etc. 479 size_type size() const { return this->_M_Finish() - this->_M_Start(); } 480 size_type length() const { return size(); } 481 size_t max_size() const { return _Base::max_size(); } 482 483 void resize(size_type __n, _CharT __c) { 484 if (__n <= size()) 485 erase(begin() + __n, end()); 486 else 487 append(__n - size(), __c); 488 } 489 490 void resize(size_type __n) { resize(__n, _M_null()); } 491 492 void reserve(size_type = 0); 493 494 size_type capacity() const 495 { return (this->_M_end_of_storage._M_data - this->_M_Start()) - 1; } 496 497 void clear() { 498 if (!empty()) { 499 _Traits::assign(*(this->_M_Start()), _M_null()); 500 this->_M_destroy_range(1); 501 this->_M_finish = this->_M_Start(); 502 } 503 } 504 505 bool empty() const { return this->_M_Start() == this->_M_Finish(); } 506 507public: // Element access. 508 509 const_reference operator[](size_type __n) const 510 { return *(this->_M_Start() + __n); } 511 reference operator[](size_type __n) 512 { return *(this->_M_Start() + __n); } 513 514 const_reference at(size_type __n) const { 515 if (__n >= size()) 516 this->_M_throw_out_of_range(); 517 return *(this->_M_Start() + __n); 518 } 519 520 reference at(size_type __n) { 521 if (__n >= size()) 522 this->_M_throw_out_of_range(); 523 return *(this->_M_Start() + __n); 524 } 525 526public: // Append, operator+=, push_back. 527 528 _Self& operator+=(const _Self& __s) { return append(__s); } 529 _Self& operator+=(const _CharT* __s) { _STLP_FIX_LITERAL_BUG(__s) return append(__s); } 530 _Self& operator+=(_CharT __c) { push_back(__c); return *this; } 531 532#if defined (_STLP_MEMBER_TEMPLATES) 533# if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 534private: // Helper functions for append. 535 template <class _InputIter> 536 _Self& _M_appendT(_InputIter __first, _InputIter __last, 537 const input_iterator_tag &) { 538 for ( ; __first != __last ; ++__first) 539 push_back(*__first); 540 return *this; 541 } 542 543 template <class _ForwardIter> 544 _Self& _M_appendT(_ForwardIter __first, _ForwardIter __last, 545 const forward_iterator_tag &) { 546 if (__first != __last) { 547 const size_type __old_size = this->size(); 548 difference_type __n = distance(__first, __last); 549 if (__STATIC_CAST(size_type,__n) > this->max_size() || __old_size > this->max_size() - __STATIC_CAST(size_type,__n)) 550 this->_M_throw_length_error(); 551 if (__old_size + __n > this->capacity()) { 552 size_type __len = __old_size + (max)(__old_size, __STATIC_CAST(size_type,__n)) + 1; 553 pointer __new_start = this->_M_end_of_storage.allocate(__len, __len); 554 pointer __new_finish = __new_start; 555 _STLP_TRY { 556 __new_finish = uninitialized_copy(this->_M_Start(), this->_M_Finish(), __new_start); 557 __new_finish = uninitialized_copy(__first, __last, __new_finish); 558 _M_construct_null(__new_finish); 559 } 560 _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish), 561 this->_M_end_of_storage.deallocate(__new_start, __len))) 562 this->_M_destroy_range(); 563 this->_M_deallocate_block(); 564 this->_M_reset(__new_start, __new_finish, __new_start + __len); 565 } 566 else { 567 _ForwardIter __f1 = __first; 568 ++__f1; 569#if defined (_STLP_USE_SHORT_STRING_OPTIM) 570 if (this->_M_using_static_buf()) 571 _M_copyT(__f1, __last, this->_M_Finish() + 1); 572 else 573#endif /* _STLP_USE_SHORT_STRING_OPTIM */ 574 uninitialized_copy(__f1, __last, this->_M_Finish() + 1); 575 _STLP_TRY { 576 _M_construct_null(this->_M_Finish() + __n); 577 } 578 _STLP_UNWIND(this->_M_destroy_ptr_range(this->_M_Finish() + 1, this->_M_Finish() + __n)) 579 _Traits::assign(*this->_M_finish, *__first); 580 this->_M_finish += __n; 581 } 582 } 583 return *this; 584 } 585 586 template <class _Integer> 587 _Self& _M_append_dispatch(_Integer __n, _Integer __x, const __true_type& /*Integral*/) 588 { return append((size_type) __n, (_CharT) __x); } 589 590 template <class _InputIter> 591 _Self& _M_append_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*Integral*/) 592 { return _M_appendT(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter)); } 593 594public: 595 // Check to see if _InputIterator is an integer type. If so, then 596 // it can't be an iterator. 597 template <class _InputIter> 598 _Self& append(_InputIter __first, _InputIter __last) { 599 typedef typename _IsIntegral<_InputIter>::_Ret _Integral; 600 return _M_append_dispatch(__first, __last, _Integral()); 601 } 602# endif 603#endif 604 605protected: 606 _Self& _M_append(const _CharT* __first, const _CharT* __last); 607 608public: 609#if !defined (_STLP_MEMBER_TEMPLATES) || \ 610 !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS) 611# if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 612 _Self& append(const _CharT* __first, const _CharT* __last) { 613 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 614 return _M_append(__first, __last); 615 } 616# endif 617#endif 618 619 _Self& append(const _Self& __s) 620 { return _M_append(__s._M_Start(), __s._M_Finish()); } 621 622 _Self& append(const _Self& __s, 623 size_type __pos, size_type __n) { 624 if (__pos > __s.size()) 625 this->_M_throw_out_of_range(); 626 return _M_append(__s._M_Start() + __pos, 627 __s._M_Start() + __pos + (min) (__n, __s.size() - __pos)); 628 } 629 630 _Self& append(const _CharT* __s, size_type __n) 631 { _STLP_FIX_LITERAL_BUG(__s) return _M_append(__s, __s+__n); } 632 _Self& append(const _CharT* __s) 633 { _STLP_FIX_LITERAL_BUG(__s) return _M_append(__s, __s + traits_type::length(__s)); } 634 _Self& append(size_type __n, _CharT __c); 635 636public: 637 void push_back(_CharT __c) { 638 if (this->_M_Finish() + 1 == this->_M_end_of_storage._M_data) 639 reserve(size() + (max)(size(), __STATIC_CAST(size_type,1))); 640 _M_construct_null(this->_M_Finish() + 1); 641 _Traits::assign(*(this->_M_Finish()), __c); 642 ++this->_M_finish; 643 } 644 645 void pop_back() { 646 _Traits::assign(*(this->_M_Finish() - 1), _M_null()); 647 this->_M_destroy_back(); 648 --this->_M_finish; 649 } 650 651public: // Assign 652 _Self& assign(const _Self& __s) 653 { return _M_assign(__s._M_Start(), __s._M_Finish()); } 654 655 _Self& assign(const _Self& __s, 656 size_type __pos, size_type __n) { 657 if (__pos > __s.size()) 658 this->_M_throw_out_of_range(); 659 return _M_assign(__s._M_Start() + __pos, 660 __s._M_Start() + __pos + (min) (__n, __s.size() - __pos)); 661 } 662 663 _Self& assign(const _CharT* __s, size_type __n) 664 { _STLP_FIX_LITERAL_BUG(__s) return _M_assign(__s, __s + __n); } 665 666 _Self& assign(const _CharT* __s) 667 { _STLP_FIX_LITERAL_BUG(__s) return _M_assign(__s, __s + _Traits::length(__s)); } 668 669 _Self& assign(size_type __n, _CharT __c); 670 671#if defined (_STLP_MEMBER_TEMPLATES) 672# if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 673private: // Helper functions for assign. 674 template <class _Integer> 675 _Self& _M_assign_dispatch(_Integer __n, _Integer __x, const __true_type& /*_Integral*/) 676 { return assign((size_type) __n, (_CharT) __x); } 677 678 template <class _InputIter> 679 _Self& _M_assign_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*_Integral*/) { 680 pointer __cur = this->_M_Start(); 681 while (__f != __l && __cur != this->_M_Finish()) { 682 _Traits::assign(*__cur, *__f); 683 ++__f; 684 ++__cur; 685 } 686 if (__f == __l) 687 erase(__cur, this->end()); 688 else 689 _M_appendT(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter)); 690 return *this; 691 } 692 693public: 694 // Check to see if _InputIterator is an integer type. If so, then 695 // it can't be an iterator. 696 template <class _InputIter> 697 _Self& assign(_InputIter __first, _InputIter __last) { 698 typedef typename _IsIntegral<_InputIter>::_Ret _Integral; 699 return _M_assign_dispatch(__first, __last, _Integral()); 700 } 701# endif 702#endif 703 704protected: 705 _Self& _M_assign(const _CharT* __f, const _CharT* __l); 706 707public: 708 709#if !defined (_STLP_MEMBER_TEMPLATES) || \ 710 !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS) 711# if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 712 _Self& assign(const _CharT* __f, const _CharT* __l) { 713 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 714 return _M_assign(__f, __l); 715 } 716# endif 717#endif 718 719public: // Insert 720 721 _Self& insert(size_type __pos, const _Self& __s) { 722 if (__pos > size()) 723 this->_M_throw_out_of_range(); 724 if (size() > max_size() - __s.size()) 725 this->_M_throw_length_error(); 726 _M_insert(begin() + __pos, __s._M_Start(), __s._M_Finish(), &__s == this); 727 return *this; 728 } 729 730 _Self& insert(size_type __pos, const _Self& __s, 731 size_type __beg, size_type __n) { 732 if (__pos > size() || __beg > __s.size()) 733 this->_M_throw_out_of_range(); 734 size_type __len = (min) (__n, __s.size() - __beg); 735 if (size() > max_size() - __len) 736 this->_M_throw_length_error(); 737 _M_insert(begin() + __pos, 738 __s._M_Start() + __beg, __s._M_Start() + __beg + __len, &__s == this); 739 return *this; 740 } 741 _Self& insert(size_type __pos, const _CharT* __s, size_type __n) { 742 _STLP_FIX_LITERAL_BUG(__s) 743 if (__pos > size()) 744 this->_M_throw_out_of_range(); 745 if (size() > max_size() - __n) 746 this->_M_throw_length_error(); 747 _M_insert(begin() + __pos, __s, __s + __n, _M_inside(__s)); 748 return *this; 749 } 750 751 _Self& insert(size_type __pos, const _CharT* __s) { 752 _STLP_FIX_LITERAL_BUG(__s) 753 if (__pos > size()) 754 this->_M_throw_out_of_range(); 755 size_type __len = _Traits::length(__s); 756 if (size() > max_size() - __len) 757 this->_M_throw_length_error(); 758 _M_insert(this->_M_Start() + __pos, __s, __s + __len, _M_inside(__s)); 759 return *this; 760 } 761 762 _Self& insert(size_type __pos, size_type __n, _CharT __c) { 763 if (__pos > size()) 764 this->_M_throw_out_of_range(); 765 if (size() > max_size() - __n) 766 this->_M_throw_length_error(); 767 insert(begin() + __pos, __n, __c); 768 return *this; 769 } 770 771 iterator insert(iterator __p, _CharT __c) { 772 _STLP_FIX_LITERAL_BUG(__p) 773 if (__p == end()) { 774 push_back(__c); 775 return this->_M_Finish() - 1; 776 } 777 else 778 return _M_insert_aux(__p, __c); 779 } 780 781 void insert(iterator __p, size_t __n, _CharT __c); 782 783protected: // Helper functions for insert. 784 785 void _M_insert(iterator __p, const _CharT* __first, const _CharT* __last, bool __self_ref); 786 787 pointer _M_insert_aux(pointer, _CharT); 788 789 void _M_copy(const _CharT* __f, const _CharT* __l, _CharT* __res) { 790 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 791 _STLP_FIX_LITERAL_BUG(__res) 792 _Traits::copy(__res, __f, __l - __f); 793 } 794 795 void _M_move(const _CharT* __f, const _CharT* __l, _CharT* __res) { 796 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 797 _Traits::move(__res, __f, __l - __f); 798 } 799 800#if defined (_STLP_MEMBER_TEMPLATES) 801# if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 802 template <class _ForwardIter> 803 void _M_insert_overflow(iterator __pos, _ForwardIter __first, _ForwardIter __last, 804 difference_type __n) { 805 const size_type __old_size = this->size(); 806 size_type __len = __old_size + (max)(__old_size, __STATIC_CAST(size_type,__n)) + 1; 807 pointer __new_start = this->_M_end_of_storage.allocate(__len, __len); 808 pointer __new_finish = __new_start; 809 _STLP_TRY { 810 __new_finish = uninitialized_copy(this->_M_Start(), __pos, __new_start); 811 __new_finish = uninitialized_copy(__first, __last, __new_finish); 812 __new_finish = uninitialized_copy(__pos, this->_M_Finish(), __new_finish); 813 _M_construct_null(__new_finish); 814 } 815 _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish), 816 this->_M_end_of_storage.deallocate(__new_start, __len))) 817 this->_M_destroy_range(); 818 this->_M_deallocate_block(); 819 this->_M_reset(__new_start, __new_finish, __new_start + __len); 820 } 821 822 template <class _InputIter> 823 void _M_insertT(iterator __p, _InputIter __first, _InputIter __last, 824 const input_iterator_tag &) { 825 for ( ; __first != __last; ++__first) { 826 __p = insert(__p, *__first); 827 ++__p; 828 } 829 } 830 831 template <class _ForwardIter> 832 void _M_insertT(iterator __pos, _ForwardIter __first, _ForwardIter __last, 833 const forward_iterator_tag &) { 834 if (__first != __last) { 835 difference_type __n = distance(__first, __last); 836 if (this->_M_end_of_storage._M_data - this->_M_finish >= __n + 1) { 837 const difference_type __elems_after = this->_M_finish - __pos; 838 if (__elems_after >= __n) { 839# if defined (_STLP_USE_SHORT_STRING_OPTIM) 840 if (this->_M_using_static_buf()) 841 _M_copy((this->_M_Finish() - __n) + 1, this->_M_Finish() + 1, this->_M_Finish() + 1); 842 else 843# endif /* _STLP_USE_SHORT_STRING_OPTIM */ 844 uninitialized_copy((this->_M_Finish() - __n) + 1, this->_M_Finish() + 1, this->_M_Finish() + 1); 845 this->_M_finish += __n; 846 _Traits::move(__pos + __n, __pos, (__elems_after - __n) + 1); 847 _M_copyT(__first, __last, __pos); 848 } 849 else { 850 pointer __old_finish = this->_M_Finish(); 851 _ForwardIter __mid = __first; 852 advance(__mid, __elems_after + 1); 853# if defined (_STLP_USE_SHORT_STRING_OPTIM) 854 if (this->_M_using_static_buf()) 855 _M_copyT(__mid, __last, this->_M_Finish() + 1); 856 else 857# endif /* _STLP_USE_SHORT_STRING_OPTIM */ 858 uninitialized_copy(__mid, __last, this->_M_Finish() + 1); 859 this->_M_finish += __n - __elems_after; 860 _STLP_TRY { 861# if defined (_STLP_USE_SHORT_STRING_OPTIM) 862 if (this->_M_using_static_buf()) 863 _M_copy(__pos, __old_finish + 1, this->_M_Finish()); 864 else 865# endif /* _STLP_USE_SHORT_STRING_OPTIM */ 866 uninitialized_copy(__pos, __old_finish + 1, this->_M_Finish()); 867 this->_M_finish += __elems_after; 868 } 869 _STLP_UNWIND((this->_M_destroy_ptr_range(__old_finish + 1, this->_M_Finish()), 870 this->_M_finish = __old_finish)) 871 _M_copyT(__first, __mid, __pos); 872 } 873 } 874 else { 875 _M_insert_overflow(__pos, __first, __last, __n); 876 } 877 } 878 } 879 880 template <class _Integer> 881 void _M_insert_dispatch(iterator __p, _Integer __n, _Integer __x, 882 const __true_type& /*Integral*/) { 883 insert(__p, (size_type) __n, (_CharT) __x); 884 } 885 886 template <class _InputIter> 887 void _M_insert_dispatch(iterator __p, _InputIter __first, _InputIter __last, 888 const __false_type& /*Integral*/) { 889 _STLP_FIX_LITERAL_BUG(__p) 890 /* 891 * Within the basic_string implementation we are only going to check for 892 * self referencing if iterators are string iterators or _CharT pointers. 893 * A user could encapsulate those iterator within their own iterator interface 894 * and in this case lead to a bad behavior, this is a known limitation. 895 */ 896 typedef typename _AreSameUnCVTypes<_InputIter, iterator>::_Ret _IsIterator; 897 typedef typename _AreSameUnCVTypes<_InputIter, const_iterator>::_Ret _IsConstIterator; 898 typedef typename _Lor2<_IsIterator, _IsConstIterator>::_Ret _CheckInside; 899 _M_insert_aux(__p, __first, __last, _CheckInside()); 900 } 901 902 template <class _RandomIter> 903 void _M_insert_aux (iterator __p, _RandomIter __first, _RandomIter __last, 904 const __true_type& /*_CheckInside*/) { 905 _STLP_FIX_LITERAL_BUG(__p) 906 _M_insert(__p, &(*__first), &(*__last), _M_inside(&(*__first))); 907 } 908 909 template<class _InputIter> 910 void _M_insert_aux (iterator __p, _InputIter __first, _InputIter __last, 911 const __false_type& /*_CheckInside*/) { 912 _STLP_FIX_LITERAL_BUG(__p) 913 _M_insertT(__p, __first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIter)); 914 } 915 916 template <class _InputIterator> 917 void _M_copyT(_InputIterator __first, _InputIterator __last, pointer __result) { 918 _STLP_FIX_LITERAL_BUG(__result) 919 for ( ; __first != __last; ++__first, ++__result) 920 _Traits::assign(*__result, *__first); 921 } 922 923# if !defined (_STLP_NO_METHOD_SPECIALIZATION) 924 void _M_copyT(const _CharT* __f, const _CharT* __l, _CharT* __res) { 925 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 926 _STLP_FIX_LITERAL_BUG(__res) 927 _Traits::copy(__res, __f, __l - __f); 928 } 929# endif 930 931public: 932 // Check to see if _InputIterator is an integer type. If so, then 933 // it can't be an iterator. 934 template <class _InputIter> 935 void insert(iterator __p, _InputIter __first, _InputIter __last) { 936 typedef typename _IsIntegral<_InputIter>::_Ret _Integral; 937 _M_insert_dispatch(__p, __first, __last, _Integral()); 938 } 939# endif 940#endif 941 942public: 943 944#if !defined (_STLP_MEMBER_TEMPLATES) || \ 945 !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS) 946 void insert(iterator __p, const _CharT* __f, const _CharT* __l) { 947 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 948 _M_insert(__p, __f, __l, _M_inside(__f)); 949 } 950#endif 951 952public: // Erase. 953 954 _Self& erase(size_type __pos = 0, size_type __n = npos) { 955 if (__pos > size()) 956 this->_M_throw_out_of_range(); 957 erase(begin() + __pos, begin() + __pos + (min) (__n, size() - __pos)); 958 return *this; 959 } 960 961 iterator erase(iterator __pos) { 962 // The move includes the terminating _CharT(). 963 _Traits::move(__pos, __pos + 1, this->_M_Finish() - __pos); 964 this->_M_destroy_back(); 965 --this->_M_finish; 966 return __pos; 967 } 968 969 iterator erase(iterator __first, iterator __last) { 970 if (__first != __last) { 971 // The move includes the terminating _CharT(). 972 traits_type::move(__first, __last, (this->_M_Finish() - __last) + 1); 973 pointer __new_finish = this->_M_Finish() - (__last - __first); 974 this->_M_destroy_ptr_range(__new_finish + 1, this->_M_Finish() + 1); 975 this->_M_finish = __new_finish; 976 } 977 return __first; 978 } 979 980public: // Replace. (Conceptually equivalent 981 // to erase followed by insert.) 982 _Self& replace(size_type __pos, size_type __n, const _Self& __s) { 983 if (__pos > size()) 984 this->_M_throw_out_of_range(); 985 const size_type __len = (min) (__n, size() - __pos); 986 if (size() - __len >= max_size() - __s.size()) 987 this->_M_throw_length_error(); 988 return _M_replace(begin() + __pos, begin() + __pos + __len, 989 __s._M_Start(), __s._M_Finish(), &__s == this); 990 } 991 992 _Self& replace(size_type __pos1, size_type __n1, const _Self& __s, 993 size_type __pos2, size_type __n2) { 994 if (__pos1 > size() || __pos2 > __s.size()) 995 this->_M_throw_out_of_range(); 996 const size_type __len1 = (min) (__n1, size() - __pos1); 997 const size_type __len2 = (min) (__n2, __s.size() - __pos2); 998 if (size() - __len1 >= max_size() - __len2) 999 this->_M_throw_length_error(); 1000 return _M_replace(begin() + __pos1, begin() + __pos1 + __len1, 1001 __s._M_Start() + __pos2, __s._M_Start() + __pos2 + __len2, &__s == this); 1002 } 1003 1004 _Self& replace(size_type __pos, size_type __n1, 1005 const _CharT* __s, size_type __n2) { 1006 _STLP_FIX_LITERAL_BUG(__s) 1007 if (__pos > size()) 1008 this->_M_throw_out_of_range(); 1009 const size_type __len = (min) (__n1, size() - __pos); 1010 if (__n2 > max_size() || size() - __len >= max_size() - __n2) 1011 this->_M_throw_length_error(); 1012 return _M_replace(begin() + __pos, begin() + __pos + __len, 1013 __s, __s + __n2, _M_inside(__s)); 1014 } 1015 1016 _Self& replace(size_type __pos, size_type __n1, const _CharT* __s) { 1017 _STLP_FIX_LITERAL_BUG(__s) 1018 if (__pos > size()) 1019 this->_M_throw_out_of_range(); 1020 const size_type __len = (min) (__n1, size() - __pos); 1021 const size_type __n2 = _Traits::length(__s); 1022 if (__n2 > max_size() || size() - __len >= max_size() - __n2) 1023 this->_M_throw_length_error(); 1024 return _M_replace(begin() + __pos, begin() + __pos + __len, 1025 __s, __s + _Traits::length(__s), _M_inside(__s)); 1026 } 1027 1028 _Self& replace(size_type __pos, size_type __n1, 1029 size_type __n2, _CharT __c) { 1030 if (__pos > size()) 1031 this->_M_throw_out_of_range(); 1032 const size_type __len = (min) (__n1, size() - __pos); 1033 if (__n2 > max_size() || size() - __len >= max_size() - __n2) 1034 this->_M_throw_length_error(); 1035 return replace(begin() + __pos, begin() + __pos + __len, __n2, __c); 1036 } 1037 1038 _Self& replace(iterator __first, iterator __last, const _Self& __s) { 1039 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 1040 return _M_replace(__first, __last, __s._M_Start(), __s._M_Finish(), &__s == this); 1041 } 1042 1043 _Self& replace(iterator __first, iterator __last, 1044 const _CharT* __s, size_type __n) { 1045 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 1046 _STLP_FIX_LITERAL_BUG(__s) 1047 return _M_replace(__first, __last, __s, __s + __n, _M_inside(__s)); 1048 } 1049 1050 _Self& replace(iterator __first, iterator __last, 1051 const _CharT* __s) { 1052 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 1053 _STLP_FIX_LITERAL_BUG(__s) 1054 return _M_replace(__first, __last, __s, __s + _Traits::length(__s), _M_inside(__s)); 1055 } 1056 1057 _Self& replace(iterator __first, iterator __last, size_type __n, _CharT __c); 1058 1059protected: // Helper functions for replace. 1060 _Self& _M_replace(iterator __first, iterator __last, 1061 const _CharT* __f, const _CharT* __l, bool __self_ref); 1062 1063public: 1064#if defined (_STLP_MEMBER_TEMPLATES) 1065# if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 1066 template <class _Integer> 1067 _Self& _M_replace_dispatch(iterator __first, iterator __last, 1068 _Integer __n, _Integer __x, const __true_type& /*IsIntegral*/) { 1069 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 1070 return replace(__first, __last, (size_type) __n, (_CharT) __x); 1071 } 1072 1073 template <class _InputIter> 1074 _Self& _M_replace_dispatch(iterator __first, iterator __last, 1075 _InputIter __f, _InputIter __l, const __false_type& /*IsIntegral*/) { 1076 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 1077 typedef typename _AreSameUnCVTypes<_InputIter, iterator>::_Ret _IsIterator; 1078 typedef typename _AreSameUnCVTypes<_InputIter, const_iterator>::_Ret _IsConstIterator; 1079 typedef typename _Lor2<_IsIterator, _IsConstIterator>::_Ret _CheckInside; 1080 return _M_replace_aux(__first, __last, __f, __l, _CheckInside()); 1081 } 1082 1083 template <class _RandomIter> 1084 _Self& _M_replace_aux(iterator __first, iterator __last, 1085 _RandomIter __f, _RandomIter __l, __true_type const& /*_CheckInside*/) { 1086 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 1087 return _M_replace(__first, __last, &(*__f), &(*__l), _M_inside(&(*__f))); 1088 } 1089 1090 template <class _InputIter> 1091 _Self& _M_replace_aux(iterator __first, iterator __last, 1092 _InputIter __f, _InputIter __l, __false_type const& /*_CheckInside*/) { 1093 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 1094 return _M_replaceT(__first, __last, __f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter)); 1095 } 1096 1097 template <class _InputIter> 1098 _Self& _M_replaceT(iterator __first, iterator __last, 1099 _InputIter __f, _InputIter __l, const input_iterator_tag&__ite_tag) { 1100 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 1101 for ( ; __first != __last && __f != __l; ++__first, ++__f) 1102 _Traits::assign(*__first, *__f); 1103 if (__f == __l) 1104 erase(__first, __last); 1105 else 1106 _M_insertT(__last, __f, __l, __ite_tag); 1107 return *this; 1108 } 1109 1110 template <class _ForwardIter> 1111 _Self& _M_replaceT(iterator __first, iterator __last, 1112 _ForwardIter __f, _ForwardIter __l, const forward_iterator_tag &__ite_tag) { 1113 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 1114 difference_type __n = distance(__f, __l); 1115 const difference_type __len = __last - __first; 1116 if (__len >= __n) { 1117 _M_copyT(__f, __l, __first); 1118 erase(__first + __n, __last); 1119 } 1120 else { 1121 _ForwardIter __m = __f; 1122 advance(__m, __len); 1123 _M_copyT(__f, __m, __first); 1124 _M_insertT(__last, __m, __l, __ite_tag); 1125 } 1126 return *this; 1127 } 1128 1129public: 1130 // Check to see if _InputIter is an integer type. If so, then 1131 // it can't be an iterator. 1132 template <class _InputIter> 1133 _Self& replace(iterator __first, iterator __last, 1134 _InputIter __f, _InputIter __l) { 1135 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 1136 typedef typename _IsIntegral<_InputIter>::_Ret _Integral; 1137 return _M_replace_dispatch(__first, __last, __f, __l, _Integral()); 1138 } 1139 1140# endif 1141#endif 1142 1143#if !defined (_STLP_MEMBER_TEMPLATES) || \ 1144 !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS) 1145# if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 1146 _Self& replace(iterator __first, iterator __last, 1147 const _CharT* __f, const _CharT* __l) { 1148 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 1149 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 1150 return _M_replace(__first, __last, __f, __l, _M_inside(__f)); 1151 } 1152# endif 1153#endif 1154 1155public: // Other modifier member functions. 1156 1157 size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const { 1158 _STLP_FIX_LITERAL_BUG(__s) 1159 if (__pos > size()) 1160 this->_M_throw_out_of_range(); 1161 const size_type __len = (min) (__n, size() - __pos); 1162 _Traits::copy(__s, this->_M_Start() + __pos, __len); 1163 return __len; 1164 } 1165 1166 void swap(_Self& __s) { 1167 this->_M_Swap(__s); 1168 } 1169 1170public: // Conversion to C string. 1171 1172 const _CharT* c_str() const { return this->_M_Start(); } 1173 const _CharT* data() const { return this->_M_Start(); } 1174 1175public: // find. 1176 1177 size_type find(const _Self& __s, size_type __pos = 0) const 1178 { return find(__s._M_Start(), __pos, __s.size()); } 1179 1180 size_type find(const _CharT* __s, size_type __pos = 0) const 1181 { _STLP_FIX_LITERAL_BUG(__s) return find(__s, __pos, _Traits::length(__s)); } 1182 1183 size_type find(const _CharT* __s, size_type __pos, size_type __n) const; 1184 1185 // WIE: Versant schema compiler 5.2.2 ICE workaround 1186 size_type find(_CharT __c) const { return find(__c, 0); } 1187 size_type find(_CharT __c, size_type __pos /* = 0 */) const; 1188 1189public: // rfind. 1190 1191 size_type rfind(const _Self& __s, size_type __pos = npos) const 1192 { return rfind(__s._M_Start(), __pos, __s.size()); } 1193 1194 size_type rfind(const _CharT* __s, size_type __pos = npos) const 1195 { _STLP_FIX_LITERAL_BUG(__s) return rfind(__s, __pos, _Traits::length(__s)); } 1196 1197 size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const; 1198 size_type rfind(_CharT __c, size_type __pos = npos) const; 1199 1200public: // find_first_of 1201 1202 size_type find_first_of(const _Self& __s, size_type __pos = 0) const 1203 { return find_first_of(__s._M_Start(), __pos, __s.size()); } 1204 1205 size_type find_first_of(const _CharT* __s, size_type __pos = 0) const 1206 { _STLP_FIX_LITERAL_BUG(__s) return find_first_of(__s, __pos, _Traits::length(__s)); } 1207 1208 size_type find_first_of(const _CharT* __s, size_type __pos, 1209 size_type __n) const; 1210 1211 size_type find_first_of(_CharT __c, size_type __pos = 0) const 1212 { return find(__c, __pos); } 1213 1214public: // find_last_of 1215 1216 size_type find_last_of(const _Self& __s, 1217 size_type __pos = npos) const 1218 { return find_last_of(__s._M_Start(), __pos, __s.size()); } 1219 1220 size_type find_last_of(const _CharT* __s, size_type __pos = npos) const 1221 { _STLP_FIX_LITERAL_BUG(__s) return find_last_of(__s, __pos, _Traits::length(__s)); } 1222 1223 size_type find_last_of(const _CharT* __s, size_type __pos, 1224 size_type __n) const; 1225 1226 size_type find_last_of(_CharT __c, size_type __pos = npos) const { 1227 return rfind(__c, __pos); 1228 } 1229 1230public: // find_first_not_of 1231 1232 size_type find_first_not_of(const _Self& __s, 1233 size_type __pos = 0) const 1234 { return find_first_not_of(__s._M_Start(), __pos, __s.size()); } 1235 1236 size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const 1237 { _STLP_FIX_LITERAL_BUG(__s) return find_first_not_of(__s, __pos, _Traits::length(__s)); } 1238 1239 size_type find_first_not_of(const _CharT* __s, size_type __pos, 1240 size_type __n) const; 1241 1242 size_type find_first_not_of(_CharT __c, size_type __pos = 0) const; 1243 1244public: // find_last_not_of 1245 1246 size_type find_last_not_of(const _Self& __s, 1247 size_type __pos = npos) const 1248 { return find_last_not_of(__s._M_Start(), __pos, __s.size()); } 1249 1250 size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const 1251 { _STLP_FIX_LITERAL_BUG(__s) return find_last_not_of(__s, __pos, _Traits::length(__s)); } 1252 1253 size_type find_last_not_of(const _CharT* __s, size_type __pos, 1254 size_type __n) const; 1255 1256 size_type find_last_not_of(_CharT __c, size_type __pos = npos) const; 1257 1258public: // Substring. 1259 _Self substr(size_type __pos = 0, size_type __n = npos) const 1260 { return _Self(*this, __pos, __n, get_allocator()); } 1261 1262public: // Compare 1263 int compare(const _Self& __s) const 1264 { return _M_compare(this->_M_Start(), this->_M_Finish(), __s._M_Start(), __s._M_Finish()); } 1265 1266 int compare(size_type __pos1, size_type __n1, 1267 const _Self& __s) const { 1268 if (__pos1 > size()) 1269 this->_M_throw_out_of_range(); 1270 return _M_compare(this->_M_Start() + __pos1, 1271 this->_M_Start() + __pos1 + (min) (__n1, size() - __pos1), 1272 __s._M_Start(), __s._M_Finish()); 1273 } 1274 1275 int compare(size_type __pos1, size_type __n1, 1276 const _Self& __s, 1277 size_type __pos2, size_type __n2) const { 1278 if (__pos1 > size() || __pos2 > __s.size()) 1279 this->_M_throw_out_of_range(); 1280 return _M_compare(this->_M_Start() + __pos1, 1281 this->_M_Start() + __pos1 + (min) (__n1, size() - __pos1), 1282 __s._M_Start() + __pos2, 1283 __s._M_Start() + __pos2 + (min) (__n2, __s.size() - __pos2)); 1284 } 1285 1286 int compare(const _CharT* __s) const { 1287 _STLP_FIX_LITERAL_BUG(__s) 1288 return _M_compare(this->_M_Start(), this->_M_Finish(), __s, __s + _Traits::length(__s)); 1289 } 1290 1291 int compare(size_type __pos1, size_type __n1, const _CharT* __s) const { 1292 _STLP_FIX_LITERAL_BUG(__s) 1293 if (__pos1 > size()) 1294 this->_M_throw_out_of_range(); 1295 return _M_compare(this->_M_Start() + __pos1, 1296 this->_M_Start() + __pos1 + (min) (__n1, size() - __pos1), 1297 __s, __s + _Traits::length(__s)); 1298 } 1299 1300 int compare(size_type __pos1, size_type __n1, const _CharT* __s, 1301 size_type __n2) const { 1302 _STLP_FIX_LITERAL_BUG(__s) 1303 if (__pos1 > size()) 1304 this->_M_throw_out_of_range(); 1305 return _M_compare(this->_M_Start() + __pos1, 1306 this->_M_Start() + __pos1 + (min) (__n1, size() - __pos1), 1307 __s, __s + __n2); 1308 } 1309 1310public: // Helper functions for compare. 1311 1312 static int _STLP_CALL _M_compare(const _CharT* __f1, const _CharT* __l1, 1313 const _CharT* __f2, const _CharT* __l2) { 1314 const ptrdiff_t __n1 = __l1 - __f1; 1315 const ptrdiff_t __n2 = __l2 - __f2; 1316 const int cmp = _Traits::compare(__f1, __f2, (min) (__n1, __n2)); 1317 return cmp != 0 ? cmp : (__n1 < __n2 ? -1 : (__n1 > __n2 ? 1 : 0)); 1318 } 1319#if defined (_STLP_USE_TEMPLATE_EXPRESSION) && !defined (_STLP_DEBUG) && !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 1320# define _STLP_STRING_SUM_BASE(__reserve, __size, __alloc) _STLP_PRIV _String_base<_CharT,_Alloc>(__alloc, __size + 1) 1321# include <stl/_string_sum_methods.h> 1322# undef _STLP_STRING_SUM_BASE 1323#endif /* _STLP_USE_TEMPLATE_EXPRESSION */ 1324}; 1325 1326#if !defined (_STLP_STATIC_CONST_INIT_BUG) 1327# if defined (__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 96) 1328template <class _CharT, class _Traits, class _Alloc> 1329const size_t basic_string<_CharT, _Traits, _Alloc>::npos = ~(size_t) 0; 1330# endif 1331#endif 1332 1333#if defined (_STLP_USE_TEMPLATE_EXPORT) 1334_STLP_EXPORT_TEMPLATE_CLASS basic_string<char, char_traits<char>, allocator<char> >; 1335# if defined (_STLP_HAS_WCHAR_T) 1336_STLP_EXPORT_TEMPLATE_CLASS basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >; 1337# endif 1338#endif /* _STLP_USE_TEMPLATE_EXPORT */ 1339 1340#if defined (basic_string) 1341_STLP_MOVE_TO_STD_NAMESPACE 1342# undef basic_string 1343#endif 1344 1345_STLP_END_NAMESPACE 1346 1347#if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 1348# include <stl/_string_workaround.h> 1349#endif 1350 1351#if defined (_STLP_DEBUG) 1352# include <stl/debug/_string.h> 1353#endif 1354 1355_STLP_BEGIN_NAMESPACE 1356 1357// ------------------------------------------------------------ 1358// Non-member functions. 1359// Swap. 1360#if defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) 1361template <class _CharT, class _Traits, class _Alloc> 1362inline void _STLP_CALL 1363swap(basic_string<_CharT,_Traits,_Alloc>& __x, 1364 basic_string<_CharT,_Traits,_Alloc>& __y) 1365{ __x.swap(__y); } 1366#endif /* _STLP_FUNCTION_TMPL_PARTIAL_ORDER */ 1367 1368#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) 1369template <class _CharT, class _Traits, class _Alloc> 1370struct __move_traits<basic_string<_CharT, _Traits, _Alloc> > { 1371 typedef __stlp_movable implemented; 1372 //Completness depends on the allocator: 1373 typedef typename __move_traits<_Alloc>::complete complete; 1374}; 1375/*#else 1376 * There is no need to specialize for string and wstring in this case 1377 * as the default __move_traits will already tell that string is movable 1378 * but not complete. We cannot define it as complete as nothing guaranty 1379 * that the STLport user hasn't specialized std::allocator for char or 1380 * wchar_t. 1381 */ 1382#endif 1383 1384_STLP_MOVE_TO_PRIV_NAMESPACE 1385 1386template <class _CharT, class _Traits, class _Alloc> 1387void _STLP_CALL _S_string_copy(const basic_string<_CharT,_Traits,_Alloc>& __s, 1388 _CharT* __buf, size_t __n); 1389 1390#if defined(_STLP_USE_WIDE_INTERFACE) 1391// A couple of functions to transfer between ASCII/Unicode 1392wstring __ASCIIToWide(const char *ascii); 1393string __WideToASCII(const wchar_t *wide); 1394#endif 1395 1396inline const char* _STLP_CALL 1397__get_c_string(const string& __str) { return __str.c_str(); } 1398 1399_STLP_MOVE_TO_STD_NAMESPACE 1400 1401_STLP_END_NAMESPACE 1402 1403#include <stl/_string_operators.h> 1404 1405#if defined(_STLP_USE_NO_IOSTREAMS) || \ 1406 (defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION)) 1407# include <stl/_string.c> 1408#endif 1409 1410#endif /* _STLP_INTERNAL_STRING_H */ 1411 1412/* 1413 * Local Variables: 1414 * mode:C++ 1415 * End: 1416 */ 1417