You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1519 lines
46 KiB
1519 lines
46 KiB
5 years ago
|
// -*- C++ -*-
|
||
|
/***************************************************************************
|
||
|
*
|
||
|
* <string> - definition of the C++ Standard Library basic_string template
|
||
|
*
|
||
|
* $Id: string 172106 2011-11-02 17:04:12Z statham $
|
||
|
*
|
||
|
***************************************************************************
|
||
|
*
|
||
|
* Copyright (c) 1994-2001 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.
|
||
|
*
|
||
|
**************************************************************************/
|
||
|
|
||
|
#ifndef _RWSTD_STRING_INCLUDED
|
||
|
#define _RWSTD_STRING_INCLUDED
|
||
|
|
||
|
#include <iosfwd>
|
||
|
#include <limits>
|
||
|
|
||
|
#include <rw/_algobase.h>
|
||
|
#include <rw/_iterator.h>
|
||
|
#include <rw/_strref.h>
|
||
|
#include <rw/_defs.h>
|
||
|
#include <rw/_error.h>
|
||
|
|
||
|
|
||
|
_RWSTD_NAMESPACE_BEGIN (std)
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits, class _Allocator>
|
||
|
class basic_string: private _Allocator
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
typedef _Traits traits_type;
|
||
|
typedef _TYPENAME traits_type::char_type value_type;
|
||
|
typedef _Allocator allocator_type;
|
||
|
|
||
|
private:
|
||
|
|
||
|
typedef _RW::__string_ref<value_type, traits_type, allocator_type>
|
||
|
_C_string_ref_type;
|
||
|
|
||
|
typedef _RWSTD_ALLOC_TYPE(allocator_type, value_type)
|
||
|
_C_value_alloc_type;
|
||
|
typedef _RWSTD_REBIND(allocator_type, _C_string_ref_type)
|
||
|
_C_ref_alloc_type;
|
||
|
|
||
|
public:
|
||
|
|
||
|
typedef _TYPENAME allocator_type::size_type size_type;
|
||
|
typedef _TYPENAME allocator_type::difference_type difference_type;
|
||
|
typedef _TYPENAME allocator_type::reference reference;
|
||
|
typedef _TYPENAME allocator_type::const_reference const_reference;
|
||
|
typedef _TYPENAME allocator_type::pointer pointer;
|
||
|
typedef _TYPENAME allocator_type::const_pointer const_pointer;
|
||
|
|
||
|
#ifndef _RWSTD_NO_DEBUG_ITER
|
||
|
|
||
|
typedef _RW::__rw_debug_iter <basic_string, pointer, pointer>
|
||
|
iterator;
|
||
|
|
||
|
typedef _RW::__rw_debug_iter <basic_string, const_pointer, pointer>
|
||
|
const_iterator;
|
||
|
|
||
|
iterator _C_make_iter (const pointer& __ptr) {
|
||
|
return iterator (*this, __ptr);
|
||
|
}
|
||
|
|
||
|
const_iterator _C_make_iter (const const_pointer& __ptr) const {
|
||
|
return const_iterator (*this, __ptr);
|
||
|
}
|
||
|
|
||
|
#else // if defined (_RWSTD_NO_DEBUG_ITER)
|
||
|
|
||
|
typedef pointer iterator;
|
||
|
typedef const_pointer const_iterator;
|
||
|
|
||
|
iterator _C_make_iter (pointer __ptr) {
|
||
|
return __ptr;
|
||
|
}
|
||
|
|
||
|
const_iterator _C_make_iter (const_pointer __ptr) const {
|
||
|
return __ptr;
|
||
|
}
|
||
|
|
||
|
#endif // _RWSTD_NO_DEBUG_ITER
|
||
|
|
||
|
|
||
|
|
||
|
#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
|
||
|
typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
|
||
|
typedef _STD::reverse_iterator<iterator> reverse_iterator;
|
||
|
#else
|
||
|
typedef _STD::reverse_iterator<const_iterator,
|
||
|
random_access_iterator_tag, value_type,
|
||
|
const_reference, const_pointer, difference_type>
|
||
|
const_reverse_iterator;
|
||
|
typedef _STD::reverse_iterator<iterator,
|
||
|
random_access_iterator_tag, value_type,
|
||
|
reference, pointer, difference_type>
|
||
|
reverse_iterator;
|
||
|
#endif
|
||
|
|
||
|
#if defined(_RWSTD_LLP64_ARCHITECTURE) && defined(_RWSTD_NO_STATIC_CONST_MEMBER_INIT)
|
||
|
static const size_type npos;
|
||
|
#else
|
||
|
_RWSTD_STATIC_CONST (size_type, npos = size_type(-1));
|
||
|
#endif
|
||
|
|
||
|
_EXPLICIT
|
||
|
basic_string (const allocator_type &__alloc = allocator_type ())
|
||
|
: allocator_type (__alloc), _C_data (_C_null ()) { }
|
||
|
|
||
|
// LWG Issue #42.
|
||
|
basic_string (const basic_string&);
|
||
|
|
||
|
basic_string (const basic_string&, size_type, size_type = npos,
|
||
|
const allocator_type& = allocator_type ());
|
||
|
|
||
|
basic_string (const_pointer, size_type,
|
||
|
const allocator_type& = allocator_type ());
|
||
|
|
||
|
basic_string (const_pointer, const allocator_type& = allocator_type ());
|
||
|
|
||
|
|
||
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
||
|
|
||
|
// pointers to the incomplete types declared below are used
|
||
|
// to disambiguate calls to template member functions
|
||
|
// requires: member function and class templates
|
||
|
// and partial specialization
|
||
|
|
||
|
template <class _InputIterator>
|
||
|
basic_string (_InputIterator, _InputIterator,
|
||
|
const allocator_type& = allocator_type ());
|
||
|
|
||
|
basic_string (int __n, value_type __c,
|
||
|
const allocator_type& __alloc = allocator_type ())
|
||
|
: allocator_type (__alloc) {
|
||
|
_C_initn (_RWSTD_STATIC_CAST (size_type, __n), __c);
|
||
|
}
|
||
|
|
||
|
basic_string (unsigned int __n, value_type __c,
|
||
|
const allocator_type& __alloc = allocator_type ())
|
||
|
: allocator_type (__alloc) {
|
||
|
_C_initn (_RWSTD_STATIC_CAST (size_type, __n), __c);
|
||
|
}
|
||
|
|
||
|
basic_string (long __n, value_type __c,
|
||
|
const allocator_type& __alloc = allocator_type ())
|
||
|
: allocator_type (__alloc) {
|
||
|
_C_initn (_RWSTD_STATIC_CAST (size_type, __n), __c);
|
||
|
}
|
||
|
|
||
|
basic_string (unsigned long __n, value_type __c,
|
||
|
const allocator_type& __alloc = allocator_type ())
|
||
|
: allocator_type (__alloc) {
|
||
|
_C_initn (_RWSTD_STATIC_CAST (size_type, __n), __c);
|
||
|
}
|
||
|
|
||
|
basic_string (short __n, value_type __c,
|
||
|
const allocator_type& __alloc = allocator_type ())
|
||
|
: allocator_type (__alloc) {
|
||
|
_C_initn (_RWSTD_STATIC_CAST (size_type, __n), __c);
|
||
|
}
|
||
|
|
||
|
basic_string (unsigned short __n, value_type __c,
|
||
|
const allocator_type& __alloc = allocator_type ())
|
||
|
: allocator_type (__alloc) {
|
||
|
_C_initn (_RWSTD_STATIC_CAST (size_type, __n), __c);
|
||
|
}
|
||
|
|
||
|
basic_string (char __n, value_type __c,
|
||
|
const allocator_type& __alloc = allocator_type ())
|
||
|
: allocator_type (__alloc) {
|
||
|
_C_initn (_RWSTD_STATIC_CAST (size_type, __n), __c);
|
||
|
}
|
||
|
|
||
|
basic_string (unsigned char __n, value_type __c,
|
||
|
const allocator_type& __alloc = allocator_type ())
|
||
|
: allocator_type (__alloc) {
|
||
|
_C_initn (_RWSTD_STATIC_CAST (size_type, __n), __c);
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifndef _RWSTD_NO_NATIVE_WCHAR_T
|
||
|
|
||
|
basic_string (wchar_t __n, value_type __c,
|
||
|
const allocator_type& __alloc = allocator_type ())
|
||
|
: allocator_type (__alloc) {
|
||
|
_C_initn (_RWSTD_STATIC_CAST (size_type, __n), __c);
|
||
|
}
|
||
|
|
||
|
#endif // _RWSTD_NO_NATIVE_WCHAR_T
|
||
|
|
||
|
|
||
|
#ifndef _RWSTD_NO_BOOL
|
||
|
|
||
|
basic_string (bool __n, value_type __c,
|
||
|
const allocator_type& __alloc = allocator_type ())
|
||
|
: allocator_type (__alloc) {
|
||
|
_C_initn (_RWSTD_STATIC_CAST (size_type, __n), __c);
|
||
|
}
|
||
|
|
||
|
#endif // _RWSTD_NO_BOOL
|
||
|
|
||
|
|
||
|
#else // if defined (_RWSTD_NO_MEMBER_TEMPLATES)
|
||
|
|
||
|
basic_string (size_type __n, value_type __c,
|
||
|
const allocator_type& __alloc = allocator_type ())
|
||
|
: allocator_type (__alloc) {
|
||
|
_C_initn (__n, __c);
|
||
|
}
|
||
|
|
||
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
||
|
|
||
|
|
||
|
basic_string (const_pointer, const_pointer,
|
||
|
const allocator_type& = allocator_type ());
|
||
|
|
||
|
~basic_string () {
|
||
|
_C_unlink();
|
||
|
}
|
||
|
|
||
|
basic_string& operator= (const basic_string&);
|
||
|
basic_string& operator= (const_pointer __s);
|
||
|
|
||
|
basic_string& operator= (value_type __c) {
|
||
|
return replace (0, size(), 1, __c);
|
||
|
}
|
||
|
|
||
|
iterator begin () {
|
||
|
_C_cow ();
|
||
|
_C_pref ()->_C_set_ref_count (0); // disable ref counting
|
||
|
return _C_make_iter (_C_data);
|
||
|
}
|
||
|
|
||
|
const_iterator begin () const {
|
||
|
return _C_make_iter (_C_data);
|
||
|
}
|
||
|
|
||
|
iterator end () {
|
||
|
// disable reference counting
|
||
|
return begin () + size ();
|
||
|
}
|
||
|
|
||
|
const_iterator end () const {
|
||
|
return _C_make_iter (_C_data + size ());
|
||
|
}
|
||
|
|
||
|
reverse_iterator rbegin () {
|
||
|
return reverse_iterator (end ());
|
||
|
}
|
||
|
|
||
|
const_reverse_iterator rbegin () const {
|
||
|
return const_reverse_iterator (end ());
|
||
|
}
|
||
|
|
||
|
reverse_iterator rend () {
|
||
|
return reverse_iterator (begin ());
|
||
|
}
|
||
|
|
||
|
const_reverse_iterator rend () const {
|
||
|
return const_reverse_iterator (begin ());
|
||
|
}
|
||
|
|
||
|
size_type size () const {
|
||
|
return _C_pref()->_C_size;
|
||
|
}
|
||
|
|
||
|
size_type length () const {
|
||
|
return size ();
|
||
|
}
|
||
|
|
||
|
size_type max_size () const {
|
||
|
return size_type (npos) - sizeof (_C_string_ref_type) - 2U;
|
||
|
}
|
||
|
|
||
|
void resize (size_type, value_type);
|
||
|
|
||
|
void resize (size_type __n) {
|
||
|
resize (__n, value_type ());
|
||
|
}
|
||
|
|
||
|
size_type capacity () const {
|
||
|
return _C_pref ()->capacity ();
|
||
|
}
|
||
|
|
||
|
void reserve (size_type = 0);
|
||
|
|
||
|
void clear () {
|
||
|
erase ();
|
||
|
}
|
||
|
|
||
|
bool empty () const {
|
||
|
return size () == 0;
|
||
|
}
|
||
|
|
||
|
const_reference operator[] (size_type) const;
|
||
|
reference operator[] (size_type);
|
||
|
|
||
|
const_reference at (size_type) const;
|
||
|
reference at (size_type);
|
||
|
|
||
|
basic_string& operator+= (const basic_string &__s) {
|
||
|
return append (__s);
|
||
|
}
|
||
|
|
||
|
basic_string& operator+= (const_pointer __s) {
|
||
|
return append (__s);
|
||
|
}
|
||
|
|
||
|
basic_string& operator+= (value_type __c) {
|
||
|
return append (size_type (1), __c);
|
||
|
}
|
||
|
|
||
|
basic_string& append (const basic_string&, size_type, size_type);
|
||
|
|
||
|
basic_string& append (const basic_string &__str);
|
||
|
|
||
|
basic_string& append (const_pointer __s, size_type __n) {
|
||
|
return replace (size (), 0, __s, __n, 0, __n), *this;
|
||
|
}
|
||
|
|
||
|
basic_string& append (const_pointer __s) {
|
||
|
return replace (size (), 0, __s);
|
||
|
}
|
||
|
|
||
|
#if !defined (_RWSTD_NO_MEMBER_TEMPLATES) \
|
||
|
&& !defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
|
||
|
|
||
|
template<class _InputIterator>
|
||
|
basic_string& append (_InputIterator __first, _InputIterator __last) {
|
||
|
// resolves to append (size_type, value_type) if _InputIterator
|
||
|
// is any integral type (even not an exact match, such as char)
|
||
|
// the cast to int is necessary to prevent an exact match
|
||
|
return append (__first, __last, _RWSTD_DISPATCH (_InputIterator));
|
||
|
}
|
||
|
|
||
|
template<class _InputIterator>
|
||
|
basic_string& append (_InputIterator __first, _InputIterator __last,
|
||
|
_RWSTD_DISPATCH_INT (false)) {
|
||
|
return replace (_C_make_iter (_C_data + size ()),
|
||
|
_C_make_iter (_C_data + size ()),
|
||
|
__first, __last), *this;
|
||
|
}
|
||
|
|
||
|
basic_string& append (size_type __n, value_type __c,
|
||
|
_RWSTD_DISPATCH_INT (true)) {
|
||
|
// unnamed arg is used for overload resolution
|
||
|
return replace (size (), 0, __n, __c);
|
||
|
}
|
||
|
|
||
|
#else // if defined (_RWSTD_NO_MEMBER_TEMPLATES)
|
||
|
|
||
|
basic_string& append (const_pointer __first, const_pointer __last) {
|
||
|
replace (size (), 0, __first, __last - __first, 0, __last - __first);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
||
|
|
||
|
basic_string& append (size_type __n, value_type __c) {
|
||
|
return replace (size (), 0, __n, __c);
|
||
|
}
|
||
|
|
||
|
void push_back (value_type __c) {
|
||
|
append (size_type (1), __c);
|
||
|
}
|
||
|
|
||
|
basic_string& assign (const basic_string &__str) {
|
||
|
return *this = __str;
|
||
|
}
|
||
|
|
||
|
basic_string& assign (const basic_string&, size_type, size_type);
|
||
|
|
||
|
basic_string& assign (const_pointer __s, size_type __n) {
|
||
|
return replace (0, size (), __s, __n, 0, __n), *this;
|
||
|
}
|
||
|
|
||
|
basic_string& assign (const_pointer __s) {
|
||
|
return *this = __s;
|
||
|
}
|
||
|
|
||
|
|
||
|
#if !defined (_RWSTD_NO_MEMBER_TEMPLATES) \
|
||
|
&& !defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
|
||
|
|
||
|
template<class _InputIterator>
|
||
|
basic_string& assign (_InputIterator __first, _InputIterator __last) {
|
||
|
// resolves to assign (size_type, value_type) if _InputIterator
|
||
|
// is any integral type (even not an exact match, such as char)
|
||
|
// the cast to int is necessary to prevent an exact match
|
||
|
return assign (__first, __last, _RWSTD_DISPATCH (_InputIterator));
|
||
|
}
|
||
|
|
||
|
template<class _InputIterator>
|
||
|
basic_string& assign (_InputIterator __first, _InputIterator __last,
|
||
|
_RWSTD_DISPATCH_INT (false)) {
|
||
|
// unnamed arg is used for overload resolution
|
||
|
// _RWSTD_COMPILE_ASSERT (sizeof (*__first));
|
||
|
return replace (_C_make_iter (_C_data),
|
||
|
_C_make_iter (_C_data + size ()), __first, __last);
|
||
|
}
|
||
|
|
||
|
basic_string& assign (size_type __n, value_type __c,
|
||
|
_RWSTD_DISPATCH_INT (true)) {
|
||
|
// unnamed arg is used for overload resolution
|
||
|
return replace (0, size (), __n, __c);
|
||
|
}
|
||
|
|
||
|
#else // if defined (_RWSTD_NO_MEMBER_TEMPLATES)
|
||
|
|
||
|
basic_string& assign (const_pointer __first, const_pointer __last) {
|
||
|
replace (size_type (), size (), __first,
|
||
|
__last - __first, size_type (), __last - __first);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
||
|
|
||
|
basic_string& assign (size_type __n, value_type __c) {
|
||
|
return replace (0, size (), __n, __c);
|
||
|
}
|
||
|
|
||
|
basic_string& insert (size_type, const basic_string&);
|
||
|
basic_string& insert (size_type, const basic_string&,
|
||
|
size_type, size_type);
|
||
|
|
||
|
basic_string& insert (size_type __pos, const_pointer __s, size_type __n) {
|
||
|
return replace (__pos, 0, __s, __n, 0, __n), *this;
|
||
|
}
|
||
|
|
||
|
basic_string& insert (size_type __pos, const_pointer __s) {
|
||
|
return insert (__pos, __s, traits_type::length (__s));
|
||
|
}
|
||
|
|
||
|
// 21.3.5.4, p10
|
||
|
iterator insert (iterator __pos, value_type __c) {
|
||
|
_RWSTD_ASSERT_RANGE (_C_make_iter (_C_data), __pos);
|
||
|
size_type __inx = __pos - _C_make_iter (_C_data);
|
||
|
return insert (__inx, &__c, 1), begin () + __inx;
|
||
|
}
|
||
|
|
||
|
|
||
|
#if !defined (_RWSTD_NO_MEMBER_TEMPLATES) \
|
||
|
&& !defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
|
||
|
|
||
|
template<class _InputIterator>
|
||
|
void insert (iterator __p,
|
||
|
_InputIterator __first, _InputIterator __last) {
|
||
|
// resolves to insert (iterator, size_type, value_type)
|
||
|
// if _InputIterator is any integral type (even not an exact match,
|
||
|
// such as char)
|
||
|
// the cast to int is necessary to avoid an exact match
|
||
|
insert (__p, __first, __last, _RWSTD_DISPATCH (_InputIterator));
|
||
|
}
|
||
|
|
||
|
void insert (iterator __p, const_iterator __first, const_iterator __last) {
|
||
|
iterator __begin = _C_make_iter (_C_data);
|
||
|
iterator __end = _C_make_iter (_C_data + size ());
|
||
|
_RWSTD_ASSERT_RANGE (__begin, __p);
|
||
|
if (__first >= __begin && __first <= __end)
|
||
|
insert (__p - __begin, basic_string (__first, __last));
|
||
|
else
|
||
|
replace (__p, __p, __first, __last);
|
||
|
}
|
||
|
|
||
|
void insert (iterator __p, iterator __first, iterator __last) {
|
||
|
insert (__p, const_iterator (__first), const_iterator (__last));
|
||
|
}
|
||
|
|
||
|
template <class _InputIterator>
|
||
|
void insert (iterator __p, _InputIterator __first, _InputIterator __last,
|
||
|
_RWSTD_DISPATCH_INT (false)) {
|
||
|
// unnamed arg is used for overload resolution
|
||
|
// _RWSTD_COMPILE_ASSERT (sizeof (*__first));
|
||
|
replace (__p, __p, __first, __last);
|
||
|
}
|
||
|
|
||
|
void insert (iterator __p, size_type __n, value_type __c,
|
||
|
_RWSTD_DISPATCH_INT (true)) {
|
||
|
// unnamed arg is used for overload resolution
|
||
|
replace (__p - _C_make_iter (_C_data), 0, __n, __c);
|
||
|
}
|
||
|
|
||
|
#else // if defined (_RWSTD_NO_MEMBER_TEMPLATES)
|
||
|
|
||
|
void insert (iterator __p, const_pointer __first, const_pointer __last) {
|
||
|
replace (__p - _C_make_iter (_C_data), 0, __first,
|
||
|
__last - __first, 0, __last - __first);
|
||
|
}
|
||
|
|
||
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
||
|
|
||
|
|
||
|
void insert (iterator __p, size_type __n, value_type __c) {
|
||
|
replace (__p - _C_make_iter (_C_data), 0, __n, __c);
|
||
|
}
|
||
|
|
||
|
basic_string& insert (size_type __pos, size_type __n, value_type __c) {
|
||
|
return replace (__pos, 0, __n, __c);
|
||
|
}
|
||
|
|
||
|
basic_string& erase (size_type = 0, size_type = npos);
|
||
|
|
||
|
iterator erase (iterator __it) {
|
||
|
return replace (__it - _C_make_iter (_C_data), 1,
|
||
|
const_pointer (0), 0, 0, 0);
|
||
|
}
|
||
|
|
||
|
iterator erase (iterator __first, iterator __last) {
|
||
|
return replace (__first - _C_make_iter (_C_data), __last - __first,
|
||
|
const_pointer (0), 0, 0, 0);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
iterator replace (size_type, size_type, const_pointer,
|
||
|
size_type, size_type, size_type);
|
||
|
|
||
|
iterator __replace_aux (size_type pos1, size_type __n1,
|
||
|
const basic_string &__str,
|
||
|
size_type pos2 = 0,
|
||
|
size_type __n2 = npos) {
|
||
|
return replace (pos1, __n1, __str.c_str(), __str.size(), pos2, __n2);
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
||
|
|
||
|
template<class _InputIterator>
|
||
|
basic_string& __replace_aux (iterator first1,
|
||
|
iterator last1,
|
||
|
_InputIterator first2,
|
||
|
_InputIterator last2);
|
||
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
||
|
|
||
|
|
||
|
public:
|
||
|
|
||
|
basic_string& replace (size_type pos1, size_type __n1,
|
||
|
const basic_string &__s,
|
||
|
size_type pos2, size_type __n2) {
|
||
|
replace (pos1, __n1, __s.c_str (), __s.size (), pos2, __n2);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
basic_string& replace (size_type __pos, size_type __n,
|
||
|
const basic_string &__s) {
|
||
|
return replace (__pos, __n, __s, 0, __s.size ());
|
||
|
}
|
||
|
|
||
|
|
||
|
basic_string& replace (size_type __pos, size_type __n1, const_pointer __s,
|
||
|
size_type __n2) {
|
||
|
return replace (__pos, __n1, __s, __n2, 0, __n2), *this;
|
||
|
}
|
||
|
|
||
|
basic_string& replace (size_type __pos, size_type __n, const_pointer __s) {
|
||
|
return replace (__pos, __n, __s, traits_type::length (__s));
|
||
|
}
|
||
|
|
||
|
basic_string& replace (size_type, size_type, size_type, value_type);
|
||
|
|
||
|
basic_string& replace (iterator __first, iterator __last,
|
||
|
const basic_string &__str) {
|
||
|
return replace (__first - _C_make_iter (_C_data),
|
||
|
__last - __first, __str);
|
||
|
}
|
||
|
|
||
|
basic_string& replace (iterator __first, iterator __last,
|
||
|
const_pointer __s, size_type __n) {
|
||
|
replace (__first - _C_make_iter (_C_data), __last - __first,
|
||
|
__s, __n, 0, __n);
|
||
|
return *this;;
|
||
|
}
|
||
|
|
||
|
basic_string&
|
||
|
replace (iterator __first, iterator __last, const_pointer __s) {
|
||
|
return replace (__first, __last, __s, traits_type::length(__s));
|
||
|
}
|
||
|
|
||
|
|
||
|
#if !defined (_RWSTD_NO_MEMBER_TEMPLATES) \
|
||
|
&& !defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
|
||
|
|
||
|
template<class _InputIterator>
|
||
|
basic_string& replace (iterator, iterator,
|
||
|
_InputIterator, _InputIterator,
|
||
|
_RWSTD_DISPATCH_INT (false));
|
||
|
|
||
|
|
||
|
basic_string& replace (iterator __first, iterator __last,
|
||
|
size_type __n, value_type __c,
|
||
|
_RWSTD_DISPATCH_INT (true)) {
|
||
|
// unnamed arg is used for overload resolution
|
||
|
return replace (__first - _C_make_iter (_C_data), __last - __first,
|
||
|
__n, __c);
|
||
|
}
|
||
|
|
||
|
template<class _InputIterator>
|
||
|
basic_string& replace (iterator __first1, iterator __last1,
|
||
|
_InputIterator __first2, _InputIterator __last2) {
|
||
|
// resolves to replace (iterator, iterator, size_type, value_type)
|
||
|
// if _InputIterator is any integral type (even not an exact match,
|
||
|
// Such as char)
|
||
|
// the cast to int is necessary to prevent an exact match
|
||
|
return replace (__first1, __last1, __first2, __last2,
|
||
|
_RWSTD_DISPATCH (_InputIterator));
|
||
|
}
|
||
|
|
||
|
#else // if defined (_RWSTD_NO_MEMBER_TEMPLATES)
|
||
|
|
||
|
basic_string& replace (iterator first1, iterator last1,
|
||
|
const_pointer first2, const_pointer last2) {
|
||
|
return replace (first1 - _C_make_iter (_C_data), last1 - first1,
|
||
|
first2, last2 - first2, 0, last2 - first2), *this;
|
||
|
}
|
||
|
|
||
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
||
|
|
||
|
basic_string& replace (iterator __first, iterator __last,
|
||
|
size_type __n, value_type __c) {
|
||
|
|
||
|
// unnamed arg is used for overload resolution
|
||
|
return replace (__first - _C_make_iter (_C_data), __last - __first,
|
||
|
__n, __c);
|
||
|
}
|
||
|
|
||
|
size_type copy (pointer, size_type, size_type = 0) const;
|
||
|
|
||
|
#ifndef _RWSTD_NO_EXT_DEEP_STRING_COPY
|
||
|
|
||
|
basic_string copy () const {
|
||
|
return basic_string (data (), data () + size ());
|
||
|
}
|
||
|
|
||
|
#endif //_RWSTD_NO_EXT_DEEP_STRING_COPY
|
||
|
|
||
|
void swap (basic_string &__s) {
|
||
|
if (get_allocator () == __s.get_allocator ()) {
|
||
|
pointer __temp = _C_data;
|
||
|
_C_data = __s._C_data;
|
||
|
__s._C_data = __temp;
|
||
|
}
|
||
|
else {
|
||
|
basic_string __tmp = *this;
|
||
|
*this = __s;
|
||
|
__s = __tmp;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// string operations
|
||
|
//
|
||
|
const_pointer c_str () const {
|
||
|
return _C_data;
|
||
|
}
|
||
|
|
||
|
const_pointer data () const {
|
||
|
return _C_data;
|
||
|
}
|
||
|
|
||
|
allocator_type get_allocator() const {
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
// 21.3.6.1, p1
|
||
|
size_type find (const basic_string &__str, size_type __pos = 0) const {
|
||
|
return find (__str.c_str (), __pos, __str.size ());
|
||
|
}
|
||
|
|
||
|
// 21.3.6.1, p4
|
||
|
size_type find (const_pointer, size_type, size_type) const;
|
||
|
|
||
|
// 21.3.6.1, p5
|
||
|
size_type find (const_pointer, size_type = 0) const;
|
||
|
|
||
|
// 21.3.6.1, p7
|
||
|
size_type find (value_type, size_type = 0) const;
|
||
|
|
||
|
// 21.3.6.2, p1
|
||
|
size_type rfind (const basic_string &__str, size_type __pos = npos) const {
|
||
|
return rfind (__str.c_str (), __pos, __str.size ());
|
||
|
}
|
||
|
|
||
|
// 21.3.6.2, p4
|
||
|
size_type rfind (const_pointer, size_type, size_type) const;
|
||
|
|
||
|
// 21.3.6.2, p5
|
||
|
size_type rfind (const_pointer __s, size_type __pos = npos) const {
|
||
|
return rfind (__s, __pos, traits_type::length (__s));
|
||
|
}
|
||
|
|
||
|
// 21.3.6.2, p7
|
||
|
size_type rfind (value_type, size_type = npos) const;
|
||
|
|
||
|
// 21.3.6.3, p1
|
||
|
size_type find_first_of (const basic_string &__str,
|
||
|
size_type __pos = 0) const {
|
||
|
return find_first_of (__str.c_str (), __pos, __str.size ());
|
||
|
}
|
||
|
|
||
|
// 21.3.6.3, p4
|
||
|
size_type find_first_of (const_pointer, size_type, size_type) const;
|
||
|
|
||
|
// 21.3.6.3, p5
|
||
|
size_type find_first_of (const_pointer, size_type = 0) const;
|
||
|
|
||
|
// 21.3.6.3, p6
|
||
|
size_type find_first_of (value_type __c, size_type __pos = 0) const {
|
||
|
return find (__c, __pos);
|
||
|
}
|
||
|
|
||
|
// 21.3.6.4, p1
|
||
|
size_type find_last_of (const basic_string &__str,
|
||
|
size_type __pos = npos) const {
|
||
|
return find_last_of (__str.c_str (), __pos, __str.size ());
|
||
|
}
|
||
|
|
||
|
// 21.3.6.4, p4
|
||
|
size_type find_last_of (const_pointer, size_type, size_type) const;
|
||
|
|
||
|
// 21.3.6.4, p5
|
||
|
size_type find_last_of (const_pointer __s, size_type __pos = npos) const {
|
||
|
return find_last_of (__s, __pos, traits_type::length (__s));
|
||
|
}
|
||
|
|
||
|
// 21.3.6.4, p7
|
||
|
size_type find_last_of (value_type __c, size_type __pos = npos) const {
|
||
|
return rfind (__c, __pos);
|
||
|
}
|
||
|
|
||
|
// 21.3.6.5, p1
|
||
|
size_type find_first_not_of (const basic_string &__str,
|
||
|
size_type __pos = 0) const {
|
||
|
return find_first_not_of (__str.c_str (), __pos, __str.size ());
|
||
|
}
|
||
|
|
||
|
// 21.3.6.5, p4
|
||
|
size_type find_first_not_of (const_pointer, size_type,
|
||
|
size_type) const;
|
||
|
|
||
|
// 21.3.6.5, p5
|
||
|
size_type find_first_not_of (const_pointer, size_type = 0) const;
|
||
|
|
||
|
// 21.3.6.5, p7
|
||
|
size_type find_first_not_of (value_type, size_type = 0) const;
|
||
|
|
||
|
// 21.3.6.6, p1
|
||
|
size_type find_last_not_of (const basic_string &__str,
|
||
|
size_type __pos = npos) const {
|
||
|
return find_last_not_of (__str.c_str (), __pos, __str.size ());
|
||
|
}
|
||
|
|
||
|
// 21.3.6.6, p4
|
||
|
size_type find_last_not_of (const_pointer, size_type, size_type) const;
|
||
|
|
||
|
// 21.3.6.6, p6
|
||
|
size_type find_last_not_of (const_pointer __s,
|
||
|
size_type __pos = npos) const {
|
||
|
return find_last_not_of (__s, __pos, traits_type::length (__s));
|
||
|
}
|
||
|
|
||
|
// 21.3.6.6, p7
|
||
|
size_type find_last_not_of (value_type, size_type = npos) const;
|
||
|
|
||
|
// 21.3.6.7
|
||
|
basic_string substr (size_type = 0, size_type = npos) const;
|
||
|
|
||
|
int compare (const basic_string &__str) const;
|
||
|
|
||
|
int compare (size_type __pos, size_type __n, const basic_string &__str) const {
|
||
|
return compare (__pos, __n, __str.c_str(), __str.size());
|
||
|
}
|
||
|
|
||
|
int compare (size_type, size_type, const basic_string&,
|
||
|
size_type, size_type) const;
|
||
|
|
||
|
int compare (const_pointer __s) const {
|
||
|
return compare (0, size (), __s, traits_type::length(__s));
|
||
|
}
|
||
|
|
||
|
// LWG Issue #5.
|
||
|
int compare (size_type __pos, size_type __n, const_pointer __s) const {
|
||
|
return compare(__pos, __n, __s, traits_type::length (__s));
|
||
|
}
|
||
|
|
||
|
int compare (size_type, size_type, const_pointer, size_type) const;
|
||
|
|
||
|
protected:
|
||
|
|
||
|
void _C_cow () { // Do copy on write as necessary
|
||
|
if (_C_pref ()->_C_ref_count() > 1)
|
||
|
_C_clone ();
|
||
|
}
|
||
|
|
||
|
void _C_cow (size_type __nc) { // Do copy on write w/ new capacity
|
||
|
if (_C_pref ()->_C_ref_count () > 1 || capacity () < __nc)
|
||
|
_C_clone (__nc);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
void _C_initn (size_type, value_type);
|
||
|
|
||
|
void _C_clone (size_type __nc = npos);
|
||
|
|
||
|
_C_string_ref_type* _C_pref () const {
|
||
|
return _RWSTD_REINTERPRET_CAST (_C_string_ref_type*, _C_data) - 1;
|
||
|
}
|
||
|
|
||
|
void _C_unlink ();
|
||
|
|
||
|
friend struct _RW::__string_ref<value_type, traits_type, allocator_type>;
|
||
|
|
||
|
#ifndef _RWSTD_NO_COLLAPSE_TEMPLATE_STATICS
|
||
|
|
||
|
static _RW::__null_ref<_CharT, _Traits, _Allocator> __nullref;
|
||
|
|
||
|
static pointer _C_null () {
|
||
|
return __nullref.data ();
|
||
|
}
|
||
|
|
||
|
#else // if defined (_RWSTD_NO_COLLAPSE_TEMPLATE_STATICS)
|
||
|
|
||
|
static pointer _C_null () {
|
||
|
typedef _RW::__null_ref<_CharT, _Traits, _Allocator> _NullRef;
|
||
|
|
||
|
return _RWSTD_REINTERPRET_CAST (_NullRef*, &_RW::__nullref)->data ();
|
||
|
}
|
||
|
|
||
|
#endif // _RWSTD_NO_COLLAPSE_TEMPLATE_STATICS
|
||
|
|
||
|
_C_string_ref_type * _C_getRep (size_type, size_type);
|
||
|
|
||
|
// for convenience
|
||
|
pointer _C_allocate (size_type __cur, size_type __cap, size_type __size) {
|
||
|
return _C_getRep (max (size_type (_RW::__rw_new_capacity (__cur, this)),
|
||
|
__cap), __size)->data ();
|
||
|
}
|
||
|
|
||
|
pointer _C_data;
|
||
|
};
|
||
|
|
||
|
|
||
|
typedef basic_string<char, char_traits<char>, allocator<char> > string;
|
||
|
|
||
|
#ifndef _RWSTD_NO_WCHAR_T
|
||
|
|
||
|
typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >
|
||
|
wstring;
|
||
|
|
||
|
#endif // _RWSTD_NO_WCHAR_T
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline void basic_string<_CharT, _Traits, _Allocator>::_C_unlink()
|
||
|
{
|
||
|
_RWSTD_ASSERT (0 != _C_data);
|
||
|
|
||
|
if (data () == _C_null ())
|
||
|
return;
|
||
|
|
||
|
if (_C_pref ()->_C_ref_count () == 0 || _C_pref ()->_C_dec_ref () == 0) {
|
||
|
// Required to pass same size to deallocate as allocate (see string.cc).
|
||
|
// Also note that we cannot call capacity() after the destroy() call.
|
||
|
size_type __size =
|
||
|
capacity () + sizeof (_C_string_ref_type) / sizeof (value_type) + 2;
|
||
|
|
||
|
// explicitly destroy POD
|
||
|
_C_pref ()->_C_destroy ();
|
||
|
|
||
|
_C_ref_alloc_type (*this).destroy (_C_pref ());
|
||
|
_RWSTD_VALUE_ALLOC (_C_value_alloc_type,
|
||
|
deallocate (_RWSTD_REINTERPRET_CAST (pointer,
|
||
|
_C_pref()),
|
||
|
__size));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline basic_string<_CharT, _Traits, _Allocator>::
|
||
|
basic_string (const basic_string<_CharT, _Traits, _Allocator> &__s)
|
||
|
: allocator_type (__s.get_allocator ())
|
||
|
{
|
||
|
if (__s._C_pref()->_C_ref_count () > 0) {
|
||
|
_C_data = __s._C_data;
|
||
|
_C_pref()->_C_inc_ref ();
|
||
|
}
|
||
|
else {
|
||
|
size_type __n = __s.size();
|
||
|
_C_data = _C_getRep (__n, __n)->data ();
|
||
|
traits_type::copy (_C_data, __s.c_str (), __n);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline basic_string<_CharT, _Traits, _Allocator>&
|
||
|
basic_string<_CharT, _Traits, _Allocator>::erase (size_type __pos,
|
||
|
size_type __n)
|
||
|
{
|
||
|
_RWSTD_REQUIRES (__pos <= size (),
|
||
|
(_RWSTD_ERROR_OUT_OF_RANGE,
|
||
|
_RWSTD_FUNC ("basic_string::erase(size_type, size_type)"),
|
||
|
__pos, size ()));
|
||
|
|
||
|
const value_type __tmp = value_type () ;
|
||
|
size_type __len = size () - __pos;
|
||
|
return replace (__pos, __n < __len ? __n : __len, &__tmp, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline _TYPENAME basic_string<_CharT, _Traits, _Allocator>::const_reference
|
||
|
basic_string<_CharT, _Traits, _Allocator>::operator[] (size_type __pos) const
|
||
|
{
|
||
|
#ifdef _RWSTD_BOUNDS_CHECKING
|
||
|
|
||
|
_RWSTD_REQUIRES (__pos <= size (),
|
||
|
(_RWSTD_ERROR_OUT_OF_RANGE,
|
||
|
_RWSTD_FUNC ("basic_string::operator[](size_type) const"),
|
||
|
__pos, size ()));
|
||
|
|
||
|
#endif // _RWSTD_BOUNDS_CHECKING
|
||
|
|
||
|
// reference counting still enabled
|
||
|
return _C_data [__pos];
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline _TYPENAME basic_string<_CharT, _Traits, _Allocator>::reference
|
||
|
basic_string<_CharT, _Traits, _Allocator>::operator[] (size_type __pos)
|
||
|
{
|
||
|
#ifdef _RWSTD_BOUNDS_CHECKING
|
||
|
|
||
|
// 21.3.4, p1 - behavior is undefined if __pos == size ()
|
||
|
_RWSTD_REQUIRES (__pos < size (),
|
||
|
(_RWSTD_ERROR_OUT_OF_RANGE,
|
||
|
_RWSTD_FUNC ("basic_string::operator[](size_type)"),
|
||
|
__pos, size ()));
|
||
|
|
||
|
#endif // _RWSTD_BOUNDS_CHECKING
|
||
|
|
||
|
// prevent reference counting
|
||
|
return begin ()[__pos];
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline _TYPENAME basic_string<_CharT, _Traits, _Allocator>::const_reference
|
||
|
basic_string<_CharT, _Traits, _Allocator>::at (size_type __pos) const
|
||
|
{
|
||
|
_RWSTD_REQUIRES (__pos < size (),
|
||
|
(_RWSTD_ERROR_OUT_OF_RANGE,
|
||
|
_RWSTD_FUNC ("basic_string::at (size_type) const"),
|
||
|
__pos, size ()));
|
||
|
|
||
|
// reference counting still enabled
|
||
|
return _C_data [__pos];
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline _TYPENAME basic_string<_CharT, _Traits, _Allocator>::reference
|
||
|
basic_string<_CharT, _Traits, _Allocator>::at (size_type __pos)
|
||
|
{
|
||
|
_RWSTD_REQUIRES (__pos < size (),
|
||
|
(_RWSTD_ERROR_OUT_OF_RANGE,
|
||
|
_RWSTD_FUNC ("basic_string::at (size_type)"),
|
||
|
__pos, size ()));
|
||
|
|
||
|
// prevent reference counting
|
||
|
return begin ()[__pos];
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline void
|
||
|
basic_string<_CharT, _Traits, _Allocator>::
|
||
|
resize (size_type __n, value_type __c)
|
||
|
{
|
||
|
_RWSTD_REQUIRES (__n <= max_size (),
|
||
|
(_RWSTD_ERROR_LENGTH_ERROR,
|
||
|
_RWSTD_FUNC ("basic_string::resize(size_type, "
|
||
|
"value_type)"), __n, max_size ()));
|
||
|
|
||
|
if (__n < size())
|
||
|
erase (__n, size () - __n);
|
||
|
else
|
||
|
replace (size (), 0, __n - size (), __c);
|
||
|
}
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline void basic_string<_CharT, _Traits, _Allocator>::
|
||
|
reserve (size_type __n)
|
||
|
{
|
||
|
_RWSTD_REQUIRES (__n <= max_size (),
|
||
|
(_RWSTD_ERROR_LENGTH_ERROR,
|
||
|
_RWSTD_FUNC ("basic_string::reserve(size_type)"),
|
||
|
__n, max_size ()));
|
||
|
|
||
|
if (__n > capacity ())
|
||
|
_C_clone (__n);
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline _TYPENAME basic_string<_CharT, _Traits, _Allocator>::size_type
|
||
|
basic_string<_CharT, _Traits, _Allocator>::
|
||
|
find (const_pointer __s, size_type __pos) const
|
||
|
{
|
||
|
_RWSTD_ASSERT (__s != 0);
|
||
|
|
||
|
// 21.3.6.1, p1, bullet 1
|
||
|
if (__pos > size ())
|
||
|
return npos;
|
||
|
|
||
|
const_pointer __where =
|
||
|
_RW::rw_traits<value_type, traits_type>::find (_C_data + __pos, __s);
|
||
|
|
||
|
return __where ? __where - _C_data : npos;
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline _TYPENAME basic_string<_CharT, _Traits, _Allocator>::size_type
|
||
|
basic_string<_CharT, _Traits, _Allocator>::
|
||
|
find (value_type __c, size_type __pos) const
|
||
|
{
|
||
|
if (__pos > size())
|
||
|
return npos;
|
||
|
|
||
|
const_pointer __where = traits_type::find (_C_data + __pos,
|
||
|
size() - __pos, __c);
|
||
|
return __where ? __where - _C_data : npos;
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline _TYPENAME basic_string<_CharT, _Traits, _Allocator>::size_type
|
||
|
basic_string<_CharT, _Traits, _Allocator>::
|
||
|
rfind (value_type __c, size_type __pos) const
|
||
|
{
|
||
|
if (!size ())
|
||
|
return npos;
|
||
|
|
||
|
if (__pos >= size ())
|
||
|
__pos = size () - 1; // start at the last valid position
|
||
|
|
||
|
const_pointer __where =
|
||
|
_RW::rw_traits<value_type, traits_type>::rfind (_C_data,
|
||
|
__c, __pos);
|
||
|
return __where ? __where - _C_data : npos;
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline _TYPENAME basic_string<_CharT, _Traits, _Allocator>::size_type
|
||
|
basic_string<_CharT, _Traits, _Allocator>::
|
||
|
find_first_of (const_pointer __s, size_type __pos) const
|
||
|
{
|
||
|
_RWSTD_ASSERT (__s != 0);
|
||
|
|
||
|
if (__pos > size())
|
||
|
return npos;
|
||
|
|
||
|
typedef _RW::rw_traits<_CharT, _Traits> __rw_traits;
|
||
|
|
||
|
size_type __i = __rw_traits::find_first_of (_C_data + __pos, __s) + __pos;
|
||
|
|
||
|
return __i >= size () ? npos : __i;
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline _TYPENAME basic_string<_CharT, _Traits, _Allocator>::size_type
|
||
|
basic_string<_CharT, _Traits, _Allocator>::
|
||
|
find_first_not_of (const_pointer __s, size_type __pos) const
|
||
|
{
|
||
|
_RWSTD_ASSERT (__s != 0);
|
||
|
|
||
|
if (__pos > size())
|
||
|
return npos;
|
||
|
|
||
|
typedef _RW::rw_traits<_CharT, _Traits> __rw_traits;
|
||
|
|
||
|
size_type __i = __rw_traits::find_first_not_of(_C_data + __pos, __s)+ __pos;
|
||
|
|
||
|
return __i >= size () ? npos : __i;
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline _TYPENAME basic_string<_CharT, _Traits, _Allocator>::size_type
|
||
|
basic_string<_CharT, _Traits, _Allocator>::
|
||
|
find_first_not_of (value_type __c, size_type __pos) const
|
||
|
{
|
||
|
return find_first_not_of (&__c, __pos, 1);
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline _TYPENAME basic_string<_CharT, _Traits, _Allocator>::size_type
|
||
|
basic_string<_CharT, _Traits, _Allocator>::
|
||
|
find_last_not_of (value_type __c, size_type __pos) const
|
||
|
{
|
||
|
#if 0
|
||
|
// disabled to work around a bug in several compilers
|
||
|
const value_type __tmp [] = { __c, value_type () };
|
||
|
#else
|
||
|
value_type __tmp [2];
|
||
|
traits_type::assign (__tmp [0], __c);
|
||
|
traits_type::assign (__tmp [1], value_type ());
|
||
|
#endif // 0/1
|
||
|
|
||
|
return find_last_not_of (__tmp, __pos);
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits, class _Allocator>
|
||
|
inline void
|
||
|
basic_string<_CharT, _Traits, _Allocator>::
|
||
|
_C_clone (size_type __nc /* = npos */)
|
||
|
{
|
||
|
size_type __len = size();
|
||
|
_C_string_ref_type * __temp = _C_getRep (npos == __nc ? size () : __nc,
|
||
|
__len > __nc ? __nc : __len);
|
||
|
traits_type::copy (__temp->data(), _C_data, size());
|
||
|
_C_unlink ();
|
||
|
_C_data = __temp->data ();
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits, class _Allocator>
|
||
|
inline int
|
||
|
basic_string<_CharT, _Traits, _Allocator>::
|
||
|
compare (const basic_string &__str) const
|
||
|
{
|
||
|
int __res = traits_type::compare (data (), __str.data (),
|
||
|
_STD::min (size (), __str.size ()));
|
||
|
|
||
|
if (0 == __res)
|
||
|
__res = size () < __str.size () ? -1 : size () != __str.size ();
|
||
|
|
||
|
return __res;
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class _CharT, class _Traits, class _Allocator>
|
||
|
inline basic_string<_CharT, _Traits, _Allocator>&
|
||
|
basic_string<_CharT, _Traits, _Allocator>::append (const basic_string &__str)
|
||
|
{
|
||
|
size_type __len = size () + __str.size ();
|
||
|
if (__len > capacity () || _C_pref ()->_C_ref_count () > 1)
|
||
|
return append (__str, 0, __str.size ());
|
||
|
|
||
|
traits_type::copy (_C_data + size (), __str.data (), __str.size () + 1);
|
||
|
_C_pref ()->_C_size = __len;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.1, p1
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline basic_string<_CharT, _Traits, _Allocator>
|
||
|
operator+ (const basic_string<_CharT, _Traits, _Allocator> &__lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator> &__rhs)
|
||
|
{
|
||
|
typedef basic_string<_CharT, _Traits, _Allocator> string_type;
|
||
|
|
||
|
// prevent reference counting while creating a copy of lhs
|
||
|
return string_type (__lhs.data (), __lhs.data () + __lhs.size ()) += __rhs;
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.1, p2
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline basic_string<_CharT, _Traits, _Allocator>
|
||
|
operator+ (const _CharT* __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return basic_string<_CharT, _Traits, _Allocator>(__lhs) += __rhs;
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.1, p4
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline basic_string<_CharT, _Traits, _Allocator>
|
||
|
operator+ (_CharT __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return basic_string<_CharT, _Traits, _Allocator>(1, __lhs) += __rhs;
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.1, p5
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline basic_string<_CharT, _Traits, _Allocator>
|
||
|
operator+ (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
const _CharT* __rhs)
|
||
|
{
|
||
|
typedef basic_string<_CharT, _Traits, _Allocator> string_type;
|
||
|
|
||
|
// prevent reference counting while creating a copy of lhs
|
||
|
return string_type (__lhs.data (), __lhs.data () + __lhs.size ()) += __rhs;
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.1, p7
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline basic_string<_CharT, _Traits, _Allocator>
|
||
|
operator+ (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
_CharT __rhs)
|
||
|
{
|
||
|
typedef basic_string<_CharT, _Traits, _Allocator> string_type;
|
||
|
|
||
|
// prevent reference counting while creating a copy of lhs
|
||
|
return string_type (__lhs.data (), __lhs.data () + __lhs.size ()) += __rhs;
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.2, p1
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator== (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return __lhs.size () == __rhs.size () && 0 == __lhs.compare (__rhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.2, p2
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator== (const _CharT* __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return 0 == __rhs.compare (__lhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.2, p3
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator== (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
const _CharT* __rhs)
|
||
|
{
|
||
|
return 0 == __lhs.compare (__rhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.4, p1
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return 0 > __lhs.compare (__rhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.4, p2
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator< (const _CharT* __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return 0 < __rhs.compare (__lhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.4, p3
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator< (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
const _CharT* __rhs)
|
||
|
{
|
||
|
return 0 > __lhs.compare (__rhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.3, p1
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator!= (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return !(__lhs == __rhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.5, p1
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return __rhs < __lhs;
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.6, p1
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator<= (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return !(__rhs < __lhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.7, p1
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator>= (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return !(__lhs < __rhs);
|
||
|
}
|
||
|
|
||
|
// 21.3.7.8, p1
|
||
|
#ifndef _RWSTD_NO_PART_SPEC_OVERLOAD
|
||
|
|
||
|
template <class _CharT, class _Traits, class _Allocator>
|
||
|
inline void swap (basic_string<_CharT, _Traits, _Allocator>& __a,
|
||
|
basic_string<_CharT, _Traits, _Allocator>& __b)
|
||
|
{
|
||
|
__a.swap (__b);
|
||
|
}
|
||
|
|
||
|
#endif // _RWSTD_NO_PART_SPEC_OVERLOAD
|
||
|
|
||
|
|
||
|
// 21.3.7.3, p2
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator!= (const _CharT* __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return !(__lhs == __rhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.3, p3
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator!= (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
const _CharT* __rhs)
|
||
|
{
|
||
|
return !(__lhs == __rhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.5, p2
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator> (const _CharT* __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return __rhs < __lhs;
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.5, p3
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator> (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
const _CharT* __rhs)
|
||
|
{
|
||
|
return __rhs < __lhs;
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.6, p2
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator<= (const _CharT* __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return !(__rhs < __lhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.6, p3
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator<= (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
const _CharT* __rhs)
|
||
|
{
|
||
|
return !(__rhs < __lhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.7, p2
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator>= (const _CharT* __lhs,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>& __rhs)
|
||
|
{
|
||
|
return !(__lhs < __rhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.7, p3
|
||
|
template <class _CharT, class _Traits , class _Allocator>
|
||
|
inline bool
|
||
|
operator>= (const basic_string<_CharT, _Traits, _Allocator>& __lhs,
|
||
|
const _CharT* __rhs)
|
||
|
{
|
||
|
return !(__lhs < __rhs);
|
||
|
}
|
||
|
|
||
|
|
||
|
// 21.3.7.9, p3 - declared here, defined inline in <ostream>
|
||
|
template<class _CharT, class _Traits, class _Allocator>
|
||
|
inline basic_ostream<_CharT, _Traits>&
|
||
|
operator<< (basic_ostream<_CharT, _Traits>&,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>&);
|
||
|
|
||
|
|
||
|
_RWSTD_NAMESPACE_END // std
|
||
|
|
||
|
|
||
|
_RWSTD_NAMESPACE_BEGIN (__rw)
|
||
|
|
||
|
_USING (namespace std);
|
||
|
|
||
|
|
||
|
#ifndef _RWSTD_NO_FUNC_PARTIAL_SPEC
|
||
|
|
||
|
// more specialized version for basic_string<>; may be further specialized
|
||
|
// in user code for example on a user-defined allocator
|
||
|
|
||
|
template <class _CharT, class _Traits, class _Allocator>
|
||
|
inline size_t
|
||
|
__rw_new_capacity (size_t __size,
|
||
|
const basic_string<_CharT, _Traits, _Allocator>*)
|
||
|
{
|
||
|
size_t __cap =
|
||
|
_RWSTD_STATIC_CAST (size_t, _RWSTD_INCREASE_STRING_CAPACITY(__size)
|
||
|
/*__size * _RWSTD_STRING_CAPACITY_RATIO*/);
|
||
|
return (__size += _RWSTD_MINIMUM_STRING_CAPACITY) > __cap ? __size : __cap;
|
||
|
}
|
||
|
|
||
|
#else // if defined (_RWSTD_NO_FUNC_PARTIAL_SPEC)
|
||
|
|
||
|
// the following specializations of the __rw_new_capacity<> function template
|
||
|
// are provided for char and wchar_t; the general case is given in the <memory>
|
||
|
|
||
|
_RWSTD_SPECIALIZED_FUNCTION
|
||
|
inline size_t __rw_new_capacity (size_t __size, const string*)
|
||
|
{
|
||
|
size_t __cap =
|
||
|
_RWSTD_STATIC_CAST (size_t, _RWSTD_INCREASE_STRING_CAPACITY(__size)
|
||
|
/*__size * _RWSTD_STRING_CAPACITY_RATIO*/);
|
||
|
return (__size += _RWSTD_MINIMUM_STRING_CAPACITY) > __cap ? __size : __cap;
|
||
|
}
|
||
|
|
||
|
_RWSTD_SPECIALIZED_FUNCTION
|
||
|
inline size_t __rw_new_capacity (size_t __size, const wstring*)
|
||
|
{
|
||
|
size_t __cap =
|
||
|
_RWSTD_STATIC_CAST (size_t, _RWSTD_INCREASE_STRING_CAPACITY(__size)
|
||
|
/*__size * _RWSTD_STRING_CAPACITY_RATIO*/);
|
||
|
return (__size += _RWSTD_MINIMUM_STRING_CAPACITY) > __cap ? __size : __cap;
|
||
|
}
|
||
|
|
||
|
#endif // _RWSTD_NO_FUNC_PARTIAL_SPEC
|
||
|
|
||
|
_RWSTD_NAMESPACE_END // __rw
|
||
|
|
||
|
|
||
|
#if _RWSTD_DEFINE_TEMPLATE (BASIC_STRING)
|
||
|
# include <string.cc>
|
||
|
#endif
|
||
|
|
||
|
|
||
|
_RWSTD_NAMESPACE_BEGIN (std)
|
||
|
|
||
|
_RWSTD_INSTANTIATE_3 (class _RWSTD_EXPORT
|
||
|
basic_string<char, char_traits<char>, allocator<char> >);
|
||
|
|
||
|
#ifndef _RWSTD_NO_WCHAR_T
|
||
|
_RWSTD_INSTANTIATE_3 (class _RWSTD_EXPORT
|
||
|
basic_string<wchar_t, char_traits<wchar_t>,
|
||
|
allocator<wchar_t> >);
|
||
|
#endif // _RWSTD_NO_WCHAR_T
|
||
|
|
||
|
_RWSTD_NAMESPACE_END // std
|
||
|
|
||
|
|
||
|
#endif // _RWSTD_STRING_INCLUDED
|
||
|
|