]> git.buserror.net Git - polintos/scott/priv.git/blob - include/c++/stl/stl/_string_workaround.h
Add STLport 5.1.4
[polintos/scott/priv.git] / include / c++ / stl / stl / _string_workaround.h
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) && \
30     !defined (basic_string)
31                    , public __stlport_class<basic_string<_CharT, _Traits, _Alloc> >
32 #endif
33 {
34 protected:                        // Protected members inherited from base.
35   typedef basic_string<_CharT, _Traits, _Alloc> _Self;
36   typedef _STLP_NO_MEM_T_STRING_BASE _Base;
37   typedef typename _Base::_Char_Is_POD _Char_Is_POD;
38
39 public:
40
41   __IMPORT_WITH_REVERSE_ITERATORS(_Base)
42
43   typedef typename _Base::_Iterator_category _Iterator_category;
44   typedef typename _Base::traits_type traits_type;
45   typedef typename _Base::_Reserve_t _Reserve_t;
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   basic_string(__move_source<_Self> src)
75     : _STLP_NO_MEM_T_STRING_BASE(__move_source<_Base>(src.get())) {}
76
77   // Check to see if _InputIterator is an integer type.  If so, then
78   // it can't be an iterator.
79 #if !(defined(__MRC__) || (defined(__SC__) && !defined(__DMC__))) //*ty 04/30/2001 - mpw compilers choke on this ctor
80   template <class _InputIterator>
81   basic_string(_InputIterator __f, _InputIterator __l,
82                const allocator_type & __a _STLP_ALLOCATOR_TYPE_DFL)
83     : _STLP_NO_MEM_T_STRING_BASE(_Base::_CalledFromWorkaround_t(), __a) {
84     typedef typename _IsIntegral<_InputIterator>::_Ret _Integral;
85     _M_initialize_dispatch(__f, __l, _Integral());
86   }
87 #  if defined (_STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS)
88   template <class _InputIterator>
89   basic_string(_InputIterator __f, _InputIterator __l)
90     : _STLP_NO_MEM_T_STRING_BASE(_Base::_CalledFromWorkaround_t(), allocator_type()) {
91     typedef typename _IsIntegral<_InputIterator>::_Ret _Integral;
92     _M_initialize_dispatch(__f, __l, _Integral());
93   }
94 #  endif
95 #endif /* !__MRC__ || (__SC__ && !__DMC__) */
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     _STLP_TRY {
119       _M_appendT(__f, __l, __tag);
120     }
121     _STLP_UNWIND(this->_M_destroy_range())
122   }
123
124   template <class _ForwardIter>
125   void _M_range_initialize(_ForwardIter __f, _ForwardIter __l,
126                            const forward_iterator_tag &) {
127     difference_type __n = distance(__f, __l);
128     this->_M_allocate_block(__n + 1);
129 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
130     if (this->_M_using_static_buf()) {
131       _M_copyT(__f, __l, this->_M_Start());
132       this->_M_finish = this->_M_Start() + __n;
133     }
134     else
135 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
136     this->_M_finish = uninitialized_copy(__f, __l, this->_M_Start());
137     this->_M_terminate_string();
138   }
139
140   template <class _InputIter>
141   void _M_range_initializeT(_InputIter __f, _InputIter __l) {
142     _M_range_initialize(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter));
143   }
144
145   template <class _Integer>
146   void _M_initialize_dispatch(_Integer __n, _Integer __x, const __true_type& /*_Integral*/) {
147     this->_M_allocate_block(__n + 1);
148 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
149     if (this->_M_using_static_buf()) {
150       _Traits::assign(this->_M_Start(), __n, __x);
151       this->_M_finish = this->_M_Start() + __n;
152     }
153     else
154 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
155     this->_M_finish = uninitialized_fill_n(this->_M_Start(), __n, __x);
156     this->_M_terminate_string();
157   }
158
159   template <class _InputIter>
160   void _M_initialize_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*_Integral*/) {
161     _M_range_initializeT(__f, __l);
162   }
163
164 public:                         // Append, operator+=, push_back.
165   _Self& operator+=(const _Self& __s) {
166     _Base::operator+=(__s);
167     return *this;
168   }
169   _Self& operator+=(const _CharT* __s) {
170     _STLP_FIX_LITERAL_BUG(__s)
171     _Base::operator+=(__s);
172     return *this;
173   }
174   _Self& operator+=(_CharT __c) {
175     _Base::operator+=(__c);
176     return *this;
177   }
178
179   _Self& append(const _Self& __s) {
180     _Base::append(__s);
181     return *this;
182   }
183
184   _Self& append(const _Self& __s,
185                 size_type __pos, size_type __n) {
186     _Base::append(__s, __pos, __n);
187     return *this;
188   }
189
190   _Self& append(const _CharT* __s, size_type __n) {
191     _STLP_FIX_LITERAL_BUG(__s)
192     _Base::append(__s, __n);
193     return *this;
194   }
195   _Self& append(const _CharT* __s) {
196     _STLP_FIX_LITERAL_BUG(__s)
197     _Base::append(__s);
198     return *this;
199   }
200   _Self& append(size_type __n, _CharT __c) {
201     _Base::append(__n, __c);
202     return *this;
203   }
204
205   // Check to see if _InputIterator is an integer type.  If so, then
206   // it can't be an iterator.
207   template <class _InputIter>
208   _Self& append(_InputIter __first, _InputIter __last) {
209     typedef typename _IsIntegral<_InputIter>::_Ret _Integral;
210     return _M_append_dispatch(__first, __last, _Integral());
211   }
212
213 #if !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS)
214   //See equivalent assign method remark.
215   _Self& append(const _CharT* __f, const _CharT* __l) {
216     _STLP_FIX_LITERAL_BUG(__f)_STLP_FIX_LITERAL_BUG(__l)
217     _Base::append(__f, __l);
218     return *this;
219   }
220 #endif
221
222 private:                        // Helper functions for append.
223
224   template <class _InputIter>
225   _Self& _M_appendT(_InputIter __first, _InputIter __last,
226                    const input_iterator_tag &) {
227     for ( ; __first != __last ; ++__first)
228       _Base::push_back(*__first);
229     return *this;
230   }
231
232   template <class _ForwardIter>
233   _Self& _M_appendT(_ForwardIter __first, _ForwardIter __last,
234                     const forward_iterator_tag &)  {
235     if (__first != __last) {
236       const size_type __old_size = this->size();
237       difference_type __n = distance(__first, __last);
238       if (__STATIC_CAST(size_type,__n) > max_size() || __old_size > max_size() - __STATIC_CAST(size_type,__n))
239         this->_M_throw_length_error();
240       if (__old_size + __n > capacity()) {
241         const size_type __len = __old_size +
242           (max)(__old_size, __STATIC_CAST(size_type,__n)) + 1;
243         pointer __new_start = this->_M_end_of_storage.allocate(__len);
244         pointer __new_finish = __new_start;
245         _STLP_TRY {
246           __new_finish = uninitialized_copy(this->_M_Start(), this->_M_Finish(), __new_start);
247           __new_finish = uninitialized_copy(__first, __last, __new_finish);
248           _M_construct_null(__new_finish);
249         }
250         _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish),
251           this->_M_end_of_storage.deallocate(__new_start,__len)))
252           this->_M_destroy_range();
253         this->_M_deallocate_block();
254         this->_M_reset(__new_start, __new_finish, __new_start + __len);
255       }
256       else {
257         _ForwardIter __f1 = __first;
258         ++__f1;
259 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
260         if (this->_M_using_static_buf())
261           _M_copyT(__f1, __last, this->_M_Finish() + 1);
262         else
263 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
264           uninitialized_copy(__f1, __last, this->_M_Finish() + 1);
265         _STLP_TRY {
266           this->_M_construct_null(this->_M_Finish() + __n);
267         }
268         _STLP_UNWIND(this->_M_destroy_ptr_range(this->_M_Finish() + 1, this->_M_Finish() + __n))
269         _Traits::assign(*this->_M_finish, *__first);
270         this->_M_finish += __n;
271       }
272     }
273     return *this;
274   }
275
276   template <class _Integer>
277   _Self& _M_append_dispatch(_Integer __n, _Integer __x, const __true_type& /*Integral*/) {
278     return append((size_type) __n, (_CharT) __x);
279   }
280
281   template <class _InputIter>
282   _Self& _M_append_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*Integral*/) {
283     return _M_appendT(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter));
284   }
285
286 public:                         // Assign
287
288   _Self& assign(const _Self& __s) {
289     _Base::assign(__s);
290     return *this;
291   }
292
293   _Self& assign(const _Self& __s,
294                 size_type __pos, size_type __n) {
295     _Base::assign(__s, __pos, __n);
296     return *this;
297   }
298
299   _Self& assign(const _CharT* __s, size_type __n) {
300     _STLP_FIX_LITERAL_BUG(__s)
301     _Base::assign(__s, __n);
302     return *this;
303   }
304
305   _Self& assign(const _CharT* __s) {
306     _STLP_FIX_LITERAL_BUG(__s)
307     _Base::assign(__s);
308     return *this;
309   }
310
311   _Self& assign(size_type __n, _CharT __c) {
312     _Base::assign(__n, __c);
313     return *this;
314   }
315
316 private:                        // Helper functions for assign.
317
318   template <class _Integer>
319   _Self& _M_assign_dispatch(_Integer __n, _Integer __x, const __true_type& /*_Integral*/) {
320     return assign((size_type) __n, (_CharT) __x);
321   }
322
323   template <class _InputIter>
324   _Self& _M_assign_dispatch(_InputIter __f, _InputIter __l, const __false_type& /*_Integral*/)  {
325     pointer __cur = this->_M_Start();
326     while (__f != __l && __cur != this->_M_Finish()) {
327       _Traits::assign(*__cur, *__f);
328       ++__f;
329       ++__cur;
330     }
331     if (__f == __l)
332       _Base::erase(__cur, this->_M_Finish());
333     else
334       _M_appendT(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter));
335     return *this;
336   }
337
338 public:
339   // Check to see if _InputIterator is an integer type.  If so, then
340   // it can't be an iterator.
341   template <class _InputIter>
342   _Self& assign(_InputIter __first, _InputIter __last) {
343     typedef typename _IsIntegral<_InputIter>::_Ret _Integral;
344     return _M_assign_dispatch(__first, __last, _Integral());
345   }
346
347 #if !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS)
348   /* This method is not part of the standard and is a specialization of the
349    * template method assign. It is only granted for convenience to call assign
350    * with mixed parameters iterator and const_iterator.
351    */
352   _Self& assign(const _CharT* __f, const _CharT* __l) {
353     _STLP_FIX_LITERAL_BUG(__f)_STLP_FIX_LITERAL_BUG(__l)
354     _Base::assign(__f, __l);
355     return *this;
356   }
357 #endif
358
359 public:                         // Insert
360
361   _Self& insert(size_type __pos, const _Self& __s) {
362     _Base::insert(__pos, __s);
363     return *this;
364   }
365
366   _Self& insert(size_type __pos, const _Self& __s,
367                 size_type __beg, size_type __n) {
368     _Base::insert(__pos, __s, __beg, __n);
369     return *this;
370   }
371   _Self& insert(size_type __pos, const _CharT* __s, size_type __n) {
372     _STLP_FIX_LITERAL_BUG(__s)
373     _Base::insert(__pos, __s, __n);
374     return *this;
375   }
376
377   _Self& insert(size_type __pos, const _CharT* __s) {
378     _STLP_FIX_LITERAL_BUG(__s)
379     _Base::insert(__pos, __s);
380     return *this;
381   }
382
383   _Self& insert(size_type __pos, size_type __n, _CharT __c) {
384     _Base::insert(__pos, __n, __c);
385     return *this;
386   }
387
388   iterator insert(iterator __p, _CharT __c) {
389     return _Base::insert(__p, __c);
390   }
391
392   void insert(iterator __p, size_t __n, _CharT __c) {
393     _Base::insert(__p, __n, __c);
394   }
395
396   // Check to see if _InputIterator is an integer type.  If so, then
397   // it can't be an iterator.
398   template <class _InputIter>
399   void insert(iterator __p, _InputIter __first, _InputIter __last) {
400     typedef typename _IsIntegral<_InputIter>::_Ret _Integral;
401     _M_insert_dispatch(__p, __first, __last, _Integral());
402   }
403
404 private:  // Helper functions for insert.
405
406   void _M_insert(iterator __p, const _CharT* __f, const _CharT* __l, bool __self_ref) {
407     _STLP_FIX_LITERAL_BUG(__f)_STLP_FIX_LITERAL_BUG(__l)
408     _Base::_M_insert(__p, __f, __l, __self_ref);
409   }
410
411   template <class _ForwardIter>
412   void _M_insert_overflow(iterator __position, _ForwardIter __first, _ForwardIter __last,
413                           difference_type __n) {
414     const size_type __old_size = this->size();
415     const size_type __len = __old_size + (max)(__old_size, __STATIC_CAST(size_type,__n)) + 1;
416     pointer __new_start = this->_M_end_of_storage.allocate(__len);
417     pointer __new_finish = __new_start;
418     _STLP_TRY {
419       __new_finish = uninitialized_copy(this->_M_Start(), __position, __new_start);
420       __new_finish = uninitialized_copy(__first, __last, __new_finish);
421       __new_finish = uninitialized_copy(__position, this->_M_Finish(), __new_finish);
422       this->_M_construct_null(__new_finish);
423     }
424     _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish),
425                   this->_M_end_of_storage.deallocate(__new_start,__len)))
426     this->_M_destroy_range();
427     this->_M_deallocate_block();
428     this->_M_reset(__new_start, __new_finish, __new_start + __len);
429   }
430
431   template <class _InputIter>
432   void _M_insertT(iterator __p, _InputIter __first, _InputIter __last,
433                   const input_iterator_tag &) {
434     for ( ; __first != __last; ++__first) {
435       __p = insert(__p, *__first);
436       ++__p;
437     }
438   }
439
440   template <class _ForwardIter>
441   void _M_insertT(iterator __position, _ForwardIter __first, _ForwardIter __last,
442                   const forward_iterator_tag &) {
443     if (__first != __last) {
444       difference_type __n = distance(__first, __last);
445       if (this->_M_end_of_storage._M_data - this->_M_finish >= __n + 1) {
446         const difference_type __elems_after = this->_M_finish - __position;
447         if (__elems_after >= __n) {
448 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
449           if (this->_M_using_static_buf())
450             _Base::_M_copy((this->_M_Finish() - __n) + 1, this->_M_Finish() + 1, this->_M_Finish() + 1);
451           else
452 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
453           uninitialized_copy((this->_M_Finish() - __n) + 1, this->_M_Finish() + 1, this->_M_Finish() + 1);
454           this->_M_finish += __n;
455           _Traits::move(__position + __n, __position, (__elems_after - __n) + 1);
456           _M_copyT(__first, __last, __position);
457         }
458         else {
459           pointer __old_finish = this->_M_Finish();
460           _ForwardIter __mid = __first;
461           advance(__mid, __elems_after + 1);
462 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
463           if (this->_M_using_static_buf())
464             _M_copyT(__mid, __last, this->_M_Finish() + 1);
465           else
466 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
467           uninitialized_copy(__mid, __last, this->_M_Finish() + 1);
468           this->_M_finish += __n - __elems_after;
469           _STLP_TRY {
470 #if defined (_STLP_USE_SHORT_STRING_OPTIM)
471             if (this->_M_using_static_buf())
472               _Base::_M_copy(__position, __old_finish + 1, this->_M_Finish());
473             else
474 #endif /* _STLP_USE_SHORT_STRING_OPTIM */
475             uninitialized_copy(__position, __old_finish + 1, this->_M_Finish());
476             this->_M_finish += __elems_after;
477           }
478           _STLP_UNWIND((this->_M_destroy_ptr_range(__old_finish + 1, this->_M_Finish()),
479                         this->_M_finish = __old_finish))
480           _M_copyT(__first, __mid, __position);
481         }
482       }
483       else {
484         _M_insert_overflow(__position, __first, __last, __n);
485       }
486     }
487   }
488
489   template <class _Integer>
490   void _M_insert_dispatch(iterator __p, _Integer __n, _Integer __x,
491                           const __true_type& /*Integral*/) {
492     insert(__p, (size_type) __n, (_CharT) __x);
493   }
494
495   template <class _InputIter>
496   void _M_insert_dispatch(iterator __p, _InputIter __first, _InputIter __last,
497                           const __false_type& /*Integral*/) {
498     _STLP_FIX_LITERAL_BUG(__p)
499     /*
500      * Within the basic_string implementation we are only going to check for
501      * self referencing if iterators are string iterators or _CharT pointers.
502      * A user could encapsulate those iterator within their own iterator interface
503      * and in this case lead to a bad behavior, this is a known limitation.
504      */
505     typedef typename _AreSameUnCVTypes<_InputIter, iterator>::_Ret _IsIterator;
506     typedef typename _AreSameUnCVTypes<_InputIter, const_iterator>::_Ret _IsConstIterator;
507     typedef typename _Lor2<_IsIterator, _IsConstIterator>::_Ret _CheckInside;
508     _M_insert_aux(__p, __first, __last, _CheckInside());
509   }
510
511   template <class _RandomIter>
512   void _M_insert_aux (iterator __p, _RandomIter __first, _RandomIter __last,
513                       const __true_type& /*_CheckInside*/) {
514     _STLP_FIX_LITERAL_BUG(__p)
515     _M_insert(__p, &(*__first), &(*__last), _Base::_M_inside(&(*__first)));
516   }
517
518   template<class _InputIter>
519   void _M_insert_aux (iterator __p, _InputIter __first, _InputIter __last,
520                       const __false_type& /*_CheckInside*/) {
521     _STLP_FIX_LITERAL_BUG(__p)
522     _M_insertT(__p, __first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIter));
523   }
524
525   template <class _InputIterator>
526   void _M_copyT(_InputIterator __first, _InputIterator __last, pointer __result) {
527     _STLP_FIX_LITERAL_BUG(__p)
528     for ( ; __first != __last; ++__first, ++__result)
529       _Traits::assign(*__result, *__first);
530   }
531
532 #if !defined (_STLP_NO_METHOD_SPECIALIZATION)
533   void _M_copyT(const _CharT* __f, const _CharT* __l, _CharT* __res) {
534     _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l) _STLP_FIX_LITERAL_BUG(__res)
535     _Base::_M_copy(__f, __l, __res);
536   }
537 #endif
538
539 public:                         // Erase.
540
541   _Self& erase(size_type __pos = 0, size_type __n = npos) {
542     _Base::erase(__pos, __n);
543     return *this;
544   }
545
546   iterator erase(iterator __pos) {
547     _STLP_FIX_LITERAL_BUG(__pos)
548     return _Base::erase(__pos);
549   }
550
551   iterator erase(iterator __first, iterator __last) {
552     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
553     return _Base::erase(__first, __last);
554   }
555
556 public:                         // Replace.  (Conceptually equivalent
557                                 // to erase followed by insert.)
558   _Self& replace(size_type __pos, size_type __n, const _Self& __s) {
559     _Base::replace(__pos, __n, __s);
560     return *this;
561   }
562
563   _Self& replace(size_type __pos1, size_type __n1, const _Self& __s,
564                  size_type __pos2, size_type __n2) {
565     _Base::replace(__pos1, __n1, __s, __pos2, __n2);
566     return *this;
567   }
568
569   _Self& replace(size_type __pos, size_type __n1,
570                  const _CharT* __s, size_type __n2) {
571     _STLP_FIX_LITERAL_BUG(__s)
572     _Base::replace(__pos, __n1, __s, __n2);
573     return *this;
574   }
575
576   _Self& replace(size_type __pos, size_type __n1, const _CharT* __s) {
577     _STLP_FIX_LITERAL_BUG(__s)
578     _Base::replace(__pos, __n1, __s);
579     return *this;
580   }
581
582   _Self& replace(size_type __pos, size_type __n1,
583                  size_type __n2, _CharT __c) {
584     _Base::replace(__pos, __n1, __n2, __c);
585     return *this;
586   }
587
588   _Self& replace(iterator __first, iterator __last, const _Self& __s) {
589     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
590     _Base::replace(__first, __last, __s);
591     return *this;
592   }
593
594   _Self& replace(iterator __first, iterator __last,
595                  const _CharT* __s, size_type __n) {
596     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
597     _STLP_FIX_LITERAL_BUG(__s)
598     _Base::replace(__first, __last, __s, __n);
599     return *this;
600   }
601
602   _Self& replace(iterator __first, iterator __last,
603                  const _CharT* __s) {
604     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
605     _STLP_FIX_LITERAL_BUG(__s)
606     _Base::replace(__first, __last, __s);
607     return *this;
608   }
609
610   _Self& replace(iterator __first, iterator __last,
611                  size_type __n, _CharT __c) {
612     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
613     _Base::replace(__first, __last, __n, __c);
614     return *this;
615   }
616
617   // Check to see if _InputIter is an integer type.  If so, then
618   // it can't be an iterator.
619   template <class _InputIter>
620   _Self& replace(iterator __first, iterator __last,
621                  _InputIter __f, _InputIter __l) {
622     _STLP_FIX_LITERAL_BUG(__first)_STLP_FIX_LITERAL_BUG(__last)
623     typedef typename _IsIntegral<_InputIter>::_Ret _Integral;
624     return _M_replace_dispatch(__first, __last, __f, __l,  _Integral());
625   }
626
627 #if !defined (_STLP_NO_METHOD_SPECIALIZATION) && !defined (_STLP_NO_EXTENSIONS)
628   _Self& replace(iterator __first, iterator __last,
629                  const _CharT* __f, const _CharT* __l) {
630     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
631     _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l)
632     _Base::replace(__first, __last, __f, __l);
633     return *this;
634   }
635 #endif
636
637 protected:                        // Helper functions for replace.
638   _Self& _M_replace(iterator __first, iterator __last,
639                     const _CharT* __f, const _CharT* __l, bool __self_ref) {
640     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
641     _STLP_FIX_LITERAL_BUG(__f) _STLP_FIX_LITERAL_BUG(__l)
642     _Base::_M_replace(__first, __last, __f, __l, __self_ref);
643     return *this;
644   }
645
646   template <class _Integer>
647   _Self& _M_replace_dispatch(iterator __first, iterator __last,
648                              _Integer __n, _Integer __x, const __true_type& /*IsIntegral*/) {
649     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
650     return replace(__first, __last, (size_type) __n, (_CharT) __x);
651   }
652
653   template <class _InputIter>
654   _Self& _M_replace_dispatch(iterator __first, iterator __last,
655                              _InputIter __f, _InputIter __l, const __false_type& /*IsIntegral*/) {
656     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
657     typedef typename _AreSameUnCVTypes<_InputIter, iterator>::_Ret _IsIterator;
658     typedef typename _AreSameUnCVTypes<_InputIter, const_iterator>::_Ret _IsConstIterator;
659     typedef typename _Lor2<_IsIterator, _IsConstIterator>::_Ret _CheckInside;
660     return _M_replace_aux(__first, __last, __f, __l, _CheckInside());
661   }
662
663   template <class _RandomIter>
664   _Self& _M_replace_aux(iterator __first, iterator __last,
665                         _RandomIter __f, _RandomIter __l, __true_type const& /*_CheckInside*/) {
666     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
667     return _M_replace(__first, __last, &(*__f), &(*__l), _Base::_M_inside(&(*__f)));
668   }
669
670   template <class _InputIter>
671   _Self& _M_replace_aux(iterator __first, iterator __last,
672                      _InputIter __f, _InputIter __l, __false_type const& /*_CheckInside*/) {
673     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
674     return _M_replaceT(__first, __last, __f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter));
675   }
676
677   template <class _InputIter>
678   _Self& _M_replaceT(iterator __first, iterator __last,
679                      _InputIter __f, _InputIter __l, const input_iterator_tag&__ite_tag) {
680     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
681     for ( ; __first != __last && __f != __l; ++__first, ++__f)
682       _Traits::assign(*__first, *__f);
683     if (__f == __l)
684       _Base::erase(__first, __last);
685     else
686       _M_insertT(__last, __f, __l, __ite_tag);
687     return *this;
688   }
689
690   template <class _ForwardIter>
691   _Self& _M_replaceT(iterator __first, iterator __last,
692                      _ForwardIter __f, _ForwardIter __l, const forward_iterator_tag &__ite_tag) {
693     _STLP_FIX_LITERAL_BUG(__first) _STLP_FIX_LITERAL_BUG(__last)
694     difference_type __n = distance(__f, __l);
695     const difference_type __len = __last - __first;
696     if (__len >= __n) {
697       _M_copyT(__f, __l, __first);
698       _Base::erase(__first + __n, __last);
699     }
700     else {
701       _ForwardIter __m = __f;
702       advance(__m, __len);
703       _M_copyT(__f, __m, __first);
704       _M_insertT(__last, __m, __l, __ite_tag);
705     }
706     return *this;
707   }
708
709 public:                         // Other modifier member functions.
710
711   void swap(_Self& __s)
712   { _Base::swap(__s); }
713
714 public:                         // Substring.
715
716   _Self substr(size_type __pos = 0, size_type __n = npos) const
717   { return _Self(*this, __pos, __n, get_allocator()); }
718
719 #if defined (_STLP_USE_TEMPLATE_EXPRESSION) && !defined (_STLP_DEBUG)
720 #  define _STLP_STRING_SUM_BASE _STLP_NO_MEM_T_STRING_BASE
721 #  include <stl/_string_sum_methods.h>
722 #  undef _STLP_STRING_SUM_BASE
723 #endif
724 };
725
726 #undef _STLP_NO_MEM_T_STRING_BASE
727
728 #if defined (basic_string)
729 _STLP_MOVE_TO_STD_NAMESPACE
730 #  undef basic_string
731 #endif
732
733 _STLP_END_NAMESPACE