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