提交 57509709 编写于 作者: J James Miller

Make staged versions of the functions that use uninit

上级 f5ab112e
......@@ -24,6 +24,7 @@ pub mod rusti {
}
/// Casts the value at `src` to U. The two types must have the same length.
#[cfg(not(stage0))]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
let mut dest: U = unstable::intrinsics::uninit();
{
......@@ -36,6 +37,19 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
dest
}
#[cfg(stage0)]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
let mut dest: U = unstable::intrinsics::init();
{
let dest_ptr: *mut u8 = rusti::transmute(&mut dest);
let src_ptr: *u8 = rusti::transmute(src);
unstable::intrinsics::memmove64(dest_ptr,
src_ptr,
sys::size_of::<U>() as u64);
}
dest
}
/**
* Move a thing into the void
*
......
......@@ -584,6 +584,7 @@ pub fn consume_reverse<T>(mut v: ~[T], f: &fn(uint, v: T)) {
}
/// Remove the last element from a vector and return it
#[cfg(not(stage0))]
pub fn pop<T>(v: &mut ~[T]) -> T {
let ln = v.len();
if ln == 0 {
......@@ -598,6 +599,21 @@ pub fn pop<T>(v: &mut ~[T]) -> T {
}
}
#[cfg(stage0)]
pub fn pop<T>(v: &mut ~[T]) -> T {
let ln = v.len();
if ln == 0 {
fail!(~"sorry, cannot vec::pop an empty vector")
}
let valptr = ptr::to_mut_unsafe_ptr(&mut v[ln - 1u]);
unsafe {
let mut val = intrinsics::init();
val <-> *valptr;
raw::set_len(v, ln - 1u);
val
}
}
/**
* Remove an element from anywhere in the vector and return it, replacing it
* with the last element. This does not preserve ordering, but is O(1).
......@@ -659,6 +675,7 @@ pub fn push_all<T:Copy>(v: &mut ~[T], rhs: &const [T]) {
}
#[inline(always)]
#[cfg(not(stage0))]
pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
let new_len = v.len() + rhs.len();
reserve(&mut *v, new_len);
......@@ -674,7 +691,25 @@ pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
}
}
#[inline(always)]
#[cfg(stage0)]
pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
let new_len = v.len() + rhs.len();
reserve(&mut *v, new_len);
unsafe {
do as_mut_buf(rhs) |p, len| {
for uint::range(0, len) |i| {
let mut x = intrinsics::init();
x <-> *ptr::mut_offset(p, i);
push(&mut *v, x);
}
}
raw::set_len(&mut rhs, 0);
}
}
/// Shorten a vector, dropping excess elements.
#[cfg(not(stage0))]
pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
do as_mut_buf(*v) |p, oldlen| {
assert!(newlen <= oldlen);
......@@ -689,10 +724,27 @@ pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
unsafe { raw::set_len(&mut *v, newlen); }
}
/// Shorten a vector, dropping excess elements.
#[cfg(stage0)]
pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
do as_mut_buf(*v) |p, oldlen| {
assert!(newlen <= oldlen);
unsafe {
// This loop is optimized out for non-drop types.
for uint::range(newlen, oldlen) |i| {
let mut dropped = intrinsics::init();
dropped <-> *ptr::mut_offset(p, i);
}
}
}
unsafe { raw::set_len(&mut *v, newlen); }
}
/**
* Remove consecutive repeated elements from a vector; if the vector is
* sorted, this removes all duplicates.
*/
#[cfg(not(stage0))]
pub fn dedup<T:Eq>(v: &mut ~[T]) {
unsafe {
if v.len() < 1 { return; }
......@@ -726,6 +778,44 @@ pub fn dedup<T:Eq>(v: &mut ~[T]) {
}
}
/**
* Remove consecutive repeated elements from a vector; if the vector is
* sorted, this removes all duplicates.
*/
#[cfg(stage0)]
pub fn dedup<T:Eq>(v: &mut ~[T]) {
unsafe {
if v.len() < 1 { return; }
let mut last_written = 0, next_to_read = 1;
do as_const_buf(*v) |p, ln| {
// We have a mutable reference to v, so we can make arbitrary
// changes. (cf. push and pop)
let p = p as *mut T;
// last_written < next_to_read <= ln
while next_to_read < ln {
// last_written < next_to_read < ln
if *ptr::mut_offset(p, next_to_read) ==
*ptr::mut_offset(p, last_written) {
let mut dropped = intrinsics::init();
dropped <-> *ptr::mut_offset(p, next_to_read);
} else {
last_written += 1;
// last_written <= next_to_read < ln
if next_to_read != last_written {
*ptr::mut_offset(p, last_written) <->
*ptr::mut_offset(p, next_to_read);
}
}
// last_written <= next_to_read < ln
next_to_read += 1;
// last_written < next_to_read <= ln
}
}
// last_written < next_to_read == ln
raw::set_len(v, last_written + 1);
}
}
// Appending
#[inline(always)]
......
......@@ -132,6 +132,7 @@ fn from_vec(xs: ~[T]) -> PriorityQueue<T> {
// vector over the junk element. This reduces the constant factor
// compared to using swaps, which involves twice as many moves.
#[cfg(not(stage0))]
priv fn siftup(&mut self, start: uint, mut pos: uint) {
unsafe {
let new = *ptr::to_unsafe_ptr(&self.data[pos]);
......@@ -151,6 +152,28 @@ fn from_vec(xs: ~[T]) -> PriorityQueue<T> {
}
}
#[cfg(stage0)]
priv fn siftup(&mut self, start: uint, mut pos: uint) {
unsafe {
let new = *ptr::to_unsafe_ptr(&self.data[pos]);
while pos > start {
let parent = (pos - 1) >> 1;
if new > self.data[parent] {
let mut x = rusti::init();
x <-> self.data[parent];
rusti::move_val_init(&mut self.data[pos], x);
pos = parent;
loop
}
break
}
rusti::move_val_init(&mut self.data[pos], new);
}
}
#[cfg(not(stage0))]
priv fn siftdown_range(&mut self, mut pos: uint, end: uint) {
unsafe {
let start = pos;
......@@ -174,6 +197,30 @@ fn from_vec(xs: ~[T]) -> PriorityQueue<T> {
}
}
#[cfg(stage0)]
priv fn siftdown_range(&mut self, mut pos: uint, end: uint) {
unsafe {
let start = pos;
let new = *ptr::to_unsafe_ptr(&self.data[pos]);
let mut child = 2 * pos + 1;
while child < end {
let right = child + 1;
if right < end && !(self.data[child] > self.data[right]) {
child = right;
}
let mut x = rusti::init();
x <-> self.data[child];
rusti::move_val_init(&mut self.data[pos], x);
pos = child;
child = 2 * pos + 1;
}
rusti::move_val_init(&mut self.data[pos], new);
self.siftup(start, pos);
}
}
priv fn siftdown(&mut self, pos: uint) {
let len = self.len();
self.siftdown_range(pos, len);
......
......@@ -46,6 +46,7 @@ fn borrow<'r>(&'r self) -> &'r T {
}
#[unsafe_destructor]
#[cfg(not(stage0))]
impl<T: Owned> Drop for Rc<T> {
fn finalize(&self) {
unsafe {
......@@ -59,6 +60,22 @@ fn finalize(&self) {
}
}
#[unsafe_destructor]
#[cfg(stage0)]
impl<T: Owned> Drop for Rc<T> {
fn finalize(&self) {
unsafe {
(*self.ptr).count -= 1;
if (*self.ptr).count == 0 {
let mut x = intrinsics::init();
x <-> *self.ptr;
free(self.ptr as *c_void)
}
}
}
}
impl<T: Owned> Clone for Rc<T> {
#[inline]
fn clone(&self) -> Rc<T> {
......@@ -154,6 +171,7 @@ fn with_mut_borrow(&self, f: &fn(&mut T)) {
}
#[unsafe_destructor]
#[cfg(not(stage0))]
impl<T: Owned> Drop for RcMut<T> {
fn finalize(&self) {
unsafe {
......@@ -167,6 +185,21 @@ fn finalize(&self) {
}
}
#[unsafe_destructor]
#[cfg(stage0)]
impl<T: Owned> Drop for RcMut<T> {
fn finalize(&self) {
unsafe {
(*self.ptr).count -= 1;
if (*self.ptr).count == 0 {
let mut x = rusti::init();
x <-> *self.ptr;
free(self.ptr as *c_void)
}
}
}
}
impl<T: Owned> Clone for RcMut<T> {
#[inline]
fn clone(&self) -> RcMut<T> {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册