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
27template <class _CharT, class _Traits, class _Alloc>
28class 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{
33private:                        // 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;
37public:
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
47public:                         // 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
112private:
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
147public:                         // 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
205private:                        // 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
247public:                         // 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
276private:                        // 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
297public:
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
318public:                         // 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)
361public:
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
368private:  // 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
454public:                         // 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
470public:                         // 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
550private:                        // 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
575public:                         // 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
581public:                         // 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