Make staged versions of the functions that use uninit
This commit is contained in:
parent
f5ab112e6b
commit
57509709b4
4 changed files with 184 additions and 0 deletions
|
@ -24,6 +24,7 @@ pub mod rusti {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Casts the value at `src` to U. The two types must have the same length.
|
/// 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 {
|
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
|
||||||
let mut dest: U = unstable::intrinsics::uninit();
|
let mut dest: U = unstable::intrinsics::uninit();
|
||||||
{
|
{
|
||||||
|
@ -36,6 +37,19 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
|
||||||
dest
|
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
|
* 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
|
/// Remove the last element from a vector and return it
|
||||||
|
#[cfg(not(stage0))]
|
||||||
pub fn pop<T>(v: &mut ~[T]) -> T {
|
pub fn pop<T>(v: &mut ~[T]) -> T {
|
||||||
let ln = v.len();
|
let ln = v.len();
|
||||||
if ln == 0 {
|
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
|
* 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).
|
* 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)]
|
#[inline(always)]
|
||||||
|
#[cfg(not(stage0))]
|
||||||
pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
|
pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
|
||||||
let new_len = v.len() + rhs.len();
|
let new_len = v.len() + rhs.len();
|
||||||
reserve(&mut *v, new_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.
|
/// Shorten a vector, dropping excess elements.
|
||||||
|
#[cfg(not(stage0))]
|
||||||
pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
|
pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
|
||||||
do as_mut_buf(*v) |p, oldlen| {
|
do as_mut_buf(*v) |p, oldlen| {
|
||||||
assert!(newlen <= oldlen);
|
assert!(newlen <= oldlen);
|
||||||
|
@ -689,10 +724,27 @@ pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
|
||||||
unsafe { raw::set_len(&mut *v, newlen); }
|
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
|
* Remove consecutive repeated elements from a vector; if the vector is
|
||||||
* sorted, this removes all duplicates.
|
* sorted, this removes all duplicates.
|
||||||
*/
|
*/
|
||||||
|
#[cfg(not(stage0))]
|
||||||
pub fn dedup<T:Eq>(v: &mut ~[T]) {
|
pub fn dedup<T:Eq>(v: &mut ~[T]) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if v.len() < 1 { return; }
|
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
|
// Appending
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
|
@ -132,6 +132,7 @@ pub impl <T:Ord> PriorityQueue<T> {
|
||||||
// vector over the junk element. This reduces the constant factor
|
// vector over the junk element. This reduces the constant factor
|
||||||
// compared to using swaps, which involves twice as many moves.
|
// compared to using swaps, which involves twice as many moves.
|
||||||
|
|
||||||
|
#[cfg(not(stage0))]
|
||||||
priv fn siftup(&mut self, start: uint, mut pos: uint) {
|
priv fn siftup(&mut self, start: uint, mut pos: uint) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let new = *ptr::to_unsafe_ptr(&self.data[pos]);
|
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) {
|
priv fn siftdown_range(&mut self, mut pos: uint, end: uint) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let start = pos;
|
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) {
|
priv fn siftdown(&mut self, pos: uint) {
|
||||||
let len = self.len();
|
let len = self.len();
|
||||||
self.siftdown_range(pos, len);
|
self.siftdown_range(pos, len);
|
||||||
|
|
|
@ -46,6 +46,7 @@ pub impl<T: Owned> Rc<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe_destructor]
|
#[unsafe_destructor]
|
||||||
|
#[cfg(not(stage0))]
|
||||||
impl<T: Owned> Drop for Rc<T> {
|
impl<T: Owned> Drop for Rc<T> {
|
||||||
fn finalize(&self) {
|
fn finalize(&self) {
|
||||||
unsafe {
|
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> {
|
impl<T: Owned> Clone for Rc<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Rc<T> {
|
fn clone(&self) -> Rc<T> {
|
||||||
|
@ -154,6 +171,7 @@ pub impl<T: Owned> RcMut<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe_destructor]
|
#[unsafe_destructor]
|
||||||
|
#[cfg(not(stage0))]
|
||||||
impl<T: Owned> Drop for RcMut<T> {
|
impl<T: Owned> Drop for RcMut<T> {
|
||||||
fn finalize(&self) {
|
fn finalize(&self) {
|
||||||
unsafe {
|
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> {
|
impl<T: Owned> Clone for RcMut<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> RcMut<T> {
|
fn clone(&self) -> RcMut<T> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue