Date: Fri, 21 Jul 2023 22:07:53 +0200
Il 21/07/23 18:58, Jerry Coffin via Std-Proposals ha scritto:
> The simplest correction is probably to specify that:
>
> ```cpp
> s1.append(s2);
> ```
>
> ...is equivalent to:
>
> ```cpp
> s1.resize(size() + s2.size() + 1);
> return append(s2.data(), s2.size());
> ```
>
Not really, because if `s1` and `s2` are the same string, the resize
above is resizing `s2` and the last line is using the wrong size (IOW,
you need to save the size in advance).
But anyhow, I don't think this is a problem at all: str.append(ptr,
size) is guaranteed to work even if `ptr` points into `str`, and that
works without particular problems:
* if you have extra spare capacity, you append in place (no allocation
needed);
* if you don't, you allocate a new buffer (and that may fail, you
throw), copy both strings in there, set the new buffer and dispose of
the old one. All the operation after the allocation cannot fail so
there's nothing to worry about. (Insert the usual rant on the fact that
in C++ we forgot that realloc(2) and more efficient allocation APIs, in
fact, do exist)
Insertions in the middle and assignments are more tricky as there you
would need to correctly handle overlaps (e.g. see _M_disjunct in
libstdc++, or QtPrivate::q_points_into_range in Qt). Or, some operations
let you even get away with building a temporary string, and then
inserting/assigning from that one!
Interestingly enough, string and e.g. vector don't have matching
requirements there; for instance it is UB to call vector::insert(pos, b,
e) with iterators pointing into the vector, while it's OK to do so for
string::insert. (Shrug)
My 2 c,
> The simplest correction is probably to specify that:
>
> ```cpp
> s1.append(s2);
> ```
>
> ...is equivalent to:
>
> ```cpp
> s1.resize(size() + s2.size() + 1);
> return append(s2.data(), s2.size());
> ```
>
Not really, because if `s1` and `s2` are the same string, the resize
above is resizing `s2` and the last line is using the wrong size (IOW,
you need to save the size in advance).
But anyhow, I don't think this is a problem at all: str.append(ptr,
size) is guaranteed to work even if `ptr` points into `str`, and that
works without particular problems:
* if you have extra spare capacity, you append in place (no allocation
needed);
* if you don't, you allocate a new buffer (and that may fail, you
throw), copy both strings in there, set the new buffer and dispose of
the old one. All the operation after the allocation cannot fail so
there's nothing to worry about. (Insert the usual rant on the fact that
in C++ we forgot that realloc(2) and more efficient allocation APIs, in
fact, do exist)
Insertions in the middle and assignments are more tricky as there you
would need to correctly handle overlaps (e.g. see _M_disjunct in
libstdc++, or QtPrivate::q_points_into_range in Qt). Or, some operations
let you even get away with building a temporary string, and then
inserting/assigning from that one!
Interestingly enough, string and e.g. vector don't have matching
requirements there; for instance it is UB to call vector::insert(pos, b,
e) with iterators pointing into the vector, while it's OK to do so for
string::insert. (Shrug)
My 2 c,
-- Giuseppe D'Angelo
Received on 2023-07-21 20:07:57