williamr@2: /*
williamr@4:  *
williamr@2:  *
williamr@2:  * Copyright (c) 1994
williamr@2:  * Hewlett-Packard Company
williamr@2:  *
williamr@2:  * Copyright (c) 1996,1997
williamr@2:  * Silicon Graphics Computer Systems, Inc.
williamr@2:  *
williamr@2:  * Copyright (c) 1997
williamr@2:  * Moscow Center for SPARC Technology
williamr@2:  *
williamr@4:  * Copyright (c) 1999
williamr@2:  * Boris Fomitchev
williamr@2:  *
williamr@2:  * This material is provided "as is", with absolutely no warranty expressed
williamr@2:  * or implied. Any use is at your own risk.
williamr@2:  *
williamr@4:  * Permission to use or copy this software for any purpose is hereby granted
williamr@2:  * without fee, provided the above notices are retained on all copies.
williamr@2:  * Permission to modify the code and to distribute modified code is granted,
williamr@2:  * provided the above notices are retained, and a notice that the code was
williamr@2:  * modified is included with the above copyright notice.
williamr@2:  *
williamr@2:  */
williamr@2: #ifndef _STLP_STRING_C
williamr@2: #define _STLP_STRING_C
williamr@2: 
williamr@4: #ifndef _STLP_INTERNAL_STRING_H
williamr@4: #  include <stl/_string.h>
williamr@2: #endif
williamr@2: 
williamr@4: #ifndef _STLP_INTERNAL_CTRAITS_FUNCTIONS_H
williamr@4: #  include <stl/_ctraits_fns.h>
williamr@4: #endif
williamr@2: 
williamr@4: #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND)
williamr@4: #  define basic_string _STLP_NO_MEM_T_NAME(str)
williamr@4: #elif defined (_STLP_DEBUG)
williamr@4: #  define basic_string _STLP_NON_DBG_NAME(str)
williamr@4: #endif
williamr@2: 
williamr@4: #if defined (_STLP_NESTED_TYPE_PARAM_BUG)
williamr@2: #  define __size_type__ size_t
williamr@2: #  define size_type size_t
williamr@4: #  define iterator _CharT*
williamr@4: #else
williamr@2: #  define __size_type__ _STLP_TYPENAME_ON_RETURN_TYPE basic_string<_CharT,_Traits,_Alloc>::size_type
williamr@4: #endif
williamr@2: 
williamr@2: _STLP_BEGIN_NAMESPACE
williamr@2: 
williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE
williamr@4: 
williamr@4: // A helper class to use a char_traits as a function object.
williamr@4: template <class _Traits>
williamr@4: struct _Not_within_traits : public unary_function<typename _Traits::char_type, bool> {
williamr@4:   typedef typename _Traits::char_type _CharT;
williamr@4:   const _CharT* _M_first;
williamr@4:   const _CharT* _M_last;
williamr@4: 
williamr@4:   _Not_within_traits(const _CharT* __f, const _CharT* __l)
williamr@4:     : _M_first(__f), _M_last(__l) {}
williamr@4: 
williamr@4:   bool operator()(const _CharT& __x) const {
williamr@4:     return find_if(_M_first, _M_last,
williamr@4:                    _STLP_PRIV _Eq_char_bound<_Traits>(__x)) == _M_last;
williamr@4:   }
williamr@4: };
williamr@4: 
williamr@2: // ------------------------------------------------------------
williamr@2: // Non-inline declarations.
williamr@2: 
williamr@4: #if !defined (basic_string)
williamr@4: _STLP_MOVE_TO_STD_NAMESPACE
williamr@4: #endif
williamr@2: 
williamr@2: // Change the string's capacity so that it is large enough to hold
williamr@2: //  at least __res_arg elements, plus the terminating _CharT().  Note that,
williamr@2: //  if __res_arg < capacity(), this member function may actually decrease
williamr@2: //  the string's capacity.
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: void basic_string<_CharT,_Traits,_Alloc>::reserve(size_type __res_arg) {
williamr@4:   if (__res_arg > max_size())
williamr@4:     this->_M_throw_length_error();
williamr@2: 
williamr@4:   size_type __n = (max)(__res_arg, size()) + 1;
williamr@4:   if (__n <= capacity() + 1)
williamr@4:     return;
williamr@2: 
williamr@4:   pointer __new_start = this->_M_end_of_storage.allocate(__n, __n);
williamr@4:   pointer __new_finish = __new_start;
williamr@4: 
williamr@4:   _STLP_TRY {
williamr@4:     __new_finish = _STLP_PRIV __ucopy(this->_M_Start(), this->_M_Finish(), __new_start);
williamr@4:     _M_construct_null(__new_finish);
williamr@4:   }
williamr@4:   _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start, __new_finish),
williamr@4:                 this->_M_end_of_storage.deallocate(__new_start, __n)))
williamr@4: 
williamr@4:   this->_M_destroy_range();
williamr@4:   this->_M_deallocate_block();
williamr@4:   this->_M_reset(__new_start, __new_finish, __new_start + __n);
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: basic_string<_CharT,_Traits,_Alloc>&
williamr@4: basic_string<_CharT,_Traits,_Alloc>::append(size_type __n, _CharT __c) {
williamr@2:   if (__n > max_size() || size() > max_size() - __n)
williamr@2:     this->_M_throw_length_error();
williamr@2:   if (size() + __n > capacity())
williamr@2:     reserve(size() + (max)(size(), __n));
williamr@2:   if (__n > 0) {
williamr@4: #if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@4:     if (this->_M_using_static_buf())
williamr@4:       _Traits::assign(this->_M_finish + 1, __n - 1, __c);
williamr@4:     else
williamr@4: #endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@4:     _STLP_PRIV __uninitialized_fill_n(this->_M_finish + 1, __n - 1, __c);
williamr@2:     _STLP_TRY {
williamr@2:       _M_construct_null(this->_M_finish + __n);
williamr@2:     }
williamr@4:     _STLP_UNWIND(this->_M_destroy_ptr_range(this->_M_finish + 1, this->_M_finish + __n))
williamr@2:     _Traits::assign(*end(), __c);
williamr@2:     this->_M_finish += __n;
williamr@2:   }
williamr@2:   return *this;
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: basic_string<_CharT, _Traits, _Alloc>&
williamr@4: basic_string<_CharT, _Traits, _Alloc>::_M_append(const _CharT* __first, const _CharT* __last) {
williamr@2:   if (__first != __last) {
williamr@2:     const size_type __old_size = size();
williamr@2:     ptrdiff_t __n = __last - __first;
williamr@2:     if ((size_type)__n > max_size() || __old_size > max_size() - __n)
williamr@2:       this->_M_throw_length_error();
williamr@2:     if (__old_size + __n > capacity()) {
williamr@4:       size_type __len = __old_size + (max)(__old_size, (size_t) __n) + 1;
williamr@4:       pointer __new_start = this->_M_end_of_storage.allocate(__len, __len);
williamr@4:       pointer __new_finish = __new_start;
williamr@2:       _STLP_TRY {
williamr@4:         __new_finish = _STLP_PRIV __ucopy(this->_M_Start(), this->_M_Finish(), __new_start);
williamr@4:         __new_finish = _STLP_PRIV __ucopy(__first, __last, __new_finish);
williamr@2:         _M_construct_null(__new_finish);
williamr@2:       }
williamr@4:       _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish),
williamr@4:                     this->_M_end_of_storage.deallocate(__new_start,__len)))
williamr@4:       this->_M_destroy_range();
williamr@2:       this->_M_deallocate_block();
williamr@4:       this->_M_reset(__new_start, __new_finish, __new_start + __len);
williamr@2:     }
williamr@2:     else {
williamr@2:       const _CharT* __f1 = __first;
williamr@2:       ++__f1;
williamr@4: #if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@4:       if (this->_M_using_static_buf())
williamr@4:         _M_copy(__f1, __last, this->_M_Finish() + 1);
williamr@4:       else
williamr@4: #endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@4:       _STLP_PRIV __ucopy(__f1, __last, this->_M_finish + 1);
williamr@2:       _STLP_TRY {
williamr@2:         _M_construct_null(this->_M_finish + __n);
williamr@2:       }
williamr@4:       _STLP_UNWIND(this->_M_destroy_ptr_range(this->_M_finish + 1, this->_M_finish + __n))
williamr@2:       _Traits::assign(*end(), *__first);
williamr@2:       this->_M_finish += __n;
williamr@2:     }
williamr@2:   }
williamr@4:   return *this;
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: basic_string<_CharT,_Traits,_Alloc>&
williamr@2: basic_string<_CharT,_Traits,_Alloc>::assign(size_type __n, _CharT __c) {
williamr@2:   if (__n <= size()) {
williamr@4:     _Traits::assign(this->_M_Start(), __n, __c);
williamr@2:     erase(begin() + __n, end());
williamr@2:   }
williamr@2:   else {
williamr@4:     if (__n < capacity()) {
williamr@4:       _Traits::assign(this->_M_Start(), size(), __c);
williamr@4:       append(__n - size(), __c);
williamr@4:     }
williamr@4:     else {
williamr@4:       _Self __str(__n, __c);
williamr@4:       this->swap(__str);
williamr@4:     }
williamr@2:   }
williamr@2:   return *this;
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: basic_string<_CharT,_Traits,_Alloc>&
williamr@4: basic_string<_CharT,_Traits,_Alloc>::_M_assign(const _CharT* __f, const _CharT* __l) {
williamr@4:   ptrdiff_t __n = __l - __f;
williamr@4:   if (__STATIC_CAST(size_type, __n) <= size()) {
williamr@4:     _Traits::copy(this->_M_Start(), __f, __n);
williamr@4:     erase(begin() + __n, end());
williamr@4:   }
williamr@4:   else {
williamr@4:     _Traits::copy(this->_M_Start(), __f, size());
williamr@4:     _M_append(__f + size(), __l);
williamr@4:   }
williamr@4:   return *this;
williamr@4: }
williamr@4: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@2: _CharT* basic_string<_CharT,_Traits,_Alloc> ::_M_insert_aux(_CharT* __p,
williamr@4:                                                             _CharT __c) {
williamr@2:   pointer __new_pos = __p;
williamr@2:   if (this->_M_finish + 1 < this->_M_end_of_storage._M_data) {
williamr@2:     _M_construct_null(this->_M_finish + 1);
williamr@2:     _Traits::move(__p + 1, __p, this->_M_finish - __p);
williamr@2:     _Traits::assign(*__p, __c);
williamr@2:     ++this->_M_finish;
williamr@2:   }
williamr@2:   else {
williamr@2:     const size_type __old_len = size();
williamr@4:     size_type __len = __old_len + (max)(__old_len, __STATIC_CAST(size_type,1)) + 1;
williamr@4:     pointer __new_start = this->_M_end_of_storage.allocate(__len, __len);
williamr@4:     pointer __new_finish = __new_start;
williamr@2:     _STLP_TRY {
williamr@4:       __new_pos = _STLP_PRIV __ucopy(this->_M_Start(), __p, __new_start);
williamr@4:       _Copy_Construct(__new_pos, __c);
williamr@2:       __new_finish = __new_pos + 1;
williamr@4:       __new_finish = _STLP_PRIV __ucopy(__p, this->_M_finish, __new_finish);
williamr@2:       _M_construct_null(__new_finish);
williamr@2:     }
williamr@4:     _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish),
williamr@4:                   this->_M_end_of_storage.deallocate(__new_start,__len)))
williamr@4:     this->_M_destroy_range();
williamr@2:     this->_M_deallocate_block();
williamr@4:     this->_M_reset(__new_start, __new_finish, __new_start + __len);
williamr@2:   }
williamr@2:   return __new_pos;
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: void basic_string<_CharT,_Traits,_Alloc>::insert(iterator __pos,
williamr@4:                                                  size_t __n, _CharT __c) {
williamr@2:   if (__n != 0) {
williamr@2:     if (size_type(this->_M_end_of_storage._M_data - this->_M_finish) >= __n + 1) {
williamr@4:       const size_type __elems_after = this->_M_finish - __pos;
williamr@2:       pointer __old_finish = this->_M_finish;
williamr@2:       if (__elems_after >= __n) {
williamr@4: #if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@4:         if (this->_M_using_static_buf())
williamr@4:           _M_copy((this->_M_finish - __n) + 1, this->_M_finish + 1, this->_M_finish + 1);
williamr@4:         else
williamr@4: #endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@4:         _STLP_PRIV __ucopy((this->_M_finish - __n) + 1, this->_M_finish + 1,
williamr@2:                            this->_M_finish + 1);
williamr@2:         this->_M_finish += __n;
williamr@4:         _Traits::move(__pos + __n, __pos, (__elems_after - __n) + 1);
williamr@4:         _Traits::assign(__pos, __n, __c);
williamr@2:       }
williamr@2:       else {
williamr@4: #if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@4:         if (this->_M_using_static_buf())
williamr@4:           _Traits::assign(this->_M_finish + 1, __n - __elems_after - 1, __c);
williamr@4:         else
williamr@4: #endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@4:         _STLP_PRIV __uninitialized_fill_n(this->_M_finish + 1, __n - __elems_after - 1, __c);
williamr@2:         this->_M_finish += __n - __elems_after;
williamr@2:         _STLP_TRY {
williamr@4: #if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@4:           if (this->_M_using_static_buf())
williamr@4:             _M_copy(__pos, __old_finish + 1, this->_M_finish);
williamr@4:           else
williamr@4: #endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@4:           _STLP_PRIV __ucopy(__pos, __old_finish + 1, this->_M_finish);
williamr@2:           this->_M_finish += __elems_after;
williamr@2:         }
williamr@4:         _STLP_UNWIND((_STLP_STD::_Destroy_Range(__old_finish + 1, this->_M_finish),
williamr@4:                       this->_M_finish = __old_finish))
williamr@4:         _Traits::assign(__pos, __elems_after + 1, __c);
williamr@2:       }
williamr@2:     }
williamr@2:     else {
williamr@4:       const size_type __old_size = size();
williamr@4:       size_type __len = __old_size + (max)(__old_size, __n) + 1;
williamr@4:       pointer __new_start = this->_M_end_of_storage.allocate(__len, __len);
williamr@4:       pointer __new_finish = __new_start;
williamr@2:       _STLP_TRY {
williamr@4:         __new_finish = _STLP_PRIV __ucopy(this->_M_Start(), __pos, __new_start);
williamr@4:         __new_finish = _STLP_PRIV __uninitialized_fill_n(__new_finish, __n, __c);
williamr@4:         __new_finish = _STLP_PRIV __ucopy(__pos, this->_M_finish, __new_finish);
williamr@2:         _M_construct_null(__new_finish);
williamr@2:       }
williamr@4:       _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish),
williamr@4:                     this->_M_end_of_storage.deallocate(__new_start,__len)))
williamr@4:       this->_M_destroy_range();
williamr@2:       this->_M_deallocate_block();
williamr@4:       this->_M_reset(__new_start, __new_finish, __new_start + __len);
williamr@2:     }
williamr@2:   }
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: void basic_string<_CharT,_Traits,_Alloc>::_M_insert(iterator __pos,
williamr@4:                                                     const _CharT* __first, const _CharT* __last,
williamr@4:                                                     bool __self_ref) {
williamr@4:   //this version has to take care about the auto referencing
williamr@2:   if (__first != __last) {
williamr@2:     const ptrdiff_t __n = __last - __first;
williamr@2:     if (this->_M_end_of_storage._M_data - this->_M_finish >= __n + 1) {
williamr@4:       const ptrdiff_t __elems_after = this->_M_finish - __pos;
williamr@2:       pointer __old_finish = this->_M_finish;
williamr@2:       if (__elems_after >= __n) {
williamr@4: #if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@4:         if (this->_M_using_static_buf())
williamr@4:           _M_copy((this->_M_finish - __n) + 1, this->_M_finish + 1, this->_M_finish + 1);
williamr@4:         else
williamr@4: #endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@4:         _STLP_PRIV __ucopy((this->_M_finish - __n) + 1, this->_M_finish + 1, this->_M_finish + 1);
williamr@2:         this->_M_finish += __n;
williamr@4:         _Traits::move(__pos + __n, __pos, (__elems_after - __n) + 1);
williamr@4:         if (!__self_ref || __last < __pos) {
williamr@4:           _M_copy(__first, __last, __pos);
williamr@4:         }
williamr@4:         else {
williamr@4:           //We have to check that the source buffer hasn't move
williamr@4:           if (__first >= __pos) {
williamr@4:             //The source buffer has move
williamr@4:             __first += __n;
williamr@4:             __last += __n;
williamr@4:             _M_copy(__first, __last, __pos);
williamr@4:           }
williamr@4:           else {
williamr@4:             //The source buffer hasn't move, it has been duplicated
williamr@4:             _M_move(__first, __last, __pos);
williamr@4:           }
williamr@4:         }
williamr@2:       }
williamr@2:       else {
williamr@4:         const_iterator __mid = __first;
williamr@4:         __mid += __elems_after + 1;
williamr@4: #if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@4:         if (this->_M_using_static_buf())
williamr@4:           _M_copy(__mid, __last, this->_M_finish + 1);
williamr@4:         else
williamr@4: #endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@4:         _STLP_PRIV __ucopy(__mid, __last, this->_M_finish + 1);
williamr@2:         this->_M_finish += __n - __elems_after;
williamr@2:         _STLP_TRY {
williamr@4: #if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@4:           if (this->_M_using_static_buf())
williamr@4:             _M_copy(__pos, __old_finish + 1, this->_M_finish);
williamr@4:           else
williamr@4: #endif /* _STLP_USE_SHORT_STRING_OPTIM */
williamr@4:           _STLP_PRIV __ucopy(__pos, __old_finish + 1, this->_M_finish);
williamr@2:           this->_M_finish += __elems_after;
williamr@2:         }
williamr@4:         _STLP_UNWIND((_STLP_STD::_Destroy_Range(__old_finish + 1, this->_M_finish),
williamr@4:                       this->_M_finish = __old_finish))
williamr@4:         if (!__self_ref)
williamr@4:           _M_copy(__first, __mid, __pos);
williamr@4:         else
williamr@4:           _M_move(__first, __mid, __pos);
williamr@2:       }
williamr@2:     }
williamr@2:     else {
williamr@4:       const size_type __old_size = size();
williamr@4:       size_type __len = __old_size + (max)(__old_size, __STATIC_CAST(const size_type,__n)) + 1;
williamr@4:       pointer __new_start = this->_M_end_of_storage.allocate(__len, __len);
williamr@4:       pointer __new_finish = __new_start;
williamr@2:       _STLP_TRY {
williamr@4:         __new_finish = _STLP_PRIV __ucopy(this->_M_Start(), __pos, __new_start);
williamr@4:         __new_finish = _STLP_PRIV __ucopy(__first, __last, __new_finish);
williamr@4:         __new_finish = _STLP_PRIV __ucopy(__pos, this->_M_finish, __new_finish);
williamr@2:         _M_construct_null(__new_finish);
williamr@2:       }
williamr@4:       _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start,__new_finish),
williamr@4:                     this->_M_end_of_storage.deallocate(__new_start,__len)))
williamr@4:       this->_M_destroy_range();
williamr@2:       this->_M_deallocate_block();
williamr@4:       this->_M_reset(__new_start, __new_finish, __new_start + __len);
williamr@2:     }
williamr@2:   }
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: basic_string<_CharT,_Traits,_Alloc>&
williamr@4: basic_string<_CharT,_Traits,_Alloc> ::replace(iterator __first, iterator __last,
williamr@4:                                               size_type __n, _CharT __c) {
williamr@4:   size_type __len = (size_type)(__last - __first);
williamr@2: 
williamr@2:   if (__len >= __n) {
williamr@2:     _Traits::assign(__first, __n, __c);
williamr@2:     erase(__first + __n, __last);
williamr@2:   }
williamr@2:   else {
williamr@2:     _Traits::assign(__first, __len, __c);
williamr@2:     insert(__last, __n - __len, __c);
williamr@2:   }
williamr@2:   return *this;
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: basic_string<_CharT,_Traits,_Alloc>&
williamr@4: basic_string<_CharT,_Traits,_Alloc> ::_M_replace(iterator __first, iterator __last,
williamr@4:                                                  const _CharT* __f, const _CharT* __l,
williamr@4:                                                  bool __self_ref) {
williamr@4:   const ptrdiff_t       __n = __l - __f;
williamr@2:   const difference_type __len = __last - __first;
williamr@2:   if (__len >= __n) {
williamr@4:     if (!__self_ref || __l < __first || __f >= __last)
williamr@4:       _M_copy(__f, __l, __first);
williamr@4:     else
williamr@4:       _M_move(__f, __l, __first);
williamr@2:     erase(__first + __n, __last);
williamr@2:   }
williamr@2:   else {
williamr@4:     if (!__self_ref || (__f >= __last) || (__l <= __first)) {
williamr@4:       //no overlap:
williamr@4:       const_iterator __m = __f + __len;
williamr@4:       _M_copy(__f, __m, __first);
williamr@4:       _M_insert(__last, __m, __l, false );
williamr@4:     }
williamr@4:     else {
williamr@4:       //we have to take care of overlaping
williamr@4:       if (__f < __first) {
williamr@4:         const_iterator __m = __f + __len;
williamr@4:         //We have to deal with possible reallocation because we do insert first.
williamr@4:         const difference_type __off_dest = __first - this->begin();
williamr@4:         const difference_type __off_src = __f - this->begin();
williamr@4:         _M_insert(__last, __m, __l, true);
williamr@4:         _Traits::move(begin() + __off_dest, begin() + __off_src, __len);
williamr@4:       }
williamr@4:       else {
williamr@4:         const_iterator __m = __f + __len;
williamr@4:         _Traits::move(__first, __f, __len);
williamr@4:         _M_insert(__last, __m, __l, true);
williamr@4:       }
williamr@4:     }
williamr@2:   }
williamr@2:   return *this;
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc> __size_type__
williamr@4: basic_string<_CharT,_Traits,_Alloc> ::find(const _CharT* __s, size_type __pos,
williamr@4:                                            size_type __n) const {
williamr@4:   const size_t __len = size();
williamr@4:   if (__pos >= __len || __pos + __n > __len)
williamr@2:     return npos;
williamr@2:   else {
williamr@4:     const_pointer __result =
williamr@4:       _STLP_STD::search(this->_M_Start() + __pos, this->_M_Finish(),
williamr@4:                         __s, __s + __n, _STLP_PRIV _Eq_traits<_Traits>());
williamr@4:     return __result != this->_M_Finish() ? __result - this->_M_Start() : npos;
williamr@2:   }
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc> __size_type__
williamr@4: basic_string<_CharT,_Traits,_Alloc> ::find(_CharT __c, size_type __pos) const {
williamr@4:   if (__pos >= size()) /*__pos + 1 > size()*/
williamr@2:     return npos;
williamr@2:   else {
williamr@4:     const_pointer __result =
williamr@4:       _STLP_STD::find_if(this->_M_Start() + __pos, this->_M_Finish(),
williamr@4:                          _STLP_PRIV _Eq_char_bound<_Traits>(__c));
williamr@4:     return __result != this->_M_Finish() ? __result - this->_M_Start() : npos;
williamr@2:   }
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: __size_type__
williamr@4: basic_string<_CharT,_Traits,_Alloc>::rfind(const _CharT* __s, size_type __pos, size_type __n) const
williamr@2: {
williamr@4:   const size_type __len = size();
williamr@4:   if ( __len < __n ) {
williamr@4:     return npos;
williamr@4:   }
williamr@4:   const_pointer __last = this->_M_Start() + (min)( __len - __n, __pos) + __n;
williamr@4:   const_pointer __result = find_end(this->_M_Start(), __last,
williamr@4:                                     __s, __s + __n, _STLP_PRIV _Eq_traits<_Traits>());
williamr@4:   return __result != __last ? __result - this->_M_Start() : npos;
williamr@4: }
williamr@4: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: __size_type__
williamr@4: basic_string<_CharT,_Traits,_Alloc>::rfind(_CharT __c, size_type __pos) const
williamr@4: {
williamr@4:   const size_type __len = size();
williamr@4:   if ( __len < 1 ) {
williamr@4:     return npos;
williamr@4:   }
williamr@4:   const_iterator __last = begin() + (min)(__len - 1, __pos) + 1;
williamr@4:   const_reverse_iterator __rresult =
williamr@4:     _STLP_STD::find_if(const_reverse_iterator(__last), rend(),
williamr@4:                        _STLP_PRIV _Eq_char_bound<_Traits>(__c));
williamr@4:   return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos;
williamr@4: }
williamr@4: 
williamr@4: template <class _CharT, class _Traits, class _Alloc> __size_type__
williamr@4: basic_string<_CharT,_Traits,_Alloc> ::find_first_of(const _CharT* __s, size_type __pos,
williamr@4:                                                     size_type __n) const {
williamr@4:   if (__pos >= size()) /*__pos + 1 > size()*/
williamr@2:     return npos;
williamr@2:   else {
williamr@4:     const_iterator __result = _STLP_PRIV __find_first_of(begin() + __pos, end(),
williamr@4:                                                          __s, __s + __n,
williamr@4:                                                          _STLP_PRIV _Eq_traits<_Traits>());
williamr@2:     return __result != end() ? __result - begin() : npos;
williamr@2:   }
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4:  __size_type__
williamr@4: basic_string<_CharT,_Traits,_Alloc> ::find_last_of(const _CharT* __s, size_type __pos,
williamr@4:                                                    size_type __n) const
williamr@2: {
williamr@2:   const size_type __len = size();
williamr@4:   if ( __len < 1 ) {
williamr@4:     return npos;
williamr@4:   }
williamr@4:   const const_iterator __last = begin() + (min)(__len - 1, __pos) + 1;
williamr@4:   const const_reverse_iterator __rresult =
williamr@4:     _STLP_PRIV __find_first_of(const_reverse_iterator(__last), rend(),
williamr@4:                                __s, __s + __n,
williamr@4:                               _STLP_PRIV _Eq_traits<_Traits>());
williamr@4:   return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos;
williamr@4: }
williamr@2: 
williamr@4: 
williamr@4: template <class _CharT, class _Traits, class _Alloc> __size_type__
williamr@4: basic_string<_CharT,_Traits,_Alloc> ::find_first_not_of(const _CharT* __s, size_type __pos,
williamr@4:                                                         size_type __n) const {
williamr@4:   typedef typename _Traits::char_type _CharType;
williamr@4:   if (__pos >= size()) /*__pos + 1 >= size()*/
williamr@2:     return npos;
williamr@2:   else {
williamr@4:     const_pointer __result = _STLP_STD::find_if(this->_M_Start() + __pos, this->_M_Finish(),
williamr@4:                                                 _STLP_PRIV _Not_within_traits<_Traits>(__CONST_CAST(const _CharType*, __s),
williamr@4:                                                                                         __CONST_CAST(const _CharType*, __s) + __n));
williamr@4:     return __result != this->_M_finish ? __result - this->_M_Start() : npos;
williamr@2:   }
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc> __size_type__
williamr@4: basic_string<_CharT,_Traits,_Alloc> ::find_first_not_of(_CharT __c, size_type __pos) const {
williamr@4:   if (1 > size())
williamr@2:     return npos;
williamr@2:   else {
williamr@4:     const_pointer __result = _STLP_STD::find_if(this->_M_Start() + __pos, this->_M_Finish(),
williamr@4:                                                 _STLP_PRIV _Neq_char_bound<_Traits>(__c));
williamr@4:     return __result != this->_M_finish ? __result - this->_M_Start() : npos;
williamr@2:   }
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: __size_type__
williamr@4: basic_string<_CharT,_Traits,_Alloc>::find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
williamr@2: {
williamr@2:   typedef typename _Traits::char_type _CharType;
williamr@2:   const size_type __len = size();
williamr@4:   if ( __len < 1 ) {
williamr@2:     return npos;
williamr@2:   }
williamr@4:   const_iterator __last = begin() + (min)(__len - 1, __pos) + 1;
williamr@4:   const_reverse_iterator __rlast = const_reverse_iterator(__last);
williamr@4:   const_reverse_iterator __rresult =
williamr@4:     _STLP_STD::find_if(__rlast, rend(),
williamr@4:                        _STLP_PRIV _Not_within_traits<_Traits>((const _CharType*)__s,
williamr@4:                                                               (const _CharType*)__s + __n));
williamr@4:   return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos;
williamr@2: }
williamr@2: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: __size_type__
williamr@4: basic_string<_CharT, _Traits, _Alloc>::find_last_not_of(_CharT __c, size_type __pos) const
williamr@2: {
williamr@2:   const size_type __len = size();
williamr@4:   if ( __len < 1 ) {
williamr@2:     return npos;
williamr@2:   }
williamr@4:   const_iterator __last = begin() + (min)(__len - 1, __pos) + 1;
williamr@4:   const_reverse_iterator __rlast = const_reverse_iterator(__last);
williamr@4:   const_reverse_iterator __rresult =
williamr@4:     _STLP_STD::find_if(__rlast, rend(),
williamr@4:                        _STLP_PRIV _Neq_char_bound<_Traits>(__c));
williamr@4:   return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos;
williamr@2: }
williamr@2: 
williamr@4: #if !defined (basic_string)
williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE
williamr@4: #endif
williamr@4: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@2: void _STLP_CALL _S_string_copy(const basic_string<_CharT,_Traits,_Alloc>& __s,
williamr@4:                                _CharT* __buf, size_t __n) {
williamr@2:   if (__n > 0) {
williamr@2:     __n = (min) (__n - 1, __s.size());
williamr@2:     _STLP_STD::copy(__s.begin(), __s.begin() + __n, __buf);
williamr@2:     __buf[__n] = _CharT();
williamr@2:   }
williamr@2: }
williamr@2: 
williamr@4: _STLP_MOVE_TO_STD_NAMESPACE
williamr@2: 
williamr@2: _STLP_END_NAMESPACE
williamr@2: 
williamr@4: #include <stl/_range_errors.h>
williamr@4: 
williamr@4: _STLP_BEGIN_NAMESPACE
williamr@4: 
williamr@4: _STLP_MOVE_TO_PRIV_NAMESPACE
williamr@4: 
williamr@4: // _String_base methods
williamr@4: template <class _Tp, class _Alloc>
williamr@4: void _String_base<_Tp,_Alloc>::_M_throw_length_error() const
williamr@4: { __stl_throw_length_error("basic_string"); }
williamr@4: 
williamr@4: template <class _Tp, class _Alloc>
williamr@4: void _String_base<_Tp, _Alloc>::_M_throw_out_of_range() const
williamr@4: { __stl_throw_out_of_range("basic_string"); }
williamr@4: 
williamr@4: template <class _Tp, class _Alloc>
williamr@4: void _String_base<_Tp, _Alloc>::_M_allocate_block(size_t __n) {
williamr@4:   if ((__n <= (max_size() + 1)) && (__n > 0)) {
williamr@4: #if defined (_STLP_USE_SHORT_STRING_OPTIM)
williamr@4:     if (__n > _DEFAULT_SIZE) {
williamr@4:       this->_M_buffers._M_dynamic_buf = _M_end_of_storage.allocate(__n, __n);
williamr@4:       this->_M_finish = this->_M_buffers._M_dynamic_buf;
williamr@4:       this->_M_end_of_storage._M_data = this->_M_finish + __n;
williamr@4:     }
williamr@4: #else
williamr@4:     this->_M_start  = _M_end_of_storage.allocate(__n, __n);
williamr@4:     this->_M_finish = this->_M_start;
williamr@4:     this->_M_end_of_storage._M_data = this->_M_finish + __n;
williamr@4: #endif /*_STLP_USE_SHORT_STRING_OPTIM  */
williamr@4:   } else {
williamr@4:     this->_M_throw_length_error();
williamr@4:   }
williamr@4: }
williamr@4: 
williamr@4: #if !defined (basic_string)
williamr@4: _STLP_MOVE_TO_STD_NAMESPACE
williamr@4: #endif
williamr@4: 
williamr@4: #if defined (_STLP_DONT_SUP_DFLT_PARAM)
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT* __s)
williamr@4:   : _STLP_PRIV _String_base<_CharT,_Alloc>(allocator_type()) {
williamr@4:   _STLP_FIX_LITERAL_BUG(__s)
williamr@4:   _M_range_initialize(__s, __s + traits_type::length(__s));
williamr@4: }
williamr@4: #endif
williamr@4: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT* __s,
williamr@4:                                                     const allocator_type& __a)
williamr@4:   : _STLP_PRIV _String_base<_CharT,_Alloc>(__a) {
williamr@4:   _STLP_FIX_LITERAL_BUG(__s)
williamr@4:   _M_range_initialize(__s, __s + traits_type::length(__s));
williamr@4: }
williamr@4: 
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: basic_string<_CharT, _Traits, _Alloc>::basic_string(const basic_string<_CharT, _Traits, _Alloc> & __s)
williamr@4:   : _STLP_PRIV _String_base<_CharT,_Alloc>(__s.get_allocator())
williamr@4: { _M_range_initialize(__s._M_Start(), __s._M_Finish()); }
williamr@4: 
williamr@4: #if defined (basic_string)
williamr@4: _STLP_MOVE_TO_STD_NAMESPACE
williamr@4: #  undef basic_string
williamr@4: #else
williamr@4: /* If basic_string is defined it means that it won't be the basic_string class
williamr@4:  * exposed to STLport users so npos do not need external linkage.
williamr@4:  */
williamr@4: #  if !defined (_STLP_STATIC_CONST_INIT_BUG)
williamr@4: #    if !defined (__GNUC__) || (__GNUC__ != 2) || (__GNUC_MINOR__ != 96)
williamr@4: template <class _CharT, class _Traits, class _Alloc>
williamr@4: const size_t basic_string<_CharT, _Traits, _Alloc>::npos;
williamr@4: #    endif
williamr@4: #  endif
williamr@4: #endif
williamr@4: 
williamr@4: _STLP_END_NAMESPACE
williamr@4: 
williamr@4: #undef __size_type__
williamr@4: #if defined (_STLP_NESTED_TYPE_PARAM_BUG)
williamr@4: #  undef size_type
williamr@4: #  undef iterator
williamr@4: #endif
williamr@2: 
williamr@2: #endif /*  _STLP_STRING_C */
williamr@2: 
williamr@2: // Local Variables:
williamr@2: // mode:C++
williamr@2: // End: