basic_string<>::_M_mutate - patch

Nathan Myers ncm@best.com
Tue Jun 29 01:51:00 GMT 1999


> 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:

    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.

BTW... yes, I think (without consulting the standard!) that 
traits_type::copy is allowed to throw, albeit for no good reason 
I know of.  If so, we need to audit whether throwing from the 
"Work in-place" case violates any guarantees about the contents of 
the string after the event. 

Nathan Myers
ncm@cantrip.org



More information about the Libstdc++ mailing list