[PR] この広告は3ヶ月以上更新がないため表示されています。
ホームページを更新後24時間以内に表示されなくなります。
/home/ntakagi/work/STLport-5.1.5/stlport/stl/_string.hGo to the documentation of this file.00001 /* 00002 * Copyright (c) 1997-1999 00003 * Silicon Graphics Computer Systems, Inc. 00004 * 00005 * Copyright (c) 1999 00006 * Boris Fomitchev 00007 * 00008 * This material is provided "as is", with absolutely no warranty expressed 00009 * or implied. Any use is at your own risk. 00010 * 00011 * Permission to use or copy this software for any purpose is hereby granted 00012 * without fee, provided the above notices are retained on all copies. 00013 * Permission to modify the code and to distribute modified code is granted, 00014 * provided the above notices are retained, and a notice that the code was 00015 * modified is included with the above copyright notice. 00016 * 00017 */ 00018 00019 #ifndef _STLP_INTERNAL_STRING_H 00020 #define _STLP_INTERNAL_STRING_H 00021 00022 #ifndef _STLP_INTERNAL_ALLOC_H 00023 # include <stl/_alloc.h> 00024 #endif 00025 00026 #ifndef _STLP_STRING_FWD_H 00027 # include <stl/_string_fwd.h> 00028 #endif 00029 00030 #ifndef _STLP_INTERNAL_FUNCTION_BASE_H 00031 # include <stl/_function_base.h> 00032 #endif 00033 00034 #ifndef _STLP_INTERNAL_ALGOBASE_H 00035 # include <stl/_algobase.h> 00036 #endif 00037 00038 #ifndef _STLP_INTERNAL_ITERATOR_H 00039 # include <stl/_iterator.h> 00040 #endif 00041 00042 #ifndef _STLP_INTERNAL_UNINITIALIZED_H 00043 # include <stl/_uninitialized.h> 00044 #endif 00045 00046 #if defined (_STLP_USE_TEMPLATE_EXPRESSION) 00047 # include <stl/_string_sum.h> 00048 #endif /* _STLP_USE_TEMPLATE_EXPRESSION */ 00049 00050 #if defined (__MWERKS__) && ! defined (_STLP_USE_OWN_NAMESPACE) 00051 00052 // MSL implementation classes expect to see the definition of streampos 00053 // when this header is included. We expect this to be fixed in later MSL 00054 // implementations 00055 # if !defined( __MSL_CPP__ ) || __MSL_CPP__ < 0x4105 00056 # include <stl/msl_string.h> 00057 # endif 00058 #endif // __MWERKS__ 00059 00060 /* 00061 * Standard C++ string class. This class has performance 00062 * characteristics very much like vector<>, meaning, for example, that 00063 * it does not perform reference-count or copy-on-write, and that 00064 * concatenation of two strings is an O(N) operation. 00065 00066 * There are three reasons why basic_string is not identical to 00067 * vector. 00068 * First, basic_string can always stores a null character 00069 * at the end (macro dependent); this makes it possible for c_str to 00070 * be a fast operation. 00071 * Second, the C++ standard requires basic_string to copy elements 00072 * using char_traits<>::assign, char_traits<>::copy, and 00073 * char_traits<>::move. This means that all of vector<>'s low-level 00074 * operations must be rewritten. Third, basic_string<> has a lot of 00075 * extra functions in its interface that are convenient but, strictly 00076 * speaking, redundant. 00077 00078 * Additionally, the C++ standard imposes a major restriction: according 00079 * to the standard, the character type _CharT must be a POD type. This 00080 * implementation weakens that restriction, and allows _CharT to be a 00081 * a user-defined non-POD type. However, _CharT must still have a 00082 * default constructor. 00083 */ 00084 00085 #include <stl/_string_base.h> 00086 00087 _STLP_BEGIN_NAMESPACE 00088 00089 // ------------------------------------------------------------ 00090 // Class basic_string. 00091 00092 // Class invariants: 00093 // (1) [start, finish) is a valid range. 00094 // (2) Each iterator in [start, finish) points to a valid object 00095 // of type value_type. 00096 // (3) *finish is a valid object of type value_type; when 00097 // value_type is not a POD it is value_type(). 00098 // (4) [finish + 1, end_of_storage) is a valid range. 00099 // (5) Each iterator in [finish + 1, end_of_storage) points to 00100 // unininitialized memory. 00101 00102 // Note one important consequence: a string of length n must manage 00103 // a block of memory whose size is at least n + 1. 00104 00105 struct _String_reserve_t {}; 00106 00107 #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 00108 # define basic_string _STLP_NO_MEM_T_NAME(str) 00109 #elif defined (_STLP_DEBUG) 00110 # define basic_string _STLP_NON_DBG_NAME(str) 00111 #endif 00112 00113 #if defined (basic_string) 00114 _STLP_MOVE_TO_PRIV_NAMESPACE 00115 #endif 00116 00117 template <class _CharT, class _Traits, class _Alloc> 00118 class basic_string : protected _STLP_PRIV _String_base<_CharT,_Alloc> 00119 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (basic_string) 00120 , public __stlport_class<basic_string<_CharT, _Traits, _Alloc> > 00121 #endif 00122 { 00123 protected: // Protected members inherited from base. 00124 typedef _STLP_PRIV _String_base<_CharT,_Alloc> _Base; 00125 typedef basic_string<_CharT, _Traits, _Alloc> _Self; 00126 // fbp : used to optimize char/wchar_t cases, and to simplify 00127 // _STLP_DEF_CONST_PLCT_NEW_BUG problem workaround 00128 typedef typename _IsIntegral<_CharT>::_Ret _Char_Is_Integral; 00129 typedef typename _IsPOD<_CharT>::_Type _Char_Is_POD; 00130 typedef random_access_iterator_tag r_a_i_t; 00131 00132 public: 00133 typedef _CharT value_type; 00134 typedef _Traits traits_type; 00135 00136 typedef value_type* pointer; 00137 typedef const value_type* const_pointer; 00138 typedef value_type& reference; 00139 typedef const value_type& const_reference; 00140 typedef typename _Base::size_type size_type; 00141 typedef ptrdiff_t difference_type; 00142 typedef random_access_iterator_tag _Iterator_category; 00143 00144 typedef const value_type* const_iterator; 00145 typedef value_type* iterator; 00146 00147 _STLP_DECLARE_RANDOM_ACCESS_REVERSE_ITERATORS; 00148 00149 #include <stl/_string_npos.h> 00150 00151 typedef _String_reserve_t _Reserve_t; 00152 00153 public: // Constructor, destructor, assignment. 00154 typedef typename _Base::allocator_type allocator_type; 00155 00156 allocator_type get_allocator() const 00157 { return _STLP_CONVERT_ALLOCATOR((const allocator_type&)this->_M_end_of_storage, _CharT); } 00158 00159 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) 00160 explicit basic_string(const allocator_type& __a = allocator_type()) 00161 #else 00162 basic_string() 00163 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type(), _Base::_DEFAULT_SIZE) 00164 { _M_terminate_string(); } 00165 explicit basic_string(const allocator_type& __a) 00166 #endif 00167 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a, _Base::_DEFAULT_SIZE) 00168 { _M_terminate_string(); } 00169 00170 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) 00171 basic_string(_Reserve_t, size_t __n, 00172 const allocator_type& __a = allocator_type()) 00173 #else 00174 basic_string(_Reserve_t, size_t __n) 00175 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type(), __n + 1) 00176 { _M_terminate_string(); } 00177 basic_string(_Reserve_t, size_t __n, const allocator_type& __a) 00178 #endif 00179 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a, __n + 1) 00180 { _M_terminate_string(); } 00181 00182 basic_string(const _Self&); 00183 00184 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) 00185 basic_string(const _Self& __s, size_type __pos, size_type __n = npos, 00186 const allocator_type& __a = allocator_type()) 00187 #else 00188 basic_string(const _Self& __s, size_type __pos) 00189 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 00190 if (__pos > __s.size()) 00191 this->_M_throw_out_of_range(); 00192 else 00193 _M_range_initialize(__s._M_Start() + __pos, __s._M_Finish()); 00194 } 00195 basic_string(const _Self& __s, size_type __pos, size_type __n) 00196 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 00197 if (__pos > __s.size()) 00198 this->_M_throw_out_of_range(); 00199 else 00200 _M_range_initialize(__s._M_Start() + __pos, 00201 __s._M_Start() + __pos + (min) (__n, __s.size() - __pos)); 00202 } 00203 basic_string(const _Self& __s, size_type __pos, size_type __n, 00204 const allocator_type& __a) 00205 #endif 00206 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a) { 00207 if (__pos > __s.size()) 00208 this->_M_throw_out_of_range(); 00209 else 00210 _M_range_initialize(__s._M_Start() + __pos, 00211 __s._M_Start() + __pos + (min) (__n, __s.size() - __pos)); 00212 } 00213 00214 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) 00215 basic_string(const _CharT* __s, size_type __n, 00216 const allocator_type& __a = allocator_type()) 00217 #else 00218 basic_string(const _CharT* __s, size_type __n) 00219 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 00220 _STLP_FIX_LITERAL_BUG(__s) 00221 _M_range_initialize(__s, __s + __n); 00222 } 00223 basic_string(const _CharT* __s, size_type __n, const allocator_type& __a) 00224 #endif 00225 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a) { 00226 _STLP_FIX_LITERAL_BUG(__s) 00227 _M_range_initialize(__s, __s + __n); 00228 } 00229 00230 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) 00231 basic_string(const _CharT* __s, 00232 const allocator_type& __a = allocator_type()); 00233 #else 00234 basic_string(const _CharT* __s); 00235 basic_string(const _CharT* __s, const allocator_type& __a); 00236 #endif 00237 00238 #if !defined (_STLP_DONT_SUP_DFLT_PARAM) 00239 basic_string(size_type __n, _CharT __c, 00240 const allocator_type& __a = allocator_type()) 00241 #else 00242 basic_string(size_type __n, _CharT __c) 00243 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type(), __n + 1) { 00244 # if defined (_STLP_USE_SHORT_STRING_OPTIM) 00245 if (this->_M_using_static_buf()) { 00246 _Traits::assign(this->_M_Start(), __n, __c); 00247 this->_M_finish = this->_M_Start() + __n; 00248 } 00249 else 00250 # endif 00251 this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_Start(), __n, __c); 00252 _M_terminate_string(); 00253 } 00254 basic_string(size_type __n, _CharT __c, const allocator_type& __a) 00255 #endif 00256 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a, __n + 1) { 00257 #if defined (_STLP_USE_SHORT_STRING_OPTIM) 00258 if (this->_M_using_static_buf()) { 00259 _Traits::assign(this->_M_Start(), __n, __c); 00260 this->_M_finish = this->_M_Start() + __n; 00261 } 00262 else 00263 #endif 00264 this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_Start(), __n, __c); 00265 _M_terminate_string(); 00266 } 00267 00268 basic_string(__move_source<_Self> src) 00269 : _STLP_PRIV _String_base<_CharT,_Alloc>(__move_source<_Base>(src.get())) {} 00270 00271 // Check to see if _InputIterator is an integer type. If so, then 00272 // it can't be an iterator. 00273 #if defined (_STLP_MEMBER_TEMPLATES) && !(defined (__MRC__) || (defined(__SC__) && !defined(__DMC__))) //*ty 04/30/2001 - mpw compilers choke on this ctor 00274 # if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 00275 template <class _InputIterator> 00276 basic_string(_InputIterator __f, _InputIterator __l, 00277 const allocator_type & __a _STLP_ALLOCATOR_TYPE_DFL) 00278 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a) { 00279 typedef typename _IsIntegral<_InputIterator>::_Ret _Integral; 00280 _M_initialize_dispatch(__f, __l, _Integral()); 00281 } 00282 # if defined (_STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS) 00283 template <class _InputIterator> 00284 basic_string(_InputIterator __f, _InputIterator __l) 00285 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 00286 typedef typename _IsIntegral<_InputIterator>::_Ret _Integral; 00287 _M_initialize_dispatch(__f, __l, _Integral()); 00288 } 00289 # endif 00290 # else 00291 /* We need an additionnal constructor to build an empty string without 00292 * any allocation or termination char*/ 00293 protected: 00294 struct _CalledFromWorkaround_t {}; 00295 basic_string(_CalledFromWorkaround_t, const allocator_type &__a) 00296 : _String_base<_CharT,_Alloc>(__a) {} 00297 public: 00298 # endif /* _STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND */ 00299 #endif /* !__MRC__ || (__SC__ && !__DMC__) */ 00300 00301 #if !(defined (_STLP_MEMBER_TEMPLATES) && !(defined (__MRC__) || (defined (__SC__) && !defined (__DMC__)))) || \ 00302 !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS) || \ 00303 defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 00304 basic_string(const _CharT* __f, const _CharT* __l, 00305 const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL) 00306 : _STLP_PRIV _String_base<_CharT,_Alloc>(__a) { 00307 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 00308 _M_range_initialize(__f, __l); 00309 } 00310 # if defined (_STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS) 00311 basic_string(const _CharT* __f, const _CharT* __l) 00312 : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) { 00313 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 00314 _M_range_initialize(__f, __l); 00315 } 00316 # endif 00317 #endif /* _STLP_MEMBER_TEMPLATES */ 00318 00319 private: 00320 template <class _InputIter> 00321 void _M_range_initialize(_InputIter __f, _InputIter __l, 00322 const input_iterator_tag &__tag) { 00323 this->_M_allocate_block(); 00324 _M_construct_null(this->_M_Finish()); 00325 _STLP_TRY { 00326 _M_appendT(__f, __l, __tag); 00327 } 00328 _STLP_UNWIND(this->_M_destroy_range()) 00329 } 00330 00331 template <class _ForwardIter> 00332 void _M_range_initialize(_ForwardIter __f, _ForwardIter __l, 00333 const forward_iterator_tag &) { 00334 difference_type __n = distance(__f, __l); 00335 this->_M_allocate_block(__n + 1); 00336 #if defined (_STLP_USE_SHORT_STRING_OPTIM) 00337 if (this->_M_using_static_buf()) { 00338 _M_copyT(__f, __l, this->_M_Start()); 00339 this->_M_finish = this->_M_Start() + __n; 00340 } 00341 else 00342 #endif /* _STLP_USE_SHORT_STRING_OPTIM */ 00343 this->_M_finish = uninitialized_copy(__f, __l, this->_M_Start()); 00344 this->_M_terminate_string(); 00345 } 00346 00347 template <class _InputIter> 00348 void _M_range_initializeT(_InputIter __f, _InputIter __l) { 00349 _M_range_initialize(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter)); 00350 } 00351 00352 template <class _Integer> 00353 void _M_initialize_dispatch(_Integer __n, _Integer __x, const __true_type& /*_Integral*/) { 00354 this->_M_allocate_block(__n + 1); 00355 #if defined (_STLP_USE_SHORT_STRING_OPTIM) 00356 if (this->_M_using_static_buf()) { 00357 _Traits::assign(this->_M_Start(), __n, __x); 00358 this->_M_finish = this->_M_Start() + __n; 00359 } 00360 else 00361 #endif /* _STLP_USE_SHORT_STRING_OPTIM */ 00362 this->_M_finish = _STLP_PRIV __uninitialized_fill_n(this->_M_Start(), __n, __x); 00363 this->_M_terminate_string(); 00364 } 00365 00366 template <class _InputIter> 00367 void _M_initialize_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*_Integral*/) { 00368 _M_range_initializeT(__f, __l); 00369 } 00370 00371 public: 00372 ~basic_string() 00373 { this->_M_destroy_range(); } 00374 00375 _Self& operator=(const _Self& __s) { 00376 if (&__s != this) 00377 _M_assign(__s._M_Start(), __s._M_Finish()); 00378 return *this; 00379 } 00380 00381 _Self& operator=(const _CharT* __s) { 00382 _STLP_FIX_LITERAL_BUG(__s) 00383 return _M_assign(__s, __s + traits_type::length(__s)); 00384 } 00385 00386 _Self& operator=(_CharT __c) 00387 { return assign(__STATIC_CAST(size_type,1), __c); } 00388 00389 protected: 00390 00391 static _CharT _STLP_CALL _M_null() 00392 { return _STLP_DEFAULT_CONSTRUCTED(_CharT); } 00393 00394 protected: // Helper functions used by constructors 00395 // and elsewhere. 00396 // fbp : simplify integer types (char, wchar) 00397 void _M_construct_null_aux(_CharT* __p, const __false_type& /*_Is_Integral*/) const { 00398 #if defined (_STLP_USE_SHORT_STRING_OPTIM) 00399 if (this->_M_using_static_buf()) 00400 _Traits::assign(*__p, _M_null()); 00401 else 00402 #endif /*_STLP_USE_SHORT_STRING_OPTIM*/ 00403 _STLP_STD::_Construct(__p); 00404 } 00405 void _M_construct_null_aux(_CharT* __p, const __true_type& /*_Is_Integral*/) const 00406 { *__p = 0; } 00407 00408 void _M_force_construct_null(_CharT*, const __true_type& /* _Is_POD */) const 00409 { /*Nothing to do*/ } 00410 void _M_force_construct_null(_CharT* __p, const __false_type& /* _Is_POD */) const 00411 { _M_construct_null_aux(__p, _Char_Is_Integral()); } 00412 00413 void _M_construct_null(_CharT* __p) const { 00414 typedef __false_type _Answer; 00415 00416 _M_force_construct_null(__p, _Answer()); 00417 } 00418 00419 protected: 00420 // Helper functions used by constructors. It is a severe error for 00421 // any of them to be called anywhere except from within constructors. 00422 void _M_terminate_string_aux(const __false_type& __is_integral) { 00423 _STLP_TRY { 00424 _M_construct_null_aux(this->_M_Finish(), __is_integral); 00425 } 00426 _STLP_UNWIND(this->_M_destroy_range(0,0)) 00427 } 00428 00429 void _M_terminate_string_aux(const __true_type& __is_integral) 00430 { _M_construct_null_aux(this->_M_Finish(), __is_integral); } 00431 00432 void _M_force_terminate_string(const __true_type& /* _Is_POD */) 00433 { /*Nothing to do*/ } 00434 void _M_force_terminate_string(const __false_type& /* _Is_POD */) 00435 { _M_terminate_string_aux(_Char_Is_Integral()); } 00436 00437 void _M_terminate_string() { 00438 typedef __false_type _Answer; 00439 00440 _M_force_terminate_string(_Answer()); 00441 } 00442 00443 bool _M_inside(const _CharT* __s) const { 00444 _STLP_FIX_LITERAL_BUG(__s) 00445 return (__s >= this->_M_Start()) && (__s < this->_M_Finish()); 00446 } 00447 00448 void _M_range_initialize(const _CharT* __f, const _CharT* __l) { 00449 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 00450 ptrdiff_t __n = __l - __f; 00451 this->_M_allocate_block(__n + 1); 00452 #if defined (_STLP_USE_SHORT_STRING_OPTIM) 00453 if (this->_M_using_static_buf()) { 00454 _M_copy(__f, __l, this->_M_Start()); 00455 this->_M_finish = this->_M_Start() + __n; 00456 } 00457 else 00458 #endif /* _STLP_USE_SHORT_STRING_OPTIM */ 00459 this->_M_finish = uninitialized_copy(__f, __l, this->_M_Start()); 00460 _M_terminate_string(); 00461 } 00462 00463 public: // Iterators. 00464 iterator begin() { return this->_M_Start(); } 00465 iterator end() { return this->_M_Finish(); } 00466 const_iterator begin() const { return this->_M_Start(); } 00467 const_iterator end() const { return this->_M_Finish(); } 00468 00469 reverse_iterator rbegin() 00470 { return reverse_iterator(this->_M_Finish()); } 00471 reverse_iterator rend() 00472 { return reverse_iterator(this->_M_Start()); } 00473 const_reverse_iterator rbegin() const 00474 { return const_reverse_iterator(this->_M_Finish()); } 00475 const_reverse_iterator rend() const 00476 { return const_reverse_iterator(this->_M_Start()); } 00477 00478 public: // Size, capacity, etc. 00479 size_type size() const { return this->_M_Finish() - this->_M_Start(); } 00480 size_type length() const { return size(); } 00481 size_t max_size() const { return _Base::max_size(); } 00482 00483 void resize(size_type __n, _CharT __c) { 00484 if (__n <= size()) 00485 erase(begin() + __n, end()); 00486 else 00487 append(__n - size(), __c); 00488 } 00489 00490 void resize(size_type __n) { resize(__n, _M_null()); } 00491 00492 void reserve(size_type = 0); 00493 00494 size_type capacity() const 00495 { return (this->_M_end_of_storage._M_data - this->_M_Start()) - 1; } 00496 00497 void clear() { 00498 if (!empty()) { 00499 _Traits::assign(*(this->_M_Start()), _M_null()); 00500 this->_M_destroy_range(1); 00501 this->_M_finish = this->_M_Start(); 00502 } 00503 } 00504 00505 bool empty() const { return this->_M_Start() == this->_M_Finish(); } 00506 00507 public: // Element access. 00508 00509 const_reference operator[](size_type __n) const 00510 { return *(this->_M_Start() + __n); } 00511 reference operator[](size_type __n) 00512 { return *(this->_M_Start() + __n); } 00513 00514 const_reference at(size_type __n) const { 00515 if (__n >= size()) 00516 this->_M_throw_out_of_range(); 00517 return *(this->_M_Start() + __n); 00518 } 00519 00520 reference at(size_type __n) { 00521 if (__n >= size()) 00522 this->_M_throw_out_of_range(); 00523 return *(this->_M_Start() + __n); 00524 } 00525 00526 public: // Append, operator+=, push_back. 00527 00528 _Self& operator+=(const _Self& __s) { return append(__s); } 00529 _Self& operator+=(const _CharT* __s) { _STLP_FIX_LITERAL_BUG(__s) return append(__s); } 00530 _Self& operator+=(_CharT __c) { push_back(__c); return *this; } 00531 00532 #if defined (_STLP_MEMBER_TEMPLATES) 00533 # if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 00534 private: // Helper functions for append. 00535 template <class _InputIter> 00536 _Self& _M_appendT(_InputIter __first, _InputIter __last, 00537 const input_iterator_tag &) { 00538 for ( ; __first != __last ; ++__first) 00539 push_back(*__first); 00540 return *this; 00541 } 00542 00543 template <class _ForwardIter> 00544 _Self& _M_appendT(_ForwardIter __first, _ForwardIter __last, 00545 const forward_iterator_tag &) { 00546 if (__first != __last) { 00547 const size_type __old_size = this->size(); 00548 difference_type __n = distance(__first, __last); 00549 if (__STATIC_CAST(size_type,__n) > this->max_size() || __old_size > this->max_size() - __STATIC_CAST(size_type,__n)) 00550 this->_M_throw_length_error(); 00551 if (__old_size + __n > this->capacity()) { 00552 size_type __len = __old_size + (max)(__old_size, __STATIC_CAST(size_type,__n)) + 1; 00553 pointer __new_start = this->_M_end_of_storage.allocate(__len, __len); 00554 pointer __new_finish = __new_start; 00555 _STLP_TRY { 00556 __new_finish = uninitialized_copy(this->_M_Start(), this->_M_Finish(), __new_start); 00557 __new_finish = uninitialized_copy(__first, __last, __new_finish); 00558 _M_construct_null(__new_finish); 00559 } 00560 _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish), 00561 this->_M_end_of_storage.deallocate(__new_start, __len))) 00562 this->_M_destroy_range(); 00563 this->_M_deallocate_block(); 00564 this->_M_reset(__new_start, __new_finish, __new_start + __len); 00565 } 00566 else { 00567 _ForwardIter __f1 = __first; 00568 ++__f1; 00569 #if defined (_STLP_USE_SHORT_STRING_OPTIM) 00570 if (this->_M_using_static_buf()) 00571 _M_copyT(__f1, __last, this->_M_Finish() + 1); 00572 else 00573 #endif /* _STLP_USE_SHORT_STRING_OPTIM */ 00574 uninitialized_copy(__f1, __last, this->_M_Finish() + 1); 00575 _STLP_TRY { 00576 _M_construct_null(this->_M_Finish() + __n); 00577 } 00578 _STLP_UNWIND(this->_M_destroy_ptr_range(this->_M_Finish() + 1, this->_M_Finish() + __n)) 00579 _Traits::assign(*this->_M_finish, *__first); 00580 this->_M_finish += __n; 00581 } 00582 } 00583 return *this; 00584 } 00585 00586 template <class _Integer> 00587 _Self& _M_append_dispatch(_Integer __n, _Integer __x, const __true_type& /*Integral*/) 00588 { return append((size_type) __n, (_CharT) __x); } 00589 00590 template <class _InputIter> 00591 _Self& _M_append_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*Integral*/) 00592 { return _M_appendT(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter)); } 00593 00594 public: 00595 // Check to see if _InputIterator is an integer type. If so, then 00596 // it can't be an iterator. 00597 template <class _InputIter> 00598 _Self& append(_InputIter __first, _InputIter __last) { 00599 typedef typename _IsIntegral<_InputIter>::_Ret _Integral; 00600 return _M_append_dispatch(__first, __last, _Integral()); 00601 } 00602 # endif 00603 #endif 00604 00605 protected: 00606 _Self& _M_append(const _CharT* __first, const _CharT* __last); 00607 00608 public: 00609 #if !defined (_STLP_MEMBER_TEMPLATES) || \ 00610 !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS) 00611 # if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 00612 _Self& append(const _CharT* __first, const _CharT* __last) { 00613 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 00614 return _M_append(__first, __last); 00615 } 00616 # endif 00617 #endif 00618 00619 _Self& append(const _Self& __s) 00620 { return _M_append(__s._M_Start(), __s._M_Finish()); } 00621 00622 _Self& append(const _Self& __s, 00623 size_type __pos, size_type __n) { 00624 if (__pos > __s.size()) 00625 this->_M_throw_out_of_range(); 00626 return _M_append(__s._M_Start() + __pos, 00627 __s._M_Start() + __pos + (min) (__n, __s.size() - __pos)); 00628 } 00629 00630 _Self& append(const _CharT* __s, size_type __n) 00631 { _STLP_FIX_LITERAL_BUG(__s) return _M_append(__s, __s+__n); } 00632 _Self& append(const _CharT* __s) 00633 { _STLP_FIX_LITERAL_BUG(__s) return _M_append(__s, __s + traits_type::length(__s)); } 00634 _Self& append(size_type __n, _CharT __c); 00635 00636 public: 00637 void push_back(_CharT __c) { 00638 if (this->_M_Finish() + 1 == this->_M_end_of_storage._M_data) 00639 reserve(size() + (max)(size(), __STATIC_CAST(size_type,1))); 00640 _M_construct_null(this->_M_Finish() + 1); 00641 _Traits::assign(*(this->_M_Finish()), __c); 00642 ++this->_M_finish; 00643 } 00644 00645 void pop_back() { 00646 _Traits::assign(*(this->_M_Finish() - 1), _M_null()); 00647 this->_M_destroy_back(); 00648 --this->_M_finish; 00649 } 00650 00651 public: // Assign 00652 _Self& assign(const _Self& __s) 00653 { return _M_assign(__s._M_Start(), __s._M_Finish()); } 00654 00655 _Self& assign(const _Self& __s, 00656 size_type __pos, size_type __n) { 00657 if (__pos > __s.size()) 00658 this->_M_throw_out_of_range(); 00659 return _M_assign(__s._M_Start() + __pos, 00660 __s._M_Start() + __pos + (min) (__n, __s.size() - __pos)); 00661 } 00662 00663 _Self& assign(const _CharT* __s, size_type __n) 00664 { _STLP_FIX_LITERAL_BUG(__s) return _M_assign(__s, __s + __n); } 00665 00666 _Self& assign(const _CharT* __s) 00667 { _STLP_FIX_LITERAL_BUG(__s) return _M_assign(__s, __s + _Traits::length(__s)); } 00668 00669 _Self& assign(size_type __n, _CharT __c); 00670 00671 #if defined (_STLP_MEMBER_TEMPLATES) 00672 # if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 00673 private: // Helper functions for assign. 00674 template <class _Integer> 00675 _Self& _M_assign_dispatch(_Integer __n, _Integer __x, const __true_type& /*_Integral*/) 00676 { return assign((size_type) __n, (_CharT) __x); } 00677 00678 template <class _InputIter> 00679 _Self& _M_assign_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*_Integral*/) { 00680 pointer __cur = this->_M_Start(); 00681 while (__f != __l && __cur != this->_M_Finish()) { 00682 _Traits::assign(*__cur, *__f); 00683 ++__f; 00684 ++__cur; 00685 } 00686 if (__f == __l) 00687 erase(__cur, this->end()); 00688 else 00689 _M_appendT(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter)); 00690 return *this; 00691 } 00692 00693 public: 00694 // Check to see if _InputIterator is an integer type. If so, then 00695 // it can't be an iterator. 00696 template <class _InputIter> 00697 _Self& assign(_InputIter __first, _InputIter __last) { 00698 typedef typename _IsIntegral<_InputIter>::_Ret _Integral; 00699 return _M_assign_dispatch(__first, __last, _Integral()); 00700 } 00701 # endif 00702 #endif 00703 00704 protected: 00705 _Self& _M_assign(const _CharT* __f, const _CharT* __l); 00706 00707 public: 00708 00709 #if !defined (_STLP_MEMBER_TEMPLATES) || \ 00710 !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS) 00711 # if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 00712 _Self& assign(const _CharT* __f, const _CharT* __l) { 00713 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 00714 return _M_assign(__f, __l); 00715 } 00716 # endif 00717 #endif 00718 00719 public: // Insert 00720 00721 _Self& insert(size_type __pos, const _Self& __s) { 00722 if (__pos > size()) 00723 this->_M_throw_out_of_range(); 00724 if (size() > max_size() - __s.size()) 00725 this->_M_throw_length_error(); 00726 _M_insert(begin() + __pos, __s._M_Start(), __s._M_Finish(), &__s == this); 00727 return *this; 00728 } 00729 00730 _Self& insert(size_type __pos, const _Self& __s, 00731 size_type __beg, size_type __n) { 00732 if (__pos > size() || __beg > __s.size()) 00733 this->_M_throw_out_of_range(); 00734 size_type __len = (min) (__n, __s.size() - __beg); 00735 if (size() > max_size() - __len) 00736 this->_M_throw_length_error(); 00737 _M_insert(begin() + __pos, 00738 __s._M_Start() + __beg, __s._M_Start() + __beg + __len, &__s == this); 00739 return *this; 00740 } 00741 _Self& insert(size_type __pos, const _CharT* __s, size_type __n) { 00742 _STLP_FIX_LITERAL_BUG(__s) 00743 if (__pos > size()) 00744 this->_M_throw_out_of_range(); 00745 if (size() > max_size() - __n) 00746 this->_M_throw_length_error(); 00747 _M_insert(begin() + __pos, __s, __s + __n, _M_inside(__s)); 00748 return *this; 00749 } 00750 00751 _Self& insert(size_type __pos, const _CharT* __s) { 00752 _STLP_FIX_LITERAL_BUG(__s) 00753 if (__pos > size()) 00754 this->_M_throw_out_of_range(); 00755 size_type __len = _Traits::length(__s); 00756 if (size() > max_size() - __len) 00757 this->_M_throw_length_error(); 00758 _M_insert(this->_M_Start() + __pos, __s, __s + __len, _M_inside(__s)); 00759 return *this; 00760 } 00761 00762 _Self& insert(size_type __pos, size_type __n, _CharT __c) { 00763 if (__pos > size()) 00764 this->_M_throw_out_of_range(); 00765 if (size() > max_size() - __n) 00766 this->_M_throw_length_error(); 00767 insert(begin() + __pos, __n, __c); 00768 return *this; 00769 } 00770 00771 iterator insert(iterator __p, _CharT __c) { 00772 _STLP_FIX_LITERAL_BUG(__p) 00773 if (__p == end()) { 00774 push_back(__c); 00775 return this->_M_Finish() - 1; 00776 } 00777 else 00778 return _M_insert_aux(__p, __c); 00779 } 00780 00781 void insert(iterator __p, size_t __n, _CharT __c); 00782 00783 protected: // Helper functions for insert. 00784 00785 void _M_insert(iterator __p, const _CharT* __first, const _CharT* __last, bool __self_ref); 00786 00787 pointer _M_insert_aux(pointer, _CharT); 00788 00789 void _M_copy(const _CharT* __f, const _CharT* __l, _CharT* __res) { 00790 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 00791 _STLP_FIX_LITERAL_BUG(__res) 00792 _Traits::copy(__res, __f, __l - __f); 00793 } 00794 00795 void _M_move(const _CharT* __f, const _CharT* __l, _CharT* __res) { 00796 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 00797 _Traits::move(__res, __f, __l - __f); 00798 } 00799 00800 #if defined (_STLP_MEMBER_TEMPLATES) 00801 # if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 00802 template <class _ForwardIter> 00803 void _M_insert_overflow(iterator __pos, _ForwardIter __first, _ForwardIter __last, 00804 difference_type __n) { 00805 const size_type __old_size = this->size(); 00806 size_type __len = __old_size + (max)(__old_size, __STATIC_CAST(size_type,__n)) + 1; 00807 pointer __new_start = this->_M_end_of_storage.allocate(__len, __len); 00808 pointer __new_finish = __new_start; 00809 _STLP_TRY { 00810 __new_finish = uninitialized_copy(this->_M_Start(), __pos, __new_start); 00811 __new_finish = uninitialized_copy(__first, __last, __new_finish); 00812 __new_finish = uninitialized_copy(__pos, this->_M_Finish(), __new_finish); 00813 _M_construct_null(__new_finish); 00814 } 00815 _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish), 00816 this->_M_end_of_storage.deallocate(__new_start, __len))) 00817 this->_M_destroy_range(); 00818 this->_M_deallocate_block(); 00819 this->_M_reset(__new_start, __new_finish, __new_start + __len); 00820 } 00821 00822 template <class _InputIter> 00823 void _M_insertT(iterator __p, _InputIter __first, _InputIter __last, 00824 const input_iterator_tag &) { 00825 for ( ; __first != __last; ++__first) { 00826 __p = insert(__p, *__first); 00827 ++__p; 00828 } 00829 } 00830 00831 template <class _ForwardIter> 00832 void _M_insertT(iterator __pos, _ForwardIter __first, _ForwardIter __last, 00833 const forward_iterator_tag &) { 00834 if (__first != __last) { 00835 difference_type __n = distance(__first, __last); 00836 if (this->_M_end_of_storage._M_data - this->_M_finish >= __n + 1) { 00837 const difference_type __elems_after = this->_M_finish - __pos; 00838 if (__elems_after >= __n) { 00839 # if defined (_STLP_USE_SHORT_STRING_OPTIM) 00840 if (this->_M_using_static_buf()) 00841 _M_copy((this->_M_Finish() - __n) + 1, this->_M_Finish() + 1, this->_M_Finish() + 1); 00842 else 00843 # endif /* _STLP_USE_SHORT_STRING_OPTIM */ 00844 uninitialized_copy((this->_M_Finish() - __n) + 1, this->_M_Finish() + 1, this->_M_Finish() + 1); 00845 this->_M_finish += __n; 00846 _Traits::move(__pos + __n, __pos, (__elems_after - __n) + 1); 00847 _M_copyT(__first, __last, __pos); 00848 } 00849 else { 00850 pointer __old_finish = this->_M_Finish(); 00851 _ForwardIter __mid = __first; 00852 advance(__mid, __elems_after + 1); 00853 # if defined (_STLP_USE_SHORT_STRING_OPTIM) 00854 if (this->_M_using_static_buf()) 00855 _M_copyT(__mid, __last, this->_M_Finish() + 1); 00856 else 00857 # endif /* _STLP_USE_SHORT_STRING_OPTIM */ 00858 uninitialized_copy(__mid, __last, this->_M_Finish() + 1); 00859 this->_M_finish += __n - __elems_after; 00860 _STLP_TRY { 00861 # if defined (_STLP_USE_SHORT_STRING_OPTIM) 00862 if (this->_M_using_static_buf()) 00863 _M_copy(__pos, __old_finish + 1, this->_M_Finish()); 00864 else 00865 # endif /* _STLP_USE_SHORT_STRING_OPTIM */ 00866 uninitialized_copy(__pos, __old_finish + 1, this->_M_Finish()); 00867 this->_M_finish += __elems_after; 00868 } 00869 _STLP_UNWIND((this->_M_destroy_ptr_range(__old_finish + 1, this->_M_Finish()), 00870 this->_M_finish = __old_finish)) 00871 _M_copyT(__first, __mid, __pos); 00872 } 00873 } 00874 else { 00875 _M_insert_overflow(__pos, __first, __last, __n); 00876 } 00877 } 00878 } 00879 00880 template <class _Integer> 00881 void _M_insert_dispatch(iterator __p, _Integer __n, _Integer __x, 00882 const __true_type& /*Integral*/) { 00883 insert(__p, (size_type) __n, (_CharT) __x); 00884 } 00885 00886 template <class _InputIter> 00887 void _M_insert_dispatch(iterator __p, _InputIter __first, _InputIter __last, 00888 const __false_type& /*Integral*/) { 00889 _STLP_FIX_LITERAL_BUG(__p) 00890 /* 00891 * Within the basic_string implementation we are only going to check for 00892 * self referencing if iterators are string iterators or _CharT pointers. 00893 * A user could encapsulate those iterator within their own iterator interface 00894 * and in this case lead to a bad behavior, this is a known limitation. 00895 */ 00896 typedef typename _AreSameUnCVTypes<_InputIter, iterator>::_Ret _IsIterator; 00897 typedef typename _AreSameUnCVTypes<_InputIter, const_iterator>::_Ret _IsConstIterator; 00898 typedef typename _Lor2<_IsIterator, _IsConstIterator>::_Ret _CheckInside; 00899 _M_insert_aux(__p, __first, __last, _CheckInside()); 00900 } 00901 00902 template <class _RandomIter> 00903 void _M_insert_aux (iterator __p, _RandomIter __first, _RandomIter __last, 00904 const __true_type& /*_CheckInside*/) { 00905 _STLP_FIX_LITERAL_BUG(__p) 00906 _M_insert(__p, &(*__first), &(*__last), _M_inside(&(*__first))); 00907 } 00908 00909 template<class _InputIter> 00910 void _M_insert_aux (iterator __p, _InputIter __first, _InputIter __last, 00911 const __false_type& /*_CheckInside*/) { 00912 _STLP_FIX_LITERAL_BUG(__p) 00913 _M_insertT(__p, __first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIter)); 00914 } 00915 00916 template <class _InputIterator> 00917 void _M_copyT(_InputIterator __first, _InputIterator __last, pointer __result) { 00918 _STLP_FIX_LITERAL_BUG(__result) 00919 for ( ; __first != __last; ++__first, ++__result) 00920 _Traits::assign(*__result, *__first); 00921 } 00922 00923 # if !defined (_STLP_NO_METHOD_SPECIALIZATION) 00924 void _M_copyT(const _CharT* __f, const _CharT* __l, _CharT* __res) { 00925 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 00926 _STLP_FIX_LITERAL_BUG(__res) 00927 _Traits::copy(__res, __f, __l - __f); 00928 } 00929 # endif 00930 00931 public: 00932 // Check to see if _InputIterator is an integer type. If so, then 00933 // it can't be an iterator. 00934 template <class _InputIter> 00935 void insert(iterator __p, _InputIter __first, _InputIter __last) { 00936 typedef typename _IsIntegral<_InputIter>::_Ret _Integral; 00937 _M_insert_dispatch(__p, __first, __last, _Integral()); 00938 } 00939 # endif 00940 #endif 00941 00942 public: 00943 00944 #if !defined (_STLP_MEMBER_TEMPLATES) || \ 00945 !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS) 00946 void insert(iterator __p, const _CharT* __f, const _CharT* __l) { 00947 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 00948 _M_insert(__p, __f, __l, _M_inside(__f)); 00949 } 00950 #endif 00951 00952 public: // Erase. 00953 00954 _Self& erase(size_type __pos = 0, size_type __n = npos) { 00955 if (__pos > size()) 00956 this->_M_throw_out_of_range(); 00957 erase(begin() + __pos, begin() + __pos + (min) (__n, size() - __pos)); 00958 return *this; 00959 } 00960 00961 iterator erase(iterator __pos) { 00962 // The move includes the terminating _CharT(). 00963 _Traits::move(__pos, __pos + 1, this->_M_Finish() - __pos); 00964 this->_M_destroy_back(); 00965 --this->_M_finish; 00966 return __pos; 00967 } 00968 00969 iterator erase(iterator __first, iterator __last) { 00970 if (__first != __last) { 00971 // The move includes the terminating _CharT(). 00972 traits_type::move(__first, __last, (this->_M_Finish() - __last) + 1); 00973 pointer __new_finish = this->_M_Finish() - (__last - __first); 00974 this->_M_destroy_ptr_range(__new_finish + 1, this->_M_Finish() + 1); 00975 this->_M_finish = __new_finish; 00976 } 00977 return __first; 00978 } 00979 00980 public: // Replace. (Conceptually equivalent 00981 // to erase followed by insert.) 00982 _Self& replace(size_type __pos, size_type __n, const _Self& __s) { 00983 if (__pos > size()) 00984 this->_M_throw_out_of_range(); 00985 const size_type __len = (min) (__n, size() - __pos); 00986 if (size() - __len >= max_size() - __s.size()) 00987 this->_M_throw_length_error(); 00988 return _M_replace(begin() + __pos, begin() + __pos + __len, 00989 __s._M_Start(), __s._M_Finish(), &__s == this); 00990 } 00991 00992 _Self& replace(size_type __pos1, size_type __n1, const _Self& __s, 00993 size_type __pos2, size_type __n2) { 00994 if (__pos1 > size() || __pos2 > __s.size()) 00995 this->_M_throw_out_of_range(); 00996 const size_type __len1 = (min) (__n1, size() - __pos1); 00997 const size_type __len2 = (min) (__n2, __s.size() - __pos2); 00998 if (size() - __len1 >= max_size() - __len2) 00999 this->_M_throw_length_error(); 01000 return _M_replace(begin() + __pos1, begin() + __pos1 + __len1, 01001 __s._M_Start() + __pos2, __s._M_Start() + __pos2 + __len2, &__s == this); 01002 } 01003 01004 _Self& replace(size_type __pos, size_type __n1, 01005 const _CharT* __s, size_type __n2) { 01006 _STLP_FIX_LITERAL_BUG(__s) 01007 if (__pos > size()) 01008 this->_M_throw_out_of_range(); 01009 const size_type __len = (min) (__n1, size() - __pos); 01010 if (__n2 > max_size() || size() - __len >= max_size() - __n2) 01011 this->_M_throw_length_error(); 01012 return _M_replace(begin() + __pos, begin() + __pos + __len, 01013 __s, __s + __n2, _M_inside(__s)); 01014 } 01015 01016 _Self& replace(size_type __pos, size_type __n1, const _CharT* __s) { 01017 _STLP_FIX_LITERAL_BUG(__s) 01018 if (__pos > size()) 01019 this->_M_throw_out_of_range(); 01020 const size_type __len = (min) (__n1, size() - __pos); 01021 const size_type __n2 = _Traits::length(__s); 01022 if (__n2 > max_size() || size() - __len >= max_size() - __n2) 01023 this->_M_throw_length_error(); 01024 return _M_replace(begin() + __pos, begin() + __pos + __len, 01025 __s, __s + _Traits::length(__s), _M_inside(__s)); 01026 } 01027 01028 _Self& replace(size_type __pos, size_type __n1, 01029 size_type __n2, _CharT __c) { 01030 if (__pos > size()) 01031 this->_M_throw_out_of_range(); 01032 const size_type __len = (min) (__n1, size() - __pos); 01033 if (__n2 > max_size() || size() - __len >= max_size() - __n2) 01034 this->_M_throw_length_error(); 01035 return replace(begin() + __pos, begin() + __pos + __len, __n2, __c); 01036 } 01037 01038 _Self& replace(iterator __first, iterator __last, const _Self& __s) { 01039 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 01040 return _M_replace(__first, __last, __s._M_Start(), __s._M_Finish(), &__s == this); 01041 } 01042 01043 _Self& replace(iterator __first, iterator __last, 01044 const _CharT* __s, size_type __n) { 01045 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 01046 _STLP_FIX_LITERAL_BUG(__s) 01047 return _M_replace(__first, __last, __s, __s + __n, _M_inside(__s)); 01048 } 01049 01050 _Self& replace(iterator __first, iterator __last, 01051 const _CharT* __s) { 01052 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 01053 _STLP_FIX_LITERAL_BUG(__s) 01054 return _M_replace(__first, __last, __s, __s + _Traits::length(__s), _M_inside(__s)); 01055 } 01056 01057 _Self& replace(iterator __first, iterator __last, size_type __n, _CharT __c); 01058 01059 protected: // Helper functions for replace. 01060 _Self& _M_replace(iterator __first, iterator __last, 01061 const _CharT* __f, const _CharT* __l, bool __self_ref); 01062 01063 public: 01064 #if defined (_STLP_MEMBER_TEMPLATES) 01065 # if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 01066 template <class _Integer> 01067 _Self& _M_replace_dispatch(iterator __first, iterator __last, 01068 _Integer __n, _Integer __x, const __true_type& /*IsIntegral*/) { 01069 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 01070 return replace(__first, __last, (size_type) __n, (_CharT) __x); 01071 } 01072 01073 template <class _InputIter> 01074 _Self& _M_replace_dispatch(iterator __first, iterator __last, 01075 _InputIter __f, _InputIter __l, const __false_type& /*IsIntegral*/) { 01076 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 01077 typedef typename _AreSameUnCVTypes<_InputIter, iterator>::_Ret _IsIterator; 01078 typedef typename _AreSameUnCVTypes<_InputIter, const_iterator>::_Ret _IsConstIterator; 01079 typedef typename _Lor2<_IsIterator, _IsConstIterator>::_Ret _CheckInside; 01080 return _M_replace_aux(__first, __last, __f, __l, _CheckInside()); 01081 } 01082 01083 template <class _RandomIter> 01084 _Self& _M_replace_aux(iterator __first, iterator __last, 01085 _RandomIter __f, _RandomIter __l, __true_type const& /*_CheckInside*/) { 01086 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 01087 return _M_replace(__first, __last, &(*__f), &(*__l), _M_inside(&(*__f))); 01088 } 01089 01090 template <class _InputIter> 01091 _Self& _M_replace_aux(iterator __first, iterator __last, 01092 _InputIter __f, _InputIter __l, __false_type const& /*_CheckInside*/) { 01093 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 01094 return _M_replaceT(__first, __last, __f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter)); 01095 } 01096 01097 template <class _InputIter> 01098 _Self& _M_replaceT(iterator __first, iterator __last, 01099 _InputIter __f, _InputIter __l, const input_iterator_tag&__ite_tag) { 01100 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 01101 for ( ; __first != __last && __f != __l; ++__first, ++__f) 01102 _Traits::assign(*__first, *__f); 01103 if (__f == __l) 01104 erase(__first, __last); 01105 else 01106 _M_insertT(__last, __f, __l, __ite_tag); 01107 return *this; 01108 } 01109 01110 template <class _ForwardIter> 01111 _Self& _M_replaceT(iterator __first, iterator __last, 01112 _ForwardIter __f, _ForwardIter __l, const forward_iterator_tag &__ite_tag) { 01113 _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last) 01114 difference_type __n = distance(__f, __l); 01115 const difference_type __len = __last - __first; 01116 if (__len >= __n) { 01117 _M_copyT(__f, __l, __first); 01118 erase(__first + __n, __last); 01119 } 01120 else { 01121 _ForwardIter __m = __f; 01122 advance(__m, __len); 01123 _M_copyT(__f, __m, __first); 01124 _M_insertT(__last, __m, __l, __ite_tag); 01125 } 01126 return *this; 01127 } 01128 01129 public: 01130 // Check to see if _InputIter is an integer type. If so, then 01131 // it can't be an iterator. 01132 template <class _InputIter> 01133 _Self& replace(iterator __first, iterator __last, 01134 _InputIter __f, _InputIter __l) { 01135 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 01136 typedef typename _IsIntegral<_InputIter>::_Ret _Integral; 01137 return _M_replace_dispatch(__first, __last, __f, __l, _Integral()); 01138 } 01139 01140 # endif 01141 #endif 01142 01143 #if !defined (_STLP_MEMBER_TEMPLATES) || \ 01144 !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS) 01145 # if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 01146 _Self& replace(iterator __first, iterator __last, 01147 const _CharT* __f, const _CharT* __l) { 01148 _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last) 01149 _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) 01150 return _M_replace(__first, __last, __f, __l, _M_inside(__f)); 01151 } 01152 # endif 01153 #endif 01154 01155 public: // Other modifier member functions. 01156 01157 size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const { 01158 _STLP_FIX_LITERAL_BUG(__s) 01159 if (__pos > size()) 01160 this->_M_throw_out_of_range(); 01161 const size_type __len = (min) (__n, size() - __pos); 01162 _Traits::copy(__s, this->_M_Start() + __pos, __len); 01163 return __len; 01164 } 01165 01166 void swap(_Self& __s) { 01167 this->_M_Swap(__s); 01168 } 01169 01170 public: // Conversion to C string. 01171 01172 const _CharT* c_str() const { return this->_M_Start(); } 01173 const _CharT* data() const { return this->_M_Start(); } 01174 01175 public: // find. 01176 01177 size_type find(const _Self& __s, size_type __pos = 0) const 01178 { return find(__s._M_Start(), __pos, __s.size()); } 01179 01180 size_type find(const _CharT* __s, size_type __pos = 0) const 01181 { _STLP_FIX_LITERAL_BUG(__s) return find(__s, __pos, _Traits::length(__s)); } 01182 01183 size_type find(const _CharT* __s, size_type __pos, size_type __n) const; 01184 01185 // WIE: Versant schema compiler 5.2.2 ICE workaround 01186 size_type find(_CharT __c) const { return find(__c, 0); } 01187 size_type find(_CharT __c, size_type __pos /* = 0 */) const; 01188 01189 public: // rfind. 01190 01191 size_type rfind(const _Self& __s, size_type __pos = npos) const 01192 { return rfind(__s._M_Start(), __pos, __s.size()); } 01193 01194 size_type rfind(const _CharT* __s, size_type __pos = npos) const 01195 { _STLP_FIX_LITERAL_BUG(__s) return rfind(__s, __pos, _Traits::length(__s)); } 01196 01197 size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const; 01198 size_type rfind(_CharT __c, size_type __pos = npos) const; 01199 01200 public: // find_first_of 01201 01202 size_type find_first_of(const _Self& __s, size_type __pos = 0) const 01203 { return find_first_of(__s._M_Start(), __pos, __s.size()); } 01204 01205 size_type find_first_of(const _CharT* __s, size_type __pos = 0) const 01206 { _STLP_FIX_LITERAL_BUG(__s) return find_first_of(__s, __pos, _Traits::length(__s)); } 01207 01208 size_type find_first_of(const _CharT* __s, size_type __pos, 01209 size_type __n) const; 01210 01211 size_type find_first_of(_CharT __c, size_type __pos = 0) const 01212 { return find(__c, __pos); } 01213 01214 public: // find_last_of 01215 01216 size_type find_last_of(const _Self& __s, 01217 size_type __pos = npos) const 01218 { return find_last_of(__s._M_Start(), __pos, __s.size()); } 01219 01220 size_type find_last_of(const _CharT* __s, size_type __pos = npos) const 01221 { _STLP_FIX_LITERAL_BUG(__s) return find_last_of(__s, __pos, _Traits::length(__s)); } 01222 01223 size_type find_last_of(const _CharT* __s, size_type __pos, 01224 size_type __n) const; 01225 01226 size_type find_last_of(_CharT __c, size_type __pos = npos) const { 01227 return rfind(__c, __pos); 01228 } 01229 01230 public: // find_first_not_of 01231 01232 size_type find_first_not_of(const _Self& __s, 01233 size_type __pos = 0) const 01234 { return find_first_not_of(__s._M_Start(), __pos, __s.size()); } 01235 01236 size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const 01237 { _STLP_FIX_LITERAL_BUG(__s) return find_first_not_of(__s, __pos, _Traits::length(__s)); } 01238 01239 size_type find_first_not_of(const _CharT* __s, size_type __pos, 01240 size_type __n) const; 01241 01242 size_type find_first_not_of(_CharT __c, size_type __pos = 0) const; 01243 01244 public: // find_last_not_of 01245 01246 size_type find_last_not_of(const _Self& __s, 01247 size_type __pos = npos) const 01248 { return find_last_not_of(__s._M_Start(), __pos, __s.size()); } 01249 01250 size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const 01251 { _STLP_FIX_LITERAL_BUG(__s) return find_last_not_of(__s, __pos, _Traits::length(__s)); } 01252 01253 size_type find_last_not_of(const _CharT* __s, size_type __pos, 01254 size_type __n) const; 01255 01256 size_type find_last_not_of(_CharT __c, size_type __pos = npos) const; 01257 01258 public: // Substring. 01259 _Self substr(size_type __pos = 0, size_type __n = npos) const 01260 { return _Self(*this, __pos, __n, get_allocator()); } 01261 01262 public: // Compare 01263 int compare(const _Self& __s) const 01264 { return _M_compare(this->_M_Start(), this->_M_Finish(), __s._M_Start(), __s._M_Finish()); } 01265 01266 int compare(size_type __pos1, size_type __n1, 01267 const _Self& __s) const { 01268 if (__pos1 > size()) 01269 this->_M_throw_out_of_range(); 01270 return _M_compare(this->_M_Start() + __pos1, 01271 this->_M_Start() + __pos1 + (min) (__n1, size() - __pos1), 01272 __s._M_Start(), __s._M_Finish()); 01273 } 01274 01275 int compare(size_type __pos1, size_type __n1, 01276 const _Self& __s, 01277 size_type __pos2, size_type __n2) const { 01278 if (__pos1 > size() || __pos2 > __s.size()) 01279 this->_M_throw_out_of_range(); 01280 return _M_compare(this->_M_Start() + __pos1, 01281 this->_M_Start() + __pos1 + (min) (__n1, size() - __pos1), 01282 __s._M_Start() + __pos2, 01283 __s._M_Start() + __pos2 + (min) (__n2, __s.size() - __pos2)); 01284 } 01285 01286 int compare(const _CharT* __s) const { 01287 _STLP_FIX_LITERAL_BUG(__s) 01288 return _M_compare(this->_M_Start(), this->_M_Finish(), __s, __s + _Traits::length(__s)); 01289 } 01290 01291 int compare(size_type __pos1, size_type __n1, const _CharT* __s) const { 01292 _STLP_FIX_LITERAL_BUG(__s) 01293 if (__pos1 > size()) 01294 this->_M_throw_out_of_range(); 01295 return _M_compare(this->_M_Start() + __pos1, 01296 this->_M_Start() + __pos1 + (min) (__n1, size() - __pos1), 01297 __s, __s + _Traits::length(__s)); 01298 } 01299 01300 int compare(size_type __pos1, size_type __n1, const _CharT* __s, 01301 size_type __n2) const { 01302 _STLP_FIX_LITERAL_BUG(__s) 01303 if (__pos1 > size()) 01304 this->_M_throw_out_of_range(); 01305 return _M_compare(this->_M_Start() + __pos1, 01306 this->_M_Start() + __pos1 + (min) (__n1, size() - __pos1), 01307 __s, __s + __n2); 01308 } 01309 01310 public: // Helper functions for compare. 01311 01312 static int _STLP_CALL _M_compare(const _CharT* __f1, const _CharT* __l1, 01313 const _CharT* __f2, const _CharT* __l2) { 01314 const ptrdiff_t __n1 = __l1 - __f1; 01315 const ptrdiff_t __n2 = __l2 - __f2; 01316 const int cmp = _Traits::compare(__f1, __f2, (min) (__n1, __n2)); 01317 return cmp != 0 ? cmp : (__n1 < __n2 ? -1 : (__n1 > __n2 ? 1 : 0)); 01318 } 01319 #if defined (_STLP_USE_TEMPLATE_EXPRESSION) && !defined (_STLP_DEBUG) && !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 01320 # define _STLP_STRING_SUM_BASE(__reserve, __size, __alloc) _STLP_PRIV _String_base<_CharT,_Alloc>(__alloc, __size + 1) 01321 # include <stl/_string_sum_methods.h> 01322 # undef _STLP_STRING_SUM_BASE 01323 #endif /* _STLP_USE_TEMPLATE_EXPRESSION */ 01324 }; 01325 01326 #if !defined (_STLP_STATIC_CONST_INIT_BUG) 01327 # if defined (__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 96) 01328 template <class _CharT, class _Traits, class _Alloc> 01329 const size_t basic_string<_CharT, _Traits, _Alloc>::npos = ~(size_t) 0; 01330 # endif 01331 #endif 01332 01333 #if defined (_STLP_USE_TEMPLATE_EXPORT) 01334 _STLP_EXPORT_TEMPLATE_CLASS basic_string<char, char_traits<char>, allocator<char> >; 01335 # if defined (_STLP_HAS_WCHAR_T) 01336 _STLP_EXPORT_TEMPLATE_CLASS basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >; 01337 # endif 01338 #endif /* _STLP_USE_TEMPLATE_EXPORT */ 01339 01340 #if defined (basic_string) 01341 _STLP_MOVE_TO_STD_NAMESPACE 01342 # undef basic_string 01343 #endif 01344 01345 _STLP_END_NAMESPACE 01346 01347 #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) 01348 # include <stl/_string_workaround.h> 01349 #endif 01350 01351 #if defined (_STLP_DEBUG) 01352 # include <stl/debug/_string.h> 01353 #endif 01354 01355 _STLP_BEGIN_NAMESPACE 01356 01357 // ------------------------------------------------------------ 01358 // Non-member functions. 01359 // Swap. 01360 #if defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER) 01361 template <class _CharT, class _Traits, class _Alloc> 01362 inline void _STLP_CALL 01363 swap(basic_string<_CharT,_Traits,_Alloc>& __x, 01364 basic_string<_CharT,_Traits,_Alloc>& __y) 01365 { __x.swap(__y); } 01366 #endif /* _STLP_FUNCTION_TMPL_PARTIAL_ORDER */ 01367 01368 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) 01369 template <class _CharT, class _Traits, class _Alloc> 01370 struct __move_traits<basic_string<_CharT, _Traits, _Alloc> > { 01371 typedef __stlp_movable implemented; 01372 //Completness depends on the allocator: 01373 typedef typename __move_traits<_Alloc>::complete complete; 01374 }; 01375 /*#else 01376 * There is no need to specialize for string and wstring in this case 01377 * as the default __move_traits will already tell that string is movable 01378 * but not complete. We cannot define it as complete as nothing guaranty 01379 * that the STLport user hasn't specialized std::allocator for char or 01380 * wchar_t. 01381 */ 01382 #endif 01383 01384 _STLP_MOVE_TO_PRIV_NAMESPACE 01385 01386 template <class _CharT, class _Traits, class _Alloc> 01387 void _STLP_CALL _S_string_copy(const basic_string<_CharT,_Traits,_Alloc>& __s, 01388 _CharT* __buf, size_t __n); 01389 01390 #if defined(_STLP_USE_WIDE_INTERFACE) 01391 // A couple of functions to transfer between ASCII/Unicode 01392 wstring __ASCIIToWide(const char *ascii); 01393 string __WideToASCII(const wchar_t *wide); 01394 #endif 01395 01396 inline const char* _STLP_CALL 01397 __get_c_string(const string& __str) { return __str.c_str(); } 01398 01399 _STLP_MOVE_TO_STD_NAMESPACE 01400 01401 _STLP_END_NAMESPACE 01402 01403 #include <stl/_string_operators.h> 01404 01405 #if defined(_STLP_USE_NO_IOSTREAMS) || \ 01406 (defined (_STLP_EXPOSE_STREAM_IMPLEMENTATION) && !defined (_STLP_LINK_TIME_INSTANTIATION)) 01407 # include <stl/_string.c> 01408 #endif 01409 01410 #endif /* _STLP_INTERNAL_STRING_H */ 01411 01412 /* 01413 * Local Variables: 01414 * mode:C++ 01415 * End: 01416 */
Generated on Mon Mar 10 15:32:39 2008 by ![]() |