This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: basic_string<>::_M_mutate - patch


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]