Skip to content

Minor improvements to Vec #415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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