Skip to content

Convert std::vec::raw::{init_elem, copy_memory} to methods, and remove aliasing &[] and &mut[] #10996

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 6 commits into from
Dec 17, 2013
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
4 changes: 1 addition & 3 deletions src/libextra/uuid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,7 @@ impl Uuid {
}

let mut uuid = Uuid{ bytes: [0, .. 16] };
unsafe {
vec::raw::copy_memory(uuid.bytes, b);
}
vec::bytes::copy_memory(uuid.bytes, b);
Some(uuid)
}

Expand Down
150 changes: 64 additions & 86 deletions src/libstd/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1621,54 +1621,38 @@ impl<T> OwnedVector<T> for ~[T] {
}

fn shift_opt(&mut self) -> Option<T> {
unsafe {
let ln = match self.len() {
0 => return None,
1 => return self.pop_opt(),
2 => {
let last = self.pop();
let first = self.pop_opt();
self.push(last);
return first;
}
x => x
};

let next_ln = self.len() - 1;

// Save the last element. We're going to overwrite its position
let work_elt = self.pop();
// We still should have room to work where what last element was
assert!(self.capacity() >= ln);
// Pretend like we have the original length so we can use
// the vector copy_memory to overwrite the hole we just made
self.set_len(ln);

// Memcopy the head element (the one we want) to the location we just
// popped. For the moment it unsafely exists at both the head and last
// positions
{
let first_slice = self.slice(0, 1);
let last_slice = self.slice(next_ln, ln);
raw::copy_memory(cast::transmute(last_slice), first_slice);
match self.len() {
0 => None,
1 => self.pop_opt(),
2 => {
let last = self.pop();
let first = self.pop_opt();
self.push(last);
first
}
len => {
unsafe {
let next_len = len - 1;

// Memcopy everything to the left one element
{
let init_slice = self.slice(0, next_ln);
let tail_slice = self.slice(1, ln);
raw::copy_memory(cast::transmute(init_slice),
tail_slice);
}
let ptr = self.as_ptr();

// copy out the head element, for the moment it exists
// unsafely on the stack and as the first element of the
// vector.
let head = ptr::read_ptr(ptr);

// Set the new length. Now the vector is back to normal
self.set_len(next_ln);
// Memcpy everything to the left one element (leaving the
// last element unsafely in two consecutive memory
// locations)
ptr::copy_memory(self.as_mut_ptr(), ptr.offset(1), next_len);

// Swap out the element we want from the end
let vp = self.as_mut_ptr();
let vp = ptr::mut_offset(vp, (next_ln - 1) as int);
// set the new length, which means the second instance of
// the last element is forgotten.
self.set_len(next_len);

Some(ptr::replace_ptr(vp, work_elt))
Some(head)
}
}
}
}

Expand Down Expand Up @@ -2069,6 +2053,19 @@ pub trait MutableVector<'a, T> {
/// Unsafely sets the element in index to the value
unsafe fn unsafe_set(self, index: uint, val: T);

/**
* Unchecked vector index assignment. Does not drop the
* old value and hence is only suitable when the vector
* is newly allocated.
*/
unsafe fn init_elem(self, i: uint, val: T);

/// Copies data from `src` to `self`.
///
/// `self` and `src` must not overlap. Fails if `self` is
/// shorter than `src`.
unsafe fn copy_memory(self, src: &[T]);

/// Similar to `as_imm_buf` but passing a `*mut T`
fn as_mut_buf<U>(self, f: |*mut T, uint| -> U) -> U;
}
Expand Down Expand Up @@ -2197,6 +2194,21 @@ impl<'a,T> MutableVector<'a, T> for &'a mut [T] {
*self.unsafe_mut_ref(index) = val;
}

#[inline]
unsafe fn init_elem(self, i: uint, val: T) {
intrinsics::move_val_init(&mut (*self.as_mut_ptr().offset(i as int)), val);
}

#[inline]
unsafe fn copy_memory(self, src: &[T]) {
self.as_mut_buf(|p_dst, len_dst| {
src.as_imm_buf(|p_src, len_src| {
assert!(len_dst >= len_src)
ptr::copy_nonoverlapping_memory(p_dst, p_src, len_src)
})
})
}

#[inline]
fn as_mut_buf<U>(self, f: |*mut T, uint| -> U) -> U {
let Slice{ data, len } = self.repr();
Expand Down Expand Up @@ -2237,10 +2249,8 @@ pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
/// Unsafe operations
pub mod raw {
use cast;
use option::Some;
use ptr;
use unstable::intrinsics;
use vec::{with_capacity, ImmutableVector, MutableVector};
use vec::{with_capacity, MutableVector};
use unstable::raw::Slice;

/**
Expand Down Expand Up @@ -2273,20 +2283,6 @@ pub mod raw {
}))
}

/**
* Unchecked vector index assignment. Does not drop the
* old value and hence is only suitable when the vector
* is newly allocated.
*/
#[inline]
pub unsafe fn init_elem<T>(v: &mut [T], i: uint, val: T) {
let mut alloc = Some(val);
v.as_mut_buf(|p, _len| {
intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i as int)),
alloc.take_unwrap());
})
}

/**
* Constructs a vector from an unsafe pointer to a buffer
*
Expand All @@ -2304,21 +2300,6 @@ pub mod raw {
dst
}

/**
* Copies data from one vector to another.
*
* Copies `src` to `dst`. The source and destination may overlap.
*/
#[inline]
pub unsafe fn copy_memory<T>(dst: &mut [T], src: &[T]) {
dst.as_mut_buf(|p_dst, len_dst| {
src.as_imm_buf(|p_src, len_src| {
assert!(len_dst >= len_src)
ptr::copy_memory(p_dst, p_src, len_src)
})
})
}

/**
* Returns a pointer to first element in slice and adjusts
* slice so it no longer contains that element. Fails if
Expand Down Expand Up @@ -2347,7 +2328,7 @@ pub mod raw {

/// Operations on `[u8]`.
pub mod bytes {
use vec::raw;
use vec::MutableVector;
use ptr;

/// A trait for operations on mutable `[u8]`s.
Expand All @@ -2365,17 +2346,14 @@ pub mod bytes {
}
}

/**
* Copies data from one vector to another.
*
* Copies `src` to `dst`. The source and destination may
* overlap. Fails if the length of `dst` is less than the length
* of `src`.
*/
/// Copies data from `src` to `dst`
///
/// `src` and `dst` must not overlap. Fails if the length of `dst`
/// is less than the length of `src`.
#[inline]
pub fn copy_memory(dst: &mut [u8], src: &[u8]) {
// Bound checks are done at vec::raw::copy_memory.
unsafe { raw::copy_memory(dst, src) }
// Bound checks are done at .copy_memory.
unsafe { dst.copy_memory(src) }
}

/**
Expand Down Expand Up @@ -3601,7 +3579,7 @@ mod tests {
unsafe {
let mut a = [1, 2, 3, 4];
let b = [1, 2, 3, 4, 5];
raw::copy_memory(a, b);
a.copy_memory(b);
}
}

Expand Down