Make staged versions of the functions that use uninit
This commit is contained in:
parent
f5ab112e6b
commit
57509709b4
@ -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 @@ pub impl <T:Ord> 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 @@ pub impl <T:Ord> 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 @@ pub impl <T:Ord> 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 @@ pub impl<T: Owned> Rc<T> {
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
#[cfg(not(stage0))]
|
||||
impl<T: Owned> Drop for Rc<T> {
|
||||
fn finalize(&self) {
|
||||
unsafe {
|
||||
@ -59,6 +60,22 @@ impl<T: Owned> Drop for Rc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[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 @@ pub impl<T: Owned> RcMut<T> {
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
#[cfg(not(stage0))]
|
||||
impl<T: Owned> Drop for RcMut<T> {
|
||||
fn finalize(&self) {
|
||||
unsafe {
|
||||
@ -167,6 +185,21 @@ impl<T: Owned> Drop for RcMut<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[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> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user