Skip to content

Commit

Permalink
Minor improvements to Vec (#415)
Browse files Browse the repository at this point in the history
  • Loading branch information
evaporei committed Dec 10, 2023
1 parent 360a768 commit f6bd083
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 64 deletions.
20 changes: 9 additions & 11 deletions src/vec/vec-drain.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl<T> IntoIterator for Vec<T> {
mem::forget(self);
IntoIter {
iter: iter,
iter,
_buf: buf,
}
}
Expand Down Expand Up @@ -135,18 +135,16 @@ impl<'a, T> Drop for Drain<'a, T> {
impl<T> Vec<T> {
pub fn drain(&mut self) -> Drain<T> {
unsafe {
let iter = RawValIter::new(&self);
let iter = unsafe { RawValIter::new(&self) };
// this is a mem::forget safety thing. If Drain is forgotten, we just
// leak the whole Vec's contents. Also we need to do this *eventually*
// anyway, so why not do it now?
self.len = 0;
// this is a mem::forget safety thing. If Drain is forgotten, we just
// leak the whole Vec's contents. Also we need to do this *eventually*
// anyway, so why not do it now?
self.len = 0;
Drain {
iter: iter,
vec: PhantomData,
}
Drain {
iter,
vec: PhantomData,
}
}
}
Expand Down
43 changes: 22 additions & 21 deletions src/vec/vec-final.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ impl<T> Vec<T> {

pub fn insert(&mut self, index: usize, elem: T) {
assert!(index <= self.len, "index out of bounds");
if self.cap() == self.len {
if self.len == self.cap() {
self.buf.grow();
}

Expand All @@ -138,14 +138,17 @@ impl<T> Vec<T> {
self.len - index,
);
ptr::write(self.ptr().add(index), elem);
self.len += 1;
}

self.len += 1;
}

pub fn remove(&mut self, index: usize) -> T {
assert!(index < self.len, "index out of bounds");

self.len -= 1;

unsafe {
self.len -= 1;
let result = ptr::read(self.ptr().add(index));
ptr::copy(
self.ptr().add(index + 1),
Expand All @@ -157,18 +160,16 @@ impl<T> Vec<T> {
}

pub fn drain(&mut self) -> Drain<T> {
unsafe {
let iter = RawValIter::new(&self);
let iter = unsafe { RawValIter::new(&self) };

// this is a mem::forget safety thing. If Drain is forgotten, we just
// leak the whole Vec's contents. Also we need to do this *eventually*
// anyway, so why not do it now?
self.len = 0;
// this is a mem::forget safety thing. If Drain is forgotten, we just
// leak the whole Vec's contents. Also we need to do this *eventually*
// anyway, so why not do it now?
self.len = 0;

Drain {
iter: iter,
vec: PhantomData,
}
Drain {
iter,
vec: PhantomData,
}
}
}
Expand Down Expand Up @@ -197,15 +198,15 @@ impl<T> IntoIterator for Vec<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
unsafe {
let iter = RawValIter::new(&self);
let buf = ptr::read(&self.buf);
mem::forget(self);
let (iter, buf) = unsafe {
(RawValIter::new(&self), ptr::read(&self.buf))
};

IntoIter {
iter: iter,
_buf: buf,
}
mem::forget(self);

IntoIter {
iter,
_buf: buf,
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/vec/vec-insert-remove.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub fn insert(&mut self, index: usize, elem: T) {
// Note: `<=` because it's valid to insert after everything
// which would be equivalent to push.
assert!(index <= self.len, "index out of bounds");
if self.cap == self.len { self.grow(); }
if self.len == self.cap { self.grow(); }
unsafe {
// ptr::copy(src, dest, len): "copy from src to dest len elems"
Expand All @@ -28,8 +28,9 @@ pub fn insert(&mut self, index: usize, elem: T) {
self.len - index,
);
ptr::write(self.ptr.as_ptr().add(index), elem);
self.len += 1;
}
self.len += 1;
}
```

Expand Down
22 changes: 10 additions & 12 deletions src/vec/vec-into-iter.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,16 @@ impl<T> IntoIterator for Vec<T> {
let cap = vec.cap;
let len = vec.len;
unsafe {
IntoIter {
buf: ptr,
cap: cap,
start: ptr.as_ptr(),
end: if cap == 0 {
// can't offset off this pointer, it's not allocated!
ptr.as_ptr()
} else {
ptr.as_ptr().add(len)
},
}
IntoIter {
buf: ptr,
cap,
start: ptr.as_ptr(),
end: if cap == 0 {
// can't offset off this pointer, it's not allocated!
ptr.as_ptr()
} else {
unsafe { ptr.as_ptr().add(len) }
},
}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/vec/vec-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ we get the same results as using `Unique<T>`:

```rust
use std::ptr::NonNull;
use std::marker::PhantomData;

pub struct Vec<T> {
ptr: NonNull<T>,
Expand Down
32 changes: 15 additions & 17 deletions src/vec/vec-raw.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,23 +131,21 @@ impl<T> IntoIterator for Vec<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
unsafe {
// need to use ptr::read to unsafely move the buf out since it's
// not Copy, and Vec implements Drop (so we can't destructure it).
let buf = ptr::read(&self.buf);
let len = self.len;
mem::forget(self);
IntoIter {
start: buf.ptr.as_ptr(),
end: if buf.cap == 0 {
// can't offset off of a pointer unless it's part of an allocation
buf.ptr.as_ptr()
} else {
buf.ptr.as_ptr().add(len)
},
_buf: buf,
}
// need to use ptr::read to unsafely move the buf out since it's
// not Copy, and Vec implements Drop (so we can't destructure it).
let buf = unsafe { ptr::read(&self.buf) };
let len = self.len;
mem::forget(self);
IntoIter {
start: buf.ptr.as_ptr(),
end: if buf.cap == 0 {
// can't offset off of a pointer unless it's part of an allocation
buf.ptr.as_ptr()
} else {
unsafe { buf.ptr.as_ptr().add(len) }
},
_buf: buf,
}
}
}
Expand Down

0 comments on commit f6bd083

Please sign in to comment.