Home | History | Annotate | Download | only in stl
      1 /*
      2  * Copyright (c) 2004
      3  * Francois Dumont
      4  *
      5  * This material is provided "as is", with absolutely no warranty expressed
      6  * or implied. Any use is at your own risk.
      7  *
      8  * Permission to use or copy this software for any purpose is hereby granted
      9  * without fee, provided the above notices are retained on all copies.
     10  * Permission to modify the code and to distribute modified code is granted,
     11  * provided the above notices are retained, and a notice that the code was
     12  * modified is included with the above copyright notice.
     13  *
     14  */
     15 
     16 //Included from _string.h, no need for macro guarding.
     17 
     18 _STLP_BEGIN_NAMESPACE
     19 
     20 #if defined (_STLP_DEBUG)
     21 #  define basic_string _STLP_NON_DBG_NAME(str)
     22 _STLP_MOVE_TO_PRIV_NAMESPACE
     23 #endif
     24 
     25 #define _STLP_NO_MEM_T_STRING_BASE _STLP_PRIV _STLP_NO_MEM_T_NAME(str)<_CharT, _Traits, _Alloc>
     26 
     27 template <class _CharT, class _Traits, class _Alloc>
     28 class basic_string : public _STLP_NO_MEM_T_STRING_BASE
     29 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (basic_string)
     30                    , public __stlport_class<basic_string<_CharT, _Traits, _Alloc> >
     31 #endif
     32 {
     33 private:                        // Protected members inherited from base.
     34   typedef basic_string<_CharT, _Traits, _Alloc> _Self;
     35   typedef _STLP_NO_MEM_T_STRING_BASE _Base;
     36   typedef typename _Base::_CalledFromWorkaround_t _CalledFromWorkaround_t;
     37 public:
     38 
     39   __IMPORT_WITH_REVERSE_ITERATORS(_Base)
     40 
     41   typedef typename _Base::_Iterator_category _Iterator_category;
     42   typedef typename _Base::traits_type traits_type;
     43   typedef typename _Base::_Reserve_t _Reserve_t;
     44 
     45 #include <stl/_string_npos.h>
     46 
     47 public:                         // Constructor, destructor, assignment.
     48   explicit basic_string(const allocator_type& __a = allocator_type())
     49     : _STLP_NO_MEM_T_STRING_BASE(__a) {}
     50 
     51   basic_string(_Reserve_t __r, size_t __n,
     52                const allocator_type& __a = allocator_type())
     53     : _STLP_NO_MEM_T_STRING_BASE(__r, __n, __a) {}
     54 
     55   basic_string(const _Self& __s)
     56     : _STLP_NO_MEM_T_STRING_BASE(__s) {}
     57 
     58   basic_string(const _Self& __s, size_type __pos, size_type __n = npos,
     59                const allocator_type& __a = allocator_type())
     60     : _STLP_NO_MEM_T_STRING_BASE(__s, __pos, __n, __a) {}
     61 
     62   basic_string(const _CharT* __s, size_type __n,
     63                const allocator_type& __a = allocator_type())
     64     : _STLP_NO_MEM_T_STRING_BASE(__s, __n, __a) {}
     65 
     66   basic_string(const _CharT* __s,
     67                const allocator_type& __a = allocator_type())
     68     : _STLP_NO_MEM_T_STRING_BASE(__s, __a) {}
     69 
     70   basic_string(size_type __n, _CharT __c,
     71                const allocator_type& __a = allocator_type())
     72     : _STLP_NO_MEM_T_STRING_BASE(__n, __c, __a) {}
     73 
     74 #if !defined (_STLP_NO_MOVE_SEMANTIC)
     75   basic_string(__move_source<_Self> src)
     76     : _STLP_NO_MEM_T_STRING_BASE(__move_source<_Base>(src.get())) {}
     77 #endif
     78 
     79   // Check to see if _InputIterator is an integer type.  If so, then
     80   // it can't be an iterator.
     81   template <class _InputIterator>
     82   basic_string(_InputIterator __f, _InputIterator __l,
     83                const allocator_type & __a _STLP_ALLOCATOR_TYPE_DFL)
     84     : _STLP_NO_MEM_T_STRING_BASE(_CalledFromWorkaround_t(), __a) {
     85     typedef typename _IsIntegral<_InputIterator>::_Ret _Integral;
     86     _M_initialize_dispatch(__f, __l, _Integral());
     87   }
     88 #  if defined (_STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS)
     89   template <class _InputIterator>
     90   basic_string(_InputIterator __f, _InputIterator __l)
     91     : _STLP_NO_MEM_T_STRING_BASE(_CalledFromWorkaround_t(), allocator_type()) {
     92     typedef typename _IsIntegral<_InputIterator>::_Ret _Integral;
     93     _M_initialize_dispatch(__f, __l, _Integral());
     94   }
     95 #  endif
     96 
     97   _Self& operator=(const _Self& __s) {
     98     _Base::operator=(__s);
     99     return *this;
    100   }
    101 
    102   _Self& operator=(const _CharT* __s) {
    103     _Base::operator=(__s);
    104     return *this;
    105   }
    106 
    107   _Self& operator=(_CharT __c) {
    108     _Base::operator=(__c);
    109     return *this;
    110   }
    111 
    112 private:
    113   template <class _InputIter>
    114   void _M_range_initialize(_InputIter __f, _InputIter __l,
    115                            const input_iterator_tag &__tag) {
    116     this->_M_allocate_block();
    117     this->_M_construct_null(this->_M_Finish());
    118     _M_appendT(__f, __l, __tag);
    119   }
    120 
    121   template <class _ForwardIter>
    122   void _M_range_initialize(_ForwardIter __f, _ForwardIter __l,
    123                            const forward_iterator_tag &) {
    124     difference_type __n = _STLP_STD::distance(__f, __l);
    125     this->_M_allocate_block(__n + 1);
    126     this->_M_finish = uninitialized_copy(__f, __l, this->_M_Start());
    127     this->_M_terminate_string();
    128   }
    129 
    130   template <class _InputIter>
    131   void _M_range_initializeT(_InputIter __f, _InputIter __l) {
    132     _M_range_initialize(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter));
    133   }
    134 
    135   template <class _Integer>
    136   void _M_initialize_dispatch(_Integer __n, _Integer __x, const __true_type& /*_Integral*/) {
    137     this->_M_allocate_block(__n + 1);
    138     this->_M_finish = uninitialized_fill_n(this->_M_Start(), __n, __x);
    139     this->_M_terminate_string();
    140   }
    141 
    142   template <class _InputIter>
    143   void _M_initialize_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*_Integral*/) {
    144     _M_range_initializeT(__f, __l);
    145   }
    146 
    147 public:                         // Append, operator+=, push_back.
    148   _Self& operator+=(const _Self& __s) {
    149     _Base::operator+=(__s);
    150     return *this;
    151   }
    152   _Self& operator+=(const _CharT* __s) {
    153     _STLP_FIX_LITERAL_BUG(__s)
    154     _Base::operator+=(__s);
    155     return *this;
    156   }
    157   _Self& operator+=(_CharT __c) {
    158     _Base::operator+=(__c);
    159     return *this;
    160   }
    161 
    162   _Self& append(const _Self& __s) {
    163     _Base::append(__s);
    164     return *this;
    165   }
    166 
    167   _Self& append(const _Self& __s,
    168                 size_type __pos, size_type __n) {
    169     _Base::append(__s, __pos, __n);
    170     return *this;
    171   }
    172 
    173   _Self& append(const _CharT* __s, size_type __n) {
    174     _STLP_FIX_LITERAL_BUG(__s)
    175     _Base::append(__s, __n);
    176     return *this;
    177   }
    178   _Self& append(const _CharT* __s) {
    179     _STLP_FIX_LITERAL_BUG(__s)
    180     _Base::append(__s);
    181     return *this;
    182   }
    183   _Self& append(size_type __n, _CharT __c) {
    184     _Base::append(__n, __c);
    185     return *this;
    186   }
    187 
    188   // Check to see if _InputIterator is an integer type.  If so, then
    189   // it can't be an iterator.
    190   template <class _InputIter>
    191   _Self& append(_InputIter __first, _InputIter __last) {
    192     typedef typename _IsIntegral<_InputIter>::_Ret _Integral;
    193     return _M_append_dispatch(__first, __last, _Integral());
    194   }
    195 
    196 #if !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS)
    197   //See equivalent assign method remark.
    198   _Self& append(const _CharT* __f, const _CharT* __l) {
    199     _STLP_FIX_LITERAL_BUG(__f)_STLP_FIX_LITERAL_BUG(__l)
    200     _Base::append(__f, __l);
    201     return *this;
    202   }
    203 #endif
    204 
    205 private:                        // Helper functions for append.
    206 
    207   template <class _InputIter>
    208   _Self& _M_appendT(_InputIter __first, _InputIter __last,
    209                    const input_iterator_tag &) {
    210     for ( ; __first != __last ; ++__first)
    211       _Base::push_back(*__first);
    212     return *this;
    213   }
    214 
    215   template <class _ForwardIter>
    216   _Self& _M_appendT(_ForwardIter __first, _ForwardIter __last,
    217                     const forward_iterator_tag &)  {
    218     if (__first != __last) {
    219       const size_type __n = __STATIC_CAST(size_type, _STLP_STD::distance(__first, __last));
    220       if (__n >= this->_M_rest()) {
    221         size_type __len = this->_M_compute_next_size(__n);
    222         pointer __new_start = this->_M_start_of_storage.allocate(__len, __len);
    223         pointer __new_finish = uninitialized_copy(this->_M_Start(), this->_M_Finish(), __new_start);
    224         __new_finish = uninitialized_copy(__first, __last, __new_finish);
    225         this->_M_construct_null(__new_finish);
    226         this->_M_deallocate_block();
    227         this->_M_reset(__new_start, __new_finish, __new_start + __len);
    228       }
    229       else {
    230         _Traits::assign(*this->_M_finish, *__first++);
    231         uninitialized_copy(__first, __last, this->_M_Finish() + 1);
    232         this->_M_construct_null(this->_M_Finish() + __n);
    233         this->_M_finish += __n;
    234       }
    235     }
    236     return *this;
    237   }
    238 
    239   template <class _Integer>
    240   _Self& _M_append_dispatch(_Integer __n, _Integer __x, const __true_type& /*Integral*/)
    241   { return append((size_type) __n, (_CharT) __x); }
    242 
    243   template <class _InputIter>
    244   _Self& _M_append_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*Integral*/)
    245   { return _M_appendT(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter)); }
    246 
    247 public:                         // Assign
    248   _Self& assign(const _Self& __s) {
    249     _Base::assign(__s);
    250     return *this;
    251   }
    252 
    253   _Self& assign(const _Self& __s,
    254                 size_type __pos, size_type __n) {
    255     _Base::assign(__s, __pos, __n);
    256     return *this;
    257   }
    258 
    259   _Self& assign(const _CharT* __s, size_type __n) {
    260     _STLP_FIX_LITERAL_BUG(__s)
    261     _Base::assign(__s, __n);
    262     return *this;
    263   }
    264 
    265   _Self& assign(const _CharT* __s) {
    266     _STLP_FIX_LITERAL_BUG(__s)
    267     _Base::assign(__s);
    268     return *this;
    269   }
    270 
    271   _Self& assign(size_type __n, _CharT __c) {
    272     _Base::assign(__n, __c);
    273     return *this;
    274   }
    275 
    276 private:                        // Helper functions for assign.
    277 
    278   template <class _Integer>
    279   _Self& _M_assign_dispatch(_Integer __n, _Integer __x, const __true_type& /*_Integral*/)
    280   { return assign((size_type) __n, (_CharT) __x); }
    281 
    282   template <class _InputIter>
    283   _Self& _M_assign_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*_Integral*/)  {
    284     pointer __cur = this->_M_Start();
    285     while (__f != __l && __cur != this->_M_Finish()) {
    286       _Traits::assign(*__cur, *__f);
    287       ++__f;
    288       ++__cur;
    289     }
    290     if (__f == __l)
    291       _Base::erase(__cur, this->_M_Finish());
    292     else
    293       _M_appendT(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter));
    294     return *this;
    295   }
    296 
    297 public:
    298   // Check to see if _InputIterator is an integer type.  If so, then
    299   // it can't be an iterator.
    300   template <class _InputIter>
    301   _Self& assign(_InputIter __first, _InputIter __last) {
    302     typedef typename _IsIntegral<_InputIter>::_Ret _Integral;
    303     return _M_assign_dispatch(__first, __last, _Integral());
    304   }
    305 
    306 #if !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS)
    307   /* This method is not part of the standard and is a specialization of the
    308    * template method assign. It is only granted for convenience to call assign
    309    * with mixed parameters iterator and const_iterator.
    310    */
    311   _Self& assign(const _CharT* __f, const _CharT* __l) {
    312     _STLP_FIX_LITERAL_BUG(__f)_STLP_FIX_LITERAL_BUG(__l)
    313     _Base::assign(__f, __l);
    314     return *this;
    315   }
    316 #endif
    317 
    318 public:                         // Insert
    319   _Self& insert(size_type __pos, const _Self& __s) {
    320     _Base::insert(__pos, __s);
    321     return *this;
    322   }
    323 
    324   _Self& insert(size_type __pos, const _Self& __s,
    325                 size_type __beg, size_type __n) {
    326     _Base::insert(__pos, __s, __beg, __n);
    327     return *this;
    328   }
    329   _Self& insert(size_type __pos, const _CharT* __s, size_type __n) {
    330     _STLP_FIX_LITERAL_BUG(__s)
    331     _Base::insert(__pos, __s, __n);
    332     return *this;
    333   }
    334 
    335   _Self& insert(size_type __pos, const _CharT* __s) {
    336     _STLP_FIX_LITERAL_BUG(__s)
    337     _Base::insert(__pos, __s);
    338     return *this;
    339   }
    340 
    341   _Self& insert(size_type __pos, size_type __n, _CharT __c) {
    342     _Base::insert(__pos, __n, __c);
    343     return *this;
    344   }
    345 
    346   iterator insert(iterator __p, _CharT __c)
    347   { return _Base::insert(__p, __c); }
    348 
    349   void insert(iterator __p, size_t __n, _CharT __c)
    350   { _Base::insert(__p, __n, __c); }
    351 
    352   // Check to see if _InputIterator is an integer type.  If so, then
    353   // it can't be an iterator.
    354   template <class _InputIter>
    355   void insert(iterator __p, _InputIter __first, _InputIter __last) {
    356     typedef typename _IsIntegral<_InputIter>::_Ret _Integral;
    357     _M_insert_dispatch(__p, __first, __last, _Integral());
    358   }
    359 
    360 #if !defined (_STLP_NO_METHOD_SPECIALIZATION)
    361 public:
    362   void insert(iterator __p, const _CharT* __f, const _CharT* __l) {
    363     _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l)
    364     _M_insert(__p, __f, __l, this->_M_inside(__f));
    365   }
    366 #endif
    367 
    368 private:  // Helper functions for insert.
    369   void _M_insert(iterator __p, const _CharT* __f, const _CharT* __l, bool __self_ref) {
    370     _STLP_FIX_LITERAL_BUG(__f)_STLP_FIX_LITERAL_BUG(__l)
    371     _Base::_M_insert(__p, __f, __l, __self_ref);
    372   }
    373 
    374   template <class _ForwardIter>
    375   void _M_insert_overflow(iterator __pos, _ForwardIter __first, _ForwardIter __last,
    376                           size_type __n) {
    377     size_type __len = this->_M_compute_next_size(__n);
    378     pointer __new_start = this->_M_start_of_storage.allocate(__len, __len);
    379     pointer __new_finish = uninitialized_copy(this->_M_Start(), __pos, __new_start);
    380     __new_finish = uninitialized_copy(__first, __last, __new_finish);
    381     __new_finish = uninitialized_copy(__pos, this->_M_Finish(), __new_finish);
    382     this->_M_construct_null(__new_finish);
    383     this->_M_deallocate_block();
    384     this->_M_reset(__new_start, __new_finish, __new_start + __len);
    385   }
    386 
    387   template <class _InputIter>
    388   void _M_insertT(iterator __p, _InputIter __first, _InputIter __last,
    389                   const input_iterator_tag &) {
    390     for ( ; __first != __last; ++__first) {
    391       __p = insert(__p, *__first);
    392       ++__p;
    393     }
    394   }
    395 
    396   template <class _ForwardIter>
    397   void _M_insertT(iterator __pos, _ForwardIter __first, _ForwardIter __last,
    398                   const forward_iterator_tag &) {
    399     if (__first != __last) {
    400       size_type __n = __STATIC_CAST(size_type, _STLP_STD::distance(__first, __last));
    401       if (__n < this->_M_rest()) {
    402         const size_type __elems_after = this->_M_finish - __pos;
    403         if (__elems_after >= __n) {
    404           uninitialized_copy((this->_M_Finish() - __n) + 1, this->_M_Finish() + 1, this->_M_Finish() + 1);
    405           this->_M_finish += __n;
    406           _Traits::move(__pos + __n, __pos, (__elems_after - __n) + 1);
    407           _M_copyT(__first, __last, __pos);
    408         }
    409         else {
    410           pointer __old_finish = this->_M_Finish();
    411           _ForwardIter __mid = __first;
    412           _STLP_STD::advance(__mid, __elems_after + 1);
    413           _STLP_STD::uninitialized_copy(__mid, __last, this->_M_Finish() + 1);
    414           this->_M_finish += __n - __elems_after;
    415           uninitialized_copy(__pos, __old_finish + 1, this->_M_Finish());
    416           this->_M_finish += __elems_after;
    417           _M_copyT(__first, __mid, __pos);
    418         }
    419       }
    420       else {
    421         _M_insert_overflow(__pos, __first, __last, __n);
    422       }
    423     }
    424   }
    425 
    426   template <class _Integer>
    427   void _M_insert_dispatch(iterator __p, _Integer __n, _Integer __x,
    428                           const __true_type& /*Integral*/)
    429   { insert(__p, (size_type) __n, (_CharT) __x); }
    430 
    431   template <class _InputIter>
    432   void _M_insert_dispatch(iterator __p, _InputIter __first, _InputIter __last,
    433                           const __false_type& /*Integral*/) {
    434     _STLP_FIX_LITERAL_BUG(__p)
    435     /* We are forced to do a temporary string to avoid the self referencing issue. */
    436     const _Self __self(__first, __last, this->get_allocator());
    437     _M_insertT(__p, __self.begin(), __self.end(), _STLP_ITERATOR_CATEGORY(__first, _InputIter));
    438   }
    439 
    440   template <class _InputIterator>
    441   void _M_copyT(_InputIterator __first, _InputIterator __last, pointer __result) {
    442     _STLP_FIX_LITERAL_BUG(__p)
    443     for ( ; __first != __last; ++__first, ++__result)
    444       _Traits::assign(*__result, *__first);
    445   }
    446 
    447 #if !defined (_STLP_NO_METHOD_SPECIALIZATION)
    448   void _M_copyT(const _CharT* __f, const _CharT* __l, _CharT* __res) {
    449     _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) _STLP_FIX_LITERAL_BUG(__res)
    450     _Base::_M_copy(__f, __l, __res);
    451   }
    452 #endif
    453 
    454 public:                         // Erase.
    455   _Self& erase(size_type __pos = 0, size_type __n = npos) {
    456     _Base::erase(__pos, __n);
    457     return *this;
    458   }
    459 
    460   iterator erase(iterator __pos) {
    461     _STLP_FIX_LITERAL_BUG(__pos)
    462     return _Base::erase(__pos);
    463   }
    464 
    465   iterator erase(iterator __first, iterator __last) {
    466     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
    467     return _Base::erase(__first, __last);
    468   }
    469 
    470 public:                         // Replace.  (Conceptually equivalent
    471                                 // to erase followed by insert.)
    472   _Self& replace(size_type __pos, size_type __n, const _Self& __s) {
    473     _Base::replace(__pos, __n, __s);
    474     return *this;
    475   }
    476 
    477   _Self& replace(size_type __pos1, size_type __n1, const _Self& __s,
    478                  size_type __pos2, size_type __n2) {
    479     _Base::replace(__pos1, __n1, __s, __pos2, __n2);
    480     return *this;
    481   }
    482 
    483   _Self& replace(size_type __pos, size_type __n1,
    484                  const _CharT* __s, size_type __n2) {
    485     _STLP_FIX_LITERAL_BUG(__s)
    486     _Base::replace(__pos, __n1, __s, __n2);
    487     return *this;
    488   }
    489 
    490   _Self& replace(size_type __pos, size_type __n1, const _CharT* __s) {
    491     _STLP_FIX_LITERAL_BUG(__s)
    492     _Base::replace(__pos, __n1, __s);
    493     return *this;
    494   }
    495 
    496   _Self& replace(size_type __pos, size_type __n1,
    497                  size_type __n2, _CharT __c) {
    498     _Base::replace(__pos, __n1, __n2, __c);
    499     return *this;
    500   }
    501 
    502   _Self& replace(iterator __first, iterator __last, const _Self& __s) {
    503     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
    504     _Base::replace(__first, __last, __s);
    505     return *this;
    506   }
    507 
    508   _Self& replace(iterator __first, iterator __last,
    509                  const _CharT* __s, size_type __n) {
    510     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
    511     _STLP_FIX_LITERAL_BUG(__s)
    512     _Base::replace(__first, __last, __s, __n);
    513     return *this;
    514   }
    515 
    516   _Self& replace(iterator __first, iterator __last,
    517                  const _CharT* __s) {
    518     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
    519     _STLP_FIX_LITERAL_BUG(__s)
    520     _Base::replace(__first, __last, __s);
    521     return *this;
    522   }
    523 
    524   _Self& replace(iterator __first, iterator __last,
    525                  size_type __n, _CharT __c) {
    526     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
    527     _Base::replace(__first, __last, __n, __c);
    528     return *this;
    529   }
    530 
    531   // Check to see if _InputIter is an integer type.  If so, then
    532   // it can't be an iterator.
    533   template <class _InputIter>
    534   _Self& replace(iterator __first, iterator __last,
    535                  _InputIter __f, _InputIter __l) {
    536     _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last)
    537     typedef typename _IsIntegral<_InputIter>::_Ret _Integral;
    538     return _M_replace_dispatch(__first, __last, __f, __l, _Integral());
    539   }
    540 
    541 #if !defined (_STLP_NO_METHOD_SPECIALIZATION)
    542   _Self& replace(iterator __first, iterator __last,
    543                  const _CharT* __f, const _CharT* __l) {
    544     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
    545     _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l)
    546     return _M_replace(__first, __last, __f, __l, this->_M_inside(__f));
    547   }
    548 #endif
    549 
    550 private:                        // Helper functions for replace.
    551   _Self& _M_replace(iterator __first, iterator __last,
    552                     const _CharT* __f, const _CharT* __l, bool __self_ref) {
    553     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
    554     _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l)
    555     _Base::_M_replace(__first, __last, __f, __l, __self_ref);
    556     return *this;
    557   }
    558 
    559   template <class _Integer>
    560   _Self& _M_replace_dispatch(iterator __first, iterator __last,
    561                              _Integer __n, _Integer __x, const __true_type& /*IsIntegral*/) {
    562     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
    563     return replace(__first, __last, (size_type) __n, (_CharT) __x);
    564   }
    565 
    566   template <class _InputIter>
    567   _Self& _M_replace_dispatch(iterator __first, iterator __last,
    568                              _InputIter __f, _InputIter __l, const __false_type& /*IsIntegral*/) {
    569     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
    570     /* We are forced to do a temporary string to avoid the self referencing issue. */
    571     const _Self __self(__f, __l, this->get_allocator());
    572     return _M_replace(__first, __last, __self._M_Start(), __self._M_Finish(), false);
    573   }
    574 
    575 public:                         // Other modifier member functions.
    576   void swap(_Self& __s) { _Base::swap(__s); }
    577 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
    578   void _M_swap_workaround(_Self& __x) { swap(__x); }
    579 #endif
    580 
    581 public:                         // Substring.
    582   _Self substr(size_type __pos = 0, size_type __n = npos) const
    583   { return _Self(*this, __pos, __n, this->get_allocator()); }
    584 
    585 #if defined (_STLP_USE_TEMPLATE_EXPRESSION) && !defined (_STLP_DEBUG)
    586 #  define _STLP_STRING_SUM_BASE _STLP_NO_MEM_T_STRING_BASE
    587 #  include <stl/_string_sum_methods.h>
    588 #  undef _STLP_STRING_SUM_BASE
    589 #endif
    590 };
    591 
    592 #undef _STLP_NO_MEM_T_STRING_BASE
    593 
    594 #if defined (basic_string)
    595 _STLP_MOVE_TO_STD_NAMESPACE
    596 #  undef basic_string
    597 #endif
    598 
    599 _STLP_END_NAMESPACE
    600