This is the mail archive of the
libstdc++@sourceware.cygnus.com
mailing list for the libstdc++ project.
Re: basic_string<>::_M_mutate - patch
- To: libstdc++@sourceware.cygnus.com
- Subject: Re: basic_string<>::_M_mutate - patch
- From: Ryszard Kabatek <rysio@rumcajs.chemie.uni-halle.de>
- Date: Tue, 29 Jun 1999 13:04:10 +0200 (CEST)
- Reply-To: Ryszard Kabatek <kabatek@chemie.uni-halle.de>
On Tue, 29 Jun 1999, Nathan Myers wrote:
>
> > Nathan as I understood you will continue the work on this patch,
> > is it correct?
>
> I'm not really equipped at the moment to test it, but what I'd like to
> see looks very much like this:
>
I agree. I will make some tests and then I will send the updated patch.
> void
> basic_string<_CharT, _Traits, _Alloc>::
> _M_mutate(size_type __pos, size_type __len1, size_type __len2)
> {
> const size_type __old_size = size();
> const size_type __new_size = __old_size + __len2 - __len1;
> const _CharT* __src = _M_data() + __pos + __len1;
> const size_type __how_much = __old_size - __pos - __len1;
>
> if (_M_rep()->_M_state > 0 || __new_size > capacity())
> // must reallocate
> {
> _Rep* __r = _Rep::_S_create(__new_size, get_allocator());
> try
> {
> if (__pos)
> traits_type::copy(__r->_M_refdata(), _M_data(), __pos);
> if (__how_much)
> traits_type::copy(__r->_M_refdata() + __pos + __len2,
> __src, __how_much);
> }
> catch (...)
> {
> __r->_M_dispose(get_allocator());
> throw;
> }
> _M_rep()->_M_dispose(get_allocator());
> _M_data(__r->_M_refdata());
> }
> else if (__how_much)
> {
> // Work in-place
> _M_rep()->_M_state = 0;
> traits_type::move(_M_data() + __pos + __len2, __src, __how_much);
> // XXX might a throw here violate any guarantees?
> }
> _M_rep()->_M_length = __new_size;
> _M_data()[__new_size] = _CharT(); // grrr. (per 21.3.4)
> // (you cannot leave those LWG people alone for a second.)
> }
>
> Also, in reserve(), I don't see the need for a separate
> definition. It seems to me that
>
> if (__res_arg > this->capacity())
> _M_mutate(this->size(), 0, __res_arg - this->size());
>
> is just the right thing.
>
First I made the same error. In this case of reserve the size()
will be set in _M_mutate to capacity() (for example from 0 to 1000).
A solution without a new implementation of reserve could be:
if (__res_arg > this->capacity()) {
size_type __old_size = this->size();
_M_mutate(__old_size, 0, __res_arg - __old_size);
_M_rep()->_M_length = __old_size;
}
I think in reserve we must not terminate the string.
Ryszard Kabatek
Martin-Luther University Halle-Wittenberg, Department of Physical Chemistry
Geusaer Str. 88, 06217 Merseburg, Germany
Tel. +49 3461 46 2487 (2466) Fax. +49 3461 46 2129