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

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