Skip to content

Commit 22d0dea

Browse files
committed
replace_slice: incorporate some feedback
1 parent 51517e5 commit 22d0dea

File tree

1 file changed

+31
-22
lines changed

1 file changed

+31
-22
lines changed

text/0000-replace-slice.md

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -82,30 +82,32 @@ impl<T> ReplaceVecSlice<T> for Vec<T> {
8282
let free_space_start = range_end;
8383
let free_space_end = free_space_start + iter_len;
8484

85-
// FIXME: merge the reallocating case with the first ptr::copy below?
86-
self.reserve(iter_len);
87-
88-
let p = self.as_mut_ptr();
89-
unsafe {
90-
// In case iter.next() panics, leak some elements rather than risk double-freeing them.
91-
self.set_len(free_space_start);
92-
// Shift everything over to make space (duplicating some elements).
93-
ptr::copy(p.offset(free_space_start as isize),
94-
p.offset(free_space_end as isize),
95-
elements_after);
96-
for i in free_space_start..free_space_end {
97-
if let Some(new_element) = iter.next() {
98-
*self.get_unchecked_mut(i) = new_element
99-
} else {
100-
// Iterator shorter than its ExactSizeIterator::len()
101-
ptr::copy(p.offset(free_space_end as isize),
102-
p.offset(i as isize),
103-
elements_after);
104-
self.set_len(i + elements_after);
105-
return
85+
if iter_len > 0 {
86+
// FIXME: merge the reallocating case with the first ptr::copy below?
87+
self.reserve(iter_len);
88+
89+
let p = self.as_mut_ptr();
90+
unsafe {
91+
// In case iter.next() panics, leak some elements rather than risk double-freeing them.
92+
self.set_len(free_space_start);
93+
// Shift everything over to make space (duplicating some elements).
94+
ptr::copy(p.offset(free_space_start as isize),
95+
p.offset(free_space_end as isize),
96+
elements_after);
97+
for i in free_space_start..free_space_end {
98+
if let Some(new_element) = iter.next() {
99+
*self.get_unchecked_mut(i) = new_element
100+
} else {
101+
// Iterator shorter than its ExactSizeIterator::len()
102+
ptr::copy(p.offset(free_space_end as isize),
103+
p.offset(i as isize),
104+
elements_after);
105+
self.set_len(i + elements_after);
106+
return
107+
}
106108
}
109+
self.set_len(free_space_end + elements_after);
107110
}
108-
self.set_len(free_space_end + elements_after);
109111
}
110112
// Iterator longer than its ExactSizeIterator::len(), degenerate to quadratic time
111113
for (new_element, i) in iter.zip(free_space_end..) {
@@ -207,3 +209,10 @@ not every program needs it, and standard library growth has a maintainance cost.
207209
* Naming.
208210
I accidentally typed `replace_range` instead of `replace_slice` several times
209211
while typing up this RFC.
212+
Update: I’m told `splice` is how this operation is called.
213+
214+
* The method could return an iterator of the replaced elements.
215+
Nothing would happen when the method is called,
216+
only when the returned iterator is advanced or dropped.
217+
There’s is precedent of this in `Vec::drain`,
218+
though the input iterator being lazily consumed could be surprising.

0 commit comments

Comments
 (0)