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 always stores a null character at the end; 69 * this makes it possible for c_str to be a fast operation. 70 * Second, the C++ standard requires basic_string to copy elements 71 * using char_traits<>::assign, char_traits<>::copy, and 72 * char_traits<>::move. This means that all of vector<>'s low-level 73 * operations must be rewritten. Third, basic_string<> has a lot of 74 * extra functions in its interface that are convenient but, strictly 75 * speaking, redundant. 76 */ 77 78 #include <stl/_string_base.h> 79 80 _STLP_BEGIN_NAMESPACE 81 82 // ------------------------------------------------------------ 83 // Class basic_string. 84 85 // Class invariants: 86 // (1) [start, finish) is a valid range. 87 // (2) Each iterator in [start, finish) points to a valid object 88 // of type value_type. 89 // (3) *finish is a valid object of type value_type; when 90 // value_type is not a POD it is value_type(). 91 // (4) [finish + 1, end_of_storage) is a valid range. 92 // (5) Each iterator in [finish + 1, end_of_storage) points to 93 // unininitialized memory. 94 95 // Note one important consequence: a string of length n must manage 96 // a block of memory whose size is at least n + 1. 97 98 _STLP_MOVE_TO_PRIV_NAMESPACE 99 struct _String_reserve_t {}; 100 _STLP_MOVE_TO_STD_NAMESPACE 101 102 #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 103 # define basic_string _STLP_NO_MEM_T_NAME(str) 104 #elif defined (_STLP_DEBUG) 105 # define basic_string _STLP_NON_DBG_NAME(str) 106 #endif 107 108 #if defined (basic_string) 109 _STLP_MOVE_TO_PRIV_NAMESPACE 110 #endif 111 112 #if defined (__DMC__) 113 # define _STLP_PRIVATE public 114 #elif defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 115 # define _STLP_PRIVATE protected 116 #else 117 # define _STLP_PRIVATE private 118 #endif 119 120 template <class _CharT, class _Traits, class _Alloc> 121 class basic_string : _STLP_PRIVATE _STLP_PRIV _String_base<_CharT,_Alloc> 122 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (basic_string) 123 , public __stlport_class<basic_string<_CharT, _Traits, _Alloc> > 124 #endif 125 { 126 _STLP_PRIVATE: // Private members inherited from base. 127 typedef _STLP_PRIV _String_base<_CharT,_Alloc> _Base; 128 typedef basic_string<_CharT, _Traits, _Alloc> _Self; 129 130 public: 131 typedef _CharT value_type; 132 typedef _Traits traits_type; 133 134 typedef value_type* pointer; 135 typedef const value_type* const_pointer; 136 typedef value_type& reference; 137 typedef const value_type& const_reference; 138 typedef typename _Base::size_type size_type; 139 typedef ptrdiff_t difference_type; 140 typedef random_access_iterator_tag _Iterator_category; 141 142 typedef const value_type* const_iterator; 143 typedef value_type* iterator; 144 145 _STLP_DECLARE_RANDOM_ACCESS_REVERSE_ITERATORS; 146 147 #include <stl/_string_npos.h> 148 149 typedef _STLP_PRIV _String_reserve_t _Reserve_t; 150 151 public: // Constructor, destructor, assignment. 152 typedef typename _Base::allocator_type allocator_type; 153 154 allocator_type get_allocator() const 155 { return _STLP_CONVERT_ALLOCATOR((const allocator_type&)this->_M_start_of_storage, _CharT); } 156 157 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) 158 explicit basic_string(const allocator_type& __a = allocator_type()) 159 #else 160 basic_string() 161 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type(), _Base::_DEFAULT_SIZE) 162 { _M_terminate_string(); } 163 explicit basic_string(const allocator_type& __a) 164 #endif 165 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a, _Base::_DEFAULT_SIZE) 166 { _M_terminate_string(); } 167 168 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) 169 basic_string(_Reserve_t, size_t __n, 170 const allocator_type& __a = allocator_type()) 171 #else 172 basic_string(_Reserve_t, size_t __n) 173 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type(), __n + 1) 174 { _M_terminate_string(); } 175 basic_string(_Reserve_t, size_t __n, const allocator_type& __a) 176 #endif 177 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a, __n + 1) 178 { _M_terminate_string(); } 179 180 basic_string(const _Self&); 181 182 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) 183 basic_string(const _Self& __s, size_type __pos, size_type __n = npos, 184 const allocator_type& __a = allocator_type()) 185 #else 186 basic_string(const _Self& __s, size_type __pos) 187 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 188 if (__pos > __s.size()) 189 this->_M_throw_out_of_range(); 190 else 191 _M_range_initialize(__s._M_Start() + __pos, __s._M_Finish()); 192 } 193 basic_string(const _Self& __s, size_type __pos, size_type __n) 194 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 195 if (__pos > __s.size()) 196 this->_M_throw_out_of_range(); 197 else 198 _M_range_initialize(__s._M_Start() + __pos, 199 __s._M_Start() + __pos + (min) (__n, __s.size() - __pos)); 200 } 201 basic_string(const _Self& __s, size_type __pos, size_type __n, 202 const allocator_type& __a) 203 #endif 204 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a) { 205 if (__pos > __s.size()) 206 this->_M_throw_out_of_range(); 207 else 208 _M_range_initialize(__s._M_Start() + __pos, 209 __s._M_Start() + __pos + (min) (__n, __s.size() - __pos)); 210 } 211 212 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) 213 basic_string(const _CharT* __s, size_type __n, 214 const allocator_type& __a = allocator_type()) 215 #else 216 basic_string(const _CharT* __s, size_type __n) 217 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 218 _STLP_FIX_LITERAL_BUG(__s) 219 _M_range_initialize(__s, __s + __n); 220 } 221 basic_string(const _CharT* __s, size_type __n, const allocator_type& __a) 222 #endif 223 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a) { 224 _STLP_FIX_LITERAL_BUG(__s) 225 _M_range_initialize(__s, __s + __n); 226 } 227 228 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) 229 basic_string(const _CharT* __s, 230 const allocator_type& __a = allocator_type()); 231 #else 232 basic_string(const _CharT* __s); 233 basic_string(const _CharT* __s, const allocator_type& __a); 234 #endif 235 236 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) 237 basic_string(size_type __n, _CharT __c, 238 const allocator_type& __a = allocator_type()) 239 #else 240 basic_string(size_type __n, _CharT __c) 241 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type(), __n + 1) { 242 this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_Start(), __n, __c); 243 _M_terminate_string(); 244 } 245 basic_string(size_type __n, _CharT __c, const allocator_type& __a) 246 #endif 247 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a, __n + 1) { 248 this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_Start(), __n, __c); 249 _M_terminate_string(); 250 } 251 252 #if !defined (_STLP_NO_MOVE_SEMANTIC) 253 basic_string(__move_source<_Self> src) 254 : _STLP_PRIV _String_base<_CharT,_Alloc>(__move_source<_Base>(src.get())) {} 255 #endif 256 257 // Check to see if _InputIterator is an integer type. If so, then 258 // it can't be an iterator. 259 #if defined (_STLP_MEMBER_TEMPLATES) && !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 260 template <class _InputIterator> 261 basic_string(_InputIterator __f, _InputIterator __l, 262 const allocator_type & __a _STLP_ALLOCATOR_TYPE_DFL) 263 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a) { 264 typedef typename _IsIntegral<_InputIterator>::_Ret _Integral; 265 _M_initialize_dispatch(__f, __l, _Integral()); 266 } 267 # if defined (_STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS) 268 template <class _InputIterator> 269 basic_string(_InputIterator __f, _InputIterator __l) 270 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 271 typedef typename _IsIntegral<_InputIterator>::_Ret _Integral; 272 _M_initialize_dispatch(__f, __l, _Integral()); 273 } 274 # endif 275 #else 276 # if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 277 basic_string(const _CharT* __f, const _CharT* __l, 278 const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL) 279 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a) { 280 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 281 _M_range_initialize(__f, __l); 282 } 283 # if defined (_STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS) 284 basic_string(const _CharT* __f, const _CharT* __l) 285 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 286 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 287 _M_range_initialize(__f, __l); 288 } 289 # endif 290 # endif 291 # if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 292 /* We need an additionnal constructor to build an empty string without 293 * any allocation or termination char*/ 294 protected: 295 struct _CalledFromWorkaround_t {}; 296 basic_string(_CalledFromWorkaround_t, const allocator_type &__a) 297 : _String_base<_CharT,_Alloc>(__a) {} 298 # endif 299 #endif 300 301 _STLP_PRIVATE: 302 size_type _M_compute_next_size(size_type __n) { 303 const size_type __size = size(); 304 if (__n > max_size() - __size) 305 this->_M_throw_length_error(); 306 size_type __len = __size + (max)(__n, __size) + 1; 307 if (__len > max_size() || __len < __size) 308 __len = max_size(); // overflow 309 return __len; 310 } 311 312 template <class _InputIter> 313 void _M_range_initialize(_InputIter __f, _InputIter __l, 314 const input_iterator_tag &__tag) { 315 this->_M_allocate_block(); 316 _M_construct_null(this->_M_Finish()); 317 _M_appendT(__f, __l, __tag); 318 } 319 320 template <class _ForwardIter> 321 void _M_range_initialize(_ForwardIter __f, _ForwardIter __l, 322 const forward_iterator_tag &) { 323 difference_type __n = _STLP_STD::distance(__f, __l); 324 this->_M_allocate_block(__n + 1); 325 this->_M_finish = uninitialized_copy(__f, __l, this->_M_Start()); 326 this->_M_terminate_string(); 327 } 328 329 template <class _InputIter> 330 void _M_range_initializeT(_InputIter __f, _InputIter __l) { 331 _M_range_initialize(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter)); 332 } 333 334 template <class _Integer> 335 void _M_initialize_dispatch(_Integer __n, _Integer __x, const __true_type& /*_Integral*/) { 336 this->_M_allocate_block(__n + 1); 337 this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_Start(), __n, __x); 338 this->_M_terminate_string(); 339 } 340 341 template <class _InputIter> 342 void _M_initialize_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*_Integral*/) { 343 _M_range_initializeT(__f, __l); 344 } 345 346 public: 347 _Self& operator=(const _Self& __s) { 348 if (&__s != this) 349 _M_assign(__s._M_Start(), __s._M_Finish()); 350 return *this; 351 } 352 353 _Self& operator=(const _CharT* __s) { 354 _STLP_FIX_LITERAL_BUG(__s) 355 return _M_assign(__s, __s + traits_type::length(__s)); 356 } 357 358 _Self& operator=(_CharT __c) 359 { return assign(__STATIC_CAST(size_type,1), __c); } 360 361 private: 362 static _CharT _STLP_CALL _M_null() 363 { return _STLP_DEFAULT_CONSTRUCTED(_CharT); } 364 365 _STLP_PRIVATE: // Helper functions used by constructors 366 // and elsewhere. 367 void _M_construct_null(_CharT* __p) const 368 { _STLP_STD::_Construct(__p); } 369 void _M_terminate_string() 370 { _M_construct_null(this->_M_Finish()); } 371 bool _M_inside(const _CharT* __s) const { 372 _STLP_FIX_LITERAL_BUG(__s) 373 return (__s >= this->_M_Start()) && (__s < this->_M_Finish()); 374 } 375 376 void _M_range_initialize(const _CharT* __f, const _CharT* __l) { 377 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 378 ptrdiff_t __n = __l - __f; 379 this->_M_allocate_block(__n + 1); 380 this->_M_finish = uninitialized_copy(__f, __l, this->_M_Start()); 381 _M_terminate_string(); 382 } 383 384 public: // Iterators. 385 iterator begin() { return this->_M_Start(); } 386 iterator end() { return this->_M_Finish(); } 387 const_iterator begin() const { return this->_M_Start(); } 388 const_iterator end() const { return this->_M_Finish(); } 389 390 reverse_iterator rbegin() 391 { return reverse_iterator(this->_M_Finish()); } 392 reverse_iterator rend() 393 { return reverse_iterator(this->_M_Start()); } 394 const_reverse_iterator rbegin() const 395 { return const_reverse_iterator(this->_M_Finish()); } 396 const_reverse_iterator rend() const 397 { return const_reverse_iterator(this->_M_Start()); } 398 399 public: // Size, capacity, etc. 400 size_type size() const { return this->_M_Finish() - this->_M_Start(); } 401 size_type length() const { return size(); } 402 size_type max_size() const { return _Base::max_size(); } 403 404 void resize(size_type __n, _CharT __c) { 405 if (__n <= size()) 406 erase(begin() + __n, end()); 407 else 408 append(__n - size(), __c); 409 } 410 411 void resize(size_type __n) { resize(__n, _M_null()); } 412 413 private: 414 void _M_reserve(size_type); 415 public: 416 void reserve(size_type = 0); 417 418 size_type capacity() const 419 { return this->_M_capacity() - 1; } 420 421 void clear() { 422 if (!empty()) { 423 _Traits::assign(*(this->_M_Start()), _M_null()); 424 this->_M_finish = this->_M_Start(); 425 } 426 } 427 428 bool empty() const { return this->_M_Start() == this->_M_Finish(); } 429 430 public: // Element access. 431 432 const_reference operator[](size_type __n) const 433 { return *(this->_M_Start() + __n); } 434 reference operator[](size_type __n) 435 { return *(this->_M_Start() + __n); } 436 437 const_reference at(size_type __n) const { 438 if (__n >= size()) 439 this->_M_throw_out_of_range(); 440 return *(this->_M_Start() + __n); 441 } 442 443 reference at(size_type __n) { 444 if (__n >= size()) 445 this->_M_throw_out_of_range(); 446 return *(this->_M_Start() + __n); 447 } 448 449 public: // Append, operator+=, push_back. 450 451 _Self& operator+=(const _Self& __s) { return append(__s); } 452 _Self& operator+=(const _CharT* __s) { _STLP_FIX_LITERAL_BUG(__s) return append(__s); } 453 _Self& operator+=(_CharT __c) { push_back(__c); return *this; } 454 455 private: 456 _Self& _M_append(const _CharT* __first, const _CharT* __last); 457 458 #if defined (_STLP_MEMBER_TEMPLATES) && !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 459 template <class _InputIter> 460 _Self& _M_appendT(_InputIter __first, _InputIter __last, 461 const input_iterator_tag &) { 462 for ( ; __first != __last ; ++__first) 463 push_back(*__first); 464 return *this; 465 } 466 467 template <class _ForwardIter> 468 _Self& _M_appendT(_ForwardIter __first, _ForwardIter __last, 469 const forward_iterator_tag &) { 470 if (__first != __last) { 471 size_type __n = __STATIC_CAST(size_type, _STLP_STD::distance(__first, __last)); 472 if (__n >= this->_M_rest()) { 473 size_type __len = _M_compute_next_size(__n); 474 pointer __new_start = this->_M_start_of_storage.allocate(__len, __len); 475 pointer __new_finish = uninitialized_copy(this->_M_Start(), this->_M_Finish(), __new_start); 476 __new_finish = uninitialized_copy(__first, __last, __new_finish); 477 _M_construct_null(__new_finish); 478 this->_M_deallocate_block(); 479 this->_M_reset(__new_start, __new_finish, __new_start + __len); 480 } 481 else { 482 _Traits::assign(*this->_M_finish, *__first++); 483 uninitialized_copy(__first, __last, this->_M_Finish() + 1); 484 _M_construct_null(this->_M_Finish() + __n); 485 this->_M_finish += __n; 486 } 487 } 488 return *this; 489 } 490 491 template <class _Integer> 492 _Self& _M_append_dispatch(_Integer __n, _Integer __x, const __true_type& /*Integral*/) 493 { return append((size_type) __n, (_CharT) __x); } 494 495 template <class _InputIter> 496 _Self& _M_append_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*Integral*/) 497 { return _M_appendT(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter)); } 498 499 public: 500 // Check to see if _InputIterator is an integer type. If so, then 501 // it can't be an iterator. 502 template <class _InputIter> 503 _Self& append(_InputIter __first, _InputIter __last) { 504 typedef typename _IsIntegral<_InputIter>::_Ret _Integral; 505 return _M_append_dispatch(__first, __last, _Integral()); 506 } 507 #else 508 public: 509 _Self& append(const _CharT* __first, const _CharT* __last) { 510 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 511 return _M_append(__first, __last); 512 } 513 #endif 514 515 public: 516 _Self& append(const _Self& __s) 517 { return _M_append(__s._M_Start(), __s._M_Finish()); } 518 519 _Self& append(const _Self& __s, 520 size_type __pos, size_type __n) { 521 if (__pos > __s.size()) 522 this->_M_throw_out_of_range(); 523 return _M_append(__s._M_Start() + __pos, 524 __s._M_Start() + __pos + (min) (__n, __s.size() - __pos)); 525 } 526 527 _Self& append(const _CharT* __s, size_type __n) 528 { _STLP_FIX_LITERAL_BUG(__s) return _M_append(__s, __s+__n); } 529 _Self& append(const _CharT* __s) 530 { _STLP_FIX_LITERAL_BUG(__s) return _M_append(__s, __s + traits_type::length(__s)); } 531 _Self& append(size_type __n, _CharT __c); 532 533 public: 534 void push_back(_CharT __c) { 535 if (this->_M_rest() == 1 ) 536 _M_reserve(_M_compute_next_size(1)); 537 _M_construct_null(this->_M_Finish() + 1); 538 _Traits::assign(*(this->_M_Finish()), __c); 539 ++this->_M_finish; 540 } 541 542 void pop_back() { 543 _Traits::assign(*(this->_M_Finish() - 1), _M_null()); 544 --this->_M_finish; 545 } 546 547 public: // Assign 548 _Self& assign(const _Self& __s) 549 { return _M_assign(__s._M_Start(), __s._M_Finish()); } 550 551 _Self& assign(const _Self& __s, 552 size_type __pos, size_type __n) { 553 if (__pos > __s.size()) 554 this->_M_throw_out_of_range(); 555 return _M_assign(__s._M_Start() + __pos, 556 __s._M_Start() + __pos + (min) (__n, __s.size() - __pos)); 557 } 558 559 _Self& assign(const _CharT* __s, size_type __n) 560 { _STLP_FIX_LITERAL_BUG(__s) return _M_assign(__s, __s + __n); } 561 562 _Self& assign(const _CharT* __s) 563 { _STLP_FIX_LITERAL_BUG(__s) return _M_assign(__s, __s + _Traits::length(__s)); } 564 565 _Self& assign(size_type __n, _CharT __c); 566 567 private: 568 _Self& _M_assign(const _CharT* __f, const _CharT* __l); 569 570 #if defined (_STLP_MEMBER_TEMPLATES) && !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 571 // Helper functions for assign. 572 template <class _Integer> 573 _Self& _M_assign_dispatch(_Integer __n, _Integer __x, const __true_type& /*_Integral*/) 574 { return assign((size_type) __n, (_CharT) __x); } 575 576 template <class _InputIter> 577 _Self& _M_assign_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*_Integral*/) { 578 pointer __cur = this->_M_Start(); 579 while (__f != __l && __cur != this->_M_Finish()) { 580 _Traits::assign(*__cur, *__f); 581 ++__f; 582 ++__cur; 583 } 584 if (__f == __l) 585 erase(__cur, this->end()); 586 else 587 _M_appendT(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter)); 588 return *this; 589 } 590 591 public: 592 // Check to see if _InputIterator is an integer type. If so, then 593 // it can't be an iterator. 594 template <class _InputIter> 595 _Self& assign(_InputIter __first, _InputIter __last) { 596 typedef typename _IsIntegral<_InputIter>::_Ret _Integral; 597 return _M_assign_dispatch(__first, __last, _Integral()); 598 } 599 #else 600 public: 601 _Self& assign(const _CharT* __f, const _CharT* __l) { 602 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 603 return _M_assign(__f, __l); 604 } 605 #endif 606 607 public: // Insert 608 _Self& insert(size_type __pos, const _Self& __s) { 609 if (__pos > size()) 610 this->_M_throw_out_of_range(); 611 if (__s.size() > max_size() - size()) 612 this->_M_throw_length_error(); 613 _M_insert(begin() + __pos, __s._M_Start(), __s._M_Finish(), &__s == this); 614 return *this; 615 } 616 617 _Self& insert(size_type __pos, const _Self& __s, 618 size_type __beg, size_type __n) { 619 if (__pos > size() || __beg > __s.size()) 620 this->_M_throw_out_of_range(); 621 size_type __len = (min) (__n, __s.size() - __beg); 622 if (__len > max_size() - size()) 623 this->_M_throw_length_error(); 624 _M_insert(begin() + __pos, 625 __s._M_Start() + __beg, __s._M_Start() + __beg + __len, &__s == this); 626 return *this; 627 } 628 _Self& insert(size_type __pos, const _CharT* __s, size_type __n) { 629 _STLP_FIX_LITERAL_BUG(__s) 630 if (__pos > size()) 631 this->_M_throw_out_of_range(); 632 if (__n > max_size() - size()) 633 this->_M_throw_length_error(); 634 _M_insert(begin() + __pos, __s, __s + __n, _M_inside(__s)); 635 return *this; 636 } 637 638 _Self& insert(size_type __pos, const _CharT* __s) { 639 _STLP_FIX_LITERAL_BUG(__s) 640 if (__pos > size()) 641 this->_M_throw_out_of_range(); 642 size_type __len = _Traits::length(__s); 643 if (__len > max_size() - size()) 644 this->_M_throw_length_error(); 645 _M_insert(this->_M_Start() + __pos, __s, __s + __len, _M_inside(__s)); 646 return *this; 647 } 648 649 _Self& insert(size_type __pos, size_type __n, _CharT __c) { 650 if (__pos > size()) 651 this->_M_throw_out_of_range(); 652 if (__n > max_size() - size()) 653 this->_M_throw_length_error(); 654 insert(begin() + __pos, __n, __c); 655 return *this; 656 } 657 658 iterator insert(iterator __p, _CharT __c) { 659 _STLP_FIX_LITERAL_BUG(__p) 660 if (__p == end()) { 661 push_back(__c); 662 return this->_M_Finish() - 1; 663 } 664 else 665 return _M_insert_aux(__p, __c); 666 } 667 668 void insert(iterator __p, size_t __n, _CharT __c); 669 670 _STLP_PRIVATE: // Helper functions for insert. 671 void _M_insert(iterator __p, const _CharT* __first, const _CharT* __last, bool __self_ref); 672 673 pointer _M_insert_aux(pointer, _CharT); 674 675 void _M_copy(const _CharT* __f, const _CharT* __l, _CharT* __res) { 676 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 677 _STLP_FIX_LITERAL_BUG(__res) 678 _Traits::copy(__res, __f, __l - __f); 679 } 680 681 void _M_move(const _CharT* __f, const _CharT* __l, _CharT* __res) { 682 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 683 _Traits::move(__res, __f, __l - __f); 684 } 685 686 #if defined (_STLP_MEMBER_TEMPLATES) 687 # if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 688 template <class _ForwardIter> 689 void _M_insert_overflow(iterator __pos, _ForwardIter __first, _ForwardIter __last, 690 size_type __n) { 691 size_type __len = _M_compute_next_size(__n); 692 pointer __new_start = this->_M_start_of_storage.allocate(__len, __len); 693 pointer __new_finish = uninitialized_copy(this->_M_Start(), __pos, __new_start); 694 __new_finish = uninitialized_copy(__first, __last, __new_finish); 695 __new_finish = uninitialized_copy(__pos, this->_M_Finish(), __new_finish); 696 _M_construct_null(__new_finish); 697 this->_M_deallocate_block(); 698 this->_M_reset(__new_start, __new_finish, __new_start + __len); 699 } 700 701 template <class _InputIter> 702 void _M_insertT(iterator __p, _InputIter __first, _InputIter __last, 703 const input_iterator_tag &) { 704 for ( ; __first != __last; ++__first) { 705 __p = insert(__p, *__first); 706 ++__p; 707 } 708 } 709 710 template <class _ForwardIter> 711 void _M_insertT(iterator __pos, _ForwardIter __first, _ForwardIter __last, 712 const forward_iterator_tag &) { 713 if (__first != __last) { 714 size_type __n = _STLP_STD::distance(__first, __last); 715 if (__n < this->_M_rest()) { 716 const size_type __elems_after = this->_M_finish - __pos; 717 if (__elems_after >= __n) { 718 uninitialized_copy((this->_M_Finish() - __n) + 1, this->_M_Finish() + 1, this->_M_Finish() + 1); 719 this->_M_finish += __n; 720 _Traits::move(__pos + __n, __pos, (__elems_after - __n) + 1); 721 _M_copyT(__first, __last, __pos); 722 } 723 else { 724 pointer __old_finish = this->_M_Finish(); 725 _ForwardIter __mid = __first; 726 _STLP_STD::advance(__mid, __elems_after + 1); 727 _STLP_STD::uninitialized_copy(__mid, __last, this->_M_Finish() + 1); 728 this->_M_finish += __n - __elems_after; 729 uninitialized_copy(__pos, __old_finish + 1, this->_M_Finish()); 730 this->_M_finish += __elems_after; 731 _M_copyT(__first, __mid, __pos); 732 } 733 } 734 else { 735 _M_insert_overflow(__pos, __first, __last, __n); 736 } 737 } 738 } 739 740 template <class _Integer> 741 void _M_insert_dispatch(iterator __p, _Integer __n, _Integer __x, 742 const __true_type& /*Integral*/) 743 { insert(__p, (size_type) __n, (_CharT) __x); } 744 745 template <class _InputIter> 746 void _M_insert_dispatch(iterator __p, _InputIter __first, _InputIter __last, 747 const __false_type& /*Integral*/) { 748 _STLP_FIX_LITERAL_BUG(__p) 749 /* We are forced to do a temporary string to avoid the self referencing issue. */ 750 const _Self __self(__first, __last, get_allocator()); 751 _M_insertT(__p, __self.begin(), __self.end(), forward_iterator_tag()); 752 } 753 754 template <class _InputIterator> 755 void _M_copyT(_InputIterator __first, _InputIterator __last, pointer __result) { 756 _STLP_FIX_LITERAL_BUG(__result) 757 for ( ; __first != __last; ++__first, ++__result) 758 _Traits::assign(*__result, *__first); 759 } 760 761 # if !defined (_STLP_NO_METHOD_SPECIALIZATION) 762 void _M_copyT(const _CharT* __f, const _CharT* __l, _CharT* __res) { 763 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 764 _STLP_FIX_LITERAL_BUG(__res) 765 _Traits::copy(__res, __f, __l - __f); 766 } 767 # endif 768 public: 769 // Check to see if _InputIterator is an integer type. If so, then 770 // it can't be an iterator. 771 template <class _InputIter> 772 void insert(iterator __p, _InputIter __first, _InputIter __last) { 773 typedef typename _IsIntegral<_InputIter>::_Ret _Integral; 774 _M_insert_dispatch(__p, __first, __last, _Integral()); 775 } 776 # endif 777 #endif 778 779 #if !defined (_STLP_MEMBER_TEMPLATES) || !defined (_STLP_NO_METHOD_SPECIALIZATION) 780 public: 781 void insert(iterator __p, const _CharT* __f, const _CharT* __l) { 782 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 783 _M_insert(__p, __f, __l, _M_inside(__f)); 784 } 785 #endif 786 787 public: // Erase. 788 _Self& erase(size_type __pos = 0, size_type __n = npos) { 789 if (__pos > size()) 790 this->_M_throw_out_of_range(); 791 erase(begin() + __pos, begin() + __pos + (min) (__n, size() - __pos)); 792 return *this; 793 } 794 795 iterator erase(iterator __pos) { 796 // The move includes the terminating _CharT(). 797 _Traits::move(__pos, __pos + 1, this->_M_Finish() - __pos); 798 --this->_M_finish; 799 return __pos; 800 } 801 802 iterator erase(iterator __first, iterator __last) { 803 if (__first != __last) { 804 // The move includes the terminating _CharT(). 805 traits_type::move(__first, __last, (this->_M_Finish() - __last) + 1); 806 this->_M_finish = this->_M_Finish() - (__last - __first); 807 } 808 return __first; 809 } 810 811 public: // Replace. (Conceptually equivalent 812 // to erase followed by insert.) 813 _Self& replace(size_type __pos, size_type __n, const _Self& __s) { 814 const size_type __size = size(); 815 if (__pos > __size) 816 this->_M_throw_out_of_range(); 817 const size_type __len = (min) (__n, __size - __pos); 818 if (__s.size() > max_size() - (__size - __len)) 819 this->_M_throw_length_error(); 820 return _M_replace(begin() + __pos, begin() + __pos + __len, 821 __s._M_Start(), __s._M_Finish(), &__s == this); 822 } 823 824 _Self& replace(size_type __pos1, size_type __n1, const _Self& __s, 825 size_type __pos2, size_type __n2) { 826 const size_type __size1 = size(); 827 const size_type __size2 = __s.size(); 828 if (__pos1 > __size1 || __pos2 > __size2) 829 this->_M_throw_out_of_range(); 830 const size_type __len1 = (min) (__n1, __size1 - __pos1); 831 const size_type __len2 = (min) (__n2, __size2 - __pos2); 832 if (__len2 > max_size() - (__size1 - __len1)) 833 this->_M_throw_length_error(); 834 return _M_replace(begin() + __pos1, begin() + __pos1 + __len1, 835 __s._M_Start() + __pos2, __s._M_Start() + __pos2 + __len2, &__s == this); 836 } 837 838 _Self& replace(size_type __pos, size_type __n1, 839 const _CharT* __s, size_type __n2) { 840 _STLP_FIX_LITERAL_BUG(__s) 841 const size_type __size = size(); 842 if (__pos > __size) 843 this->_M_throw_out_of_range(); 844 const size_type __len = (min) (__n1, __size - __pos); 845 if (__n2 > max_size() - (__size - __len)) 846 this->_M_throw_length_error(); 847 return _M_replace(begin() + __pos, begin() + __pos + __len, 848 __s, __s + __n2, _M_inside(__s)); 849 } 850 851 _Self& replace(size_type __pos, size_type __n1, const _CharT* __s) { 852 _STLP_FIX_LITERAL_BUG(__s) 853 return replace(__pos, __n1, __s, _Traits::length(__s)); 854 } 855 856 _Self& replace(size_type __pos, size_type __n1, 857 size_type __n2, _CharT __c) { 858 const size_type __size = size(); 859 if (__pos > __size) 860 this->_M_throw_out_of_range(); 861 const size_type __len = (min) (__n1, __size - __pos); 862 if (__n2 > max_size() - (__size - __len)) 863 this->_M_throw_length_error(); 864 return replace(begin() + __pos, begin() + __pos + __len, __n2, __c); 865 } 866 867 _Self& replace(iterator __first, iterator __last, const _Self& __s) { 868 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 869 return _M_replace(__first, __last, __s._M_Start(), __s._M_Finish(), &__s == this); 870 } 871 872 _Self& replace(iterator __first, iterator __last, 873 const _CharT* __s, size_type __n) { 874 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 875 _STLP_FIX_LITERAL_BUG(__s) 876 return _M_replace(__first, __last, __s, __s + __n, _M_inside(__s)); 877 } 878 879 _Self& replace(iterator __first, iterator __last, 880 const _CharT* __s) { 881 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 882 _STLP_FIX_LITERAL_BUG(__s) 883 return _M_replace(__first, __last, __s, __s + _Traits::length(__s), _M_inside(__s)); 884 } 885 886 _Self& replace(iterator __first, iterator __last, size_type __n, _CharT __c); 887 888 _STLP_PRIVATE: // Helper functions for replace. 889 _Self& _M_replace(iterator __first, iterator __last, 890 const _CharT* __f, const _CharT* __l, bool __self_ref); 891 892 #if defined (_STLP_MEMBER_TEMPLATES) && !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 893 template <class _Integer> 894 _Self& _M_replace_dispatch(iterator __first, iterator __last, 895 _Integer __n, _Integer __x, const __true_type& /*IsIntegral*/) { 896 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 897 return replace(__first, __last, (size_type) __n, (_CharT) __x); 898 } 899 900 template <class _InputIter> 901 _Self& _M_replace_dispatch(iterator __first, iterator __last, 902 _InputIter __f, _InputIter __l, const __false_type& /*IsIntegral*/) { 903 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 904 /* We are forced to do a temporary string to avoid the self referencing issue. */ 905 const _Self __self(__f, __l, get_allocator()); 906 return _M_replace(__first, __last, __self._M_Start(), __self._M_Finish(), false); 907 } 908 909 public: 910 // Check to see if _InputIter is an integer type. If so, then 911 // it can't be an iterator. 912 template <class _InputIter> 913 _Self& replace(iterator __first, iterator __last, 914 _InputIter __f, _InputIter __l) { 915 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 916 typedef typename _IsIntegral<_InputIter>::_Ret _Integral; 917 return _M_replace_dispatch(__first, __last, __f, __l, _Integral()); 918 } 919 #endif 920 921 #if !defined (_STLP_MEMBER_TEMPLATES) || !defined (_STLP_NO_METHOD_SPECIALIZATION) 922 public: 923 _Self& replace(iterator __first, iterator __last, 924 const _CharT* __f, const _CharT* __l) { 925 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 926 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 927 return _M_replace(__first, __last, __f, __l, _M_inside(__f)); 928 } 929 #endif 930 931 public: // Other modifier member functions. 932 933 size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const { 934 _STLP_FIX_LITERAL_BUG(__s) 935 if (__pos > size()) 936 this->_M_throw_out_of_range(); 937 const size_type __len = (min) (__n, size() - __pos); 938 _Traits::copy(__s, this->_M_Start() + __pos, __len); 939 return __len; 940 } 941 942 void swap(_Self& __s) { this->_M_swap(__s); } 943 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) 944 void _M_swap_workaround(_Self& __x) { swap(__x); } 945 #endif 946 947 public: // Conversion to C string. 948 949 const _CharT* c_str() const { return this->_M_Start(); } 950 const _CharT* data() const { return this->_M_Start(); } 951 952 public: // find. 953 size_type find(const _Self& __s, size_type __pos = 0) const 954 { return find(__s._M_Start(), __pos, __s.size()); } 955 956 size_type find(const _CharT* __s, size_type __pos = 0) const 957 { _STLP_FIX_LITERAL_BUG(__s) return find(__s, __pos, _Traits::length(__s)); } 958 959 size_type find(const _CharT* __s, size_type __pos, size_type __n) const; 960 961 // WIE: Versant schema compiler 5.2.2 ICE workaround 962 size_type find(_CharT __c) const { return find(__c, 0); } 963 size_type find(_CharT __c, size_type __pos /* = 0 */) const; 964 965 public: // rfind. 966 size_type rfind(const _Self& __s, size_type __pos = npos) const 967 { return rfind(__s._M_Start(), __pos, __s.size()); } 968 969 size_type rfind(const _CharT* __s, size_type __pos = npos) const 970 { _STLP_FIX_LITERAL_BUG(__s) return rfind(__s, __pos, _Traits::length(__s)); } 971 972 size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const; 973 size_type rfind(_CharT __c, size_type __pos = npos) const; 974 975 public: // find_first_of 976 size_type find_first_of(const _Self& __s, size_type __pos = 0) const 977 { return find_first_of(__s._M_Start(), __pos, __s.size()); } 978 979 size_type find_first_of(const _CharT* __s, size_type __pos = 0) const 980 { _STLP_FIX_LITERAL_BUG(__s) return find_first_of(__s, __pos, _Traits::length(__s)); } 981 982 size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; 983 984 size_type find_first_of(_CharT __c, size_type __pos = 0) const 985 { return find(__c, __pos); } 986 987 public: // find_last_of 988 size_type find_last_of(const _Self& __s, size_type __pos = npos) const 989 { return find_last_of(__s._M_Start(), __pos, __s.size()); } 990 991 size_type find_last_of(const _CharT* __s, size_type __pos = npos) const 992 { _STLP_FIX_LITERAL_BUG(__s) return find_last_of(__s, __pos, _Traits::length(__s)); } 993 994 size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; 995 996 size_type find_last_of(_CharT __c, size_type __pos = npos) const 997 { return rfind(__c, __pos); } 998 999 public: // find_first_not_of 1000 size_type find_first_not_of(const _Self& __s, size_type __pos = 0) const 1001 { return find_first_not_of(__s._M_Start(), __pos, __s.size()); } 1002 1003 size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const 1004 { _STLP_FIX_LITERAL_BUG(__s) return find_first_not_of(__s, __pos, _Traits::length(__s)); } 1005 1006 size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const; 1007 1008 size_type find_first_not_of(_CharT __c, size_type __pos = 0) const; 1009 1010 public: // find_last_not_of 1011 size_type find_last_not_of(const _Self& __s, size_type __pos = npos) const 1012 { return find_last_not_of(__s._M_Start(), __pos, __s.size()); } 1013 1014 size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const 1015 { _STLP_FIX_LITERAL_BUG(__s) return find_last_not_of(__s, __pos, _Traits::length(__s)); } 1016 1017 size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const; 1018 1019 size_type find_last_not_of(_CharT __c, size_type __pos = npos) const; 1020 1021 public: // Substring. 1022 _Self substr(size_type __pos = 0, size_type __n = npos) const 1023 { return _Self(*this, __pos, __n, get_allocator()); } 1024 1025 public: // Compare 1026 int compare(const _Self& __s) const 1027 { return _M_compare(this->_M_Start(), this->_M_Finish(), __s._M_Start(), __s._M_Finish()); } 1028 1029 int compare(size_type __pos1, size_type __n1, const _Self& __s) const { 1030 if (__pos1 > size()) 1031 this->_M_throw_out_of_range(); 1032 return _M_compare(this->_M_Start() + __pos1, 1033 this->_M_Start() + __pos1 + (min) (__n1, size() - __pos1), 1034 __s._M_Start(), __s._M_Finish()); 1035 } 1036 1037 int compare(size_type __pos1, size_type __n1, const _Self& __s, 1038 size_type __pos2, size_type __n2) const { 1039 if (__pos1 > size() || __pos2 > __s.size()) 1040 this->_M_throw_out_of_range(); 1041 return _M_compare(this->_M_Start() + __pos1, 1042 this->_M_Start() + __pos1 + (min) (__n1, size() - __pos1), 1043 __s._M_Start() + __pos2, 1044 __s._M_Start() + __pos2 + (min) (__n2, __s.size() - __pos2)); 1045 } 1046 1047 int compare(const _CharT* __s) const { 1048 _STLP_FIX_LITERAL_BUG(__s) 1049 return _M_compare(this->_M_Start(), this->_M_Finish(), __s, __s + _Traits::length(__s)); 1050 } 1051 1052 int compare(size_type __pos1, size_type __n1, const _CharT* __s) const { 1053 _STLP_FIX_LITERAL_BUG(__s) 1054 if (__pos1 > size()) 1055 this->_M_throw_out_of_range(); 1056 return _M_compare(this->_M_Start() + __pos1, 1057 this->_M_Start() + __pos1 + (min) (__n1, size() - __pos1), 1058 __s, __s + _Traits::length(__s)); 1059 } 1060 1061 int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const { 1062 _STLP_FIX_LITERAL_BUG(__s) 1063 if (__pos1 > size()) 1064 this->_M_throw_out_of_range(); 1065 return _M_compare(this->_M_Start() + __pos1, 1066 this->_M_Start() + __pos1 + (min) (__n1, size() - __pos1), 1067 __s, __s + __n2); 1068 } 1069 1070 public: // Helper functions for compare. 1071 static int _STLP_CALL _M_compare(const _CharT* __f1, const _CharT* __l1, 1072 const _CharT* __f2, const _CharT* __l2) { 1073 const ptrdiff_t __n1 = __l1 - __f1; 1074 const ptrdiff_t __n2 = __l2 - __f2; 1075 const int cmp = _Traits::compare(__f1, __f2, (min) (__n1, __n2)); 1076 return cmp != 0 ? cmp : (__n1 < __n2 ? -1 : (__n1 > __n2 ? 1 : 0)); 1077 } 1078 #if defined (_STLP_USE_TEMPLATE_EXPRESSION) && !defined (_STLP_DEBUG) && !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 1079 # define _STLP_STRING_SUM_BASE(__reserve, __size, __alloc) _STLP_PRIV _String_base<_CharT,_Alloc>(__alloc, __size + 1) 1080 # include <stl/_string_sum_methods.h> 1081 # undef _STLP_STRING_SUM_BASE 1082 #endif 1083 }; 1084 1085 #undef _STLP_PRIVATE 1086 1087 #if defined (__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 96) 1088 template <class _CharT, class _Traits, class _Alloc> 1089 const size_t basic_string<_CharT, _Traits, _Alloc>::npos = ~(size_t) 0; 1090 #endif 1091 1092 #if defined (_STLP_USE_TEMPLATE_EXPORT) 1093 _STLP_EXPORT_TEMPLATE_CLASS basic_string<char, char_traits<char>, allocator<char> >; 1094 # if defined (_STLP_HAS_WCHAR_T) 1095 _STLP_EXPORT_TEMPLATE_CLASS basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >; 1096 # endif 1097 #endif /* _STLP_USE_TEMPLATE_EXPORT */ 1098 1099 #if defined (basic_string) 1100 _STLP_MOVE_TO_STD_NAMESPACE 1101 # undef basic_string 1102 #endif 1103 1104 _STLP_END_NAMESPACE 1105 1106 #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 1107 # include <stl/_string_workaround.h> 1108 #endif 1109 1110 #if defined (_STLP_DEBUG) 1111 # include <stl/debug/_string.h> 1112 #endif 1113 1114 _STLP_BEGIN_NAMESPACE 1115 1116 // ------------------------------------------------------------ 1117 // Non-member functions. 1118 // Swap. 1119 #if defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) 1120 template <class _CharT, class _Traits, class _Alloc> 1121 inline void _STLP_CALL 1122 swap(basic_string<_CharT,_Traits,_Alloc>& __x, 1123 basic_string<_CharT,_Traits,_Alloc>& __y) 1124 { __x.swap(__y); } 1125 #else 1126 inline void _STLP_CALL swap(string& __x, string& __y) 1127 { __x.swap(__y); } 1128 # if defined (_STLP_HAS_WCHAR_T) 1129 inline void _STLP_CALL swap(wstring& __x, wstring& __y) 1130 { __x.swap(__y); } 1131 # endif 1132 #endif 1133 1134 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) && !defined (_STLP_NO_MOVE_SEMANTIC) 1135 template <class _CharT, class _Traits, class _Alloc> 1136 struct __move_traits<basic_string<_CharT, _Traits, _Alloc> > { 1137 typedef __true_type implemented; 1138 //Completness depends on the allocator: 1139 typedef typename __move_traits<_Alloc>::complete complete; 1140 }; 1141 /*#else 1142 * There is no need to specialize for string and wstring in this case 1143 * as the default __move_traits will already tell that string is movable 1144 * but not complete. We cannot define it as complete as nothing guaranty 1145 * that the STLport user hasn't specialized std::allocator for char or 1146 * wchar_t. 1147 */ 1148 #endif 1149 1150 _STLP_MOVE_TO_PRIV_NAMESPACE 1151 1152 template <class _CharT, class _Traits, class _Alloc> 1153 void _STLP_CALL _S_string_copy(const basic_string<_CharT,_Traits,_Alloc>& __s, 1154 _CharT* __buf, size_t __n); 1155 1156 #if defined(_STLP_USE_WIDE_INTERFACE) 1157 // A couple of functions to transfer between ASCII/Unicode 1158 wstring __ASCIIToWide(const char *ascii); 1159 string __WideToASCII(const wchar_t *wide); 1160 #endif 1161 1162 inline const char* _STLP_CALL 1163 __get_c_string(const string& __str) { return __str.c_str(); } 1164 1165 _STLP_MOVE_TO_STD_NAMESPACE 1166 1167 _STLP_END_NAMESPACE 1168 1169 #include <stl/_string_operators.h> 1170 1171 #if defined(_STLP_USE_NO_IOSTREAMS) || \ 1172 (defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION)) 1173 # include <stl/_string.c> 1174 #endif 1175 1176 #endif /* _STLP_INTERNAL_STRING_H */ 1177 1178 /* 1179 * Local Variables: 1180 * mode:C++ 1181 * End: 1182 */ 1183