aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2005-12-05 00:32:31 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2005-12-05 00:32:31 +0000
commitcf8829194fb63dc0c25253934e1cff4bf4c7f6ca (patch)
tree92c651354a9a4c8882011f990f958ea570368aaf /libstdc++-v3
parent7343398692a7c9fbdeea485e51d34ef0a5be9c5b (diff)
downloadgcc-cf8829194fb63dc0c25253934e1cff4bf4c7f6ca.zip
gcc-cf8829194fb63dc0c25253934e1cff4bf4c7f6ca.tar.gz
gcc-cf8829194fb63dc0c25253934e1cff4bf4c7f6ca.tar.bz2
vstring.h (__versa_string<>::operator+, [...]): Move out of line...
2005-12-04 Paolo Carlini <pcarlini@suse.de> * include/ext/vstring.h (__versa_string<>::operator+, all versions): Move out of line... * include/ext/vstring.tcc (__versa_string<>::operator+): ... here; consistently use reserve for the benefit of sso_string_base; prefer push_back to single-char append when appropriate. * include/ext/vstring.h (__versa_string<>::push_back): Don't call _M_reserve, _M_mutate instead. (reserve): Just forward to _M_reserve. * include/ext/vstring.tcc (__versa_string<>::_M_reserve): Remove. * include/ext/rc_string_base.h (__rc_string_base<>::_M_reserve): Also do the initial checks (first on length, in case __res == capacity). * include/ext/sso_string_base.h (__sso_string_base<>::_M_reserve: Likewise; don't call _M_set_length unnecessarily. 2005-12-04 Paolo Carlini <pcarlini@suse.de> * include/ext/vstring.h (__versa_string<>::_M_append): New. (append(const __versa_string&), append(const __versa_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 __versa_string&, size_type, size_type), assign(const _CharT*), replace(size_type, size_type, const _CharT*, size_type)): Forward to _M_replace. * include/ext/vstring.tcc (__versa_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. 2005-12-04 Paolo Carlini <pcarlini@suse.de> * include/ext/vstring.tcc (__versa_string<>::_M_replace): Perform _M_check_length at the beginning and remove it from ... (replace, _M_replace_dispatch, _M_replace_aux, assign): ... here. (assign): Now move inline. (resize): Don't call _M_check_length redundantly, append does. 2005-12-04 Paolo Carlini <pcarlini@suse.de> * include/ext/sso_string_base.h (__sso_string_base<>::_M_get_allocator): Add non const version. * include/ext/rc_string_base.h (__rc_string_base<>::_M_get_allocator): Likewise. * include/ext/sso_string_base.h (__sso_string_base<>::_M_erase): Add. * include/ext/rc_string_base.h (__rc_string_base<>::_M_erase): Likewise. (_M_leak_hard): Use it. * include/ext/vstring.h (__versa_string<>::clear, erase, all versions): Use it. * include/ext/vstring.tcc (__versa_string<>::resize): Likewise. * include/ext/vstring.h (__versa_string<>::_M_replace_safe): Remove. * include/ext/vstring.h (__versa_string<>::_M_replace): New, does the in-place work or delegates to _M_mutate in case of reallocation. * include/ext/vstring.tcc (__versa_string<>::_M_replace_safe): Remove. * include/ext/vstring.tcc (__versa_string<>::_M_replace): Define. (assign, replace, _M_replace_dispatch, _M_replace_aux): Use it. * include/ext/sso_string_base.h (__sso_string_base<>::_M_mutate): Change to manage only reallocations. * include/ext/rc_string_base.h (__rc_string_base<>::_M_mutate): Likewise. * include/ext/vstring.h (__versa_string<>::insert(size_type, const __versa_string&), insert(size_type, const __versa_string&, size_type, size_type), insert(size_type, const _CharT*, size_type), insert(size_type, const _CharT*)): Delegate to replace. * include/ext/vstring.h (__versa_string<>::reserve): Move out of line. * include/ext/vstring.tcc (__versa_string<>::reserve): Do the checks and call _M_reserve. * include/ext/vstring.h (__versa_string<>::append): Call _M_reserve instead of reserve. * include/ext/vstring.tcc (__versa_string<>::append, all versions): Likewise. * include/ext/sso_string_base.h (__sso_string_base<>::_M_reserve): Adjust. * include/ext/rc_string_base.h (__rc_string_base<>::_M_reserve): Likewise. From-SVN: r108034
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog85
-rw-r--r--libstdc++-v3/include/ext/rc_string_base.h71
-rw-r--r--libstdc++-v3/include/ext/sso_string_base.h81
-rw-r--r--libstdc++-v3/include/ext/vstring.h122
-rw-r--r--libstdc++-v3/include/ext/vstring.tcc316
5 files changed, 374 insertions, 301 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index de206f6..3dcd4d8 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,88 @@
+2005-12-04 Paolo Carlini <pcarlini@suse.de>
+
+ * include/ext/vstring.h (__versa_string<>::operator+, all
+ versions): Move out of line...
+ * include/ext/vstring.tcc (__versa_string<>::operator+): ...
+ here; consistently use reserve for the benefit of sso_string_base;
+ prefer push_back to single-char append when appropriate.
+
+ * include/ext/vstring.h (__versa_string<>::push_back): Don't
+ call _M_reserve, _M_mutate instead.
+ (reserve): Just forward to _M_reserve.
+ * include/ext/vstring.tcc (__versa_string<>::_M_reserve): Remove.
+ * include/ext/rc_string_base.h (__rc_string_base<>::_M_reserve): Also
+ do the initial checks (first on length, in case __res == capacity).
+ * include/ext/sso_string_base.h (__sso_string_base<>::_M_reserve:
+ Likewise; don't call _M_set_length unnecessarily.
+
+2005-12-04 Paolo Carlini <pcarlini@suse.de>
+
+ * include/ext/vstring.h (__versa_string<>::_M_append): New.
+ (append(const __versa_string&), append(const __versa_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 __versa_string&, size_type, size_type),
+ assign(const _CharT*), replace(size_type, size_type,
+ const _CharT*, size_type)): Forward to _M_replace.
+ * include/ext/vstring.tcc (__versa_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.
+
+2005-12-04 Paolo Carlini <pcarlini@suse.de>
+
+ * include/ext/vstring.tcc (__versa_string<>::_M_replace):
+ Perform _M_check_length at the beginning and remove it from ...
+ (replace, _M_replace_dispatch, _M_replace_aux, assign): ... here.
+ (assign): Now move inline.
+ (resize): Don't call _M_check_length redundantly, append does.
+
+2005-12-04 Paolo Carlini <pcarlini@suse.de>
+
+ * include/ext/sso_string_base.h (__sso_string_base<>::_M_get_allocator):
+ Add non const version.
+ * include/ext/rc_string_base.h (__rc_string_base<>::_M_get_allocator):
+ Likewise.
+
+ * include/ext/sso_string_base.h (__sso_string_base<>::_M_erase): Add.
+ * include/ext/rc_string_base.h (__rc_string_base<>::_M_erase): Likewise.
+ (_M_leak_hard): Use it.
+ * include/ext/vstring.h (__versa_string<>::clear, erase, all
+ versions): Use it.
+ * include/ext/vstring.tcc (__versa_string<>::resize): Likewise.
+
+ * include/ext/vstring.h (__versa_string<>::_M_replace_safe):
+ Remove.
+ * include/ext/vstring.h (__versa_string<>::_M_replace): New, does
+ the in-place work or delegates to _M_mutate in case of reallocation.
+ * include/ext/vstring.tcc (__versa_string<>::_M_replace_safe):
+ Remove.
+ * include/ext/vstring.tcc (__versa_string<>::_M_replace): Define.
+ (assign, replace, _M_replace_dispatch, _M_replace_aux): Use it.
+ * include/ext/sso_string_base.h (__sso_string_base<>::_M_mutate):
+ Change to manage only reallocations.
+ * include/ext/rc_string_base.h (__rc_string_base<>::_M_mutate):
+ Likewise.
+
+ * include/ext/vstring.h (__versa_string<>::insert(size_type,
+ const __versa_string&), insert(size_type, const __versa_string&,
+ size_type, size_type), insert(size_type, const _CharT*, size_type),
+ insert(size_type, const _CharT*)): Delegate to replace.
+
+ * include/ext/vstring.h (__versa_string<>::reserve): Move out of
+ line.
+ * include/ext/vstring.tcc (__versa_string<>::reserve): Do the
+ checks and call _M_reserve.
+ * include/ext/vstring.h (__versa_string<>::append): Call _M_reserve
+ instead of reserve.
+ * include/ext/vstring.tcc (__versa_string<>::append, all versions):
+ Likewise.
+ * include/ext/sso_string_base.h (__sso_string_base<>::_M_reserve):
+ Adjust.
+ * include/ext/rc_string_base.h (__rc_string_base<>::_M_reserve):
+ Likewise.
+
2005-12-02 David Billinghurst (David.Billinghurst@riotinto.com)
PR testsuite/25193
diff --git a/libstdc++-v3/include/ext/rc_string_base.h b/libstdc++-v3/include/ext/rc_string_base.h
index 8fb7531..9636a81 100644
--- a/libstdc++-v3/include/ext/rc_string_base.h
+++ b/libstdc++-v3/include/ext/rc_string_base.h
@@ -311,6 +311,10 @@ namespace __gnu_cxx
~__rc_string_base()
{ _M_dispose(); }
+ allocator_type&
+ _M_get_allocator()
+ { return _M_dataplus; }
+
const allocator_type&
_M_get_allocator() const
{ return _M_dataplus; }
@@ -325,7 +329,11 @@ namespace __gnu_cxx
_M_reserve(size_type __res);
void
- _M_mutate(size_type __pos, size_type __len1, size_type __len2);
+ _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
+ size_type __len2);
+
+ void
+ _M_erase(size_type __pos, size_type __n);
};
template<typename _CharT, typename _Traits, typename _Alloc>
@@ -377,8 +385,8 @@ namespace __gnu_cxx
// NB: Need an array of char_type[__capacity], plus a terminating
// null char_type() element, plus enough for the _Rep data structure,
- // plus sizeof(size_type) - 1 to upper round to a size multiple
- // of sizeof(size_type).
+ // plus sizeof(_Rep) - 1 to upper round to a size multiple of
+ // sizeof(_Rep).
// Whew. Seemingly so needy, yet so elemental.
size_type __size = ((__capacity + 1) * sizeof(_CharT)
+ 2 * sizeof(_Rep) - 1);
@@ -458,7 +466,7 @@ namespace __gnu_cxx
_M_leak_hard()
{
if (_M_is_shared())
- _M_mutate(0, 0, 0);
+ _M_erase(0, 0);
_M_set_leaked();
}
@@ -490,7 +498,7 @@ namespace __gnu_cxx
{
while (__beg != __end)
{
- if (__len == __r->_M_capacity)
+ if (__len == __r->_M_info._M_capacity)
{
// Allocate more space.
_Rep* __another = _Rep::_S_create(__len + 1, __len, __a);
@@ -594,12 +602,12 @@ namespace __gnu_cxx
__rc_string_base<_CharT, _Traits, _Alloc>::
_M_reserve(size_type __res)
{
+ // Make sure we don't shrink below the current size.
+ if (__res < _M_length())
+ __res = _M_length();
+
if (__res != _M_capacity() || _M_is_shared())
{
- // Make sure we don't shrink below the current size.
- if (__res < _M_length())
- __res = _M_length();
-
_CharT* __tmp = _M_rep()->_M_clone(_M_get_allocator(),
__res - _M_length());
_M_dispose();
@@ -610,13 +618,35 @@ namespace __gnu_cxx
template<typename _CharT, typename _Traits, typename _Alloc>
void
__rc_string_base<_CharT, _Traits, _Alloc>::
- _M_mutate(size_type __pos, size_type __len1, size_type __len2)
+ _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
+ size_type __len2)
{
- const size_type __old_size = _M_length();
- const size_type __new_size = __old_size + __len2 - __len1;
- const size_type __how_much = __old_size - __pos - __len1;
+ const size_type __how_much = _M_length() - __pos - __len1;
+
+ _Rep* __r = _Rep::_S_create(_M_length() + __len2 - __len1,
+ _M_capacity(), _M_get_allocator());
- if (__new_size > _M_capacity() || _M_is_shared())
+ if (__pos)
+ _S_copy(__r->_M_refdata(), _M_data(), __pos);
+ if (__s && __len2)
+ _S_copy(__r->_M_refdata() + __pos, __s, __len2);
+ if (__how_much)
+ _S_copy(__r->_M_refdata() + __pos + __len2,
+ _M_data() + __pos + __len1, __how_much);
+
+ _M_dispose();
+ _M_data(__r->_M_refdata());
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ void
+ __rc_string_base<_CharT, _Traits, _Alloc>::
+ _M_erase(size_type __pos, size_type __n)
+ {
+ const size_type __new_size = _M_length() - __n;
+ const size_type __how_much = _M_length() - __pos - __n;
+
+ if (_M_is_shared())
{
// Must reallocate.
_Rep* __r = _Rep::_S_create(__new_size, _M_capacity(),
@@ -625,19 +655,20 @@ namespace __gnu_cxx
if (__pos)
_S_copy(__r->_M_refdata(), _M_data(), __pos);
if (__how_much)
- _S_copy(__r->_M_refdata() + __pos + __len2,
- _M_data() + __pos + __len1, __how_much);
+ _S_copy(__r->_M_refdata() + __pos,
+ _M_data() + __pos + __n, __how_much);
_M_dispose();
_M_data(__r->_M_refdata());
}
- else if (__how_much && __len1 != __len2)
+ else if (__how_much && __n)
{
// Work in-place.
- _S_move(_M_data() + __pos + __len2,
- _M_data() + __pos + __len1, __how_much);
+ _S_move(_M_data() + __pos,
+ _M_data() + __pos + __n, __how_much);
}
- _M_rep()->_M_set_length(__new_size);
+
+ _M_rep()->_M_set_length(__new_size);
}
} // namespace __gnu_cxx
diff --git a/libstdc++-v3/include/ext/sso_string_base.h b/libstdc++-v3/include/ext/sso_string_base.h
index f4bd3fb..e552a57 100644
--- a/libstdc++-v3/include/ext/sso_string_base.h
+++ b/libstdc++-v3/include/ext/sso_string_base.h
@@ -202,6 +202,10 @@ namespace __gnu_cxx
~__sso_string_base()
{ _M_dispose(); }
+ allocator_type&
+ _M_get_allocator()
+ { return _M_dataplus; }
+
const allocator_type&
_M_get_allocator() const
{ return _M_dataplus; }
@@ -216,7 +220,11 @@ namespace __gnu_cxx
_M_reserve(size_type __res);
void
- _M_mutate(size_type __pos, size_type __len1, size_type __len2);
+ _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
+ size_type __len2);
+
+ void
+ _M_erase(size_type __pos, size_type __n);
};
template<typename _CharT, typename _Traits, typename _Alloc>
@@ -471,19 +479,18 @@ namespace __gnu_cxx
__sso_string_base<_CharT, _Traits, _Alloc>::
_M_reserve(size_type __res)
{
+ // Make sure we don't shrink below the current size.
+ if (__res < _M_length())
+ __res = _M_length();
+
const size_type __capacity = _M_capacity();
if (__res != __capacity)
{
- // Make sure we don't shrink below the current size.
- if (__res < _M_length())
- __res = _M_length();
-
if (__res > __capacity
|| __res > size_type(_S_local_capacity))
{
_CharT* __tmp = _M_create(__res, __capacity);
- if (_M_length())
- _S_copy(__tmp, _M_data(), _M_length());
+ _S_copy(__tmp, _M_data(), _M_length() + 1);
_M_dispose();
_M_data(__tmp);
_M_capacity(__res);
@@ -491,49 +498,49 @@ namespace __gnu_cxx
else if (!_M_is_local())
{
const size_type __tmp_capacity = _M_allocated_capacity;
- if (_M_length())
- _S_copy(_M_local_data, _M_data(), _M_length());
+ _S_copy(_M_local_data, _M_data(), _M_length() + 1);
_M_destroy(__tmp_capacity + 1);
_M_data(_M_local_data);
- }
-
- _M_set_length(_M_length());
+ }
}
}
template<typename _CharT, typename _Traits, typename _Alloc>
void
__sso_string_base<_CharT, _Traits, _Alloc>::
- _M_mutate(size_type __pos, size_type __len1, size_type __len2)
+ _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
+ const size_type __len2)
{
- const size_type __old_size = _M_length();
- const size_type __new_size = __old_size + __len2 - __len1;
- const size_type __how_much = __old_size - __pos - __len1;
+ const size_type __how_much = _M_length() - __pos - __len1;
- if (__new_size > _M_capacity())
- {
- // Must reallocate.
- size_type __new_capacity = __new_size;
- _CharT* __r = _M_create(__new_capacity, _M_capacity());
+ size_type __new_capacity = _M_length() + __len2 - __len1;
+ _CharT* __r = _M_create(__new_capacity, _M_capacity());
+
+ if (__pos)
+ _S_copy(__r, _M_data(), __pos);
+ if (__s && __len2)
+ _S_copy(__r + __pos, __s, __len2);
+ if (__how_much)
+ _S_copy(__r + __pos + __len2,
+ _M_data() + __pos + __len1, __how_much);
+
+ _M_dispose();
+ _M_data(__r);
+ _M_capacity(__new_capacity);
+ }
- if (__pos)
- _S_copy(__r, _M_data(), __pos);
- if (__how_much)
- _S_copy(__r + __pos + __len2,
- _M_data() + __pos + __len1, __how_much);
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ void
+ __sso_string_base<_CharT, _Traits, _Alloc>::
+ _M_erase(size_type __pos, size_type __n)
+ {
+ const size_type __how_much = _M_length() - __pos - __n;
- _M_dispose();
- _M_data(__r);
- _M_capacity(__new_capacity);
- }
- else if (__how_much && __len1 != __len2)
- {
- // Work in-place.
- _S_move(_M_data() + __pos + __len2,
- _M_data() + __pos + __len1, __how_much);
- }
+ if (__how_much && __n)
+ _S_move(_M_data() + __pos, _M_data() + __pos + __n,
+ __how_much);
- _M_set_length(__new_size);
+ _M_set_length(_M_length() - __n);
}
} // namespace __gnu_cxx
diff --git a/libstdc++-v3/include/ext/vstring.h b/libstdc++-v3/include/ext/vstring.h
index 1aaa876..4a52285 100644
--- a/libstdc++-v3/include/ext/vstring.h
+++ b/libstdc++-v3/include/ext/vstring.h
@@ -402,14 +402,14 @@ namespace __gnu_cxx
*/
void
reserve(size_type __res_arg = 0)
- { this->_M_reserve(__res_arg); }
+ { this->_M_reserve(__res_arg); }
/**
* Erases the string, making it empty.
*/
void
clear()
- { this->_M_mutate(0, this->size(), 0); }
+ { this->_M_erase(size_type(0), this->size()); }
/**
* Returns true if the %string is empty. Equivalent to *this == "".
@@ -529,7 +529,8 @@ namespace __gnu_cxx
* @return Reference to this string.
*/
__versa_string&
- append(const __versa_string& __str);
+ append(const __versa_string& __str)
+ { return _M_append(__str._M_data(), __str.size()); }
/**
* @brief Append a substring.
@@ -544,7 +545,10 @@ namespace __gnu_cxx
* characters in @a str, the remainder of @a str is appended.
*/
__versa_string&
- append(const __versa_string& __str, size_type __pos, size_type __n);
+ append(const __versa_string& __str, size_type __pos, size_type __n)
+ { return _M_append(__str._M_data()
+ + __str._M_check(__pos, "__versa_string::append"),
+ __str._M_limit(__pos, __n)); }
/**
* @brief Append a C substring.
@@ -553,7 +557,12 @@ namespace __gnu_cxx
* @return Reference to this string.
*/
__versa_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, "__versa_string::append");
+ return _M_append(__s, __n);
+ }
/**
* @brief Append a C string.
@@ -564,7 +573,9 @@ namespace __gnu_cxx
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, "__versa_string::append");
+ return _M_append(__s, __n);
}
/**
@@ -576,7 +587,8 @@ namespace __gnu_cxx
* Appends n copies of c to this string.
*/
__versa_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.
@@ -598,11 +610,11 @@ namespace __gnu_cxx
void
push_back(_CharT __c)
{
- const size_type __len = 1 + this->size();
- if (__len > this->capacity() || this->_M_is_shared())
- this->reserve(__len);
- traits_type::assign(this->_M_data()[this->size()], __c);
- this->_M_set_length(__len);
+ const size_type __size = this->size();
+ if (__size + 1 > this->capacity() || this->_M_is_shared())
+ this->_M_mutate(__size, size_type(0), 0, size_type(1));
+ traits_type::assign(this->_M_data()[__size], __c);
+ this->_M_set_length(__size + 1);
}
/**
@@ -631,9 +643,9 @@ namespace __gnu_cxx
*/
__versa_string&
assign(const __versa_string& __str, size_type __pos, size_type __n)
- { return this->assign(__str._M_data()
- + __str._M_check(__pos, "__versa_string::assign"),
- __str._M_limit(__pos, __n)); }
+ { return _M_replace(size_type(0), this->size(), __str._M_data()
+ + __str._M_check(__pos, "__versa_string::assign"),
+ __str._M_limit(__pos, __n)); }
/**
* @brief Set value to a C substring.
@@ -646,7 +658,11 @@ namespace __gnu_cxx
* available characters in @a s, the remainder of @a s is used.
*/
__versa_string&
- assign(const _CharT* __s, size_type __n);
+ assign(const _CharT* __s, size_type __n)
+ {
+ __glibcxx_requires_string_len(__s, __n);
+ return _M_replace(size_type(0), this->size(), __s, __n);
+ }
/**
* @brief Set value to contents of a C string.
@@ -661,7 +677,8 @@ namespace __gnu_cxx
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));
}
/**
@@ -735,7 +752,8 @@ namespace __gnu_cxx
*/
__versa_string&
insert(size_type __pos1, const __versa_string& __str)
- { return this->insert(__pos1, __str, size_type(0), __str.size()); }
+ { return this->replace(__pos1, size_type(0),
+ __str._M_data(), __str.size()); }
/**
* @brief Insert a substring.
@@ -758,9 +776,9 @@ namespace __gnu_cxx
__versa_string&
insert(size_type __pos1, const __versa_string& __str,
size_type __pos2, size_type __n)
- { return this->insert(__pos1, __str._M_data()
- + __str._M_check(__pos2, "__versa_string::insert"),
- __str._M_limit(__pos2, __n)); }
+ { return this->replace(__pos1, size_type(0), __str._M_data()
+ + __str._M_check(__pos2, "__versa_string::insert"),
+ __str._M_limit(__pos2, __n)); }
/**
* @brief Insert a C substring.
@@ -779,7 +797,8 @@ namespace __gnu_cxx
* thrown.
*/
__versa_string&
- insert(size_type __pos, const _CharT* __s, size_type __n);
+ insert(size_type __pos, const _CharT* __s, size_type __n)
+ { return this->replace(__pos, size_type(0), __s, __n); }
/**
* @brief Insert a C string.
@@ -800,7 +819,8 @@ namespace __gnu_cxx
insert(size_type __pos, const _CharT* __s)
{
__glibcxx_requires_string(__s);
- return this->insert(__pos, __s, traits_type::length(__s));
+ return this->replace(__pos, size_type(0), __s,
+ traits_type::length(__s));
}
/**
@@ -843,7 +863,7 @@ namespace __gnu_cxx
const size_type __pos = __p - _M_ibegin();
_M_replace_aux(__pos, size_type(0), size_type(1), __c);
this->_M_set_leaked();
- return _M_ibegin() + __pos;
+ return iterator(this->_M_data() + __pos);
}
/**
@@ -863,8 +883,8 @@ namespace __gnu_cxx
__versa_string&
erase(size_type __pos = 0, size_type __n = npos)
{
- this->_M_mutate(_M_check(__pos, "__versa_string::erase"),
- _M_limit(__pos, __n), size_type(0));
+ this->_M_erase(_M_check(__pos, "__versa_string::erase"),
+ _M_limit(__pos, __n));
return *this;
}
@@ -882,9 +902,9 @@ namespace __gnu_cxx
_GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin()
&& __position < _M_iend());
const size_type __pos = __position - _M_ibegin();
- this->_M_mutate(__pos, size_type(1), size_type(0));
+ this->_M_erase(__pos, size_type(1));
this->_M_set_leaked();
- return _M_ibegin() + __pos;
+ return iterator(this->_M_data() + __pos);
}
/**
@@ -902,9 +922,9 @@ namespace __gnu_cxx
_GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
&& __last <= _M_iend());
const size_type __pos = __first - _M_ibegin();
- this->_M_mutate(__pos, __last - __first, size_type(0));
+ this->_M_erase(__pos, __last - __first);
this->_M_set_leaked();
- return _M_ibegin() + __pos;
+ return iterator(this->_M_data() + __pos);
}
/**
@@ -974,7 +994,12 @@ namespace __gnu_cxx
*/
__versa_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, "__versa_string::replace"),
+ _M_limit(__pos, __n1), __s, __n2);
+ }
/**
* @brief Replace characters with value of a C string.
@@ -1187,8 +1212,11 @@ namespace __gnu_cxx
_CharT __c);
__versa_string&
- _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
- size_type __n2);
+ _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
+ const size_type __len2);
+
+ __versa_string&
+ _M_append(const _CharT* __s, size_type __n);
public:
@@ -1771,12 +1799,7 @@ namespace __gnu_cxx
template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>
operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
- const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
- {
- __versa_string<_CharT, _Traits, _Alloc, _Base> __str(__lhs);
- __str.append(__rhs);
- return __str;
- }
+ const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs);
/**
* @brief Concatenate C string and string.
@@ -1810,14 +1833,9 @@ namespace __gnu_cxx
*/
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
- inline __versa_string<_CharT, _Traits, _Alloc, _Base>
+ __versa_string<_CharT, _Traits, _Alloc, _Base>
operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
- const _CharT* __rhs)
- {
- __versa_string<_CharT, _Traits, _Alloc, _Base> __str(__lhs);
- __str.append(__rhs);
- return __str;
- }
+ const _CharT* __rhs);
/**
* @brief Concatenate string and character.
@@ -1827,17 +1845,9 @@ namespace __gnu_cxx
*/
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
- inline __versa_string<_CharT, _Traits, _Alloc, _Base>
+ __versa_string<_CharT, _Traits, _Alloc, _Base>
operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
- _CharT __rhs)
- {
- typedef __versa_string<_CharT, _Traits, _Alloc, _Base>
- __string_type;
- typedef typename __string_type::size_type __size_type;
- __string_type __str(__lhs);
- __str.append(__size_type(1), __rhs);
- return __str;
- }
+ _CharT __rhs);
// operator ==
/**
diff --git a/libstdc++-v3/include/ext/vstring.tcc b/libstdc++-v3/include/ext/vstring.tcc
index 76fa96b..2fed7e2 100644
--- a/libstdc++-v3/include/ext/vstring.tcc
+++ b/libstdc++-v3/include/ext/vstring.tcc
@@ -47,192 +47,37 @@ namespace __gnu_cxx
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
- __versa_string<_CharT, _Traits, _Alloc, _Base>&
- __versa_string<_CharT, _Traits, _Alloc, _Base>::
- assign(const _CharT* __s, size_type __n)
- {
- __glibcxx_requires_string_len(__s, __n);
- _M_check_length(this->size(), __n, "__versa_string::assign");
- if (_M_disjunct(__s) || this->_M_is_shared())
- return _M_replace_safe(size_type(0), this->size(), __s, __n);
- else
- {
- // Work in-place.
- const size_type __pos = __s - this->_M_data();
- if (__pos >= __n)
- this->_S_copy(this->_M_data(), __s, __n);
- else if (__pos)
- this->_S_move(this->_M_data(), __s, __n);
- this->_M_set_length(__n);
- return *this;
- }
- }
-
- template<typename _CharT, typename _Traits, typename _Alloc,
- template <typename, typename, typename> class _Base>
- __versa_string<_CharT, _Traits, _Alloc, _Base>&
+ void
__versa_string<_CharT, _Traits, _Alloc, _Base>::
- append(size_type __n, _CharT __c)
+ resize(size_type __n, _CharT __c)
{
- if (__n)
- {
- _M_check_length(size_type(0), __n, "__versa_string::append");
- const size_type __len = __n + this->size();
- if (__len > this->capacity() || this->_M_is_shared())
- this->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,
template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>&
__versa_string<_CharT, _Traits, _Alloc, _Base>::
- 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, "__versa_string::append");
- const size_type __len = __n + this->size();
- if (__len > this->capacity() || this->_M_is_shared())
- {
- if (_M_disjunct(__s))
- this->reserve(__len);
- else
- {
- const size_type __off = __s - this->_M_data();
- this->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,
- template <typename, typename, typename> class _Base>
- __versa_string<_CharT, _Traits, _Alloc, _Base>&
- __versa_string<_CharT, _Traits, _Alloc, _Base>::
- append(const __versa_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->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,
- template <typename, typename, typename> class _Base>
- __versa_string<_CharT, _Traits, _Alloc, _Base>&
- __versa_string<_CharT, _Traits, _Alloc, _Base>::
- append(const __versa_string& __str, size_type __pos, size_type __n)
- {
- __str._M_check(__pos, "__versa_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->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,
- template <typename, typename, typename> class _Base>
- __versa_string<_CharT, _Traits, _Alloc, _Base>&
- __versa_string<_CharT, _Traits, _Alloc, _Base>::
- insert(size_type __pos, const _CharT* __s, size_type __n)
- {
- __glibcxx_requires_string_len(__s, __n);
- _M_check(__pos, "__versa_string::insert");
- _M_check_length(size_type(0), __n, "__versa_string::insert");
- if (_M_disjunct(__s) || this->_M_is_shared())
- return _M_replace_safe(__pos, size_type(0), __s, __n);
- else
- {
- // Work in-place.
- const size_type __off = __s - this->_M_data();
- this->_M_mutate(__pos, 0, __n);
- __s = this->_M_data() + __off;
- _CharT* __p = this->_M_data() + __pos;
- if (__s + __n <= __p)
- this->_S_copy(__p, __s, __n);
- else if (__s >= __p)
- this->_S_copy(__p, __s + __n, __n);
- else
- {
- const size_type __nleft = __p - __s;
- this->_S_copy(__p, __s, __nleft);
- this->_S_copy(__p + __nleft, __p + __n, __n - __nleft);
- }
- return *this;
- }
- }
-
- template<typename _CharT, typename _Traits, typename _Alloc,
- template <typename, typename, typename> class _Base>
- __versa_string<_CharT, _Traits, _Alloc, _Base>&
- __versa_string<_CharT, _Traits, _Alloc, _Base>::
- replace(size_type __pos, size_type __n1, const _CharT* __s,
- size_type __n2)
- {
- __glibcxx_requires_string_len(__s, __n2);
- _M_check(__pos, "__versa_string::replace");
- __n1 = _M_limit(__pos, __n1);
- _M_check_length(__n1, __n2, "__versa_string::replace");
- bool __left;
- if (_M_disjunct(__s) || this->_M_is_shared())
- return _M_replace_safe(__pos, __n1, __s, __n2);
- else if ((__left = __s + __n2 <= this->_M_data() + __pos)
- || this->_M_data() + __pos + __n1 <= __s)
- {
- // Work in-place: non-overlapping case.
- size_type __off = __s - this->_M_data();
- __left ? __off : (__off += __n2 - __n1);
- this->_M_mutate(__pos, __n1, __n2);
- this->_S_copy(this->_M_data() + __pos,
- this->_M_data() + __off, __n2);
- return *this;
- }
- else
- {
- // Todo: overlapping case.
- const __versa_string __tmp(__s, __n2);
- return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
- }
- }
-
- template<typename _CharT, typename _Traits, typename _Alloc,
- template <typename, typename, typename> class _Base>
- void
- __versa_string<_CharT, _Traits, _Alloc, _Base>::
- resize(size_type __n, _CharT __c)
- {
- const size_type __size = this->size();
- _M_check_length(__size, __n, "__versa_string::resize");
- if (__size < __n)
- this->append(__n - __size, __c);
- else if (__n < __size)
- this->erase(__n);
- // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
- }
-
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
template<typename _InputIterator>
@@ -243,10 +88,8 @@ namespace __gnu_cxx
{
const __versa_string __s(__k1, __k2);
const size_type __n1 = __i2 - __i1;
- _M_check_length(__n1, __s.size(),
- "__versa_string::_M_replace_dispatch");
- return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(),
- __s.size());
+ return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(),
+ __s.size());
}
template<typename _CharT, typename _Traits, typename _Alloc,
@@ -257,9 +100,25 @@ namespace __gnu_cxx
_CharT __c)
{
_M_check_length(__n1, __n2, "__versa_string::_M_replace_aux");
- this->_M_mutate(__pos1, __n1, __n2);
+
+ 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;
}
@@ -267,23 +126,77 @@ namespace __gnu_cxx
template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>&
__versa_string<_CharT, _Traits, _Alloc, _Base>::
- _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
- size_type __n2)
+ _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
+ const size_type __len2)
{
- this->_M_mutate(__pos1, __n1, __n2);
- if (__n2)
- this->_S_copy(this->_M_data() + __pos1, __s, __n2);
+ _M_check_length(__len1, __len2, "__versa_string::_M_replace");
+
+ const size_type __old_size = this->size();
+ const size_type __new_size = __old_size + __len2 - __len1;
+
+ if (__new_size <= this->capacity() && !this->_M_is_shared())
+ {
+ _CharT* __p = this->_M_data() + __pos;
+
+ const size_type __how_much = __old_size - __pos - __len1;
+ 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 (__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);
+ }
+ }
+ }
+ }
+ else
+ this->_M_mutate(__pos, __len1, __s, __len2);
+
+ this->_M_set_length(__new_size);
return *this;
}
-
+
+ template<typename _CharT, typename _Traits, typename _Alloc,
+ template <typename, typename, typename> class _Base>
+ __versa_string<_CharT, _Traits, _Alloc, _Base>
+ operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+ const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+ {
+ __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
+ __str.reserve(__lhs.size() + __rhs.size());
+ __str.append(__lhs);
+ __str.append(__rhs);
+ return __str;
+ }
+
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>
operator+(const _CharT* __lhs,
- const __versa_string<_CharT, _Traits, _Alloc>& __rhs)
+ const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
{
__glibcxx_requires_string(__lhs);
- typedef __versa_string<_CharT, _Traits, _Alloc> __string_type;
+ typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
typedef typename __string_type::size_type __size_type;
const __size_type __len = _Traits::length(__lhs);
__string_type __str;
@@ -299,13 +212,40 @@ namespace __gnu_cxx
operator+(_CharT __lhs,
const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
{
- typedef __versa_string<_CharT, _Traits, _Alloc> __string_type;
+ __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
+ __str.reserve(__rhs.size() + 1);
+ __str.push_back(__lhs);
+ __str.append(__rhs);
+ return __str;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc,
+ template <typename, typename, typename> class _Base>
+ __versa_string<_CharT, _Traits, _Alloc, _Base>
+ operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+ const _CharT* __rhs)
+ {
+ __glibcxx_requires_string(__rhs);
+ typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
typedef typename __string_type::size_type __size_type;
+ const __size_type __len = _Traits::length(__rhs);
__string_type __str;
- const __size_type __len = __rhs.size();
- __str.reserve(__len + 1);
- __str.append(__size_type(1), __lhs);
- __str.append(__rhs);
+ __str.reserve(__lhs.size() + __len);
+ __str.append(__lhs);
+ __str.append(__rhs, __len);
+ return __str;
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc,
+ template <typename, typename, typename> class _Base>
+ __versa_string<_CharT, _Traits, _Alloc, _Base>
+ operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+ _CharT __rhs)
+ {
+ __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
+ __str.reserve(__lhs.size() + 1);
+ __str.append(__lhs);
+ __str.push_back(__rhs);
return __str;
}