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 
get_allocator()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
basic_string()160   basic_string()
161       : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type(), _Base::_DEFAULT_SIZE)
162   { _M_terminate_string(); }
basic_string(const allocator_type & __a)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
basic_string(_Reserve_t,size_t __n)172   basic_string(_Reserve_t, size_t __n)
173     : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type(), __n + 1)
174   { _M_terminate_string(); }
basic_string(_Reserve_t,size_t __n,const allocator_type & __a)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
basic_string(const _Self & __s,size_type __pos)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   }
basic_string(const _Self & __s,size_type __pos,size_type __n)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   }
basic_string(const _Self & __s,size_type __pos,size_type __n,const allocator_type & __a)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
basic_string(const _CharT * __s,size_type __n)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     }
basic_string(const _CharT * __s,size_type __n,const allocator_type & __a)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
basic_string(size_type __n,_CharT __c)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   }
basic_string(size_type __n,_CharT __c,const allocator_type & __a)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)
basic_string(__move_source<_Self> src)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>
basic_string(_InputIterator __f,_InputIterator __l,const allocator_type & __a _STLP_ALLOCATOR_TYPE_DFL)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>
basic_string(_InputIterator __f,_InputIterator __l)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)
basic_string(const _CharT * __f,const _CharT * __l,const allocator_type & __a _STLP_ALLOCATOR_TYPE_DFL)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)
basic_string(const _CharT * __f,const _CharT * __l)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 {};
basic_string(_CalledFromWorkaround_t,const allocator_type & __a)296   basic_string(_CalledFromWorkaround_t, const allocator_type &__a)
297     : _String_base<_CharT,_Alloc>(__a) {}
298 #  endif
299 #endif
300 
301 _STLP_PRIVATE:
_M_compute_next_size(size_type __n)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>
_M_range_initialize(_InputIter __f,_InputIter __l,const input_iterator_tag & __tag)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>
_M_range_initialize(_ForwardIter __f,_ForwardIter __l,const forward_iterator_tag &)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>
_M_range_initializeT(_InputIter __f,_InputIter __l)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>
_M_initialize_dispatch(_Integer __n,_Integer __x,const __true_type &)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>
_M_initialize_dispatch(_InputIter __f,_InputIter __l,const __false_type &)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:
_M_null()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.
_M_construct_null(_CharT * __p)367   void _M_construct_null(_CharT* __p) const
368   { _STLP_STD::_Construct(__p); }
_M_terminate_string()369   void _M_terminate_string()
370   { _M_construct_null(this->_M_Finish()); }
_M_inside(const _CharT * __s)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 
_M_range_initialize(const _CharT * __f,const _CharT * __l)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.
begin()385   iterator begin()             { return this->_M_Start(); }
end()386   iterator end()               { return this->_M_Finish(); }
begin()387   const_iterator begin() const { return this->_M_Start(); }
end()388   const_iterator end()   const { return this->_M_Finish(); }
389 
rbegin()390   reverse_iterator rbegin()
391   { return reverse_iterator(this->_M_Finish()); }
rend()392   reverse_iterator rend()
393   { return reverse_iterator(this->_M_Start()); }
rbegin()394   const_reverse_iterator rbegin() const
395   { return const_reverse_iterator(this->_M_Finish()); }
rend()396   const_reverse_iterator rend()   const
397   { return const_reverse_iterator(this->_M_Start()); }
398 
399 public:                         // Size, capacity, etc.
size()400   size_type size() const     { return this->_M_Finish() - this->_M_Start(); }
length()401   size_type length() const   { return size(); }
max_size()402   size_type max_size() const { return _Base::max_size(); }
403 
resize(size_type __n,_CharT __c)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 
resize(size_type __n)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 
capacity()418   size_type capacity() const
419   { return this->_M_capacity() - 1; }
420 
clear()421   void clear() {
422     if (!empty()) {
423       _Traits::assign(*(this->_M_Start()), _M_null());
424       this->_M_finish = this->_M_Start();
425     }
426   }
427 
empty()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 
at(size_type __n)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 
at(size_type __n)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>
_M_appendT(_InputIter __first,_InputIter __last,const input_iterator_tag &)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>
_M_appendT(_ForwardIter __first,_ForwardIter __last,const forward_iterator_tag &)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>
_M_append_dispatch(_Integer __n,_Integer __x,const __true_type &)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>
_M_append_dispatch(_InputIter __f,_InputIter __l,const __false_type &)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>
append(_InputIter __first,_InputIter __last)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:
append(const _CharT * __first,const _CharT * __last)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:
append(const _Self & __s)516   _Self& append(const _Self& __s)
517   { return _M_append(__s._M_Start(), __s._M_Finish()); }
518 
append(const _Self & __s,size_type __pos,size_type __n)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 
append(const _CharT * __s,size_type __n)527   _Self& append(const _CharT* __s, size_type __n)
528   { _STLP_FIX_LITERAL_BUG(__s) return _M_append(__s, __s+__n); }
append(const _CharT * __s)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:
push_back(_CharT __c)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 
pop_back()542   void pop_back() {
543     _Traits::assign(*(this->_M_Finish() - 1), _M_null());
544     --this->_M_finish;
545   }
546 
547 public:                         // Assign
assign(const _Self & __s)548   _Self& assign(const _Self& __s)
549   { return _M_assign(__s._M_Start(), __s._M_Finish()); }
550 
assign(const _Self & __s,size_type __pos,size_type __n)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 
assign(const _CharT * __s,size_type __n)559   _Self& assign(const _CharT* __s, size_type __n)
560   { _STLP_FIX_LITERAL_BUG(__s) return _M_assign(__s, __s + __n); }
561 
assign(const _CharT * __s)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>
_M_assign_dispatch(_Integer __n,_Integer __x,const __true_type &)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>
_M_assign_dispatch(_InputIter __f,_InputIter __l,const __false_type &)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>
assign(_InputIter __first,_InputIter __last)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:
assign(const _CharT * __f,const _CharT * __l)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
insert(size_type __pos,const _Self & __s)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 
insert(size_type __pos,const _Self & __s,size_type __beg,size_type __n)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   }
insert(size_type __pos,const _CharT * __s,size_type __n)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 
insert(size_type __pos,const _CharT * __s)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 
insert(size_type __pos,size_type __n,_CharT __c)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 
insert(iterator __p,_CharT __c)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 
_M_copy(const _CharT * __f,const _CharT * __l,_CharT * __res)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 
_M_move(const _CharT * __f,const _CharT * __l,_CharT * __res)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>
_M_insert_overflow(iterator __pos,_ForwardIter __first,_ForwardIter __last,size_type __n)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>
_M_insertT(iterator __p,_InputIter __first,_InputIter __last,const input_iterator_tag &)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>
_M_insertT(iterator __pos,_ForwardIter __first,_ForwardIter __last,const forward_iterator_tag &)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>
_M_insert_dispatch(iterator __p,_Integer __n,_Integer __x,const __true_type &)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>
_M_insert_dispatch(iterator __p,_InputIter __first,_InputIter __last,const __false_type &)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>
_M_copyT(_InputIterator __first,_InputIterator __last,pointer __result)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)
_M_copyT(const _CharT * __f,const _CharT * __l,_CharT * __res)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>
insert(iterator __p,_InputIter __first,_InputIter __last)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:
insert(iterator __p,const _CharT * __f,const _CharT * __l)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 
erase(iterator __pos)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 
erase(iterator __first,iterator __last)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.)
replace(size_type __pos,size_type __n,const _Self & __s)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 
replace(size_type __pos1,size_type __n1,const _Self & __s,size_type __pos2,size_type __n2)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 
replace(size_type __pos,size_type __n1,const _CharT * __s,size_type __n2)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 
replace(size_type __pos,size_type __n1,const _CharT * __s)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 
replace(size_type __pos,size_type __n1,size_type __n2,_CharT __c)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 
replace(iterator __first,iterator __last,const _Self & __s)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 
replace(iterator __first,iterator __last,const _CharT * __s,size_type __n)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 
replace(iterator __first,iterator __last,const _CharT * __s)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>
_M_replace_dispatch(iterator __first,iterator __last,_Integer __n,_Integer __x,const __true_type &)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>
_M_replace_dispatch(iterator __first,iterator __last,_InputIter __f,_InputIter __l,const __false_type &)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>
replace(iterator __first,iterator __last,_InputIter __f,_InputIter __l)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:
replace(iterator __first,iterator __last,const _CharT * __f,const _CharT * __l)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 
swap(_Self & __s)942   void swap(_Self& __s) { this->_M_swap(__s); }
943 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
_M_swap_workaround(_Self & __x)944   void _M_swap_workaround(_Self& __x) { swap(__x); }
945 #endif
946 
947 public:                         // Conversion to C string.
948 
c_str()949   const _CharT* c_str() const { return this->_M_Start(); }
data()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
find(_CharT __c)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
compare(const _Self & __s)1026   int compare(const _Self& __s) const
1027   { return _M_compare(this->_M_Start(), this->_M_Finish(), __s._M_Start(), __s._M_Finish()); }
1028 
compare(size_type __pos1,size_type __n1,const _Self & __s)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 
compare(size_type __pos1,size_type __n1,const _Self & __s,size_type __pos2,size_type __n2)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 
compare(const _CharT * __s)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 
compare(size_type __pos1,size_type __n1,const _CharT * __s)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 
compare(size_type __pos1,size_type __n1,const _CharT * __s,size_type __n2)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.
_M_compare(const _CharT * __f1,const _CharT * __l1,const _CharT * __f2,const _CharT * __l2)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
swap(basic_string<_CharT,_Traits,_Alloc> & __x,basic_string<_CharT,_Traits,_Alloc> & __y)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