// Components for manipulating sequences of characters -*- C++ -*-
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
#pragma GCC system_header
#include <bits/atomicity.h>
+#include <debug/debug.h>
namespace std
{
* [_Rep]
* _M_length
* [basic_string<char_type>] _M_capacity
- * _M_dataplus _M_state
+ * _M_dataplus _M_refcount
* _M_p ----------------> unnamed array of char_type
* @endcode
*
{
// Types:
public:
- typedef _Traits traits_type;
- typedef typename _Traits::char_type value_type;
- typedef _Alloc allocator_type;
- typedef typename _Alloc::size_type size_type;
- typedef typename _Alloc::difference_type difference_type;
- typedef typename _Alloc::reference reference;
- typedef typename _Alloc::const_reference const_reference;
- typedef typename _Alloc::pointer pointer;
- typedef typename _Alloc::const_pointer const_pointer;
+ typedef _Traits traits_type;
+ typedef typename _Traits::char_type value_type;
+ typedef _Alloc allocator_type;
+ typedef typename _Alloc::size_type size_type;
+ typedef typename _Alloc::difference_type difference_type;
+ typedef typename _Alloc::reference reference;
+ typedef typename _Alloc::const_reference const_reference;
+ typedef typename _Alloc::pointer pointer;
+ typedef typename _Alloc::const_pointer const_pointer;
typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator;
typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
const_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
private:
// _Rep: string representation
// Invariants:
- // 1. String really contains _M_length + 1 characters; last is set
- // to 0 only on call to c_str(). We avoid instantiating
- // _CharT() where the interface does not require it.
+ // 1. String really contains _M_length + 1 characters: due to 21.3.4
+ // must be kept null-terminated.
// 2. _M_capacity >= _M_length
- // Allocated memory is always _M_capacity + (1 * sizeof(_CharT)).
- // 3. _M_references has three states:
+ // Allocated memory is always (_M_capacity + 1) * sizeof(_CharT).
+ // 3. _M_refcount has three states:
// -1: leaked, one reference, no ref-copies allowed, non-const.
// 0: one reference, non-const.
// n>0: n + 1 references, operations require a lock, const.
struct _Rep_base
{
- size_type _M_length;
- size_type _M_capacity;
- _Atomic_word _M_references;
+ size_type _M_length;
+ size_type _M_capacity;
+ _Atomic_word _M_refcount;
};
struct _Rep : _Rep_base
// Solving for m:
// m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
// In addition, this implementation quarters this amount.
- static const size_type _S_max_size;
- static const _CharT _S_terminal;
+ static const size_type _S_max_size;
+ static const _CharT _S_terminal;
// The following storage is init'd to 0 by the linker, resulting
// (carefully) in an empty string with one reference.
static size_type _S_empty_rep_storage[];
- static _Rep&
+ static _Rep&
_S_empty_rep()
{ return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); }
-
+
bool
_M_is_leaked() const
- { return this->_M_references < 0; }
+ { return this->_M_refcount < 0; }
bool
_M_is_shared() const
- { return this->_M_references > 0; }
+ { return this->_M_refcount > 0; }
void
_M_set_leaked()
- { this->_M_references = -1; }
+ { this->_M_refcount = -1; }
void
_M_set_sharable()
- { this->_M_references = 0; }
+ { this->_M_refcount = 0; }
_CharT*
_M_refdata() throw()
{ return reinterpret_cast<_CharT*>(this + 1); }
- _CharT&
- operator[](size_t __s) throw()
- { return _M_refdata() [__s]; }
-
_CharT*
_M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
{
// Create & Destroy
static _Rep*
- _S_create(size_t, const _Alloc&);
+ _S_create(size_type, size_type, const _Alloc&);
void
_M_dispose(const _Alloc& __a)
{
if (__builtin_expect(this != &_S_empty_rep(), false))
- if (__exchange_and_add(&this->_M_references, -1) <= 0)
+ if (__gnu_cxx::__exchange_and_add(&this->_M_refcount, -1) <= 0)
_M_destroy(__a);
} // XXX MT
_M_refcopy() throw()
{
if (__builtin_expect(this != &_S_empty_rep(), false))
- __atomic_add(&this->_M_references, 1);
+ __gnu_cxx::__atomic_add(&this->_M_refcount, 1);
return _M_refdata();
} // XXX MT
// size that the allocator can hold.
/// @var
/// Value returned by various member functions when they fail.
- static const size_type npos = static_cast<size_type>(-1);
+ static const size_type npos = static_cast<size_type>(-1);
private:
// Data Members (private):
- mutable _Alloc_hider _M_dataplus;
+ mutable _Alloc_hider _M_dataplus;
_CharT*
_M_data() const
_M_leak_hard();
}
- iterator
- _M_check(size_type __pos) const
+ size_type
+ _M_check(size_type __pos, const char* __s) const
{
if (__pos > this->size())
- __throw_out_of_range(__N("basic_string::_M_check"));
- return _M_ibegin() + __pos;
+ __throw_out_of_range(__N(__s));
+ return __pos;
}
- // NB: _M_fold doesn't check for a bad __pos1 value.
- iterator
- _M_fold(size_type __pos, size_type __off) const
+ // NB: _M_limit doesn't check for a bad __pos value.
+ size_type
+ _M_limit(size_type __pos, size_type __off) const
{
const bool __testoff = __off < this->size() - __pos;
- const size_type __newoff = __testoff ? __off : this->size() - __pos;
- return (_M_ibegin() + __pos + __newoff);
+ return __testoff ? __off : this->size() - __pos;
}
// _S_copy_chars is a separate template to permit specialization
size_type __n, const _Alloc& __a);
/**
- * @brief Construct string as copy of a C substring.
- * @param s Source C string.
+ * @brief Construct string initialized by a character array.
+ * @param s Source character array.
* @param n Number of characters to copy.
* @param a Allocator to use (default is default allocator).
+ *
+ * NB: s must have at least n characters, '\0' has no special
+ * meaning.
*/
basic_string(const _CharT* __s, size_type __n,
const _Alloc& __a = _Alloc());
* @param str Source string.
*/
basic_string&
- operator=(const basic_string& __str) { return this->assign(__str); }
+ operator=(const basic_string& __str)
+ { return this->assign(__str); }
/**
* @brief Copy contents of @a s into this string.
* @param s Source null-terminated string.
*/
basic_string&
- operator=(const _CharT* __s) { return this->assign(__s); }
+ operator=(const _CharT* __s)
+ { return this->assign(__s); }
/**
* @brief Set value to string of length 1.
* (*this)[0] == @a c.
*/
basic_string&
- operator=(_CharT __c) { return this->assign(1, __c); }
+ operator=(_CharT __c)
+ {
+ this->assign(1, __c);
+ return *this;
+ }
// Iterators:
/**
*/
const_reference
operator[] (size_type __pos) const
- { return _M_data()[__pos]; }
+ {
+ _GLIBCXX_DEBUG_ASSERT(__pos <= size());
+ return _M_data()[__pos];
+ }
/**
* @brief Subscript access to the data contained in the %string.
reference
operator[](size_type __pos)
{
+ _GLIBCXX_DEBUG_ASSERT(__pos < size());
_M_leak();
return _M_data()[__pos];
}
*/
basic_string&
append(const _CharT* __s)
- { return this->append(__s, traits_type::length(__s)); }
+ {
+ __glibcxx_requires_string(__s);
+ return this->append(__s, traits_type::length(__s));
+ }
/**
* @brief Append multiple characters.
* Appends n copies of c to this string.
*/
basic_string&
- append(size_type __n, _CharT __c);
+ append(size_type __n, _CharT __c)
+ { return _M_replace_aux(this->size(), size_type(0), __n, __c); }
/**
* @brief Append a range of characters.
*/
void
push_back(_CharT __c)
- { this->replace(_M_iend(), _M_iend(), 1, __c); }
+ { _M_replace_aux(this->size(), size_type(0), size_type(1), __c); }
/**
* @brief Set value to contents of another string.
* of available characters in @a str, the remainder of @a str is used.
*/
basic_string&
- assign(const basic_string& __str, size_type __pos, size_type __n);
+ assign(const basic_string& __str, size_type __pos, size_type __n)
+ { return this->assign(__str._M_data()
+ + __str._M_check(__pos, "basic_string::assign"),
+ __str._M_limit(__pos, __n)); }
/**
* @brief Set value to a C substring.
*/
basic_string&
assign(const _CharT* __s)
- { return this->assign(__s, traits_type::length(__s)); }
+ {
+ __glibcxx_requires_string(__s);
+ return this->assign(__s, traits_type::length(__s));
+ }
/**
* @brief Set value to multiple characters.
*/
basic_string&
assign(size_type __n, _CharT __c)
- { return this->replace(_M_ibegin(), _M_iend(), __n, __c); }
+ { return _M_replace_aux(size_type(0), this->size(), __n, __c); }
/**
* @brief Set value to a range of characters.
* @brief Insert a range of characters.
* @param p Iterator referencing location in string to insert at.
* @param beg Start of range.
- * @param end End of range.
+ * @param end End of range.
* @throw std::length_error If new length exceeds @c max_size().
*
* Inserts characters in range [beg,end). If adding characters causes
*/
basic_string&
insert(size_type __pos1, const basic_string& __str)
- { return this->insert(__pos1, __str, 0, __str.size()); }
+ { return this->insert(__pos1, __str, size_type(0), __str.size()); }
/**
* @brief Insert a substring.
*/
basic_string&
insert(size_type __pos1, const basic_string& __str,
- size_type __pos2, size_type __n);
+ size_type __pos2, size_type __n)
+ { return this->insert(__pos1, __str._M_data()
+ + __str._M_check(__pos2, "basic_string::insert"),
+ __str._M_limit(__pos2, __n)); }
/**
* @brief Insert a C substring.
* @return Reference to this string.
* @throw std::length_error If new length exceeds @c max_size().
* @throw std::out_of_range If @a pos is beyond the end of this
- * string.
+ * string.
*
* Inserts the first @a n characters of @a s starting at @a pos. If
* adding characters causes the length to exceed max_size(),
*/
basic_string&
insert(size_type __pos, const _CharT* __s)
- { return this->insert(__pos, __s, traits_type::length(__s)); }
+ {
+ __glibcxx_requires_string(__s);
+ return this->insert(__pos, __s, traits_type::length(__s));
+ }
/**
* @brief Insert multiple characters.
*/
basic_string&
insert(size_type __pos, size_type __n, _CharT __c)
- {
- this->insert(_M_check(__pos), __n, __c);
- return *this;
- }
+ { return _M_replace_aux(_M_check(__pos, "basic_string::insert"),
+ size_type(0), __n, __c); }
/**
* @brief Insert one character.
* @param c The character to insert.
* @return Iterator referencing newly inserted char.
* @throw std::length_error If new length exceeds @c max_size().
- * @throw std::out_of_range If @a p is beyond the end of this string.
*
* Inserts character @a c at position referenced by @a p. If adding
* character causes the length to exceed max_size(), length_error is
* The value of the string doesn't change if an error is thrown.
*/
iterator
- insert(iterator __p, _CharT __c = _CharT())
+ insert(iterator __p, _CharT __c)
{
+ _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
const size_type __pos = __p - _M_ibegin();
- this->insert(_M_check(__pos), size_type(1), __c);
+ _M_replace_aux(__pos, size_type(0), size_type(1), __c);
_M_rep()->_M_set_leaked();
- return this->_M_ibegin() + __pos;
+ return this->_M_ibegin() + __pos;
}
/**
*/
basic_string&
erase(size_type __pos = 0, size_type __n = npos)
- {
- return this->replace(_M_check(__pos), _M_fold(__pos, __n),
- _M_data(), _M_data());
- }
+ { return _M_replace_safe(_M_check(__pos, "basic_string::erase"),
+ _M_limit(__pos, __n), NULL, size_type(0)); }
/**
* @brief Remove one character.
* @param position Iterator referencing the character to remove.
* @return iterator referencing same location after removal.
- * @throw std::out_of_range If @a position is beyond the end of this
- * string.
*
- * Removes the character at @a position from this string. If @a
- * position is beyond end of string, out_of_range is thrown. The value
+ * Removes the character at @a position from this string. The value
* of the string doesn't change if an error is thrown.
*/
iterator
erase(iterator __position)
{
- const size_type __i = __position - _M_ibegin();
- this->replace(__position, __position + 1, _M_data(), _M_data());
+ _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin()
+ && __position < _M_iend());
+ const size_type __pos = __position - _M_ibegin();
+ _M_replace_safe(__pos, size_type(1), NULL, size_type(0));
_M_rep()->_M_set_leaked();
- return _M_ibegin() + __i;
+ return _M_ibegin() + __pos;
}
/**
* @param first Iterator referencing the first character to remove.
* @param last Iterator referencing the end of the range.
* @return Iterator referencing location of first after removal.
- * @throw std::out_of_range If @a first is beyond the end of this
- * string.
*
* Removes the characters in the range [first,last) from this string.
- * If @a first is beyond end of string, out_of_range is thrown. The
- * value of the string doesn't change if an error is thrown.
+ * The value of the string doesn't change if an error is thrown.
*/
iterator
erase(iterator __first, iterator __last)
{
- const size_type __i = __first - _M_ibegin();
- this->replace(__first, __last, _M_data(), _M_data());
+ _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
+ && __last <= _M_iend());
+ const size_type __pos = __first - _M_ibegin();
+ _M_replace_safe(__pos, __last - __first, NULL, size_type(0));
_M_rep()->_M_set_leaked();
- return _M_ibegin() + __i;
+ return _M_ibegin() + __pos;
}
/**
* @param str String to insert.
* @return Reference to this string.
* @throw std::out_of_range If @a pos is beyond the end of this
- * string.
+ * string.
* @throw std::length_error If new length exceeds @c max_size().
*
* Removes the characters in the range [pos,pos+n) from this string.
* @param n2 Number of characters from str to use.
* @return Reference to this string.
* @throw std::out_of_range If @a pos1 > size() or @a pos2 >
- * str.size().
+ * str.size().
* @throw std::length_error If new length exceeds @c max_size().
*
* Removes the characters in the range [pos1,pos1 + n) from this
*/
basic_string&
replace(size_type __pos1, size_type __n1, const basic_string& __str,
- size_type __pos2, size_type __n2);
+ size_type __pos2, size_type __n2)
+ { return this->replace(__pos1, __n1, __str._M_data()
+ + __str._M_check(__pos2, "basic_string::replace"),
+ __str._M_limit(__pos2, __n2)); }
/**
* @brief Replace characters with value of a C substring.
*/
basic_string&
replace(size_type __pos, size_type __n1, const _CharT* __s)
- { return this->replace(__pos, __n1, __s, traits_type::length(__s)); }
+ {
+ __glibcxx_requires_string(__s);
+ return this->replace(__pos, __n1, __s, traits_type::length(__s));
+ }
/**
* @brief Replace characters with multiple characters.
*/
basic_string&
replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
- { return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c); }
+ { return _M_replace_aux(_M_check(__pos, "basic_string::replace"),
+ _M_limit(__pos, __n1), __n2, __c); }
/**
* @brief Replace range of characters with string.
* change if an error is thrown.
*/
basic_string&
- replace(iterator __i1, iterator __i2,
- const _CharT* __s, size_type __n)
- { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); }
+ replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
+ {
+ _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+ && __i2 <= _M_iend());
+ return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n);
+ }
/**
* @brief Replace range of characters with C string.
*/
basic_string&
replace(iterator __i1, iterator __i2, const _CharT* __s)
- { return this->replace(__i1, __i2, __s, traits_type::length(__s)); }
+ {
+ __glibcxx_requires_string(__s);
+ return this->replace(__i1, __i2, __s, traits_type::length(__s));
+ }
/**
* @brief Replace range of characters with multiple characters
*/
basic_string&
replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
- { return _M_replace_aux(__i1, __i2, __n, __c); }
+ {
+ _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+ && __i2 <= _M_iend());
+ return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c);
+ }
/**
* @brief Replace range of characters with range.
basic_string&
replace(iterator __i1, iterator __i2,
_InputIterator __k1, _InputIterator __k2)
- { typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
- return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); }
+ {
+ _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+ && __i2 <= _M_iend());
+ __glibcxx_requires_valid_range(__k1, __k2);
+ typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+ return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
+ }
// Specializations for the common case of pointer and iterator:
// useful to avoid the overhead of temporary buffering in _M_replace.
basic_string&
replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
- { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
- __k1, __k2 - __k1); }
+ {
+ _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+ && __i2 <= _M_iend());
+ __glibcxx_requires_valid_range(__k1, __k2);
+ return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+ __k1, __k2 - __k1);
+ }
basic_string&
- replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2)
- { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
- __k1, __k2 - __k1); }
+ replace(iterator __i1, iterator __i2,
+ const _CharT* __k1, const _CharT* __k2)
+ {
+ _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+ && __i2 <= _M_iend());
+ __glibcxx_requires_valid_range(__k1, __k2);
+ return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+ __k1, __k2 - __k1);
+ }
basic_string&
replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
- { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
- __k1.base(), __k2 - __k1);
- }
+ {
+ _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+ && __i2 <= _M_iend());
+ __glibcxx_requires_valid_range(__k1, __k2);
+ return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+ __k1.base(), __k2 - __k1);
+ }
basic_string&
- replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2)
- { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
- __k1.base(), __k2 - __k1);
- }
-
+ replace(iterator __i1, iterator __i2,
+ const_iterator __k1, const_iterator __k2)
+ {
+ _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
+ && __i2 <= _M_iend());
+ __glibcxx_requires_valid_range(__k1, __k2);
+ return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+ __k1.base(), __k2 - __k1);
+ }
+
private:
template<class _Integer>
basic_string&
- _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n,
+ _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n,
_Integer __val, __true_type)
- { return _M_replace_aux(__i1, __i2, __n, __val); }
+ { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); }
template<class _InputIterator>
basic_string&
_M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
- _InputIterator __k2, __false_type)
- {
- typedef typename iterator_traits<_InputIterator>::iterator_category
- _Category;
- return _M_replace(__i1, __i2, __k1, __k2, _Category());
- }
+ _InputIterator __k2, __false_type);
basic_string&
- _M_replace_aux(iterator __i1, iterator __i2, size_type __n2, _CharT __c);
-
- template<class _InputIterator>
- basic_string&
- _M_replace(iterator __i1, iterator __i2, _InputIterator __k1,
- _InputIterator __k2, input_iterator_tag);
+ _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
+ _CharT __c)
+ {
+ if (this->max_size() - (this->size() - __n1) < __n2)
+ __throw_length_error(__N("basic_string::_M_replace_aux"));
+ _M_mutate(__pos1, __n1, __n2);
+ if (__n2 == 1)
+ _M_data()[__pos1] = __c;
+ else if (__n2)
+ traits_type::assign(_M_data() + __pos1, __n2, __c);
+ return *this;
+ }
- template<class _ForwardIterator>
- basic_string&
- _M_replace_safe(iterator __i1, iterator __i2, _ForwardIterator __k1,
- _ForwardIterator __k2);
+ basic_string&
+ _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
+ size_type __n2)
+ {
+ _M_mutate(__pos1, __n1, __n2);
+ if (__n2 == 1)
+ _M_data()[__pos1] = *__s;
+ else if (__n2)
+ traits_type::copy(_M_data() + __pos1, __s, __n2);
+ return *this;
+ }
// _S_construct_aux is used to implement the 21.3.1 para 15 which
// requires special behaviour if _InIter is an integral type
template<class _InIterator>
static _CharT*
- _S_construct_aux(_InIterator __beg, _InIterator __end, const _Alloc& __a,
- __false_type)
+ _S_construct_aux(_InIterator __beg, _InIterator __end,
+ const _Alloc& __a, __false_type)
{
typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
return _S_construct(__beg, __end, __a, _Tag());
template<class _InIterator>
static _CharT*
- _S_construct_aux(_InIterator __beg, _InIterator __end, const _Alloc& __a,
- __true_type)
- {
- return _S_construct(static_cast<size_type>(__beg),
- static_cast<value_type>(__end), __a);
- }
+ _S_construct_aux(_InIterator __beg, _InIterator __end,
+ const _Alloc& __a, __true_type)
+ { return _S_construct(static_cast<size_type>(__beg),
+ static_cast<value_type>(__end), __a); }
template<class _InIterator>
static _CharT*
* happen.
*/
const _CharT*
- c_str() const
- {
- // MT: This assumes concurrent writes are OK.
- const size_type __n = this->size();
- traits_type::assign(_M_data()[__n], _Rep::_S_terminal);
- return _M_data();
- }
+ c_str() const { return _M_data(); }
/**
* @brief Return const pointer to contents.
*
- * This is a handle to internal data. It may not be null-terminated.
- * Do not modify or dire things may happen.
+ * This is a handle to internal data. Do not modify or dire things may
+ * happen.
*/
const _CharT*
data() const { return _M_data(); }
*/
size_type
find(const _CharT* __s, size_type __pos = 0) const
- { return this->find(__s, __pos, traits_type::length(__s)); }
+ {
+ __glibcxx_requires_string(__s);
+ return this->find(__s, __pos, traits_type::length(__s));
+ }
/**
* @brief Find position of a character.
*/
size_type
rfind(const _CharT* __s, size_type __pos = npos) const
- { return this->rfind(__s, __pos, traits_type::length(__s)); }
+ {
+ __glibcxx_requires_string(__s);
+ return this->rfind(__s, __pos, traits_type::length(__s));
+ }
/**
* @brief Find last position of a character.
*/
size_type
find_first_of(const _CharT* __s, size_type __pos = 0) const
- { return this->find_first_of(__s, __pos, traits_type::length(__s)); }
+ {
+ __glibcxx_requires_string(__s);
+ return this->find_first_of(__s, __pos, traits_type::length(__s));
+ }
/**
* @brief Find position of a character.
*/
size_type
find_last_of(const _CharT* __s, size_type __pos = npos) const
- { return this->find_last_of(__s, __pos, traits_type::length(__s)); }
+ {
+ __glibcxx_requires_string(__s);
+ return this->find_last_of(__s, __pos, traits_type::length(__s));
+ }
/**
* @brief Find last position of a character.
*/
size_type
find_first_not_of(const _CharT* __s, size_type __pos = 0) const
- { return this->find_first_not_of(__s, __pos, traits_type::length(__s)); }
+ {
+ __glibcxx_requires_string(__s);
+ return this->find_first_not_of(__s, __pos, traits_type::length(__s));
+ }
/**
* @brief Find position of a different character.
*/
size_type
find_last_not_of(const _CharT* __s, size_type __pos = npos) const
- { return this->find_last_not_of(__s, __pos, traits_type::length(__s)); }
+ {
+ __glibcxx_requires_string(__s);
+ return this->find_last_not_of(__s, __pos, traits_type::length(__s));
+ }
/**
* @brief Find last position of a different character.
*/
basic_string
substr(size_type __pos = 0, size_type __n = npos) const
- {
- if (__pos > this->size())
- __throw_out_of_range(__N("basic_string::substr"));
- return basic_string(*this, __pos, __n);
- }
+ { return basic_string(*this,
+ _M_check(__pos, "basic_string::substr"), __n); }
/**
* @brief Compare to a string.
compare(size_type __pos, size_type __n1, const _CharT* __s) const;
/**
- * @brief Compare substring against a C substring.
+ * @brief Compare substring against a character array.
* @param pos1 Index of first character of substring.
* @param n1 Number of characters in substring.
- * @param s C string to compare against.
- * @param n2 Number of characters in substring of s.
+ * @param s character array to compare against.
+ * @param n2 Number of characters of s.
* @return Integer < 0, 0, or > 0.
*
* Form the substring of this string from the @a n1 characters starting
- * at @a pos1. Form the substring of @a s from the first @a n
- * characters of @a s. Returns an integer < 0 if this substring is
- * ordered before the substring of @a s, 0 if their values are
- * equivalent, or > 0 if this substring is ordered after the substring
- * of @a s. If the lengths of this substring and @a n are different,
- * the shorter one is ordered first. If they are the same, returns the
- * result of traits::compare(substring.data(),s,size());
+ * at @a pos1. Form a string from the first @a n2 characters of @a s.
+ * Returns an integer < 0 if this substring is ordered before the string
+ * from @a s, 0 if their values are equivalent, or > 0 if this substring
+ * is ordered after the string from @a s. If the lengths of this
+ * substring and @a n2 are different, the shorter one is ordered first.
+ * If they are the same, returns the result of
+ * traits::compare(substring.data(),s,size());
+ *
+ * NB: s must have at least n2 characters, '\0' has no special
+ * meaning.
*/
int
compare(size_type __pos, size_type __n1, const _CharT* __s,
* @param lhs First string.
* @param rhs Last string.
* @return New string with value of @a lhs followed by @a rhs.
- */
- template<typename _CharT, typename _Traits, typename _Alloc>
+ */
+ template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>
operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
* @param lhs First string.
* @param rhs Last string.
* @return New string with value of @a lhs followed by @a rhs.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT,_Traits,_Alloc>
operator+(const _CharT* __lhs,
* @param lhs First string.
* @param rhs Last string.
* @return New string with @a lhs followed by @a rhs.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT,_Traits,_Alloc>
operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs);
* @param lhs First string.
* @param rhs Last string.
* @return New string with @a lhs followed by @a rhs.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline basic_string<_CharT, _Traits, _Alloc>
operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
* @param lhs First string.
* @param rhs Last string.
* @return New string with @a lhs followed by @a rhs.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline basic_string<_CharT, _Traits, _Alloc>
operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
{
- typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
+ typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
typedef typename __string_type::size_type __size_type;
__string_type __str(__lhs);
__str.append(__size_type(1), __rhs);
* @param lhs First string.
* @param rhs Second string.
* @return True if @a lhs.compare(@a rhs) == 0. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
* @param lhs C string.
* @param rhs String.
* @return True if @a rhs.compare(@a lhs) == 0. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator==(const _CharT* __lhs,
* @param lhs String.
* @param rhs C string.
* @return True if @a lhs.compare(@a rhs) == 0. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
* @param lhs First string.
* @param rhs Second string.
* @return True if @a lhs.compare(@a rhs) != 0. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
* @param lhs C string.
* @param rhs String.
* @return True if @a rhs.compare(@a lhs) != 0. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator!=(const _CharT* __lhs,
* @param lhs String.
* @param rhs C string.
* @return True if @a lhs.compare(@a rhs) != 0. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
* @param lhs First string.
* @param rhs Second string.
* @return True if @a lhs precedes @a rhs. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
* @param lhs String.
* @param rhs C string.
* @return True if @a lhs precedes @a rhs. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
* @param lhs C string.
* @param rhs String.
* @return True if @a lhs precedes @a rhs. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator<(const _CharT* __lhs,
* @param lhs First string.
* @param rhs Second string.
* @return True if @a lhs follows @a rhs. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
* @param lhs String.
* @param rhs C string.
* @return True if @a lhs follows @a rhs. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
* @param lhs C string.
* @param rhs String.
* @return True if @a lhs follows @a rhs. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator>(const _CharT* __lhs,
* @param lhs First string.
* @param rhs Second string.
* @return True if @a lhs doesn't follow @a rhs. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
* @param lhs String.
* @param rhs C string.
* @return True if @a lhs doesn't follow @a rhs. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
* @param lhs C string.
* @param rhs String.
* @return True if @a lhs doesn't follow @a rhs. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator<=(const _CharT* __lhs,
* @param lhs First string.
* @param rhs Second string.
* @return True if @a lhs doesn't precede @a rhs. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
* @param lhs String.
* @param rhs C string.
* @return True if @a lhs doesn't precede @a rhs. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
* @param lhs C string.
* @param rhs String.
* @return True if @a lhs doesn't precede @a rhs. False otherwise.
- */
+ */
template<typename _CharT, typename _Traits, typename _Alloc>
inline bool
operator>=(const _CharT* __lhs,
const basic_string<_CharT, _Traits, _Alloc>& __rhs)
{ return __rhs.compare(__lhs) <= 0; }
-
/**
* @brief Swap contents of two strings.
* @param lhs First string.
* @param rhs Second string.
*
- * Exchanges the contents of @a lhs and @a rhs in constant time.
+ * Exchanges the contents of @a lhs and @a rhs in constant time.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
inline void