https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110945

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2023-08-08
             Status|UNCONFIRMED                 |NEW

--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #4)
> because string::assign has to handle possible aliasing. It's valid to do
> things like str.assign(str.data()+1, str.data()+2).

Even more problematic is something like:

str.assign(make_move_iterator(str.begin()), make_move_iterator(str.begin()+n));

or something similar with a counted_iterator wrapped in a common_iterator.

We can't rely on the iterators not being (convertible to) const char* to decide
that they don't alias the existing content, because arbitrary iterator types
could still alias the characters in the string.

It might be better to not use replace(begin(), end(), first, last) for
assign(first, last) though, because when we're replacing the entire string we
don't need the code that decides if we need to shuffle the existing content
around.

And _M_replace_dispatch creates a new copy anyway:

      _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
                          _InputIterator __k1, _InputIterator __k2,
                          std::__false_type)
      {
        // _GLIBCXX_RESOLVE_LIB_DEFECTS
        // 2788. unintentionally require a default constructible allocator
        const basic_string __s(__k1, __k2, this->get_allocator());
        const size_type __n1 = __i2 - __i1;
        return _M_replace(__i1 - begin(), __n1, __s._M_data(),
                          __s.size());
      }

So maybe assign(InputIterator, InputIterator) could just do:

        basic_string&
        assign(_InputIterator __first, _InputIterator __last)
        { return assign(basic_string(__first, __last)); }

We know _M_replace_dispatch will make a copy anyway.

Reply via email to