From 27182b4e2e79e6e26c5c38b992fd66dda5a3eae4 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 30 Nov 2005 13:20:40 +0000 Subject: 2005-11-30 Paolo Carlini * include/ext/sso_string.h (__sso_string<>::_M_get_allocator): Add non const version. * include/ext/rc_string.h (__rc_string<>::_M_get_allocator): Likewise. * include/bits/basic_string.h (basic_string(__gnu_cxx::__rvalref<>): Use it. * include/bits/stl_vector.h (vector<>::_M_get_Tp_allocator): Change to return by ref and add non const version. (vector(const vector&), vector(__gnu_cxx::__rvalref<>)): Use it. * include/bits/stl_deque.h (deque<>::_M_get_Tp_allocator): Likewise. (deque(const deque&), deque(__gnu_cxx::__rvalref<>)): Likewise. (_M_destroy_data): Adjust. * include/ext/sso_string.h (__sso_string<>::_M_erase): Add. * include/ext/rc_string.h (__rc_string<>::_M_erase): Likewise. (_M_leak_hard): Use it. * include/bits/basic_string.h (basic_string<>::clear, erase, all versions): Use it. * include/bits/basic_string.tcc (basic_string<>::resize): Likewise. * include/bits/basic_string.h (basic_string<>::_M_replace_safe): Remove. * include/bits/basic_string.h (basic_string<>::_M_replace): New, does the in-place work or delegates to _M_mutate in case of reallocation. * include/bits/basic_string.tcc (basic_string<>::_M_replace_safe): Remove. * include/bits/basic_string.tcc (basic_string<>::_M_replace): Define. (assign, replace, _M_replace_dispatch, _M_replace_aux): Use it. * include/ext/sso_string.h (__sso_string<>::_M_mutate): Change to manage only reallocations. * include/ext/rc_string.h (__rc_string<>::_M_mutate): Likewise. * include/bits/basic_string.h (basic_string<>::insert(size_type, const basic_string&), insert(size_type, const basic_string&, size_type, size_type), insert(size_type, const _CharT*, size_type), insert(size_type, const _CharT*)): Delegate to replace. * include/bits/basic_string.h (basic_string<>::reserve): Move out of line. * include/bits/basic_string.tcc (basic_string<>::reserve): Do the checks and call _M_reserve. * include/bits/basic_string.h (basic_string<>::append): Call _M_reserve instead of reserve. * include/bits/basic_string.tcc (basic_string<>::append, all versions): Likewise. * include/ext/sso_string.h (__sso_string<>::_M_reserve): Adjust. * include/ext/rc_string.h (__rc_string<>::_M_reserve): Likewise. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/libstdcxx_so_7-branch@107718 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog.libstdcxx_so_7-branch | 49 +++++++ libstdc++-v3/include/bits/basic_string.h | 41 +++--- libstdc++-v3/include/bits/basic_string.tcc | 183 +++++++++++++-------------- libstdc++-v3/include/bits/stl_deque.h | 22 ++-- libstdc++-v3/include/bits/stl_vector.h | 13 +- libstdc++-v3/include/ext/rc_string.h | 74 +++++++---- libstdc++-v3/include/ext/sso_string.h | 109 ++++++++-------- 7 files changed, 287 insertions(+), 204 deletions(-) diff --git a/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch b/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch index 30373dfca14..7d0eb621a68 100644 --- a/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch +++ b/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch @@ -1,3 +1,52 @@ +2005-11-30 Paolo Carlini + + * include/ext/sso_string.h (__sso_string<>::_M_get_allocator): Add + non const version. + * include/ext/rc_string.h (__rc_string<>::_M_get_allocator): Likewise. + * include/bits/basic_string.h (basic_string(__gnu_cxx::__rvalref<>): + Use it. + * include/bits/stl_vector.h (vector<>::_M_get_Tp_allocator): Change + to return by ref and add non const version. + (vector(const vector&), vector(__gnu_cxx::__rvalref<>)): Use it. + * include/bits/stl_deque.h (deque<>::_M_get_Tp_allocator): Likewise. + (deque(const deque&), deque(__gnu_cxx::__rvalref<>)): Likewise. + (_M_destroy_data): Adjust. + + * include/ext/sso_string.h (__sso_string<>::_M_erase): Add. + * include/ext/rc_string.h (__rc_string<>::_M_erase): Likewise. + (_M_leak_hard): Use it. + * include/bits/basic_string.h (basic_string<>::clear, erase, all + versions): Use it. + * include/bits/basic_string.tcc (basic_string<>::resize): Likewise. + + * include/bits/basic_string.h (basic_string<>::_M_replace_safe): + Remove. + * include/bits/basic_string.h (basic_string<>::_M_replace): New, does + the in-place work or delegates to _M_mutate in case of reallocation. + * include/bits/basic_string.tcc (basic_string<>::_M_replace_safe): + Remove. + * include/bits/basic_string.tcc (basic_string<>::_M_replace): Define. + (assign, replace, _M_replace_dispatch, _M_replace_aux): Use it. + * include/ext/sso_string.h (__sso_string<>::_M_mutate): Change to + manage only reallocations. + * include/ext/rc_string.h (__rc_string<>::_M_mutate): Likewise. + + * include/bits/basic_string.h (basic_string<>::insert(size_type, + const basic_string&), insert(size_type, const basic_string&, size_type, + size_type), insert(size_type, const _CharT*, size_type), + insert(size_type, const _CharT*)): Delegate to replace. + + * include/bits/basic_string.h (basic_string<>::reserve): Move out of + line. + * include/bits/basic_string.tcc (basic_string<>::reserve): Do the + checks and call _M_reserve. + * include/bits/basic_string.h (basic_string<>::append): Call _M_reserve + instead of reserve. + * include/bits/basic_string.tcc (basic_string<>::append, all versions): + Likewise. + * include/ext/sso_string.h (__sso_string<>::_M_reserve): Adjust. + * include/ext/rc_string.h (__rc_string<>::_M_reserve): Likewise. + 2005-11-26 Paolo Carlini * testsuite/23_containers/vector/modifiers/erase/1.cc: Fix typos, diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index fb4e89e6030..f02a20006ed 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -118,8 +118,7 @@ namespace std const bool __testoff = __off < this->size() - __pos; return __testoff ? __off : this->size() - __pos; } - - // True if _Rep and source do not overlap. + bool _M_disjunct(const _CharT* __s) const { @@ -175,7 +174,7 @@ namespace std */ template basic_string(__gnu_cxx::__rvalref<_String> __str) - : __string_base(__str.__ref.get_allocator()) + : __string_base(__str.__ref._M_get_allocator()) { this->swap(__str.__ref); } /** @@ -447,15 +446,14 @@ namespace std * data. */ void - reserve(size_type __res_arg = 0) - { this->_M_reserve(__res_arg); } - + reserve(size_type __res_arg = 0); + /** * 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 == "". @@ -646,7 +644,7 @@ namespace std { const size_type __len = 1 + this->size(); if (__len > this->capacity() || this->_M_is_shared()) - this->reserve(__len); + this->_M_reserve(__len); traits_type::assign(this->_M_data()[this->size()], __c); this->_M_set_length(__len); } @@ -781,7 +779,8 @@ namespace std */ basic_string& insert(size_type __pos1, const basic_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. @@ -804,9 +803,9 @@ namespace std basic_string& insert(size_type __pos1, const basic_string& __str, 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)); } + { return this->replace(__pos1, size_type(0), __str._M_data() + + __str._M_check(__pos2, "basic_string::insert"), + __str._M_limit(__pos2, __n)); } /** * @brief Insert a C substring. @@ -825,7 +824,8 @@ namespace std * thrown. */ basic_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. @@ -846,7 +846,8 @@ namespace std 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)); } /** @@ -909,8 +910,8 @@ namespace std basic_string& erase(size_type __pos = 0, size_type __n = npos) { - this->_M_mutate(_M_check(__pos, "basic_string::erase"), - _M_limit(__pos, __n), size_type(0)); + this->_M_erase(_M_check(__pos, "basic_string::erase"), + _M_limit(__pos, __n)); return *this; } @@ -928,7 +929,7 @@ namespace std _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; } @@ -948,7 +949,7 @@ namespace std _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; } @@ -1230,8 +1231,8 @@ namespace std _CharT __c); basic_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); public: diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index 589e5361d60..2eed5f89ba5 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -51,6 +51,21 @@ namespace std const typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>::npos; + template + void + basic_string<_CharT, _Traits, _Alloc>:: + reserve(size_type __res_arg) + { + if (__res_arg != this->capacity() || this->_M_is_shared()) + { + // Make sure we don't shrink below the current size. + if (__res_arg < this->size()) + __res_arg = this->size(); + + this->_M_reserve(__res_arg); + } + } + template basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: @@ -58,20 +73,8 @@ namespace std { __glibcxx_requires_string_len(__s, __n); _M_check_length(this->size(), __n, "basic_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; - } - } + return _M_replace(size_type(0), this->size(), __s, __n); + } template basic_string<_CharT, _Traits, _Alloc>& @@ -83,7 +86,7 @@ namespace std _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->reserve(__len); + this->_M_reserve(__len); this->_S_assign(this->_M_data() + this->size(), __n, __c); this->_M_set_length(__len); } @@ -102,12 +105,12 @@ namespace std const size_type __len = __n + this->size(); if (__len > this->capacity() || this->_M_is_shared()) { - if (_M_disjunct(__s)) - this->reserve(__len); + if (this->_M_disjunct(__s)) + this->_M_reserve(__len); else { const size_type __off = __s - this->_M_data(); - this->reserve(__len); + this->_M_reserve(__len); __s = this->_M_data() + __off; } } @@ -127,7 +130,7 @@ namespace std { const size_type __len = __size + this->size(); if (__len > this->capacity() || this->_M_is_shared()) - this->reserve(__len); + this->_M_reserve(__len); this->_S_copy(this->_M_data() + this->size(), __str._M_data(), __size); this->_M_set_length(__len); @@ -146,76 +149,26 @@ namespace std { const size_type __len = __n + this->size(); if (__len > this->capacity() || this->_M_is_shared()) - this->reserve(__len); + 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 - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: - insert(size_type __pos, const _CharT* __s, size_type __n) - { - __glibcxx_requires_string_len(__s, __n); - _M_check(__pos, "basic_string::insert"); - _M_check_length(size_type(0), __n, "basic_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 - 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); - _M_check_length(__n1, __n2, "basic_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 basic_string __tmp(__s, __n2); - return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2); - } - } + template + 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); + _M_check_length(__n1, __n2, "basic_string::replace"); + return _M_replace(__pos, __n1, __s, __n2); + } template void @@ -227,8 +180,7 @@ namespace std if (__size < __n) this->append(__n - __size, __c); else if (__n < __size) - this->erase(__n); - // else nothing (in particular, avoid calling _M_mutate() unnecessarily.) + this->_M_erase(__n, __size - __n); } template @@ -241,8 +193,8 @@ namespace std const basic_string __s(__k1, __k2); const size_type __n1 = __i2 - __i1; _M_check_length(__n1, __s.size(), "basic_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 @@ -252,7 +204,7 @@ namespace std _CharT __c) { _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); - this->_M_mutate(__pos1, __n1, __n2); + _M_replace(__pos1, __n1, 0, __n2); if (__n2) this->_S_assign(this->_M_data() + __pos1, __n2, __c); return *this; @@ -261,15 +213,58 @@ namespace std template basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: - _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); + 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) + { + 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 if (__how_much && __len1 != __len2) + this->_S_move(__p + __len2, __p + __len1, __how_much); + } + else + this->_M_mutate(__pos, __len1, __s, __len2); + + this->_M_set_length(__new_size); return *this; } - + template basic_string<_CharT, _Traits, _Alloc> operator+(const _CharT* __lhs, diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index 398012d94c8..73b40c0600f 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -339,6 +339,7 @@ namespace _GLIBCXX_STD operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) { return __x + __n; } + /** * @if maint * Deque base class. This class provides the unified face for %deque's @@ -396,7 +397,11 @@ namespace _GLIBCXX_STD { } }; - _Tp_alloc_type + _Tp_alloc_type& + _M_get_Tp_allocator() + { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); } + + const _Tp_alloc_type& _M_get_Tp_allocator() const { return *static_cast(&this->_M_impl); } @@ -684,7 +689,7 @@ namespace _GLIBCXX_STD * by @a x. */ deque(const deque& __x) - : _Base(__x.get_allocator(), __x.size()) + : _Base(__x._M_get_Tp_allocator(), __x.size()) { std::__uninitialized_copy_a(__x.begin(), __x.end(), this->_M_impl._M_start, _M_get_Tp_allocator()); } @@ -701,9 +706,8 @@ namespace _GLIBCXX_STD */ template deque(__gnu_cxx::__rvalref<_Deque> __x) - : _Base(__x.__ref.get_allocator(), 0) - { this->swap(__x.__ref); } - + : _Base(__x.__ref._M_get_Tp_allocator(), 0) + { this->swap(__x.__ref); } /** * @brief Builds a %deque from a range. @@ -862,7 +866,8 @@ namespace _GLIBCXX_STD * in reverse element order. */ reverse_iterator - rend() { return reverse_iterator(this->_M_impl._M_start); } + rend() + { return reverse_iterator(this->_M_impl._M_start); } /** * Returns a read-only (constant) reverse iterator that points @@ -1491,11 +1496,12 @@ namespace _GLIBCXX_STD // NB: Doesn't deallocate the nodes. template void - _M_destroy_data(iterator __first, iterator __last, _Alloc1) + _M_destroy_data(iterator __first, iterator __last, const _Alloc1&) { _M_destroy_data_aux(__first, __last); } void - _M_destroy_data(iterator __first, iterator __last, std::allocator<_Tp>) + _M_destroy_data(iterator __first, iterator __last, + const std::allocator<_Tp>&) { typedef typename std::__is_scalar::__type _Has_trivial_destructor; diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 25134e20273..93db8406b06 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -92,7 +92,11 @@ namespace _GLIBCXX_STD public: typedef _Alloc allocator_type; - _Tp_alloc_type + _Tp_alloc_type& + _M_get_Tp_allocator() + { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); } + + const _Tp_alloc_type& _M_get_Tp_allocator() const { return *static_cast(&this->_M_impl); } @@ -227,7 +231,7 @@ namespace _GLIBCXX_STD * @a x (for fast expansion) will not be copied. */ vector(const vector& __x) - : _Base(__x.size(), __x.get_allocator()) + : _Base(__x.size(), __x._M_get_Tp_allocator()) { this->_M_impl._M_finish = std::__uninitialized_copy_a(__x.begin(), __x.end(), this->_M_impl._M_start, @@ -246,7 +250,7 @@ namespace _GLIBCXX_STD */ template vector(__gnu_cxx::__rvalref<_Vector> __x) - : _Base(__x.__ref.get_allocator()) + : _Base(__x.__ref._M_get_Tp_allocator()) { this->swap(__x.__ref); } /** @@ -282,8 +286,7 @@ namespace _GLIBCXX_STD */ ~vector() { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, - _M_get_Tp_allocator()); - } + _M_get_Tp_allocator()); } /** * @brief %Vector assignment operator. diff --git a/libstdc++-v3/include/ext/rc_string.h b/libstdc++-v3/include/ext/rc_string.h index eb3e66f7c17..2b47ea3745c 100644 --- a/libstdc++-v3/include/ext/rc_string.h +++ b/libstdc++-v3/include/ext/rc_string.h @@ -310,6 +310,10 @@ namespace __gnu_cxx ~__rc_string() { _M_dispose(); } + allocator_type& + _M_get_allocator() + { return _M_dataplus; } + const allocator_type& _M_get_allocator() const { return _M_dataplus; } @@ -324,7 +328,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 @@ -456,7 +464,7 @@ namespace __gnu_cxx _M_leak_hard() { if (_M_is_shared()) - _M_mutate(0, 0, 0); + _M_erase(0, 0); _M_set_leaked(); } @@ -592,29 +600,44 @@ namespace __gnu_cxx __rc_string<_CharT, _Traits, _Alloc>:: _M_reserve(size_type __res) { - 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(); - _M_data(__tmp); - } + _CharT* __tmp = _M_rep()->_M_clone(_M_get_allocator(), + __res - _M_length()); + _M_dispose(); + _M_data(__tmp); + } + + template + void + __rc_string<_CharT, _Traits, _Alloc>:: + _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, + size_type __len2) + { + const size_type __how_much = _M_length() - __pos - __len1; + + _Rep* __r = _Rep::_S_create(_M_length() + __len2 - __len1, + _M_capacity(), _M_get_allocator()); + + 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 void __rc_string<_CharT, _Traits, _Alloc>:: - _M_mutate(size_type __pos, size_type __len1, size_type __len2) + _M_erase(size_type __pos, size_type __n) { - 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 __new_size = _M_length() - __n; + const size_type __how_much = _M_length() - __pos - __n; - if (__new_size > _M_capacity() || _M_is_shared()) + if (_M_is_shared()) { // Must reallocate. _Rep* __r = _Rep::_S_create(__new_size, _M_capacity(), @@ -623,20 +646,21 @@ 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 #endif /* _RC_STRING_H */ diff --git a/libstdc++-v3/include/ext/sso_string.h b/libstdc++-v3/include/ext/sso_string.h index 65eb9a31291..8324657f469 100644 --- a/libstdc++-v3/include/ext/sso_string.h +++ b/libstdc++-v3/include/ext/sso_string.h @@ -202,6 +202,10 @@ namespace __gnu_cxx ~__sso_string() { _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 @@ -471,69 +479,66 @@ namespace __gnu_cxx _M_reserve(size_type __res) { 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()); - _M_dispose(); - _M_data(__tmp); - _M_capacity(__res); - } - 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()); - _M_destroy(__tmp_capacity + 1); - _M_data(_M_local_data); - } - - _M_set_length(_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()); + _M_dispose(); + _M_data(__tmp); + _M_capacity(__res); } + 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()); + _M_destroy(__tmp_capacity + 1); + _M_data(_M_local_data); + } + + _M_set_length(_M_length()); } template void __sso_string<_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 + void + __sso_string<_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 #endif /* _SSO_STRING_H */ -- cgit v1.2.3