diff options
author | Paolo Carlini <pcarlini@suse.de> | 2005-12-05 00:32:31 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2005-12-05 00:32:31 +0000 |
commit | cf8829194fb63dc0c25253934e1cff4bf4c7f6ca (patch) | |
tree | 92c651354a9a4c8882011f990f958ea570368aaf /libstdc++-v3 | |
parent | 7343398692a7c9fbdeea485e51d34ef0a5be9c5b (diff) | |
download | gcc-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/ChangeLog | 85 | ||||
-rw-r--r-- | libstdc++-v3/include/ext/rc_string_base.h | 71 | ||||
-rw-r--r-- | libstdc++-v3/include/ext/sso_string_base.h | 81 | ||||
-rw-r--r-- | libstdc++-v3/include/ext/vstring.h | 122 | ||||
-rw-r--r-- | libstdc++-v3/include/ext/vstring.tcc | 316 |
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; } |