5 * This material is provided "as is", with absolutely no warranty expressed
6 * or implied. Any use is at your own risk.
8 * Permission to use or copy this software for any purpose is hereby granted
9 * without fee, provided the above notices are retained on all copies.
10 * Permission to modify the code and to distribute modified code is granted,
11 * provided the above notices are retained, and a notice that the code was
12 * modified is included with the above copyright notice.
16 //Included from _string.h, no need for macro guarding.
20 #if defined (_STLP_DEBUG)
21 # define basic_string _STLP_NON_DBG_NAME(str)
22 _STLP_MOVE_TO_PRIV_NAMESPACE
25 #define _STLP_NO_MEM_T_STRING_BASE _STLP_PRIV _STLP_NO_MEM_T_NAME(str)<_CharT, _Traits, _Alloc>
27 template <class _CharT
, class _Traits
, class _Alloc
>
28 class basic_string
: public _STLP_NO_MEM_T_STRING_BASE
29 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (basic_string)
30 , public __stlport_class
<basic_string
<_CharT
, _Traits
, _Alloc
> >
33 private: // Protected members inherited from base.
34 typedef basic_string
<_CharT
, _Traits
, _Alloc
> _Self
;
35 typedef _STLP_NO_MEM_T_STRING_BASE _Base
;
36 typedef typename
_Base::_CalledFromWorkaround_t _CalledFromWorkaround_t
;
39 __IMPORT_WITH_REVERSE_ITERATORS(_Base
)
41 typedef typename
_Base::_Iterator_category _Iterator_category
;
42 typedef typename
_Base::traits_type traits_type
;
43 typedef typename
_Base::_Reserve_t _Reserve_t
;
45 #include <stl/_string_npos.h>
47 public: // Constructor, destructor, assignment.
48 explicit basic_string(const allocator_type
& __a
= allocator_type())
49 : _STLP_NO_MEM_T_STRING_BASE(__a
) {}
51 basic_string(_Reserve_t __r
, size_t __n
,
52 const allocator_type
& __a
= allocator_type())
53 : _STLP_NO_MEM_T_STRING_BASE(__r
, __n
, __a
) {}
55 basic_string(const _Self
& __s
)
56 : _STLP_NO_MEM_T_STRING_BASE(__s
) {}
58 basic_string(const _Self
& __s
, size_type __pos
, size_type __n
= npos
,
59 const allocator_type
& __a
= allocator_type())
60 : _STLP_NO_MEM_T_STRING_BASE(__s
, __pos
, __n
, __a
) {}
62 basic_string(const _CharT
* __s
, size_type __n
,
63 const allocator_type
& __a
= allocator_type())
64 : _STLP_NO_MEM_T_STRING_BASE(__s
, __n
, __a
) {}
66 basic_string(const _CharT
* __s
,
67 const allocator_type
& __a
= allocator_type())
68 : _STLP_NO_MEM_T_STRING_BASE(__s
, __a
) {}
70 basic_string(size_type __n
, _CharT __c
,
71 const allocator_type
& __a
= allocator_type())
72 : _STLP_NO_MEM_T_STRING_BASE(__n
, __c
, __a
) {}
74 #if !defined (_STLP_NO_MOVE_SEMANTIC)
75 basic_string(__move_source
<_Self
> src
)
76 : _STLP_NO_MEM_T_STRING_BASE(__move_source
<_Base
>(src
.get())) {}
79 // Check to see if _InputIterator is an integer type. If so, then
80 // it can't be an iterator.
81 template <class _InputIterator
>
82 basic_string(_InputIterator __f
, _InputIterator __l
,
83 const allocator_type
& __a _STLP_ALLOCATOR_TYPE_DFL
)
84 : _STLP_NO_MEM_T_STRING_BASE(_CalledFromWorkaround_t(), __a
) {
85 typedef typename _IsIntegral
<_InputIterator
>::_Ret _Integral
;
86 _M_initialize_dispatch(__f
, __l
, _Integral());
88 # if defined (_STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS)
89 template <class _InputIterator
>
90 basic_string(_InputIterator __f
, _InputIterator __l
)
91 : _STLP_NO_MEM_T_STRING_BASE(_CalledFromWorkaround_t(), allocator_type()) {
92 typedef typename _IsIntegral
<_InputIterator
>::_Ret _Integral
;
93 _M_initialize_dispatch(__f
, __l
, _Integral());
97 _Self
& operator=(const _Self
& __s
) {
98 _Base::operator=(__s
);
102 _Self
& operator=(const _CharT
* __s
) {
103 _Base::operator=(__s
);
107 _Self
& operator=(_CharT __c
) {
108 _Base::operator=(__c
);
113 template <class _InputIter
>
114 void _M_range_initialize(_InputIter __f
, _InputIter __l
,
115 const input_iterator_tag
&__tag
) {
116 this->_M_allocate_block();
117 this->_M_construct_null(this->_M_Finish());
118 _M_appendT(__f
, __l
, __tag
);
121 template <class _ForwardIter
>
122 void _M_range_initialize(_ForwardIter __f
, _ForwardIter __l
,
123 const forward_iterator_tag
&) {
124 difference_type __n
= _STLP_STD::distance(__f
, __l
);
125 this->_M_allocate_block(__n
+ 1);
126 this->_M_finish
= uninitialized_copy(__f
, __l
, this->_M_Start());
127 this->_M_terminate_string();
130 template <class _InputIter
>
131 void _M_range_initializeT(_InputIter __f
, _InputIter __l
) {
132 _M_range_initialize(__f
, __l
, _STLP_ITERATOR_CATEGORY(__f
, _InputIter
));
135 template <class _Integer
>
136 void _M_initialize_dispatch(_Integer __n
, _Integer __x
, const __true_type
& /*_Integral*/) {
137 this->_M_allocate_block(__n
+ 1);
138 this->_M_finish
= uninitialized_fill_n(this->_M_Start(), __n
, __x
);
139 this->_M_terminate_string();
142 template <class _InputIter
>
143 void _M_initialize_dispatch(_InputIter __f
, _InputIter __l
, const __false_type
& /*_Integral*/) {
144 _M_range_initializeT(__f
, __l
);
147 public: // Append, operator+=, push_back.
148 _Self
& operator+=(const _Self
& __s
) {
149 _Base::operator+=(__s
);
152 _Self
& operator+=(const _CharT
* __s
) {
153 _STLP_FIX_LITERAL_BUG(__s
)
154 _Base::operator+=(__s
);
157 _Self
& operator+=(_CharT __c
) {
158 _Base::operator+=(__c
);
162 _Self
& append(const _Self
& __s
) {
167 _Self
& append(const _Self
& __s
,
168 size_type __pos
, size_type __n
) {
169 _Base::append(__s
, __pos
, __n
);
173 _Self
& append(const _CharT
* __s
, size_type __n
) {
174 _STLP_FIX_LITERAL_BUG(__s
)
175 _Base::append(__s
, __n
);
178 _Self
& append(const _CharT
* __s
) {
179 _STLP_FIX_LITERAL_BUG(__s
)
183 _Self
& append(size_type __n
, _CharT __c
) {
184 _Base::append(__n
, __c
);
188 // Check to see if _InputIterator is an integer type. If so, then
189 // it can't be an iterator.
190 template <class _InputIter
>
191 _Self
& append(_InputIter __first
, _InputIter __last
) {
192 typedef typename _IsIntegral
<_InputIter
>::_Ret _Integral
;
193 return _M_append_dispatch(__first
, __last
, _Integral());
196 #if !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS)
197 //See equivalent assign method remark.
198 _Self
& append(const _CharT
* __f
, const _CharT
* __l
) {
199 _STLP_FIX_LITERAL_BUG(__f
)_STLP_FIX_LITERAL_BUG(__l
)
200 _Base::append(__f
, __l
);
205 private: // Helper functions for append.
207 template <class _InputIter
>
208 _Self
& _M_appendT(_InputIter __first
, _InputIter __last
,
209 const input_iterator_tag
&) {
210 for ( ; __first
!= __last
; ++__first
)
211 _Base::push_back(*__first
);
215 template <class _ForwardIter
>
216 _Self
& _M_appendT(_ForwardIter __first
, _ForwardIter __last
,
217 const forward_iterator_tag
&) {
218 if (__first
!= __last
) {
219 const size_type __n
= __STATIC_CAST(size_type
, _STLP_STD::distance(__first
, __last
));
220 if (__n
>= this->_M_rest()) {
221 size_type __len
= this->_M_compute_next_size(__n
);
222 pointer __new_start
= this->_M_start_of_storage
.allocate(__len
, __len
);
223 pointer __new_finish
= uninitialized_copy(this->_M_Start(), this->_M_Finish(), __new_start
);
224 __new_finish
= uninitialized_copy(__first
, __last
, __new_finish
);
225 this->_M_construct_null(__new_finish
);
226 this->_M_deallocate_block();
227 this->_M_reset(__new_start
, __new_finish
, __new_start
+ __len
);
230 _Traits::assign(*this->_M_finish
, *__first
++);
231 uninitialized_copy(__first
, __last
, this->_M_Finish() + 1);
232 this->_M_construct_null(this->_M_Finish() + __n
);
233 this->_M_finish
+= __n
;
239 template <class _Integer
>
240 _Self
& _M_append_dispatch(_Integer __n
, _Integer __x
, const __true_type
& /*Integral*/)
241 { return append((size_type
) __n
, (_CharT
) __x
); }
243 template <class _InputIter
>
244 _Self
& _M_append_dispatch(_InputIter __f
, _InputIter __l
, const __false_type
& /*Integral*/)
245 { return _M_appendT(__f
, __l
, _STLP_ITERATOR_CATEGORY(__f
, _InputIter
)); }
248 _Self
& assign(const _Self
& __s
) {
253 _Self
& assign(const _Self
& __s
,
254 size_type __pos
, size_type __n
) {
255 _Base::assign(__s
, __pos
, __n
);
259 _Self
& assign(const _CharT
* __s
, size_type __n
) {
260 _STLP_FIX_LITERAL_BUG(__s
)
261 _Base::assign(__s
, __n
);
265 _Self
& assign(const _CharT
* __s
) {
266 _STLP_FIX_LITERAL_BUG(__s
)
271 _Self
& assign(size_type __n
, _CharT __c
) {
272 _Base::assign(__n
, __c
);
276 private: // Helper functions for assign.
278 template <class _Integer
>
279 _Self
& _M_assign_dispatch(_Integer __n
, _Integer __x
, const __true_type
& /*_Integral*/)
280 { return assign((size_type
) __n
, (_CharT
) __x
); }
282 template <class _InputIter
>
283 _Self
& _M_assign_dispatch(_InputIter __f
, _InputIter __l
, const __false_type
& /*_Integral*/) {
284 pointer __cur
= this->_M_Start();
285 while (__f
!= __l
&& __cur
!= this->_M_Finish()) {
286 _Traits::assign(*__cur
, *__f
);
291 _Base::erase(__cur
, this->_M_Finish());
293 _M_appendT(__f
, __l
, _STLP_ITERATOR_CATEGORY(__f
, _InputIter
));
298 // Check to see if _InputIterator is an integer type. If so, then
299 // it can't be an iterator.
300 template <class _InputIter
>
301 _Self
& assign(_InputIter __first
, _InputIter __last
) {
302 typedef typename _IsIntegral
<_InputIter
>::_Ret _Integral
;
303 return _M_assign_dispatch(__first
, __last
, _Integral());
306 #if !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS)
307 /* This method is not part of the standard and is a specialization of the
308 * template method assign. It is only granted for convenience to call assign
309 * with mixed parameters iterator and const_iterator.
311 _Self
& assign(const _CharT
* __f
, const _CharT
* __l
) {
312 _STLP_FIX_LITERAL_BUG(__f
)_STLP_FIX_LITERAL_BUG(__l
)
313 _Base::assign(__f
, __l
);
319 _Self
& insert(size_type __pos
, const _Self
& __s
) {
320 _Base::insert(__pos
, __s
);
324 _Self
& insert(size_type __pos
, const _Self
& __s
,
325 size_type __beg
, size_type __n
) {
326 _Base::insert(__pos
, __s
, __beg
, __n
);
329 _Self
& insert(size_type __pos
, const _CharT
* __s
, size_type __n
) {
330 _STLP_FIX_LITERAL_BUG(__s
)
331 _Base::insert(__pos
, __s
, __n
);
335 _Self
& insert(size_type __pos
, const _CharT
* __s
) {
336 _STLP_FIX_LITERAL_BUG(__s
)
337 _Base::insert(__pos
, __s
);
341 _Self
& insert(size_type __pos
, size_type __n
, _CharT __c
) {
342 _Base::insert(__pos
, __n
, __c
);
346 iterator
insert(iterator __p
, _CharT __c
)
347 { return _Base::insert(__p
, __c
); }
349 void insert(iterator __p
, size_t __n
, _CharT __c
)
350 { _Base::insert(__p
, __n
, __c
); }
352 // Check to see if _InputIterator is an integer type. If so, then
353 // it can't be an iterator.
354 template <class _InputIter
>
355 void insert(iterator __p
, _InputIter __first
, _InputIter __last
) {
356 typedef typename _IsIntegral
<_InputIter
>::_Ret _Integral
;
357 _M_insert_dispatch(__p
, __first
, __last
, _Integral());
360 #if !defined (_STLP_NO_METHOD_SPECIALIZATION)
362 void insert(iterator __p
, const _CharT
* __f
, const _CharT
* __l
) {
363 _STLP_FIX_LITERAL_BUG(__f
) _STLP_FIX_LITERAL_BUG(__l
)
364 _M_insert(__p
, __f
, __l
, this->_M_inside(__f
));
368 private: // Helper functions for insert.
369 void _M_insert(iterator __p
, const _CharT
* __f
, const _CharT
* __l
, bool __self_ref
) {
370 _STLP_FIX_LITERAL_BUG(__f
)_STLP_FIX_LITERAL_BUG(__l
)
371 _Base::_M_insert(__p
, __f
, __l
, __self_ref
);
374 template <class _ForwardIter
>
375 void _M_insert_overflow(iterator __pos
, _ForwardIter __first
, _ForwardIter __last
,
377 size_type __len
= this->_M_compute_next_size(__n
);
378 pointer __new_start
= this->_M_start_of_storage
.allocate(__len
, __len
);
379 pointer __new_finish
= uninitialized_copy(this->_M_Start(), __pos
, __new_start
);
380 __new_finish
= uninitialized_copy(__first
, __last
, __new_finish
);
381 __new_finish
= uninitialized_copy(__pos
, this->_M_Finish(), __new_finish
);
382 this->_M_construct_null(__new_finish
);
383 this->_M_deallocate_block();
384 this->_M_reset(__new_start
, __new_finish
, __new_start
+ __len
);
387 template <class _InputIter
>
388 void _M_insertT(iterator __p
, _InputIter __first
, _InputIter __last
,
389 const input_iterator_tag
&) {
390 for ( ; __first
!= __last
; ++__first
) {
391 __p
= insert(__p
, *__first
);
396 template <class _ForwardIter
>
397 void _M_insertT(iterator __pos
, _ForwardIter __first
, _ForwardIter __last
,
398 const forward_iterator_tag
&) {
399 if (__first
!= __last
) {
400 size_type __n
= __STATIC_CAST(size_type
, _STLP_STD::distance(__first
, __last
));
401 if (__n
< this->_M_rest()) {
402 const size_type __elems_after
= this->_M_finish
- __pos
;
403 if (__elems_after
>= __n
) {
404 uninitialized_copy((this->_M_Finish() - __n
) + 1, this->_M_Finish() + 1, this->_M_Finish() + 1);
405 this->_M_finish
+= __n
;
406 _Traits::move(__pos
+ __n
, __pos
, (__elems_after
- __n
) + 1);
407 _M_copyT(__first
, __last
, __pos
);
410 pointer __old_finish
= this->_M_Finish();
411 _ForwardIter __mid
= __first
;
412 _STLP_STD::advance(__mid
, __elems_after
+ 1);
413 _STLP_STD::uninitialized_copy(__mid
, __last
, this->_M_Finish() + 1);
414 this->_M_finish
+= __n
- __elems_after
;
415 uninitialized_copy(__pos
, __old_finish
+ 1, this->_M_Finish());
416 this->_M_finish
+= __elems_after
;
417 _M_copyT(__first
, __mid
, __pos
);
421 _M_insert_overflow(__pos
, __first
, __last
, __n
);
426 template <class _Integer
>
427 void _M_insert_dispatch(iterator __p
, _Integer __n
, _Integer __x
,
428 const __true_type
& /*Integral*/)
429 { insert(__p
, (size_type
) __n
, (_CharT
) __x
); }
431 template <class _InputIter
>
432 void _M_insert_dispatch(iterator __p
, _InputIter __first
, _InputIter __last
,
433 const __false_type
& /*Integral*/) {
434 _STLP_FIX_LITERAL_BUG(__p
)
435 /* We are forced to do a temporary string to avoid the self referencing issue. */
436 const _Self
__self(__first
, __last
, this->get_allocator());
437 _M_insertT(__p
, __self
.begin(), __self
.end(), _STLP_ITERATOR_CATEGORY(__first
, _InputIter
));
440 template <class _InputIterator
>
441 void _M_copyT(_InputIterator __first
, _InputIterator __last
, pointer __result
) {
442 _STLP_FIX_LITERAL_BUG(__p
)
443 for ( ; __first
!= __last
; ++__first
, ++__result
)
444 _Traits::assign(*__result
, *__first
);
447 #if !defined (_STLP_NO_METHOD_SPECIALIZATION)
448 void _M_copyT(const _CharT
* __f
, const _CharT
* __l
, _CharT
* __res
) {
449 _STLP_FIX_LITERAL_BUG(__f
) _STLP_FIX_LITERAL_BUG(__l
) _STLP_FIX_LITERAL_BUG(__res
)
450 _Base::_M_copy(__f
, __l
, __res
);
455 _Self
& erase(size_type __pos
= 0, size_type __n
= npos
) {
456 _Base::erase(__pos
, __n
);
460 iterator
erase(iterator __pos
) {
461 _STLP_FIX_LITERAL_BUG(__pos
)
462 return _Base::erase(__pos
);
465 iterator
erase(iterator __first
, iterator __last
) {
466 _STLP_FIX_LITERAL_BUG(__first
) _STLP_FIX_LITERAL_BUG(__last
)
467 return _Base::erase(__first
, __last
);
470 public: // Replace. (Conceptually equivalent
471 // to erase followed by insert.)
472 _Self
& replace(size_type __pos
, size_type __n
, const _Self
& __s
) {
473 _Base::replace(__pos
, __n
, __s
);
477 _Self
& replace(size_type __pos1
, size_type __n1
, const _Self
& __s
,
478 size_type __pos2
, size_type __n2
) {
479 _Base::replace(__pos1
, __n1
, __s
, __pos2
, __n2
);
483 _Self
& replace(size_type __pos
, size_type __n1
,
484 const _CharT
* __s
, size_type __n2
) {
485 _STLP_FIX_LITERAL_BUG(__s
)
486 _Base::replace(__pos
, __n1
, __s
, __n2
);
490 _Self
& replace(size_type __pos
, size_type __n1
, const _CharT
* __s
) {
491 _STLP_FIX_LITERAL_BUG(__s
)
492 _Base::replace(__pos
, __n1
, __s
);
496 _Self
& replace(size_type __pos
, size_type __n1
,
497 size_type __n2
, _CharT __c
) {
498 _Base::replace(__pos
, __n1
, __n2
, __c
);
502 _Self
& replace(iterator __first
, iterator __last
, const _Self
& __s
) {
503 _STLP_FIX_LITERAL_BUG(__first
) _STLP_FIX_LITERAL_BUG(__last
)
504 _Base::replace(__first
, __last
, __s
);
508 _Self
& replace(iterator __first
, iterator __last
,
509 const _CharT
* __s
, size_type __n
) {
510 _STLP_FIX_LITERAL_BUG(__first
) _STLP_FIX_LITERAL_BUG(__last
)
511 _STLP_FIX_LITERAL_BUG(__s
)
512 _Base::replace(__first
, __last
, __s
, __n
);
516 _Self
& replace(iterator __first
, iterator __last
,
518 _STLP_FIX_LITERAL_BUG(__first
) _STLP_FIX_LITERAL_BUG(__last
)
519 _STLP_FIX_LITERAL_BUG(__s
)
520 _Base::replace(__first
, __last
, __s
);
524 _Self
& replace(iterator __first
, iterator __last
,
525 size_type __n
, _CharT __c
) {
526 _STLP_FIX_LITERAL_BUG(__first
) _STLP_FIX_LITERAL_BUG(__last
)
527 _Base::replace(__first
, __last
, __n
, __c
);
531 // Check to see if _InputIter is an integer type. If so, then
532 // it can't be an iterator.
533 template <class _InputIter
>
534 _Self
& replace(iterator __first
, iterator __last
,
535 _InputIter __f
, _InputIter __l
) {
536 _STLP_FIX_LITERAL_BUG(__first
)_STLP_FIX_LITERAL_BUG(__last
)
537 typedef typename _IsIntegral
<_InputIter
>::_Ret _Integral
;
538 return _M_replace_dispatch(__first
, __last
, __f
, __l
, _Integral());
541 #if !defined (_STLP_NO_METHOD_SPECIALIZATION)
542 _Self
& replace(iterator __first
, iterator __last
,
543 const _CharT
* __f
, const _CharT
* __l
) {
544 _STLP_FIX_LITERAL_BUG(__first
) _STLP_FIX_LITERAL_BUG(__last
)
545 _STLP_FIX_LITERAL_BUG(__f
) _STLP_FIX_LITERAL_BUG(__l
)
546 return _M_replace(__first
, __last
, __f
, __l
, this->_M_inside(__f
));
550 private: // Helper functions for replace.
551 _Self
& _M_replace(iterator __first
, iterator __last
,
552 const _CharT
* __f
, const _CharT
* __l
, bool __self_ref
) {
553 _STLP_FIX_LITERAL_BUG(__first
) _STLP_FIX_LITERAL_BUG(__last
)
554 _STLP_FIX_LITERAL_BUG(__f
) _STLP_FIX_LITERAL_BUG(__l
)
555 _Base::_M_replace(__first
, __last
, __f
, __l
, __self_ref
);
559 template <class _Integer
>
560 _Self
& _M_replace_dispatch(iterator __first
, iterator __last
,
561 _Integer __n
, _Integer __x
, const __true_type
& /*IsIntegral*/) {
562 _STLP_FIX_LITERAL_BUG(__first
) _STLP_FIX_LITERAL_BUG(__last
)
563 return replace(__first
, __last
, (size_type
) __n
, (_CharT
) __x
);
566 template <class _InputIter
>
567 _Self
& _M_replace_dispatch(iterator __first
, iterator __last
,
568 _InputIter __f
, _InputIter __l
, const __false_type
& /*IsIntegral*/) {
569 _STLP_FIX_LITERAL_BUG(__first
) _STLP_FIX_LITERAL_BUG(__last
)
570 /* We are forced to do a temporary string to avoid the self referencing issue. */
571 const _Self
__self(__f
, __l
, this->get_allocator());
572 return _M_replace(__first
, __last
, __self
._M_Start(), __self
._M_Finish(), false);
575 public: // Other modifier member functions.
576 void swap(_Self
& __s
) { _Base::swap(__s
); }
577 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
578 void _M_swap_workaround(_Self
& __x
) { swap(__x
); }
581 public: // Substring.
582 _Self
substr(size_type __pos
= 0, size_type __n
= npos
) const
583 { return _Self(*this, __pos
, __n
, this->get_allocator()); }
585 #if defined (_STLP_USE_TEMPLATE_EXPRESSION) && !defined (_STLP_DEBUG)
586 # define _STLP_STRING_SUM_BASE _STLP_NO_MEM_T_STRING_BASE
587 # include <stl/_string_sum_methods.h>
588 # undef _STLP_STRING_SUM_BASE
592 #undef _STLP_NO_MEM_T_STRING_BASE
594 #if defined (basic_string)
595 _STLP_MOVE_TO_STD_NAMESPACE