_string.h

00001 /*
00002  * Copyright (c) 1997-1999
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Copyright (c) 1999 
00006  * Boris Fomitchev
00007  *
00008  * This material is provided "as is", with absolutely no warranty expressed
00009  * or implied. Any use is at your own risk.
00010  *
00011  * Permission to use or copy this software for any purpose is hereby granted 
00012  * without fee, provided the above notices are retained on all copies.
00013  * Permission to modify the code and to distribute modified code is granted,
00014  * provided the above notices are retained, and a notice that the code was
00015  * modified is included with the above copyright notice.
00016  *
00017  */
00018 
00019 #ifndef _STLP_STRING_H
00020 #define _STLP_STRING_H
00021 
00022 #ifndef _STLP_MEMORY
00023 # include <memory> 
00024 #endif
00025 
00026 # ifndef _STLP_CCTYPE
00027 #  include <cctype> 
00028 # endif
00029 
00030 #ifndef _STLP_STRING_FWD_H
00031 #  include <stl/_string_fwd.h> 
00032 #endif
00033 
00034 #ifndef _STLP_INTERNAL_FUNCTION_BASE_H
00035 # include <stl/_function.h> 
00036 #endif
00037 
00038 # include <stl/_ctraits_fns.h>  
00039 #ifndef _STLP_INTERNAL_ALGOBASE_H
00040 # include <stl/_algobase.h> 
00041 #endif
00042 
00043 #ifndef _STLP_INTERNAL_ITERATOR_H
00044 # include <stl/_iterator.h> 
00045 #endif
00046 
00047 #if defined( __MWERKS__ ) && ! defined (_STLP_USE_OWN_NAMESPACE)
00048 
00049 // MSL implementation classes expect to see the definition of streampos
00050 // when this header is included. We expect this to be fixed in later MSL
00051 // implementations
00052 # if !defined( __MSL_CPP__ ) || __MSL_CPP__ < 0x4105
00053 #  include <stl/msl_string.h> 
00054 # endif
00055 
00056 #endif // __MWERKS__
00057 
00058 // Standard C++ string class.  This class has performance
00059 // characteristics very much like vector<>, meaning, for example, that
00060 // it does not perform reference-count or copy-on-write, and that
00061 // concatenation of two strings is an O(N) operation. 
00062 
00063 // There are three reasons why basic_string is not identical to
00064 // vector.  First, basic_string always stores a null character at the
00065 // end; this makes it possible for c_str to be a fast operation.
00066 // Second, the C++ standard requires basic_string to copy elements
00067 // using char_traits<>::assign, char_traits<>::copy, and
00068 // char_traits<>::move.  This means that all of vector<>'s low-level
00069 // operations must be rewritten.  Third, basic_string<> has a lot of
00070 // extra functions in its interface that are convenient but, strictly
00071 // speaking, redundant.
00072 
00073 // Additionally, the C++ standard imposes a major restriction: according
00074 // to the standard, the character type _CharT must be a POD type.  This
00075 // implementation weakens that restriction, and allows _CharT to be a
00076 // a user-defined non-POD type.  However, _CharT must still have a
00077 // default constructor.
00078 
00079 _STLP_BEGIN_NAMESPACE
00080 
00081 # ifdef _STLP_DEBUG
00082 #  define basic_string _Nondebug_string
00083 # endif
00084 
00085 // A helper class to use a char_traits as a function object.
00086 
00087 template <class _Traits> struct _Not_within_traits
00088   : public unary_function<typename _Traits::char_type, bool> {
00089   typedef typename _Traits::char_type _CharT;
00090   const _CharT* _M_first;
00091   const _CharT* _M_last;
00092 
00093   _Not_within_traits(const typename _Traits::char_type* __f, 
00094                      const typename _Traits::char_type* __l) 
00095     : _M_first(__f), _M_last(__l) {}
00096 
00097   bool operator()(const typename _Traits::char_type& __x) const {
00098     return find_if((_CharT*)_M_first, (_CharT*)_M_last, 
00099                    _Eq_char_bound<_Traits>(__x)) == (_CharT*)_M_last;
00100   }
00101 };
00102 
00103 // ------------------------------------------------------------
00104 // Class _String_base.  
00105 
00106 // _String_base is a helper class that makes it it easier to write an
00107 // exception-safe version of basic_string.  The constructor allocates,
00108 // but does not initialize, a block of memory.  The destructor
00109 // deallocates, but does not destroy elements within, a block of
00110 // memory.  The destructor assumes that _M_start either is null, or else
00111 // points to a block of memory that was allocated using _String_base's 
00112 // allocator and whose size is _M_end_of_storage._M_data - _M_start.
00113 
00114 template <class _Tp, class _Alloc> class _String_base {
00115 public:
00116   _STLP_FORCE_ALLOCATORS(_Tp, _Alloc)
00117   typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
00118   _Tp*    _M_start;
00119   _Tp*    _M_finish;
00120   _STLP_alloc_proxy<_Tp*, _Tp, allocator_type> _M_end_of_storage;
00121                                 // Precondition: 0 < __n <= max_size().
00122   void _M_allocate_block(size_t);
00123   void _M_deallocate_block() 
00124     { _M_end_of_storage.deallocate(_M_start, _M_end_of_storage._M_data - _M_start); }
00125   
00126   size_t max_size() const { return (size_t(-1) / sizeof(_Tp)) - 1; }
00127 
00128   _String_base(const allocator_type& __a)
00129     : _M_start(0), _M_finish(0), _M_end_of_storage(__a, (_Tp*)0) {}
00130   
00131   _String_base(const allocator_type& __a, size_t __n)
00132     : _M_start(0), _M_finish(0), _M_end_of_storage(__a, (_Tp*)0)
00133     { _M_allocate_block(__n); }
00134 
00135   ~_String_base() { _M_deallocate_block(); }
00136 
00137   void _M_throw_length_error() const;
00138   void _M_throw_out_of_range() const;
00139 };
00140 
00141 # if defined (_STLP_USE_TEMPLATE_EXPORT)
00142 _STLP_EXPORT_TEMPLATE_CLASS _String_base<char, allocator<char> >;
00143 #  if defined (_STLP_HAS_WCHAR_T)
00144 _STLP_EXPORT_TEMPLATE_CLASS _String_base<wchar_t, allocator<wchar_t> >;
00145 #  endif
00146 # endif /* _STLP_USE_TEMPLATE_EXPORT */
00147 
00148 // ------------------------------------------------------------
00149 // Class basic_string.  
00150 
00151 // Class invariants:
00152 // (1) [start, finish) is a valid range.
00153 // (2) Each iterator in [start, finish) points to a valid object
00154 //     of type value_type.
00155 // (3) *finish is a valid object of type value_type; in particular,
00156 //     it is value_type().
00157 // (4) [finish + 1, end_of_storage) is a valid range.
00158 // (5) Each iterator in [finish + 1, end_of_storage) points to 
00159 //     unininitialized memory.
00160 
00161 // Note one important consequence: a string of length n must manage
00162 // a block of memory whose size is at least n + 1.  
00163 
00164 struct _String_reserve_t {};
00165 
00166 template <class _CharT, class _Traits, class _Alloc> class basic_string : protected _String_base<_CharT,_Alloc> {
00167 private:                        // Protected members inherited from base.
00168   typedef _String_base<_CharT,_Alloc> _Base;
00169   typedef basic_string<_CharT, _Traits, _Alloc> _Self;
00170   // fbp : used to optimize char/wchar_t cases, and to simplify
00171   // _STLP_DEFAULT_CONSTRUCTOR_BUG problem workaround
00172   typedef typename _Is_integer<_CharT>::_Integral _Char_Is_Integral;
00173 public:
00174   typedef _CharT value_type;
00175   typedef _Traits traits_type;
00176 
00177   typedef value_type* pointer;
00178   typedef const value_type* const_pointer;
00179   typedef value_type& reference;
00180   typedef const value_type& const_reference;
00181   typedef size_t size_type;
00182   typedef ptrdiff_t difference_type;
00183   typedef random_access_iterator_tag _Iterator_category;
00184 
00185   typedef const value_type*                const_iterator;
00186   typedef value_type*                      iterator;
00187 
00188   _STLP_DECLARE_RANDOM_ACCESS_REVERSE_ITERATORS;
00189 
00190 # ifdef _STLP_STATIC_CONST_INIT_BUG
00191   enum { npos = -1 };
00192 # else
00193   static const size_t npos = ~(size_t)0;
00194 # endif
00195 
00196   typedef _String_reserve_t _Reserve_t;
00197 # if defined (_STLP_USE_NATIVE_STRING) && ! defined (_STLP_DEBUG)
00198 #  if (defined(__IBMCPP__) && (500 <= __IBMCPP__) && (__IBMCPP__ < 600) )
00199    // this typedef is being used for conversions
00200    typedef typename _STLP_VENDOR_STD::basic_string<_CharT,_Traits, 
00201     typename _STLP_VENDOR_STD::allocator<_CharT> > __std_string;
00202 #  else
00203    // this typedef is being used for conversions
00204    typedef _STLP_VENDOR_STD::basic_string<_CharT,_Traits, 
00205     _STLP_VENDOR_STD::allocator<_CharT> > __std_string;
00206 #  endif
00207 # endif
00208   
00209 public:                         // Constructor, destructor, assignment.
00210   typedef typename _String_base<_CharT,_Alloc>::allocator_type allocator_type;
00211 
00212   allocator_type get_allocator() const {
00213     return _STLP_CONVERT_ALLOCATOR((const allocator_type&)this->_M_end_of_storage, _CharT);
00214   }
00215 
00216   basic_string();
00217 
00218   explicit basic_string(const allocator_type& __a)
00219     : _String_base<_CharT,_Alloc>(__a, 8) { 
00220     _M_terminate_string(); 
00221   }
00222 
00223   basic_string(_Reserve_t, size_t __n,
00224                const allocator_type& __a = allocator_type())
00225     : _String_base<_CharT,_Alloc>(__a, __n + 1) { 
00226     _M_terminate_string(); 
00227   }
00228 
00229   basic_string(const basic_string<_CharT, _Traits, _Alloc>&);
00230 
00231   basic_string(const _Self& __s, size_type __pos, size_type __n = npos,
00232                const allocator_type& __a = allocator_type()) 
00233     : _String_base<_CharT,_Alloc>(__a) {
00234     if (__pos > __s.size())
00235       this->_M_throw_out_of_range();
00236     else
00237       _M_range_initialize(__s._M_start + __pos,
00238                           __s._M_start + __pos + (min) (__n, __s.size() - __pos));
00239   }
00240 
00241   basic_string(const _CharT* __s, size_type __n,
00242                const allocator_type& __a = allocator_type()) 
00243     : _String_base<_CharT,_Alloc>(__a) 
00244     { 
00245       _STLP_FIX_LITERAL_BUG(__s)
00246       _M_range_initialize(__s, __s + __n); 
00247     }
00248 
00249   basic_string(const _CharT* __s,
00250                const allocator_type& __a = allocator_type());
00251 
00252   basic_string(size_type __n, _CharT __c,
00253                const allocator_type& __a = allocator_type())
00254     : _String_base<_CharT,_Alloc>(__a, __n + 1)
00255   {
00256     this->_M_finish = uninitialized_fill_n(this->_M_start, __n, __c);
00257     _M_terminate_string();
00258   }
00259 
00260   // Check to see if _InputIterator is an integer type.  If so, then
00261   // it can't be an iterator.
00262 #if defined (_STLP_MEMBER_TEMPLATES) && !(defined(__MRC__)||defined(__SC__))            //*ty 04/30/2001 - mpw compilers choke on this ctor
00263 # ifdef _STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS
00264   template <class _InputIterator> basic_string(_InputIterator __f, _InputIterator __l)
00265     : _String_base<_CharT,_Alloc>(allocator_type())
00266   {
00267     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00268     _M_initialize_dispatch(__f, __l, _Integral());
00269   }
00270 # endif
00271   template <class _InputIterator> basic_string(_InputIterator __f, _InputIterator __l,
00272                const allocator_type & __a _STLP_ALLOCATOR_TYPE_DFL)
00273     : _String_base<_CharT,_Alloc>(__a)
00274   {
00275     typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00276     _M_initialize_dispatch(__f, __l, _Integral());
00277   }
00278 #else /* _STLP_MEMBER_TEMPLATES */
00279 
00280   basic_string(const _CharT* __f, const _CharT* __l,
00281                const allocator_type& __a = allocator_type())
00282     : _String_base<_CharT,_Alloc>(__a)
00283   {
00284     _STLP_FIX_LITERAL_BUG(__f)  _STLP_FIX_LITERAL_BUG(__l)
00285     _M_range_initialize(__f, __l);
00286   }
00287 
00288 #endif
00289 
00290 # if defined (_STLP_USE_NATIVE_STRING) && ! defined (_STLP_DEBUG)
00291   // these conversion operations still needed for
00292   // strstream, etc.
00293   basic_string (const __std_string& __x): _String_base<_CharT,_Alloc>(allocator_type())
00294     {
00295       const _CharT* __s = __x.data();
00296       _M_range_initialize(__s, __s + __x.size()); 
00297     }
00298   
00299   operator __std_string() const { return __std_string(this->data(), this->size()); }
00300 # endif
00301 
00302   ~basic_string() { _Destroy(this->_M_start, this->_M_finish + 1); }
00303     
00304   _Self& operator=(const _Self& __s) {
00305     if (&__s != this) 
00306       assign(__s._M_start, __s._M_finish);
00307     return *this;
00308   }
00309 
00310   _Self& operator=(const _CharT* __s) { 
00311     _STLP_FIX_LITERAL_BUG(__s)
00312     return assign(__s, __s + traits_type::length(__s)); 
00313   }
00314 
00315   _Self& operator=(_CharT __c)
00316     { return assign(__STATIC_CAST(size_type,1), __c); }
00317 
00318   static _CharT _STLP_CALL _M_null() {
00319     return _STLP_DEFAULT_CONSTRUCTED(_CharT);
00320   }
00321 
00322 private:                        // Helper functions used by constructors
00323                                 // and elsewhere.
00324   // fbp : simplify integer types (char, wchar)
00325   void _M_construct_null_aux(_CharT* __p, const __false_type&) {
00326     _Construct(__p);
00327   }
00328   void _M_construct_null_aux(_CharT* __p, const __true_type&) {
00329     *__p = 0;
00330   }
00331 
00332   void _M_construct_null(_CharT* __p) {
00333     _M_construct_null_aux(__p, _Char_Is_Integral());
00334   }
00335 
00336 private:                        
00337   // Helper functions used by constructors.  It is a severe error for
00338   // any of them to be called anywhere except from within constructors.
00339 
00340   void _M_terminate_string_aux(const __false_type&) {
00341     _STLP_TRY {
00342       _M_construct_null(this->_M_finish);
00343     }
00344     _STLP_UNWIND(_Destroy(this->_M_start, this->_M_finish));
00345   }
00346 
00347   void _M_terminate_string_aux(const __true_type&) {
00348     *(this->_M_finish)=0;
00349   }
00350 
00351   void _M_terminate_string() {
00352     _M_terminate_string_aux(_Char_Is_Integral());
00353   }
00354 
00355 #ifdef _STLP_MEMBER_TEMPLATES
00356     
00357   template <class _InputIter> void _M_range_initialize(_InputIter __f, _InputIter __l,
00358                            const input_iterator_tag &) {
00359     this->_M_allocate_block(8);
00360     _M_construct_null(this->_M_finish);
00361     _STLP_TRY {
00362       append(__f, __l);
00363     }
00364     _STLP_UNWIND(_Destroy(this->_M_start, this->_M_finish + 1));
00365   }
00366 
00367   template <class _ForwardIter> void _M_range_initialize(_ForwardIter __f, _ForwardIter __l, 
00368                            const forward_iterator_tag &) {
00369     difference_type __n = distance(__f, __l);
00370     this->_M_allocate_block(__n + 1);
00371     this->_M_finish = uninitialized_copy(__f, __l, this->_M_start);
00372     _M_terminate_string();
00373   }
00374 
00375   template <class _InputIter> void _M_range_initialize(_InputIter __f, _InputIter __l) {
00376     _M_range_initialize(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter));
00377   }
00378 
00379   template <class _Integer> void _M_initialize_dispatch(_Integer __n, _Integer __x, const __true_type&) {
00380     this->_M_allocate_block(__n + 1);
00381     this->_M_finish = uninitialized_fill_n(this->_M_start, __n, __x);
00382     _M_terminate_string();
00383   }
00384 
00385   template <class _InputIter> void _M_initialize_dispatch(_InputIter __f, _InputIter __l, const __false_type&) {
00386      _M_range_initialize(__f, __l);
00387   }
00388     
00389 #else /* _STLP_MEMBER_TEMPLATES */
00390 
00391   void _M_range_initialize(const _CharT* __f, const _CharT* __l) {
00392     ptrdiff_t __n = __l - __f;
00393     this->_M_allocate_block(__n + 1);
00394     this->_M_finish = uninitialized_copy(__f, __l, this->_M_start);
00395     _M_terminate_string();
00396   }
00397 
00398 #endif /* _STLP_MEMBER_TEMPLATES */
00399 
00400 public:                         // Iterators.
00401   iterator begin()             { return this->_M_start; }
00402   iterator end()               { return this->_M_finish; }
00403   const_iterator begin() const { return this->_M_start; }
00404   const_iterator end()   const { return this->_M_finish; }  
00405 
00406   reverse_iterator rbegin()             
00407     { return reverse_iterator(this->_M_finish); }
00408   reverse_iterator rend()               
00409     { return reverse_iterator(this->_M_start); }
00410   const_reverse_iterator rbegin() const 
00411     { return const_reverse_iterator(this->_M_finish); }
00412   const_reverse_iterator rend()   const 
00413     { return const_reverse_iterator(this->_M_start); }
00414 
00415 public:                         // Size, capacity, etc.
00416   size_type size() const { return this->_M_finish - this->_M_start; }
00417   size_type length() const { return size(); }
00418 
00419   size_t max_size() const { return _Base::max_size(); }
00420 
00421 
00422   void resize(size_type __n, _CharT __c) {
00423     if (__n <= size())
00424       erase(begin() + __n, end());
00425     else
00426       append(__n - size(), __c);
00427   }
00428   void resize(size_type __n) { resize(__n, _M_null()); }
00429 
00430   void reserve(size_type = 0);
00431 
00432   size_type capacity() const { return (this->_M_end_of_storage._M_data - this->_M_start) - 1; }
00433 
00434   void clear() {
00435     if (!empty()) {
00436       _Traits::assign(*(this->_M_start), _M_null());
00437       _Destroy(this->_M_start+1, this->_M_finish+1);
00438       this->_M_finish = this->_M_start;
00439     }
00440   } 
00441 
00442   bool empty() const { return this->_M_start == this->_M_finish; }    
00443 
00444 public:                         // Element access.
00445 
00446   const_reference operator[](size_type __n) const
00447     { return *(this->_M_start + __n); }
00448   reference operator[](size_type __n)
00449     { return *(this->_M_start + __n); }
00450 
00451   const_reference at(size_type __n) const {
00452     if (__n >= size())
00453       this->_M_throw_out_of_range();
00454     return *(this->_M_start + __n);
00455   }
00456 
00457   reference at(size_type __n) {
00458     if (__n >= size())
00459       this->_M_throw_out_of_range();
00460     return *(this->_M_start + __n);
00461   }
00462 
00463 public:                         // Append, operator+=, push_back.
00464 
00465   _Self& operator+=(const _Self& __s) { return append(__s); }
00466   _Self& operator+=(const _CharT* __s) { _STLP_FIX_LITERAL_BUG(__s) return append(__s); }
00467   _Self& operator+=(_CharT __c) { push_back(__c); return *this; }
00468 
00469   _Self& append(const _Self& __s) 
00470     { return append(__s._M_start, __s._M_finish); }
00471 
00472   _Self& append(const _Self& __s,
00473                        size_type __pos, size_type __n)
00474   {
00475     if (__pos > __s.size())
00476       this->_M_throw_out_of_range();
00477     return append(__s._M_start + __pos,
00478                   __s._M_start + __pos + (min) (__n, __s.size() - __pos));
00479   }
00480 
00481   _Self& append(const _CharT* __s, size_type __n) 
00482     { _STLP_FIX_LITERAL_BUG(__s) return append(__s, __s+__n); }
00483   _Self& append(const _CharT* __s) 
00484     { _STLP_FIX_LITERAL_BUG(__s) return append(__s, __s + traits_type::length(__s)); }
00485   _Self& append(size_type __n, _CharT __c);
00486 
00487 #ifdef _STLP_MEMBER_TEMPLATES
00488 
00489   // Check to see if _InputIterator is an integer type.  If so, then
00490   // it can't be an iterator.
00491   template <class _InputIter> _Self& append(_InputIter __first, _InputIter __last) {
00492     typedef typename _Is_integer<_InputIter>::_Integral _Integral;
00493     return _M_append_dispatch(__first, __last, _Integral());
00494   }
00495 
00496 #else /* _STLP_MEMBER_TEMPLATES */
00497 
00498   _Self& append(const _CharT* __first, const _CharT* __last);
00499 
00500 #endif /* _STLP_MEMBER_TEMPLATES */
00501 
00502   void push_back(_CharT __c) {
00503     if (this->_M_finish + 1 == this->_M_end_of_storage._M_data)
00504       reserve(size() + (max)(size(), __STATIC_CAST(size_type,1)));
00505     _M_construct_null(this->_M_finish + 1);
00506     _Traits::assign(*(this->_M_finish), __c);
00507     ++this->_M_finish;
00508   }
00509 
00510   void pop_back() {
00511     _Traits::assign(*(this->_M_finish - 1), _M_null());
00512     _Destroy(this->_M_finish);
00513     --this->_M_finish;
00514   }
00515 
00516 private:                        // Helper functions for append.
00517 
00518 #ifdef _STLP_MEMBER_TEMPLATES
00519 
00520   template <class _InputIter> _Self& append(_InputIter __first, _InputIter __last, const input_iterator_tag &)
00521   {
00522           for ( ; __first != __last ; ++__first)
00523             push_back(*__first);
00524           return *this;
00525         }
00526 
00527   template <class _ForwardIter> _Self& append(_ForwardIter __first, _ForwardIter __last, 
00528                        const forward_iterator_tag &)  {
00529     if (__first != __last) {
00530             const size_type __old_size = size();
00531             difference_type __n = distance(__first, __last);
00532             if (__STATIC_CAST(size_type,__n) > max_size() || __old_size > max_size() - __STATIC_CAST(size_type,__n))
00533               this->_M_throw_length_error();
00534             if (__old_size + __n > capacity()) {
00535               const size_type __len = __old_size +
00536                                     (max)(__old_size, __STATIC_CAST(size_type,__n)) + 1;
00537               pointer __new_start = this->_M_end_of_storage.allocate(__len);
00538               pointer __new_finish = __new_start;
00539               _STLP_TRY {
00540                 __new_finish = uninitialized_copy(this->_M_start, this->_M_finish, __new_start);
00541                 __new_finish = uninitialized_copy(__first, __last, __new_finish);
00542                 _M_construct_null(__new_finish);
00543               }
00544               _STLP_UNWIND((_Destroy(__new_start,__new_finish),
00545                             this->_M_end_of_storage.deallocate(__new_start,__len)));
00546               _Destroy(this->_M_start, this->_M_finish + 1);
00547               this->_M_deallocate_block();
00548               this->_M_start = __new_start;
00549               this->_M_finish = __new_finish;
00550               this->_M_end_of_storage._M_data = __new_start + __len; 
00551             }
00552             else {
00553               _ForwardIter __f1 = __first;
00554               ++__f1;
00555               uninitialized_copy(__f1, __last, this->_M_finish + 1);
00556               _STLP_TRY {
00557                 _M_construct_null(this->_M_finish + __n);
00558               }
00559               _STLP_UNWIND(_Destroy(this->_M_finish + 1, this->_M_finish + __n));
00560               _Traits::assign(*end(), *__first);
00561               this->_M_finish += __n;
00562             }
00563           }
00564           return *this;  
00565         }
00566 
00567   template <class _Integer> _Self& _M_append_dispatch(_Integer __n, _Integer __x, const __true_type&) {
00568     return append((size_type) __n, (_CharT) __x);
00569   }
00570 
00571   template <class _InputIter> _Self& _M_append_dispatch(_InputIter __f, _InputIter __l,
00572                                    const __false_type&) {
00573     return append(__f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter));
00574   }
00575 
00576 #endif /* _STLP_MEMBER_TEMPLATES */
00577 
00578 public:                         // Assign
00579   
00580   _Self& assign(const _Self& __s) 
00581     { return assign(__s._M_start, __s._M_finish); }
00582 
00583   _Self& assign(const _Self& __s, 
00584                        size_type __pos, size_type __n) {
00585     if (__pos > __s.size())
00586       this->_M_throw_out_of_range();
00587     return assign(__s._M_start + __pos, 
00588                   __s._M_start + __pos + (min) (__n, __s.size() - __pos));
00589   }
00590 
00591   _Self& assign(const _CharT* __s, size_type __n)
00592     { _STLP_FIX_LITERAL_BUG(__s) return assign(__s, __s + __n); }
00593 
00594   _Self& assign(const _CharT* __s)
00595     { _STLP_FIX_LITERAL_BUG(__s) return assign(__s, __s + _Traits::length(__s)); }
00596 
00597   _Self& assign(size_type __n, _CharT __c);
00598 
00599 #ifdef _STLP_MEMBER_TEMPLATES
00600 
00601   // Check to see if _InputIterator is an integer type.  If so, then
00602   // it can't be an iterator.
00603   template <class _InputIter> _Self& assign(_InputIter __first, _InputIter __last) {
00604     typedef typename _Is_integer<_InputIter>::_Integral _Integral;
00605     return _M_assign_dispatch(__first, __last, _Integral());
00606   }
00607 #else
00608 
00609   _Self& assign(const _CharT* __f, const _CharT* __l);
00610 #endif  /* _STLP_MEMBER_TEMPLATES */
00611 
00612 private:                        // Helper functions for assign.
00613 
00614 #ifdef _STLP_MEMBER_TEMPLATES
00615 
00616   template <class _Integer> _Self& _M_assign_dispatch(_Integer __n, _Integer __x, const __true_type&) {
00617     return assign((size_type) __n, (_CharT) __x);
00618   }
00619 
00620   template <class _InputIter> _Self& _M_assign_dispatch(_InputIter __f, _InputIter __l,
00621                                    const __false_type&)  {
00622           pointer __cur = this->_M_start;
00623           while (__f != __l && __cur != this->_M_finish) {
00624             _Traits::assign(*__cur, *__f);
00625             ++__f;
00626             ++__cur;
00627           }
00628           if (__f == __l)
00629             erase(__cur, end());
00630           else
00631             append(__f, __l);
00632           return *this;
00633         }
00634 
00635 #endif  /* _STLP_MEMBER_TEMPLATES */
00636 
00637 public:                         // Insert
00638 
00639   _Self& insert(size_type __pos, const _Self& __s) {
00640     if (__pos > size())
00641       this->_M_throw_out_of_range();
00642     if (size() > max_size() - __s.size())
00643       this->_M_throw_length_error();
00644     insert(begin() + __pos, __s._M_start, __s._M_finish);
00645     return *this;
00646   }
00647 
00648   _Self& insert(size_type __pos, const _Self& __s,
00649                        size_type __beg, size_type __n) {
00650     if (__pos > size() || __beg > __s.size())
00651       this->_M_throw_out_of_range();
00652     size_type __len = (min) (__n, __s.size() - __beg);
00653     if (size() > max_size() - __len)
00654       this->_M_throw_length_error();
00655     insert(begin() + __pos,
00656            __s._M_start + __beg, __s._M_start + __beg + __len);
00657     return *this;
00658   }
00659 
00660   _Self& insert(size_type __pos, const _CharT* __s, size_type __n) {
00661     _STLP_FIX_LITERAL_BUG(__s)
00662     if (__pos > size())
00663       this->_M_throw_out_of_range();
00664     if (size() > max_size() - __n)
00665       this->_M_throw_length_error();
00666     insert(begin() + __pos, __s, __s + __n);
00667     return *this;
00668   }
00669 
00670   _Self& insert(size_type __pos, const _CharT* __s) {
00671     _STLP_FIX_LITERAL_BUG(__s)
00672     if (__pos > size())
00673       this->_M_throw_out_of_range();
00674     size_type __len = _Traits::length(__s);
00675     if (size() > max_size() - __len)
00676       this->_M_throw_length_error();
00677     insert(this->_M_start + __pos, __s, __s + __len);
00678     return *this;
00679   }
00680     
00681   _Self& insert(size_type __pos, size_type __n, _CharT __c) {
00682     if (__pos > size())
00683       this->_M_throw_out_of_range();
00684     if (size() > max_size() - __n)
00685       this->_M_throw_length_error();
00686     insert(begin() + __pos, __n, __c);
00687     return *this;
00688   }
00689 
00690   iterator insert(iterator __p, _CharT __c) {
00691     _STLP_FIX_LITERAL_BUG(__p)
00692     if (__p == end()) {
00693       push_back(__c);
00694       return this->_M_finish - 1;
00695     }
00696     else
00697       return _M_insert_aux(__p, __c);
00698   }
00699 
00700   void insert(iterator __p, size_t __n, _CharT __c);
00701 
00702 #ifdef _STLP_MEMBER_TEMPLATES
00703 
00704   // Check to see if _InputIterator is an integer type.  If so, then
00705   // it can't be an iterator.
00706   template <class _InputIter> void insert(iterator __p, _InputIter __first, _InputIter __last) {
00707     typedef typename _Is_integer<_InputIter>::_Integral _Integral;
00708     _M_insert_dispatch(__p, __first, __last, _Integral());
00709   }
00710 
00711 #else /* _STLP_MEMBER_TEMPLATES */
00712 
00713   void insert(iterator __p, const _CharT* __first, const _CharT* __last);
00714 
00715 #endif /* _STLP_MEMBER_TEMPLATES */
00716 
00717 private:                        // Helper functions for insert.
00718 
00719 #ifdef _STLP_MEMBER_TEMPLATES
00720 
00721   template <class _InputIter> void insert(iterator __p, _InputIter __first, _InputIter __last,
00722               const input_iterator_tag &)
00723   {
00724           for ( ; __first != __last; ++__first) {
00725             __p = insert(__p, *__first);
00726             ++__p;
00727           }
00728         }
00729 
00730   template <class _ForwardIter> void insert(iterator __position, _ForwardIter __first, _ForwardIter __last, 
00731               const forward_iterator_tag &)  {
00732     if (__first != __last) {
00733       difference_type __n = distance(__first, __last);
00734       if (this->_M_end_of_storage._M_data - this->_M_finish >= __n + 1) {
00735         const difference_type __elems_after = this->_M_finish - __position;
00736         pointer __old_finish = this->_M_finish;
00737         if (__elems_after >= __n) {
00738           uninitialized_copy((this->_M_finish - __n) + 1, this->_M_finish + 1,
00739                              this->_M_finish + 1);
00740           this->_M_finish += __n;
00741           _Traits::move(__position + __n,
00742                         __position, (__elems_after - __n) + 1);
00743           _M_copy(__first, __last, __position);
00744               }
00745         else {
00746           _ForwardIter __mid = __first;
00747           advance(__mid, __elems_after + 1);
00748           uninitialized_copy(__mid, __last, this->_M_finish + 1);
00749           this->_M_finish += __n - __elems_after;
00750                 _STLP_TRY {
00751                   uninitialized_copy(__position, __old_finish + 1, this->_M_finish);
00752                   this->_M_finish += __elems_after;
00753                 }
00754                 _STLP_UNWIND((_Destroy(__old_finish + 1, this->_M_finish), 
00755                               this->_M_finish = __old_finish));
00756                 _M_copy(__first, __mid, __position);
00757         }
00758       }
00759       else {
00760         const size_type __old_size = size();        
00761         const size_type __len
00762           = __old_size + (max)(__old_size, __STATIC_CAST(size_type,__n)) + 1;
00763               pointer __new_start = this->_M_end_of_storage.allocate(__len);
00764               pointer __new_finish = __new_start;
00765               _STLP_TRY {
00766                 __new_finish = uninitialized_copy(this->_M_start, __position, __new_start);
00767                 __new_finish = uninitialized_copy(__first, __last, __new_finish);
00768                 __new_finish
00769                   = uninitialized_copy(__position, this->_M_finish, __new_finish);
00770                 _M_construct_null(__new_finish);
00771               }
00772               _STLP_UNWIND((_Destroy(__new_start,__new_finish),
00773                             this->_M_end_of_storage.deallocate(__new_start,__len)));
00774               _Destroy(this->_M_start, this->_M_finish + 1);
00775               this->_M_deallocate_block();
00776               this->_M_start = __new_start;
00777               this->_M_finish = __new_finish;
00778               this->_M_end_of_storage._M_data = __new_start + __len; 
00779             }
00780     }
00781   }
00782 
00783   template <class _Integer> void _M_insert_dispatch(iterator __p, _Integer __n, _Integer __x,
00784                           const __true_type&) {
00785     insert(__p, (size_type) __n, (_CharT) __x);
00786   }
00787 
00788   template <class _InputIter> void _M_insert_dispatch(iterator __p, _InputIter __first, _InputIter __last,
00789                           const __false_type&) {
00790     insert(__p, __first, __last, _STLP_ITERATOR_CATEGORY(__first, _InputIter));
00791   }
00792 
00793   template <class _InputIterator> void 
00794   _M_copy(_InputIterator __first, _InputIterator __last, pointer __result) {
00795     for ( ; __first != __last; ++__first, ++__result)
00796       _Traits::assign(*__result, *__first);
00797   }
00798 
00799 #endif /* _STLP_MEMBER_TEMPLATES */
00800 
00801   pointer _M_insert_aux(pointer, _CharT);
00802 
00803   void 
00804   _M_copy(const _CharT* __first, const _CharT* __last, _CharT* __result) {
00805     _Traits::copy(__result, __first, __last - __first);
00806   }
00807 
00808 public:                         // Erase.
00809 
00810   _Self& erase(size_type __pos = 0, size_type __n = npos) {
00811     if (__pos > size())
00812       this->_M_throw_out_of_range();
00813     erase(begin() + __pos, begin() + __pos + (min) (__n, size() - __pos));
00814     return *this;
00815   }  
00816 
00817   iterator erase(iterator __position) {
00818                                 // The move includes the terminating _CharT().
00819     _Traits::move(__position, __position + 1, this->_M_finish - __position);
00820     _Destroy(this->_M_finish);
00821     --this->_M_finish;
00822     return __position;
00823   }
00824 
00825   iterator erase(iterator __first, iterator __last) {
00826     if (__first != __last) {
00827                                 // The move includes the terminating _CharT().
00828       traits_type::move(__first, __last, (this->_M_finish - __last) + 1);
00829       pointer __new_finish = this->_M_finish - (__last - __first);
00830       _Destroy(__new_finish + 1, this->_M_finish + 1);
00831       this->_M_finish = __new_finish;
00832     }
00833     return __first;
00834   }
00835 
00836 public:                         // Replace.  (Conceptually equivalent
00837                                 // to erase followed by insert.)
00838   _Self& replace(size_type __pos, size_type __n, 
00839                         const _Self& __s) {
00840     if (__pos > size())
00841       this->_M_throw_out_of_range();
00842     const size_type __len = (min) (__n, size() - __pos);
00843     if (size() - __len >= max_size() - __s.size())
00844       this->_M_throw_length_error();
00845     return replace(begin() + __pos, begin() + __pos + __len, 
00846                    __s._M_start, __s._M_finish);
00847   }
00848 
00849   _Self& replace(size_type __pos1, size_type __n1,
00850                         const _Self& __s,
00851                         size_type __pos2, size_type __n2) {
00852     if (__pos1 > size() || __pos2 > __s.size())
00853       this->_M_throw_out_of_range();
00854     const size_type __len1 = (min) (__n1, size() - __pos1);
00855     const size_type __len2 = (min) (__n2, __s.size() - __pos2);
00856     if (size() - __len1 >= max_size() - __len2)
00857       this->_M_throw_length_error();
00858     return replace(begin() + __pos1, begin() + __pos1 + __len1,
00859                    __s._M_start + __pos2, __s._M_start + __pos2 + __len2);
00860   }
00861 
00862   _Self& replace(size_type __pos, size_type __n1,
00863                         const _CharT* __s, size_type __n2) {
00864     _STLP_FIX_LITERAL_BUG(__s)
00865     if (__pos > size())
00866       this->_M_throw_out_of_range();
00867     const size_type __len = (min) (__n1, size() - __pos);
00868     if (__n2 > max_size() || size() - __len >= max_size() - __n2)
00869       this->_M_throw_length_error();
00870     return replace(begin() + __pos, begin() + __pos + __len,
00871                    __s, __s + __n2);
00872   }
00873 
00874   _Self& replace(size_type __pos, size_type __n1,
00875                         const _CharT* __s) {
00876     _STLP_FIX_LITERAL_BUG(__s)
00877     if (__pos > size())
00878       this->_M_throw_out_of_range();
00879     const size_type __len = (min) (__n1, size() - __pos);
00880     const size_type __n2 = _Traits::length(__s);
00881     if (__n2 > max_size() || size() - __len >= max_size() - __n2)
00882       this->_M_throw_length_error();
00883     return replace(begin() + __pos, begin() + __pos + __len,
00884                    __s, __s + _Traits::length(__s));
00885   }
00886 
00887   _Self& replace(size_type __pos, size_type __n1,
00888                         size_type __n2, _CharT __c) {
00889     if (__pos > size())
00890       this->_M_throw_out_of_range();
00891     const size_type __len = (min) (__n1, size() - __pos);
00892     if (__n2 > max_size() || size() - __len >= max_size() - __n2)
00893       this->_M_throw_length_error();
00894     return replace(begin() + __pos, begin() + __pos + __len, __n2, __c);
00895   }
00896 
00897   _Self& replace(iterator __first, iterator __last, 
00898                         const _Self& __s) 
00899     { return replace(__first, __last, __s._M_start, __s._M_finish); }
00900 
00901   _Self& replace(iterator __first, iterator __last,
00902                         const _CharT* __s, size_type __n) 
00903     { _STLP_FIX_LITERAL_BUG(__s) return replace(__first, __last, __s, __s + __n); }
00904 
00905   _Self& replace(iterator __first, iterator __last,
00906                         const _CharT* __s) {
00907     _STLP_FIX_LITERAL_BUG(__s)
00908     return replace(__first, __last, __s, __s + _Traits::length(__s));
00909   }
00910 
00911   _Self& replace(iterator __first, iterator __last, 
00912                         size_type __n, _CharT __c);
00913 
00914   // Check to see if _InputIterator is an integer type.  If so, then
00915   // it can't be an iterator.
00916 #ifdef _STLP_MEMBER_TEMPLATES
00917   template <class _InputIter> _Self& replace(iterator __first, iterator __last,
00918                         _InputIter __f, _InputIter __l) {
00919     typedef typename _Is_integer<_InputIter>::_Integral _Integral;
00920     return _M_replace_dispatch(__first, __last, __f, __l,  _Integral());
00921   }
00922 #else /* _STLP_MEMBER_TEMPLATES */
00923   _Self& replace(iterator __first, iterator __last,
00924                  const _CharT* __f, const _CharT* __l);
00925 #endif /* _STLP_MEMBER_TEMPLATES */
00926 
00927 private:                        // Helper functions for replace.
00928 
00929 #ifdef _STLP_MEMBER_TEMPLATES
00930 
00931   template <class _Integer> _Self& _M_replace_dispatch(iterator __first, iterator __last,
00932                                     _Integer __n, _Integer __x,
00933                                     const __true_type&) {
00934     return replace(__first, __last, (size_type) __n, (_CharT) __x);
00935   }
00936 
00937   template <class _InputIter> _Self& _M_replace_dispatch(iterator __first, iterator __last,
00938                                     _InputIter __f, _InputIter __l,
00939                                     const __false_type&) {
00940     return replace(__first, __last, __f, __l, _STLP_ITERATOR_CATEGORY(__f, _InputIter));
00941   }
00942 
00943   template <class _InputIter> _Self& replace(iterator __first, iterator __last,
00944                         _InputIter __f, _InputIter __l, const input_iterator_tag &)  {
00945           for ( ; __first != __last && __f != __l; ++__first, ++__f)
00946             _Traits::assign(*__first, *__f);
00947 
00948           if (__f == __l)
00949             erase(__first, __last);
00950           else
00951             insert(__last, __f, __l);
00952           return *this;
00953         }
00954 
00955   template <class _ForwardIter> _Self& replace(iterator __first, iterator __last,
00956                         _ForwardIter __f, _ForwardIter __l, 
00957                         const forward_iterator_tag &)  {
00958           difference_type __n = distance(__f, __l);
00959           const difference_type __len = __last - __first;
00960           if (__len >= __n) {
00961             _M_copy(__f, __l, __first);
00962             erase(__first + __n, __last);
00963           }
00964           else {
00965             _ForwardIter __m = __f;
00966             advance(__m, __len);
00967             _M_copy(__f, __m, __first);
00968             insert(__last, __m, __l);
00969           }
00970           return *this;
00971         }
00972 
00973 #endif /* _STLP_MEMBER_TEMPLATES */
00974 
00975 public:                         // Other modifier member functions.
00976 
00977   size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const {
00978     _STLP_FIX_LITERAL_BUG(__s)
00979     if (__pos > size())
00980       this->_M_throw_out_of_range();
00981     const size_type __len = (min) (__n, size() - __pos);
00982     _Traits::copy(__s, this->_M_start + __pos, __len);
00983     return __len;
00984   }
00985 
00986   void swap(_Self& __s) {
00987     _STLP_STD::swap(this->_M_start, __s._M_start);
00988     _STLP_STD::swap(this->_M_finish, __s._M_finish);
00989     _STLP_STD::swap(this->_M_end_of_storage, __s._M_end_of_storage);
00990   }
00991 
00992 public:                         // Conversion to C string.
00993 
00994   const _CharT* c_str() const { return this->_M_start; }
00995   const _CharT* data()  const { return this->_M_start; }
00996 
00997 public:                         // find.
00998 
00999   size_type find(const _Self& __s, size_type __pos = 0) const 
01000     { return find(__s._M_start, __pos, __s.size()); }
01001 
01002   size_type find(const _CharT* __s, size_type __pos = 0) const 
01003     { _STLP_FIX_LITERAL_BUG(__s) return find(__s, __pos, _Traits::length(__s)); }
01004 
01005   size_type find(const _CharT* __s, size_type __pos, size_type __n) const;
01006   size_type find(_CharT __c, size_type __pos = 0) const;
01007 
01008 public:                         // rfind.
01009 
01010   size_type rfind(const _Self& __s, size_type __pos = npos) const 
01011     { return rfind(__s._M_start, __pos, __s.size()); }
01012 
01013   size_type rfind(const _CharT* __s, size_type __pos = npos) const 
01014     { _STLP_FIX_LITERAL_BUG(__s) return rfind(__s, __pos, _Traits::length(__s)); }
01015 
01016   size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const;
01017   size_type rfind(_CharT __c, size_type __pos = npos) const;
01018 
01019 public:                         // find_first_of
01020   
01021   size_type find_first_of(const _Self& __s, size_type __pos = 0) const 
01022     { return find_first_of(__s._M_start, __pos, __s.size()); }
01023 
01024   size_type find_first_of(const _CharT* __s, size_type __pos = 0) const 
01025     { _STLP_FIX_LITERAL_BUG(__s) return find_first_of(__s, __pos, _Traits::length(__s)); }
01026 
01027   size_type find_first_of(const _CharT* __s, size_type __pos, 
01028                           size_type __n) const;
01029 
01030   size_type find_first_of(_CharT __c, size_type __pos = 0) const 
01031     { return find(__c, __pos); }
01032 
01033 public:                         // find_last_of
01034 
01035   size_type find_last_of(const _Self& __s,
01036                          size_type __pos = npos) const
01037     { return find_last_of(__s._M_start, __pos, __s.size()); }
01038 
01039   size_type find_last_of(const _CharT* __s, size_type __pos = npos) const 
01040     { _STLP_FIX_LITERAL_BUG(__s) return find_last_of(__s, __pos, _Traits::length(__s)); }
01041 
01042   size_type find_last_of(const _CharT* __s, size_type __pos, 
01043                          size_type __n) const;
01044 
01045   size_type find_last_of(_CharT __c, size_type __pos = npos) const {
01046     return rfind(__c, __pos);
01047   }
01048 
01049 public:                         // find_first_not_of
01050 
01051   size_type find_first_not_of(const _Self& __s, 
01052                               size_type __pos = 0) const 
01053     { return find_first_not_of(__s._M_start, __pos, __s.size()); }
01054 
01055   size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const 
01056     { _STLP_FIX_LITERAL_BUG(__s) return find_first_not_of(__s, __pos, _Traits::length(__s)); }
01057 
01058   size_type find_first_not_of(const _CharT* __s, size_type __pos,
01059                               size_type __n) const;
01060 
01061   size_type find_first_not_of(_CharT __c, size_type __pos = 0) const;
01062 
01063 public:                         // find_last_not_of
01064 
01065   size_type find_last_not_of(const _Self& __s, 
01066                              size_type __pos = npos) const
01067     { return find_last_not_of(__s._M_start, __pos, __s.size()); }
01068 
01069   size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const
01070     { _STLP_FIX_LITERAL_BUG(__s) return find_last_not_of(__s, __pos, _Traits::length(__s)); }
01071 
01072   size_type find_last_not_of(const _CharT* __s, size_type __pos,
01073                              size_type __n) const;
01074 
01075   size_type find_last_not_of(_CharT __c, size_type __pos = npos) const;
01076 
01077 public:                         // Substring.
01078 
01079   _Self substr(size_type __pos = 0, size_type __n = npos) const {
01080     if (__pos > size())
01081       this->_M_throw_out_of_range();
01082     return _Self(this->_M_start + __pos, 
01083                         this->_M_start + __pos + (min) (__n, size() - __pos));
01084   }
01085 
01086 public:                         // Compare
01087 
01088   int compare(const _Self& __s) const 
01089     { return _M_compare(this->_M_start, this->_M_finish, __s._M_start, __s._M_finish); }
01090 
01091   int compare(size_type __pos1, size_type __n1,
01092               const _Self& __s) const {
01093     if (__pos1 > size())
01094       this->_M_throw_out_of_range();
01095     return _M_compare(this->_M_start + __pos1, 
01096                       this->_M_start + __pos1 + (min) (__n1, size() - __pos1),
01097                       __s._M_start, __s._M_finish);
01098   }
01099     
01100   int compare(size_type __pos1, size_type __n1,
01101               const _Self& __s,
01102               size_type __pos2, size_type __n2) const {
01103     if (__pos1 > size() || __pos2 > __s.size())
01104       this->_M_throw_out_of_range();
01105     return _M_compare(this->_M_start + __pos1, 
01106                       this->_M_start + __pos1 + (min) (__n1, size() - __pos1),
01107                       __s._M_start + __pos2, 
01108                       __s._M_start + __pos2 + (min) (__n2, __s.size() - __pos2));
01109   }
01110 
01111   int compare(const _CharT* __s) const {
01112     _STLP_FIX_LITERAL_BUG(__s) 
01113       return _M_compare(this->_M_start, this->_M_finish, __s, __s + _Traits::length(__s));
01114   }
01115 
01116   int compare(size_type __pos1, size_type __n1, const _CharT* __s) const {
01117     _STLP_FIX_LITERAL_BUG(__s)
01118     if (__pos1 > size())
01119       this->_M_throw_out_of_range();
01120     return _M_compare(this->_M_start + __pos1, 
01121                       this->_M_start + __pos1 + (min) (__n1, size() - __pos1),
01122                       __s, __s + _Traits::length(__s));
01123   }
01124 
01125   int compare(size_type __pos1, size_type __n1, const _CharT* __s,
01126               size_type __n2) const {
01127     _STLP_FIX_LITERAL_BUG(__s)
01128     if (__pos1 > size())
01129       this->_M_throw_out_of_range();
01130     return _M_compare(this->_M_start + __pos1, 
01131                       this->_M_start + __pos1 + (min) (__n1, size() - __pos1),
01132                       __s, __s + __n2);
01133   }
01134 
01135 public:                        // Helper functions for compare.
01136   
01137   static int _STLP_CALL _M_compare(const _CharT* __f1, const _CharT* __l1,
01138                         const _CharT* __f2, const _CharT* __l2) {
01139     const ptrdiff_t __n1 = __l1 - __f1;
01140     const ptrdiff_t __n2 = __l2 - __f2;
01141     const int cmp = _Traits::compare(__f1, __f2, (min) (__n1, __n2));
01142     return cmp != 0 ? cmp : (__n1 < __n2 ? -1 : (__n1 > __n2 ? 1 : 0));
01143   }
01144 };
01145 
01146 
01147 # if defined (_STLP_USE_TEMPLATE_EXPORT)
01148 _STLP_EXPORT_TEMPLATE_CLASS basic_string<char, char_traits<char>, allocator<char> >;
01149 #  if defined (_STLP_HAS_WCHAR_T)
01150 _STLP_EXPORT_TEMPLATE_CLASS basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >;
01151 #  endif
01152 # endif /* _STLP_USE_TEMPLATE_EXPORT */
01153 
01154 // ------------------------------------------------------------
01155 // Non-member functions.
01156 
01157 template <class _CharT, class _Traits, class _Alloc> inline basic_string<_CharT,_Traits,_Alloc> _STLP_CALL
01158 operator+(const basic_string<_CharT,_Traits,_Alloc>& __s,
01159           const basic_string<_CharT,_Traits,_Alloc>& __y)
01160 {
01161   typedef basic_string<_CharT,_Traits,_Alloc> _Str;
01162   typedef typename _Str::_Reserve_t _Reserve_t;
01163 # if defined (__GNUC__) //&& !defined (__SYMBIAN32__)
01164   // gcc counts this as a function
01165   _Str __result  = _Str(_Reserve_t(),__s.size() + __y.size());
01166 # else
01167   _Str __result(_Reserve_t(), __s.size() + __y.size());
01168 # endif
01169   __result.append(__s);
01170   __result.append(__y);
01171   return __result;
01172 }
01173 
01174 //# if (defined (__GNUC__) && !defined (__SYMBIAN32__)) || defined (__MLCCPP__)
01175 # if defined (__GNUC__) || defined (__MLCCPP__)
01176 #  define _STLP_INIT_AMBIGUITY 1
01177 # endif
01178 
01179 template <class _CharT, class _Traits, class _Alloc> inline basic_string<_CharT,_Traits,_Alloc> _STLP_CALL
01180 operator+(const _CharT* __s,
01181           const basic_string<_CharT,_Traits,_Alloc>& __y) {
01182   _STLP_FIX_LITERAL_BUG(__s)
01183   typedef basic_string<_CharT,_Traits,_Alloc> _Str;
01184   typedef typename _Str::_Reserve_t _Reserve_t;
01185   const size_t __n = _Traits::length(__s);
01186 # ifdef _STLP_INIT_AMBIGUITY
01187   _Str __result = _Str(_Reserve_t(), __n + __y.size());
01188 # else
01189   _Str __result(_Reserve_t(), __n + __y.size());
01190 # endif
01191   __result.append(__s, __s + __n);
01192   __result.append(__y);
01193   return __result;
01194 }
01195 
01196 template <class _CharT, class _Traits, class _Alloc> inline basic_string<_CharT,_Traits,_Alloc> _STLP_CALL
01197 operator+(_CharT __c,
01198           const basic_string<_CharT,_Traits,_Alloc>& __y) {
01199   typedef basic_string<_CharT,_Traits,_Alloc> _Str;
01200   typedef typename _Str::_Reserve_t _Reserve_t;
01201 # ifdef _STLP_INIT_AMBIGUITY
01202   _Str __result = _Str(_Reserve_t(), 1 + __y.size());
01203 # else
01204   _Str __result(_Reserve_t(), 1 + __y.size());
01205 # endif
01206   __result.push_back(__c);
01207   __result.append(__y);
01208   return __result;
01209 }
01210 
01211 template <class _CharT, class _Traits, class _Alloc> inline basic_string<_CharT,_Traits,_Alloc> _STLP_CALL
01212 operator+(const basic_string<_CharT,_Traits,_Alloc>& __x,
01213           const _CharT* __s) {
01214   _STLP_FIX_LITERAL_BUG(__s)
01215   typedef basic_string<_CharT,_Traits,_Alloc> _Str;
01216   typedef typename _Str::_Reserve_t _Reserve_t;
01217   const size_t __n = _Traits::length(__s);
01218 # ifdef _STLP_INIT_AMBIGUITY
01219   _Str __result = _Str(_Reserve_t(), __x.size() + __n, __x.get_allocator());
01220 # else
01221   _Str __result(_Reserve_t(), __x.size() + __n, __x.get_allocator());
01222 # endif
01223   __result.append(__x);
01224   __result.append(__s, __s + __n);
01225   return __result;
01226 }
01227 
01228 template <class _CharT, class _Traits, class _Alloc> inline basic_string<_CharT,_Traits,_Alloc> _STLP_CALL
01229 operator+(const basic_string<_CharT,_Traits,_Alloc>& __x,
01230           const _CharT __c) {
01231   typedef basic_string<_CharT,_Traits,_Alloc> _Str;
01232   typedef typename _Str::_Reserve_t _Reserve_t;
01233 # ifdef _STLP_INIT_AMBIGUITY
01234   _Str __result = _Str(_Reserve_t(), __x.size() + 1, __x.get_allocator());
01235 # else
01236   _Str __result(_Reserve_t(), __x.size() + 1, __x.get_allocator());
01237 # endif
01238   __result.append(__x);
01239   __result.push_back(__c);
01240   return __result;
01241 }
01242 
01243 # undef _STLP_INIT_AMBIGUITY
01244 
01245 // Operator== and operator!=
01246 
01247 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01248 operator==(const basic_string<_CharT,_Traits,_Alloc>& __x,
01249            const basic_string<_CharT,_Traits,_Alloc>& __y) {
01250   return __x.size() == __y.size() && _Traits::compare(__x.data(), __y.data(), __x.size()) == 0;
01251 }
01252 
01253 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01254 operator==(const _CharT* __s,
01255            const basic_string<_CharT,_Traits,_Alloc>& __y) {
01256   _STLP_FIX_LITERAL_BUG(__s)
01257   size_t __n = _Traits::length(__s);
01258   return __n == __y.size() && _Traits::compare(__s, __y.data(), __n) == 0;
01259 }
01260 
01261 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01262 operator==(const basic_string<_CharT,_Traits,_Alloc>& __x,
01263            const _CharT* __s) {
01264   _STLP_FIX_LITERAL_BUG(__s)
01265   size_t __n = _Traits::length(__s);
01266   return __x.size() == __n && _Traits::compare(__x.data(), __s, __n) == 0;
01267 }
01268 
01269 // Operator< (and also >, <=, and >=).
01270 
01271 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01272 operator<(const basic_string<_CharT,_Traits,_Alloc>& __x,
01273           const basic_string<_CharT,_Traits,_Alloc>& __y) {
01274   return basic_string<_CharT,_Traits,_Alloc> ::_M_compare(__x.begin(), __x.end(), 
01275                  __y.begin(), __y.end()) < 0;
01276 }
01277 
01278 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01279 operator<(const _CharT* __s,
01280           const basic_string<_CharT,_Traits,_Alloc>& __y) {
01281   _STLP_FIX_LITERAL_BUG(__s)
01282   size_t __n = _Traits::length(__s);
01283   return basic_string<_CharT,_Traits,_Alloc> ::_M_compare(__s, __s + __n, __y.begin(), __y.end()) < 0;
01284 }
01285 
01286 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01287 operator<(const basic_string<_CharT,_Traits,_Alloc>& __x,
01288           const _CharT* __s) {
01289   _STLP_FIX_LITERAL_BUG(__s)
01290   size_t __n = _Traits::length(__s);
01291   return basic_string<_CharT,_Traits,_Alloc> ::_M_compare(__x.begin(), __x.end(), __s, __s + __n) < 0;
01292 }
01293 
01294 #ifdef _STLP_USE_SEPARATE_RELOPS_NAMESPACE
01295 
01296 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01297 operator!=(const basic_string<_CharT,_Traits,_Alloc>& __x,
01298            const basic_string<_CharT,_Traits,_Alloc>& __y) {
01299   return !(__x == __y);
01300 }
01301 
01302 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01303 operator>(const basic_string<_CharT,_Traits,_Alloc>& __x,
01304           const basic_string<_CharT,_Traits,_Alloc>& __y) {
01305   return __y < __x;
01306 }
01307 
01308 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01309 operator<=(const basic_string<_CharT,_Traits,_Alloc>& __x,
01310            const basic_string<_CharT,_Traits,_Alloc>& __y) {
01311   return !(__y < __x);
01312 }
01313 
01314 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01315 operator>=(const basic_string<_CharT,_Traits,_Alloc>& __x,
01316            const basic_string<_CharT,_Traits,_Alloc>& __y) {
01317   return !(__x < __y);
01318 }
01319 
01320 #endif /* _STLP_USE_SEPARATE_RELOPS_NAMESPACE */
01321 
01322 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL 
01323 operator!=(const _CharT* __s,
01324            const basic_string<_CharT,_Traits,_Alloc>& __y) {
01325   _STLP_FIX_LITERAL_BUG(__s)
01326   return !(__s == __y);
01327 }
01328 
01329 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL 
01330 operator!=(const basic_string<_CharT,_Traits,_Alloc>& __x,
01331            const _CharT* __s) {
01332   _STLP_FIX_LITERAL_BUG(__s)
01333   return !(__x == __s);
01334 }
01335 
01336 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01337 operator>(const _CharT* __s,
01338           const basic_string<_CharT,_Traits,_Alloc>& __y) {
01339   _STLP_FIX_LITERAL_BUG(__s)
01340   return __y < __s;
01341 }
01342 
01343 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01344 operator>(const basic_string<_CharT,_Traits,_Alloc>& __x,
01345           const _CharT* __s) {
01346   _STLP_FIX_LITERAL_BUG(__s)
01347   return __s < __x;
01348 }
01349 
01350 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01351 operator<=(const _CharT* __s,
01352            const basic_string<_CharT,_Traits,_Alloc>& __y) {
01353   _STLP_FIX_LITERAL_BUG(__s)
01354   return !(__y < __s);
01355 }
01356 
01357 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01358 operator<=(const basic_string<_CharT,_Traits,_Alloc>& __x,
01359            const _CharT* __s) {
01360   _STLP_FIX_LITERAL_BUG(__s)
01361   return !(__s < __x);
01362 }
01363 
01364 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01365 operator>=(const _CharT* __s,
01366            const basic_string<_CharT,_Traits,_Alloc>& __y) {
01367   _STLP_FIX_LITERAL_BUG(__s)
01368   return !(__s < __y);
01369 }
01370 
01371 template <class _CharT, class _Traits, class _Alloc> inline bool _STLP_CALL
01372 operator>=(const basic_string<_CharT,_Traits,_Alloc>& __x,
01373            const _CharT* __s) {
01374   _STLP_FIX_LITERAL_BUG(__s)
01375   return !(__x < __s);
01376 }
01377 
01378 
01379 // Swap.
01380 
01381 #ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
01382 
01383 template <class _CharT, class _Traits, class _Alloc> inline void _STLP_CALL
01384 swap(basic_string<_CharT,_Traits,_Alloc>& __x,
01385      basic_string<_CharT,_Traits,_Alloc>& __y) {
01386   __x.swap(__y);
01387 }
01388 
01389 #endif /* _STLP_FUNCTION_TMPL_PARTIAL_ORDER */
01390 
01391 template <class _CharT, class _Traits, class _Alloc> void  _STLP_CALL _S_string_copy(const basic_string<_CharT,_Traits,_Alloc>& __s,
01392                     _CharT* __buf,
01393                     size_t __n);
01394 
01395 # undef basic_string
01396 
01397 _STLP_END_NAMESPACE
01398 
01399 # ifdef _STLP_DEBUG
01400 #  include <stl/debug/_string.h> 
01401 # endif
01402 
01403 # if !defined (_STLP_LINK_TIME_INSTANTIATION)
01404 #  include <stl/_string.c> 
01405 # endif
01406 
01407 # include <stl/_string_io.h>  
01408 # include <stl/_string_hash.h>  
01409 
01410 #endif /* _STLP_STRING */
01411 
01412 
01413 // Local Variables:
01414 // mode:C++
01415 // End:

Generated on Mon Jun 5 10:20:47 2006 for Intelligence.kdevelop by  doxygen 1.4.6