home *** CD-ROM | disk | FTP | other *** search
- #ifndef __STRING_CC
- #define __STRING_CC
- #pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
- /***************************************************************************
- *
- * string.cc - Definitions for the Standard Library string classes
- *
- ***************************************************************************
- *
- * Copyright (c) 1994-1999 Rogue Wave Software, Inc. All Rights Reserved.
- *
- * This computer software is owned by Rogue Wave Software, Inc. and is
- * protected by U.S. copyright laws and other laws and by international
- * treaties. This computer software is furnished by Rogue Wave Software,
- * Inc. pursuant to a written license agreement and may be used, copied,
- * transmitted, and stored only in accordance with the terms of such
- * license and with the inclusion of the above copyright notice. This
- * computer software or any other copies thereof may not be provided or
- * otherwise made available to any other person.
- *
- * U.S. Government Restricted Rights. This computer software is provided
- * with Restricted Rights. Use, duplication, or disclosure by the
- * Government is subject to restrictions as set forth in subparagraph (c)
- * (1) (ii) of The Rights in Technical Data and Computer Software clause
- * at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
- * Commercial Computer Software รป Restricted Rights at 48 CFR 52.227-19,
- * as applicable. Manufacturer is Rogue Wave Software, Inc., 5500
- * Flatiron Parkway, Boulder, Colorado 80301 USA.
- *
- **************************************************************************/
- #include <stdcomp.h>
-
- //
- // Members for class basic_string
- //
-
- #ifndef _RWSTD_NO_NAMESPACE
- namespace std {
- #endif
-
- // basic_string<...>::__nullref
- #ifndef _RWSTD_NO_STATIC_DEF3
- template <class charT, class traits, class Allocator >
- const _TYPENAME basic_string<charT, traits, Allocator>::__null_ref_type
- basic_string<charT, traits, Allocator>::__nullref;
- #endif
- // basic_string<...>::npos
- #if defined(__BORLANDC__) && !defined(_RTLDLL)
- #ifdef _RWSTD_MSC22_STATIC_INIT_BUG
- #define npos (size_type)-1
- #else
- template <class charT, class traits, class Allocator >
- const _TYPENAME basic_string<charT, traits, Allocator>::size_type
- basic_string<charT, traits, Allocator>::npos
- #ifdef _RWSTD_NO_STATIC_CAST
- = (_TYPENAME basic_string<charT, traits, Allocator>::size_type) -1;
- #else
- = static_cast</* _TYPENAME */ basic_string<charT, traits, Allocator>::size_type>(-1); // RW_BUG
- #endif
-
- #endif /* __BORLANDC__ && !_RTLDLL */
- #endif /*_RWSTD_MSC22_STATIC_INIT_BUG*/
-
- template <class charT, class traits, class Allocator >
- _TYPENAME basic_string<charT, traits, Allocator>::__string_ref_type *
- basic_string<charT, traits, Allocator>::__getRep (size_type capac,
- size_type nchar)
-
- {
- if (capac < nchar)
- capac = nchar;
-
- if ((capac | nchar) == 0)
- {
- __getNullRep()->__addReference();
- return __getNullRep();
- }
-
- //
- // Allocate, then initialize the __string_ref, then
- // initialize each character in the buffer.
- //
- __value_alloc_type va(__data_);
- #ifdef _RWSTD_NO_STATIC_CAST
- __string_ref_type * ret = (__string_ref_type *)
- va.allocate(capac + sizeof(__rep_type)/sizeof(charT) + 2,0);
- #else
- __string_ref_type * ret =
- reinterpret_cast<__string_ref_type*>
- (va.allocate(capac + sizeof(__rep_type)/sizeof(charT) + 2,0));
- #endif
-
- __ref_alloc_type(__data_).construct(ret, __string_ref_type());
- charT * d = ret->data();
- va.construct(d,charT());
-
- ret->__capacity_ = capac;
- ret->__setRefCount(1);
- ret->data()[ret->__nchars_ = nchar] = (charT)0; // Terminating null
- return ret;
- }
-
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator>::basic_string (
- const basic_string<charT, traits, Allocator> & s,
- size_type pos, size_type n,
- const Allocator& alloc)
- : __data_(0,alloc)
- {
- _RWSTD_THROW(pos > s.length(), out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_StringIndexOutOfRange,
- "basic_string( const basic_string&,size_type,size_type)", pos,s.length()).msgstr());
-
- size_type slen = s.length() - pos;
- size_type rlen = n < slen ? n : slen;
- size_type nlen = n == npos ? 0 : n;
- size_type maxlen = nlen > rlen ? nlen : rlen;
- __data_ = __getRep(maxlen, rlen)->data();
-
- traits::copy(__data_.data(), &s.__data_.data()[pos], rlen);
- }
-
- template <class charT, class traits, class Allocator >
- void basic_string<charT, traits, Allocator>::__initn (
- size_type n,
- charT c)
- {
- _RWSTD_THROW(n == npos, length_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_InvalidSizeParam,
- "basic_string::__initn(size_t,char)", n,npos).msgstr());
-
- __data_ = __getRep(n, n)->data();
-
- while (n--) traits::assign(__data_.data()[n], c);
- }
-
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator>::basic_string (
- const charT* s,
- size_type n,
- const Allocator& alloc)
- : __data_(0,alloc)
- {
- _RWSTD_THROW(s == 0, logic_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_UnexpectedNullPtr,
- "basic_string( const charT*,size_type,const Allocator&)").msgstr());
-
- _RWSTD_THROW(n == npos, length_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_InvalidSizeParam,
- "basic_string( const charT*,size_type,const Allocator&)",n,npos).msgstr());
-
- __data_ = __getRep(n, n)->data();
- traits::copy(__data_.data(), s, n);
- }
-
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator>::basic_string (
- const charT* s,
- const Allocator& alloc)
- : __data_(0,alloc)
- {
- _RWSTD_THROW(s == 0, logic_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_UnexpectedNullPtr,
- "basic_string(const charT*,const Allocator&)").msgstr());
-
- size_type len = traits::length(s);
- __data_ = __getRep(len, len)->data();
-
- traits::copy(__data_.data(), s, len);
- }
-
- #ifdef _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator>::basic_string (
- const charT* s,
- size_type n)
- : __data_(0,Allocator())
- {
- _RWSTD_THROW(s == 0, logic_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_UnexpectedNullPtr,
- "basic_string( const charT*,size_type)").msgstr());
-
- _RWSTD_THROW(n == npos, length_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_InvalidSizeParam,
- "basic_string(const charT*,size_type)",n,npos).msgstr());
-
- __data_ = __getRep(n, n)->data();
-
- traits::copy(__data_.data(), s, n);
- }
-
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator>::basic_string (
- const charT* s)
- : __data_(0,Allocator())
- {
- _RWSTD_THROW(s == 0, logic_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_UnexpectedNullPtr,
- "basic_string(const charT*)").msgstr());
-
- size_type len = traits::length(s);
- __data_ = __getRep(len, len)->data();
-
- traits::copy(__data_.data(), s, len);
- }
- #endif
-
- #ifndef _RWSTD_NO_MEMBER_TEMPLATES
- template <class charT, class traits , class Allocator >
- template <class InputIterator>
- basic_string<charT, traits, Allocator>::basic_string (InputIterator first,
- InputIterator last,
- const Allocator &alloc)
- : __data_(0,alloc)
- {
- __data_ = __getRep(1,0)->data();
- replace(__data_.data(),__data_.data(),first,last);
- }
- #endif /* _RWSTD_NO_MEMBER_TEMPLATES */
-
- template <class charT, class traits , class Allocator >
- basic_string<charT, traits, Allocator>::basic_string (const charT* first,
- const charT* last,
- const Allocator& alloc)
- : __data_(0,alloc)
- {
- __data_ = __getRep(last-first,0)->data();
- replace(0,0,first,last-first,0,last-first);
- }
-
- #ifdef _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
- template <class charT, class traits , class Allocator >
- basic_string<charT, traits, Allocator>::basic_string (const charT* first,
- const charT* last)
- : __data_(0,Allocator())
- {
- __data_ = __getRep(last-first,0)->data();
- replace(0,0,first,last-first,0,last-first);
- }
- #endif /* _RWSTD_NO_DEFAULT_TEMPLATE_ARGS */
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator> &
- basic_string<charT, traits, Allocator>::operator= (
- const basic_string<charT, traits, Allocator>& str)
- {
- if (this != &str)
- {
- if (str.__pref()->__references() > 0)
- {
- str.__pref()->__addReference();
- __unLink();
- __data_ = str.__data_.data();
- }
- else
- this->operator=(str.c_str());
- }
- return *this;
- }
-
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator> &
- basic_string<charT, traits, Allocator>::operator= (const charT* s)
- {
- _RWSTD_THROW(s == 0, logic_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_UnexpectedNullPtr,
- "basic_string::operator= (const charT*)").msgstr());
-
- if (traits::eq(*s, __eos()))
- {
- if (__pref()->__references() == 1)
- {
- __pref()->__nchars_ = 0;
- traits::assign(__data_.data()[0], __eos());
- }
- else
- {
- __unLink();
- __getNullRep()->__addReference();
- __data_ = __getNullRep()->data();
- }
- return *this;
- }
-
- return replace(0, length(), s, traits::length(s));
- }
-
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator> &
- basic_string<charT, traits, Allocator>::append (
- const basic_string<charT, traits, Allocator>& str,
- size_type pos,
- size_type n)
- {
- _RWSTD_THROW(pos > str.length(), out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_StringIndexOutOfRange,
- "basic_string::append(basic_string&,size_type,size_type)", pos,str.length()).msgstr());
-
- size_type slen = str.length() - pos;
- size_type rlen = n < slen ? n : slen;
-
- _RWSTD_THROW(length() >= npos - rlen, length_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_ResultLenInvalid,
- "basic_string::append(const basic_string&,size_type,size_type)",
- length(),npos-rlen).msgstr());
-
- replace(length(), 0, str.data(), str.length(), pos, n);
-
- return *this;
- }
-
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator> &
- basic_string<charT, traits, Allocator>::append (
- const basic_string<charT, traits, Allocator>& str)
- {
- _RWSTD_THROW(length() >= npos - str.length(), length_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_ResultLenInvalid,
- "basic_string::append(const basic_string&)",length(),str.length()).msgstr());
-
- replace(length(), 0, str.data(), str.length());
-
- return *this;
- }
-
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator> &
- basic_string<charT, traits, Allocator>::assign (
- const basic_string<charT, traits, Allocator>& str,
- size_type pos,
- size_type n)
- {
- _RWSTD_THROW(pos > str.length(), out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_PosBeyondEndOfString,
- "basic_string::assign(basic_string&,size_type,size_type)", pos,str.length()).msgstr());
-
- size_type slen = str.length() - pos;
- size_type rlen = n < slen ? n : slen;
- return replace(0, length(), str, pos, rlen);
- }
-
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator> &
- basic_string<charT, traits, Allocator>::assign (
- const basic_string<charT, traits, Allocator>& str)
- {
- return replace(0, length(), str);
- }
-
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator> &
- basic_string<charT, traits, Allocator>::insert (
- size_type pos1,
- const basic_string<charT, traits, Allocator>& str,
- size_type pos2,
- size_type n)
- {
- _RWSTD_THROW(pos1 > length() || pos2 > str.length(), out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_StringIndexOutOfRange,
- "basic_string::insert(size_t,const basic_string&,size_t,size_t)",
- pos1 > length() ? pos1:pos2,str.length()).msgstr());
-
- size_type slen = str.length() - pos2;
- size_type rlen = n < slen ? n : slen;
-
- _RWSTD_THROW( length() >= npos - rlen, length_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_ResultLenInvalid,
- "basic_string::insert(size_t,const basic_string&,size_t,size_t)",
- length(),npos - rlen).msgstr());
-
- return replace(pos1, 0, str, pos2, n);
- }
-
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator> &
- basic_string<charT, traits, Allocator>::insert (
- size_type pos1,
- const basic_string<charT, traits, Allocator>& str)
- {
- _RWSTD_THROW(pos1 > length(), out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_StringIndexOutOfRange,
- "basic_string::insert(size_t,const basic_string&)",pos1,length()).msgstr());
-
- _RWSTD_THROW(length() >= npos - str.length(), length_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_ResultLenInvalid,
- "basic_string::insert(size_t,const basic_string&)",
- length(), npos - str.length()).msgstr());
-
- return replace(pos1, 0, str);
- }
-
- template <class charT, class traits, class Allocator >
- _TYPENAME basic_string<charT, traits, Allocator>::iterator
- basic_string<charT, traits, Allocator>::replace (
- size_type pos1,
- size_type n1,
- const charT* cs,
- size_type cslen,
- size_type pos2,
- size_type n2)
- {
- _RWSTD_THROW(pos1 > length() || pos2 > cslen, out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_StringIndexOutOfRange,
- "basic_string::replace(size_t,size_t,char*,size_t,size_t,size_t)",
- pos1 > length() ? pos1:pos2,length() > cslen ? length():cslen).msgstr());
-
- size_type slen = length() - pos1;
- size_type xlen = n1 < slen ? n1 : slen;
- size_type clen = cslen - pos2;
- size_type rlen = n2 < clen ? n2 : clen;
-
- _RWSTD_THROW(length() - xlen >= npos - rlen, length_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_ResultLenInvalid,
- "basic_string::replace(size_t,size_t,char*,size_t,size_t,size_t)",
- length()-xlen,npos - rlen).msgstr());
-
- size_type tot = length() - xlen + rlen; // Final string length.
-
- if (!tot)
- {
- // Special case a substitution that leaves the string empty.
- __unLink();
- __getNullRep()->__addReference();
- __data_ = __getNullRep()->data();
- }
- else
- {
- size_type rem = length() - xlen - pos1; // Length of bit at end of string
- // Check for shared representation, insufficient capacity,
- // or overlap copy.
- if ( (__pref()->__references() > 1)
- || (__getCapac() < tot)
- || (cs && (cs >= data() && cs < data()+length())))
- {
- // Need to allocate a new reference.
- __string_ref_type * temp = __getRep(tot,tot);
- if (pos1) traits::copy(temp->data(), __data_.data(), pos1);
- if (rlen) traits::copy(temp->data()+pos1, cs+pos2, rlen);
- if (rem ) traits::copy(temp->data()+pos1+rlen, __data_.data()+pos1+n1, rem);
- __unLink();
- __data_ = temp->data();
- }
- else
- {
- // Current reference has enough room.
- if (rem) traits::move(__data_.data()+pos1+rlen, __data_.data()+pos1+n1, rem);
- if (rlen) traits::move(__data_.data()+pos1, cs+pos2, rlen);
- __data_.data()[__pref()->__nchars_ = tot] = __eos(); // Add terminating null
- }
- }
- return __data_.data() + pos1;
- }
-
- template <class charT, class traits , class Allocator >
- basic_string<charT, traits, Allocator> &
- basic_string<charT, traits, Allocator>::replace (size_type pos,
- size_type n,
- size_type n2,
- charT c)
- {
- _RWSTD_THROW(pos > length(), out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_StringIndexOutOfRange,
- "basic_string:::replace(size_t,size_t,size_t,char)", pos,length()).msgstr());
-
- size_type slen = length() - pos;
- size_type xlen = n < slen ? n : slen;
-
- _RWSTD_THROW(length() - xlen >= npos - n2, length_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_ResultLenInvalid,
- "basic_string::replace(size_t,size_t,size_t,char)",
- length()-xlen,npos - n2).msgstr());
-
- size_type tot = length() - xlen + n2; // Final string length.
-
- if (!tot)
- {
- // Special case a substitution that leaves the string empty.
- __unLink();
- __getNullRep()->__addReference();
- __data_ = __getNullRep()->data();
- }
- else
- {
- size_type rem = length() - xlen - pos; // Length of bit at end of string
- // Check for shared representation, insufficient capacity,
- if ( (__pref()->__references() > 1) || (__getCapac() < tot))
- {
- // Need to allocate a new reference.
- __string_ref_type * temp = __getRep(tot,tot);
- if (pos) traits::copy(temp->data(), __data_.data(), pos);
- if (n2) traits::assign(temp->data()+pos, n2,c);
- if (rem ) traits::copy(temp->data()+pos+n2, __data_.data()+pos+n, rem);
- __unLink();
- __data_ = temp->data();
- }
- else
- {
- // Current reference has enough room.
- if (rem) traits::move(__data_.data()+pos+n2, __data_.data()+pos+n, rem);
- if (n2) traits::assign(__data_.data()+pos, n2, c);
- __data_.data()[__pref()->__nchars_ = tot] = __eos(); // Add terminating null
- }
- }
- return *this;
- }
-
- #ifndef _RWSTD_NO_MEMBER_TEMPLATES
-
- // Since we have no way of knowing how much is out there
- // between first2 and last2 we have to allocate some space
- // in chunks as needed and copy over characters in groups
- // until we reach the end of the range. After that
- // we can tidy things up. We avoid this using replace_aux
- // any time we have an InputIterator capable of giving us
- // the distance information we need. If InputIterator
- // is really a charT* then we should never even get here.
- template<class charT, class traits , class Allocator >
- template<class InputIterator>
- inline basic_string<charT, traits, Allocator>&
- basic_string<charT, traits, Allocator>::replace (
- iterator first1,
- iterator last1,
- InputIterator first2,
- InputIterator last2)
- {
- iterator first = first1;
- iterator last = last1;
-
- // Use a (probably)faster algorithm if possible
- if (__is_bidirectional_iterator(__iterator_category(first2)))
- return __replace_aux(first1,last1,first2,last2);
-
- _RWSTD_THROW((first > end() || last > end()),out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_StringIndexOutOfRange,
- "basic_string::replace(iterator,iterator,InputIterato,InputIterato)"
- ,first > end() ? first : last,end()).msgstr());
-
- while (first2 != last2)
- {
- _RWSTD_THROW(first - __data_.data() == (int)npos,length_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_ResultLenInvalid,
- "basic_string::replace(iterator,iterator,InputIterator,InputIterator)"
- ,first-__data_.data(),npos).msgstr());
- if (first == last)
- {
- // Need to allocate a more room.
- // First get the amount to increase buffer size
- size_type delta = __RWSTD::__rw_allocation_size((value_type*)0,
- (size_type)0,
- (size_type)0);
- delta = delta > 0 ? delta : 1;
- size_type tot = delta + size();
- // Now get new buffer
- __string_ref_type * temp = __getRep(tot,tot);
- // Now copy data from old to new, leaving a hole for additions
- size_type current = last-begin();
- traits::copy(temp->data(),__data_.data(),current);
- traits::copy(temp->data()+current+delta,last,end()-last);
- __unLink();
- __data_ = temp->data();
- first = __data_.data() + current;
- last = first + delta;
- }
- // Copy data over
- *first++ = *first2++;
- }
- if (first != last)
- replace(first-__data_.data(),last-first,0,(charT)' '); // Clean up
-
- return *this;
- }
-
- // Special function for random access and bi-directional iterators
- // Avoids the possibility of multiple allocations
- // We still have to copy characters over one at a time.
- template<class charT, class traits , class Allocator >
- template<class InputIterator>
- inline basic_string<charT, traits, Allocator>&
- basic_string<charT, traits, Allocator>::__replace_aux (
- iterator first1,
- iterator last1,
- InputIterator first2,
- InputIterator last2)
- {
- difference_type n2 = 0;
- distance(first2,last2,n2);
- size_type n = last1-first1;
- size_type pos = first1 - __data_.data();
-
- _RWSTD_THROW(pos > length(),out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_StringIndexOutOfRange,
- "basic_string::__replace_aux(iterator,iterator,InputIterator,InputIterator)"
- ,pos,length()).msgstr());
-
- size_type slen = length() - pos;
- size_type xlen = n < slen ? n : slen;
-
- _RWSTD_THROW(length() - xlen >= npos - n2,length_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_ResultLenInvalid,
- "basic_string::__replace_aux(iterator,iterator,InputIterator,InputIterator)"
- ,length() - xlen, npos - n2).msgstr());
-
- size_type tot = length() - xlen + n2; // Final string length.
-
- if (!tot)
- {
- // Special case a substitution that leaves the string empty.
- __unLink();
- __getNullRep()->__addReference();
- __data_ = __getNullRep()->data();
- }
-
- else
- {
- size_type d = 0;
- size_type rem = length() - xlen - pos; // Length of bit at end of string
- // Check for shared representation, insufficient capacity,
- if ( (__pref()->__references() > 1) || (__getCapac() < tot))
- {
- // Need to allocate a new reference.
- __string_ref_type * temp = __getRep(tot,tot);
- if (pos) traits::copy(temp->data(), __data_.data(), pos);
- for (d = 0; d < (size_type)n2; d++)
- *(temp->data()+pos+d) = *first2++;
- if (rem )
- traits::copy(temp->data()+pos+n2, __data_.data()+pos+n, rem);
- __unLink();
- __data_ = temp->data();
- }
- else
- {
- // Current reference has enough room.
- if (rem)
- traits::move(__data_.data()+pos+n2, __data_.data()+pos+n, rem);
- for (d = 0; d < (size_type)n2; d++)
- *(__data_.data()+pos+d) = *first2++;
- __data_.data()[__pref()->__nchars_ = tot] = __eos(); // Add terminating null
- }
- }
- return *this;
- }
- #endif // _RWSTD_NO_MEMBER_TEMPLATES
-
- template <class charT, class traits, class Allocator >
- _TYPENAME basic_string<charT, traits, Allocator>::size_type
- basic_string<charT, traits, Allocator>::copy (charT* s,
- size_type n,
- size_type pos) const
- {
- _RWSTD_THROW(pos > length(), out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_PosBeyondEndOfString,
- "basic_string::copy(char*,size_t,size_t)",pos,length()).msgstr());
-
- size_type slen = length() - pos;
- size_type rlen = n < slen ? n : slen;
- traits::copy(s, __data_.data()+pos, rlen);
- return rlen;
- }
- template <class charT, class traits , class Allocator >
- _TYPENAME basic_string<charT, traits, Allocator>::size_type
- basic_string<charT, traits, Allocator>::find (const charT* s,
- size_type pos,
- size_type n) const
- {
- _RWSTD_THROW(s == 0, logic_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_UnexpectedNullPtr,
- "basic_string::find(char*,size_t,size_t) const").msgstr());
-
- for (size_type xpos = pos; (xpos + n) <= length() ; xpos++)
- {
- if (!traits::compare(__data_.data()+xpos,s,n))
- return xpos;
- }
-
- return npos;
- }
-
- template <class charT, class traits , class Allocator >
- _TYPENAME basic_string<charT, traits, Allocator>::size_type
- basic_string<charT, traits, Allocator>::rfind (const charT* s,
- size_type pos,
- size_type n) const
- {
-
- _RWSTD_THROW(s == 0, logic_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_UnexpectedNullPtr,
- "basic_string::rfind(char*,size_t,size_t) const").msgstr());
-
- if (length() < n)
- return npos;
-
- size_type slen = length() -n;
- size_type xpos_start = slen < pos ? slen : pos;
-
- for (size_type xpos = xpos_start+1; xpos != 0 ; xpos--)
- {
- if (!traits::compare(__data_.data()+xpos-1,s,n))
- return xpos-1;
- }
-
- return npos;
- }
-
- template <class charT, class traits , class Allocator >
- _TYPENAME basic_string<charT, traits, Allocator>::size_type
- basic_string<charT, traits, Allocator>::find_first_of (const charT* s,
- size_type pos,
- size_type n) const
- {
-
- _RWSTD_THROW(s == 0, logic_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_UnexpectedNullPtr,
- "basic_string::find_first_of(char*,size_t,size_t) const").msgstr());
-
- for (size_type xpos = pos; xpos < length() ; xpos++)
- {
- for (size_type i = 0; i < n ; i++)
- if (traits::eq(__data_.data()[xpos], s[i]))
- return xpos;
- }
-
- return npos;
- }
- template <class charT, class traits , class Allocator >
- _TYPENAME basic_string<charT, traits, Allocator>::size_type
- basic_string<charT, traits, Allocator>::find_last_of (const charT* s,
- size_type pos,
- size_type n) const
- {
- _RWSTD_THROW(s == 0, logic_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_UnexpectedNullPtr,
- "basic_string::find_last_of(char*,size_t,size_t) const").msgstr());
-
- if (length())
- {
- size_type slen = length() -1;
- size_type xpos_start = pos < slen ? pos : slen;
- for (size_type xpos = xpos_start+1; xpos != 0 ; xpos--)
- {
- for(size_type i = 0; i < n ; i++)
- if (traits::eq(__data_.data()[xpos-1], s[i]))
- return xpos-1;
- }
- }
- return npos;
- }
-
- template <class charT, class traits , class Allocator >
- _TYPENAME basic_string<charT, traits, Allocator>::size_type
- basic_string<charT, traits, Allocator>::find_first_not_of (const charT* s,
- size_type pos,
- size_type n) const
- {
- _RWSTD_THROW(s == 0, logic_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_UnexpectedNullPtr,
- "basic_string::find_first_not_of(char*,size_t,size_t) const").msgstr());
-
- for (size_type xpos = pos; xpos < length() ; xpos++)
- {
- bool found = false;
- for (size_type i = 0; i < n ; i++)
- {
- if (traits::eq(__data_.data()[xpos], s[i]))
- {
- found = true;
- break;
- }
- }
- if (!found)
- return xpos;
- }
-
- return npos;
- }
-
- template <class charT, class traits , class Allocator >
- _TYPENAME basic_string<charT, traits, Allocator>::size_type
- basic_string<charT, traits, Allocator>::find_last_not_of(const charT* s,
- size_type pos,
- size_type n) const
- {
- _RWSTD_THROW(s == 0, logic_error,
- __RWSTD::except_msg_string(__RWSTD::__rwse_UnexpectedNullPtr,
- "basic_string::find_last_not_of(char*,size_t,size_t) const").msgstr());
-
- if (length())
- {
- size_type slen = length() -1;
- size_type xpos_start = pos < slen ? pos : slen;
- for (size_type xpos = xpos_start+1; xpos != 0 ; xpos--)
- {
- bool found = false;
- for (size_type i = 0; i < n ; i++)
- {
- if (traits::eq(__data_.data()[xpos-1], s[i]))
- {
- found = true;
- break;
- }
- }
- if (!found)
- return xpos-1;
- }
- }
-
- return npos;
- }
-
- template <class charT, class traits, class Allocator >
- basic_string<charT, traits, Allocator>
- basic_string<charT, traits, Allocator>::substr (size_type pos,
- size_type n) const
- {
- _RWSTD_THROW(pos > length(), out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_PosBeyondEndOfString,
- "basic_string::substr(size_t,size_t) const",pos, length()).msgstr());
-
- size_type slen = length() -pos;
- size_type rlen = n < slen ? n : slen;
- return basic_string<charT, traits, Allocator>(__data_.data()+pos, rlen);
- }
-
- template <class charT, class traits, class Allocator >
- int
- basic_string<charT, traits, Allocator>::compare (
- size_type pos1, size_type n1,
- const basic_string<charT, traits, Allocator>& str,
- size_type pos2, size_type n2) const
- {
- _RWSTD_THROW(pos1+n1 > length() || pos2+n2 > str.length(),out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_PosBeyondEndOfString,
- "basic_string::compare(size_t,size_t,const basic_string&,size_t,size_t) const",
- pos1+n1 > length() ? (pos1+n1) : (pos2+n2),length() > str.length() ? length(): str.length()).msgstr());
-
- return compare(pos1,n1,str.c_str()+pos2,n2);
- }
-
- template <class charT, class traits, class Allocator >
- int
- basic_string<charT, traits, Allocator>::compare (
- size_type pos1, size_type n1,
- const basic_string<charT, traits, Allocator>& str) const
- {
- _RWSTD_THROW(pos1+n1 > length() ,out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_PosBeyondEndOfString,
- "basic_string::compare(size_t,size_t,const basic_string&) const",
- pos1+n1 ,length()).msgstr());
-
- return compare(pos1,n1,str.c_str(),str.length());
- }
-
- template <class charT, class traits , class Allocator >
- int
- basic_string<charT, traits, Allocator>::compare (size_type pos,
- size_type n1,
- const charT* s,
- size_type n2) const
- {
- _RWSTD_THROW(pos > length() ,out_of_range,
- __RWSTD::except_msg_string(__RWSTD::__rwse_PosBeyondEndOfString,
- "basic_string::compare(size_t,size_t,const const charT*,size_t) const",
- pos ,length()).msgstr());
- if(length() - pos < n1)
- n1 = length() - pos;
- size_type rlen = n1 < n2 ? n1 : n2;
- int result = traits::compare(__data_.data()+pos, s, rlen);
-
- if (result == 0)
- result = (n1 < n2) ? -1 : (n1 != n2);
-
- return result;
- }
-
- template <class charT, class traits, class Allocator >
- void basic_string<charT, traits, Allocator>::__clobber (size_type nc)
- {
- if (__pref()->__references() > 1 || (__getCapac() < nc))
- {
- __unLink();
- __data_ = __getRep(nc, 0)->data();
- }
- else
- __data_.data()[__pref()->__nchars_ = 0] = 0;
- }
-
- template <class charT, class traits, class Allocator >
- void basic_string<charT, traits, Allocator>::__clone()
- {
- __string_ref_type * temp = __getRep(length(), length());
- traits::copy(temp->data(), data(), length());
- __unLink();
- __data_ = temp->data();
- }
-
- template <class charT, class traits, class Allocator >
- void basic_string<charT, traits, Allocator>::__clone (size_type nc)
- {
- size_type len = length();
- if (len > nc) len = nc;
- __string_ref_type * temp = __getRep(nc, len);
- traits::copy(temp->data(), data(), length());
- __unLink();
- __data_ = temp->data();
- }
-
- #ifdef _RWSTD_MSC22_STATIC_INIT_BUG
- #undef npos
- #endif
-
- //
- // Inserters and Extractors
- //
-
- #ifndef _RW_STD_IOSTREAM
-
- template<class charT, class traits, class Allocator>
- istream & _RWSTDExportTemplate operator>> (istream & is,
- basic_string<charT, traits, Allocator > & s)
- {
- int c;
-
- if (!is.ipfx())
- return is;
-
- s.erase();
- c = is.rdbuf()->sbumpc();
-
- #ifdef _RWSTD_MS40_ISTREAM_BUG
- _TYPENAME size_t i =0;
- _TYPENAME size_t end = s.max_size();
- #else
- _TYPENAME Allocator::size_type i = 0;
- _TYPENAME Allocator::size_type end = s.max_size();
- #endif
- if (is.width())
- end = (int)end < is.width() ? end : is.width();
-
- while (c != EOF && !isspace(c))
- {
- s.append(1,(charT)c);
- i++;
- if (i == end)
- break;
- c = is.rdbuf()->sbumpc();
- }
- if (c == EOF)
- is.clear(ios::eofbit | is.rdstate());
- if (!i)
- is.clear(ios::failbit | is.rdstate());
-
- is.width(0);
- return is;
- }
- template<class charT, class traits, class Allocator>
- ostream & _RWSTDExportTemplate operator<< (ostream & os,
- const basic_string<charT, traits, Allocator > & s)
- {
- os << s.data();
- return os;
- }
-
- template<class Stream, class charT, class traits, class Allocator>
- Stream& _RWSTDExportTemplate
- getline (Stream& is, basic_string<charT, traits, Allocator>& str, charT delim)
- {
- int c;
-
- if (!is.ipfx(1))
- return is;
-
- str.erase();
- c = is.rdbuf()->sbumpc();
-
- #ifdef _RWSTD_MS40_ISTREAM_BUG
- size_t i = 0;
- size_t end = str.max_size();
- #else
- _TYPENAME Allocator::size_type i = 0;
- _TYPENAME Allocator::size_type end = str.max_size();
- #endif
-
- while (c != EOF)
- {
- i++;
- if ((charT)c == delim)
- break;
- if (i == end)
- {
- is.clear(ios::failbit | is.rdstate());
- break;
- }
-
- str.append(1,(charT)c);
- c = is.rdbuf()->sbumpc();
- }
- if (c == EOF)
- is.clear(ios::eofbit | is.rdstate());
- if (!i)
- is.clear(ios::failbit | is.rdstate());
-
- is.isfx();
- return is;
- }
- #endif /* not defined _RW_STD_IOSTREAM */
-
- #ifndef _RWSTD_NO_NAMESPACE
- }
- #endif
-
- #pragma option pop
- #endif /* __STRING_CC */
-