This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[v3, v7-branch] string::append, other minor things
- From: Paolo Carlini <pcarlini at suse dot de>
- To: "'gcc-patches at gcc dot gnu dot org'" <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 02 Dec 2005 17:01:45 +0100
- Subject: [v3, v7-branch] string::append, other minor things
Hi,
I'm finally rather happy with the code :) Modulo bug fixes, will be also
the shape of ext/vstring.h delivered with 4.1.0.
Tested x86-linux, both string bases.
Paolo.
////////////////////
2005-12-02 Paolo Carlini <pcarlini@suse.de>
* include/bits/basic_string.h (basic_string<>::_M_append): New.
(append(const basic_string&), append(const basic_string&,
size_type, size_type), append(const _CharT*, size_type),
append(const _CharT*)): Use it.
(append(size_type, _CharT)): Delegate to _M_replace_aux.
(assign(const basic_string&, size_type, size_type),
assign(const _CharT*), replace(size_type, size_type,
const _CharT*, size_type)): Forward to _M_replace.
* include/bits/basic_string.tcc (basic_string<>::_M_append):
Define, core append functionality.
(_M_replace): Simplify, move __s == 0 case to _M_replace_aux.
(_M_replace_aux): Reorganize, don't call _M_replace.
Index: include/bits/basic_string.h
===================================================================
--- include/bits/basic_string.h (revision 107825)
+++ include/bits/basic_string.h (working copy)
@@ -573,7 +573,8 @@
* @return Reference to this string.
*/
basic_string&
- append(const basic_string& __str);
+ append(const basic_string& __str)
+ { return _M_append(__str._M_data(), __str.size()); }
/**
* @brief Append a substring.
@@ -588,7 +589,10 @@
* characters in @a str, the remainder of @a str is appended.
*/
basic_string&
- append(const basic_string& __str, size_type __pos, size_type __n);
+ append(const basic_string& __str, size_type __pos, size_type __n)
+ { return _M_append(__str._M_data()
+ + __str._M_check(__pos, "basic_string::append"),
+ __str._M_limit(__pos, __n)); }
/**
* @brief Append a C substring.
@@ -597,7 +601,12 @@
* @return Reference to this string.
*/
basic_string&
- append(const _CharT* __s, size_type __n);
+ append(const _CharT* __s, size_type __n)
+ {
+ __glibcxx_requires_string_len(__s, __n);
+ _M_check_length(size_type(0), __n, "basic_string::append");
+ return _M_append(__s, __n);
+ }
/**
* @brief Append a C string.
@@ -608,7 +617,9 @@
append(const _CharT* __s)
{
__glibcxx_requires_string(__s);
- return this->append(__s, traits_type::length(__s));
+ const size_type __n = traits_type::length(__s);
+ _M_check_length(size_type(0), __n, "basic_string::append");
+ return _M_append(__s, __n);
}
/**
@@ -620,7 +631,8 @@
* 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.
@@ -675,9 +687,9 @@
*/
basic_string&
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)); }
+ { return _M_replace(size_type(0), this->size(), __str._M_data()
+ + __str._M_check(__pos, "basic_string::assign"),
+ __str._M_limit(__pos, __n)); }
/**
* @brief Set value to a C substring.
@@ -709,7 +721,8 @@
assign(const _CharT* __s)
{
__glibcxx_requires_string(__s);
- return this->assign(__s, traits_type::length(__s));
+ return _M_replace(size_type(0), this->size(), __s,
+ traits_type::length(__s));
}
/**
@@ -1022,7 +1035,12 @@
*/
basic_string&
replace(size_type __pos, size_type __n1, const _CharT* __s,
- size_type __n2);
+ size_type __n2)
+ {
+ __glibcxx_requires_string_len(__s, __n2);
+ return _M_replace(_M_check(__pos, "basic_string::replace"),
+ _M_limit(__pos, __n1), __s, __n2);
+ }
/**
* @brief Replace characters with value of a C string.
@@ -1238,6 +1256,9 @@
_M_replace(size_type __pos, size_type __len1, const _CharT* __s,
const size_type __len2);
+ basic_string&
+ _M_append(const _CharT* __s, size_type __n);
+
public:
/**
Index: include/bits/basic_string.tcc
===================================================================
--- include/bits/basic_string.tcc (revision 107825)
+++ include/bits/basic_string.tcc (working copy)
@@ -67,111 +67,37 @@
}
template<typename _CharT, typename _Traits, typename _Alloc>
- basic_string<_CharT, _Traits, _Alloc>&
+ void
basic_string<_CharT, _Traits, _Alloc>::
- append(size_type __n, _CharT __c)
+ resize(size_type __n, _CharT __c)
{
- if (__n)
- {
- _M_check_length(size_type(0), __n, "basic_string::append");
- const size_type __len = __n + this->size();
- if (__len > this->capacity() || this->_M_is_shared())
- this->_M_reserve(__len);
- this->_S_assign(this->_M_data() + this->size(), __n, __c);
- this->_M_set_length(__len);
- }
- return *this;
+ const size_type __size = this->size();
+ if (__size < __n)
+ this->append(__n - __size, __c);
+ else if (__n < __size)
+ this->_M_erase(__n, __size - __n);
}
template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>&
basic_string<_CharT, _Traits, _Alloc>::
- append(const _CharT* __s, size_type __n)
+ _M_append(const _CharT* __s, size_type __n)
{
- __glibcxx_requires_string_len(__s, __n);
- if (__n)
- {
- _M_check_length(size_type(0), __n, "basic_string::append");
- const size_type __len = __n + this->size();
- if (__len > this->capacity() || this->_M_is_shared())
- {
- if (this->_M_disjunct(__s))
- this->_M_reserve(__len);
- else
- {
- const size_type __off = __s - this->_M_data();
- this->_M_reserve(__len);
- __s = this->_M_data() + __off;
- }
- }
- this->_S_copy(this->_M_data() + this->size(), __s, __n);
- this->_M_set_length(__len);
- }
- return *this;
- }
+ const size_type __len = __n + this->size();
- template<typename _CharT, typename _Traits, typename _Alloc>
- basic_string<_CharT, _Traits, _Alloc>&
- basic_string<_CharT, _Traits, _Alloc>::
- append(const basic_string& __str)
- {
- const size_type __size = __str.size();
- if (__size)
+ if (__len <= this->capacity() && !this->_M_is_shared())
{
- const size_type __len = __size + this->size();
- if (__len > this->capacity() || this->_M_is_shared())
- this->_M_reserve(__len);
- this->_S_copy(this->_M_data() + this->size(), __str._M_data(),
- __size);
- this->_M_set_length(__len);
+ if (__n)
+ this->_S_copy(this->_M_data() + this->size(), __s, __n);
}
- return *this;
- }
+ else
+ this->_M_mutate(this->size(), size_type(0), __s, __n);
- template<typename _CharT, typename _Traits, typename _Alloc>
- basic_string<_CharT, _Traits, _Alloc>&
- basic_string<_CharT, _Traits, _Alloc>::
- append(const basic_string& __str, size_type __pos, size_type __n)
- {
- __str._M_check(__pos, "basic_string::append");
- __n = __str._M_limit(__pos, __n);
- if (__n)
- {
- const size_type __len = __n + this->size();
- if (__len > this->capacity() || this->_M_is_shared())
- this->_M_reserve(__len);
- this->_S_copy(this->_M_data() + this->size(),
- __str._M_data() + __pos, __n);
- this->_M_set_length(__len);
- }
+ this->_M_set_length(__len);
return *this;
}
template<typename _CharT, typename _Traits, typename _Alloc>
- basic_string<_CharT, _Traits, _Alloc>&
- basic_string<_CharT, _Traits, _Alloc>::
- replace(size_type __pos, size_type __n1, const _CharT* __s,
- size_type __n2)
- {
- __glibcxx_requires_string_len(__s, __n2);
- _M_check(__pos, "basic_string::replace");
- __n1 = _M_limit(__pos, __n1);
- return _M_replace(__pos, __n1, __s, __n2);
- }
-
- template<typename _CharT, typename _Traits, typename _Alloc>
- void
- basic_string<_CharT, _Traits, _Alloc>::
- resize(size_type __n, _CharT __c)
- {
- const size_type __size = this->size();
- if (__size < __n)
- this->append(__n - __size, __c);
- else if (__n < __size)
- this->_M_erase(__n, __size - __n);
- }
-
- template<typename _CharT, typename _Traits, typename _Alloc>
template<typename _InputIterator>
basic_string<_CharT, _Traits, _Alloc>&
basic_string<_CharT, _Traits, _Alloc>::
@@ -190,9 +116,26 @@
_M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
_CharT __c)
{
- _M_replace(__pos1, __n1, 0, __n2);
+ _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
+
+ const size_type __old_size = this->size();
+ const size_type __new_size = __old_size + __n2 - __n1;
+
+ if (__new_size <= this->capacity() && !this->_M_is_shared())
+ {
+ _CharT* __p = this->_M_data() + __pos1;
+
+ const size_type __how_much = __old_size - __pos1 - __n1;
+ if (__how_much && __n1 != __n2)
+ this->_S_move(__p + __n2, __p + __n1, __how_much);
+ }
+ else
+ this->_M_mutate(__pos1, __n1, 0, __n2);
+
if (__n2)
this->_S_assign(this->_M_data() + __pos1, __n2, __c);
+
+ this->_M_set_length(__new_size);
return *this;
}
@@ -206,45 +149,41 @@
const size_type __old_size = this->size();
const size_type __new_size = __old_size + __len2 - __len1;
- const size_type __how_much = __old_size - __pos - __len1;
if (__new_size <= this->capacity() && !this->_M_is_shared())
{
_CharT* __p = this->_M_data() + __pos;
- if (__s)
+
+ const size_type __how_much = __old_size - __pos - __len1;
+ if (_M_disjunct(__s))
{
- if (_M_disjunct(__s))
+ if (__how_much && __len1 != __len2)
+ this->_S_move(__p + __len2, __p + __len1, __how_much);
+ if (__len2)
+ this->_S_copy(__p, __s, __len2);
+ }
+ else
+ {
+ // Work in-place.
+ if (__len2 && __len2 <= __len1)
+ this->_S_move(__p, __s, __len2);
+ if (__how_much && __len1 != __len2)
+ this->_S_move(__p + __len2, __p + __len1, __how_much);
+ if (__len2 > __len1)
{
- if (__how_much && __len1 != __len2)
- this->_S_move(__p + __len2, __p + __len1, __how_much);
- if (__len2)
- this->_S_copy(__p, __s, __len2);
- }
- else
- {
- // Work in-place.
- if (__len2 && __len2 <= __len1)
+ if (__s + __len2 <= __p + __len1)
this->_S_move(__p, __s, __len2);
- if (__how_much && __len1 != __len2)
- this->_S_move(__p + __len2, __p + __len1, __how_much);
- if (__len2 > __len1)
+ else if (__s >= __p + __len1)
+ this->_S_copy(__p, __s + __len2 - __len1, __len2);
+ else
{
- if (__s + __len2 <= __p + __len1)
- this->_S_move(__p, __s, __len2);
- else if (__s >= __p + __len1)
- this->_S_copy(__p, __s + __len2 - __len1, __len2);
- else
- {
- const size_type __nleft = (__p + __len1) - __s;
- this->_S_move(__p, __s, __nleft);
- this->_S_copy(__p + __nleft, __p + __len2,
- __len2 - __nleft);
- }
+ const size_type __nleft = (__p + __len1) - __s;
+ this->_S_move(__p, __s, __nleft);
+ this->_S_copy(__p + __nleft, __p + __len2,
+ __len2 - __nleft);
}
}
}
- else if (__how_much && __len1 != __len2)
- this->_S_move(__p + __len2, __p + __len1, __how_much);
}
else
this->_M_mutate(__pos, __len1, __s, __len2);