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
99struct _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
120template <class _CharT, class _Traits, class _Alloc>
121class 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
130public:
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
151public:                         // 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*/
294protected:
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
346public:
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
361private:
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
384public:                         // 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
399public:                         // 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
413private:
414  void _M_reserve(size_type);
415public:
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
430public:                         // 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
449public:                         // 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
455private:
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
499public:
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
508public:
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
515public:
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
533public:
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
547public:                         // 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
567private:
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
591public:
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
600public:
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
607public:                         // 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
768public:
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)
780public:
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
787public:                         // 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
811public:                         // 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
909public:
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)
922public:
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
931public:                         // 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
947public:                         // 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
952public: // 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
965public: // 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
975public: // 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
987public: // 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
999public: // 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
1010public: // 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
1021public: // Substring.
1022  _Self substr(size_type __pos = 0, size_type __n = npos) const
1023  { return _Self(*this, __pos, __n, get_allocator()); }
1024
1025public: // 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
1070public: // 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)
1088template <class _CharT, class _Traits, class _Alloc>
1089const 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)
1120template <class _CharT, class _Traits, class _Alloc>
1121inline void _STLP_CALL
1122swap(basic_string<_CharT,_Traits,_Alloc>& __x,
1123     basic_string<_CharT,_Traits,_Alloc>& __y)
1124{ __x.swap(__y); }
1125#else
1126inline void _STLP_CALL swap(string& __x, string& __y)
1127{ __x.swap(__y); }
1128#  if defined (_STLP_HAS_WCHAR_T)
1129inline 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)
1135template <class _CharT, class _Traits, class _Alloc>
1136struct __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
1152template <class _CharT, class _Traits, class _Alloc>
1153void _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
1158wstring __ASCIIToWide(const char *ascii);
1159string __WideToASCII(const wchar_t *wide);
1160#endif
1161
1162inline 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