diff --git a/mk/crates.mk b/mk/crates.mk index a8f14bab1e891..7b6369cb4de04 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -49,12 +49,12 @@ # automatically generated for all stage/host/target combinations. ################################################################################ -TARGET_CRATES := std extra green rustuv native flate arena glob +TARGET_CRATES := prim std extra green rustuv native flate arena glob HOST_CRATES := syntax rustc rustdoc rustpkg CRATES := $(TARGET_CRATES) $(HOST_CRATES) TOOLS := compiletest rustpkg rustdoc rustc -DEPS_std := native:rustrt +DEPS_std := prim native:rustrt DEPS_extra := std DEPS_green := std DEPS_rustuv := std native:uv native:uv_support diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs index ee80fa1c4c46e..c07612a17f42e 100644 --- a/src/libextra/dlist.rs +++ b/src/libextra/dlist.rs @@ -86,7 +86,14 @@ impl Rawlink { /// Convert the `Rawlink` into an Option value fn resolve_immut(&self) -> Option<&T> { - unsafe { self.p.to_option() } + if self.p.is_null() { + None + } else { + unsafe { + let p: &T = &*self.p; + Some(p) + } + } } /// Convert the `Rawlink` into an Option value diff --git a/src/libstd/cast.rs b/src/libprim/cast.rs similarity index 65% rename from src/libstd/cast.rs rename to src/libprim/cast.rs index eec7d28e134bb..0f4c39868970b 100644 --- a/src/libstd/cast.rs +++ b/src/libprim/cast.rs @@ -10,20 +10,7 @@ //! Unsafe casting functions -use ptr::RawPtr; -use mem; -use unstable::intrinsics; -use ptr::copy_nonoverlapping_memory; - -/// Casts the value at `src` to U. The two types must have the same length. -#[inline] -pub unsafe fn transmute_copy(src: &T) -> U { - let mut dest: U = intrinsics::uninit(); - let dest_ptr: *mut u8 = transmute(&mut dest); - let src_ptr: *u8 = transmute(src); - copy_nonoverlapping_memory(dest_ptr, src_ptr, mem::size_of::()); - dest -} +use intrinsics; /** * Move a thing into the void @@ -35,13 +22,6 @@ pub unsafe fn transmute_copy(src: &T) -> U { #[inline] pub unsafe fn forget(thing: T) { intrinsics::forget(thing); } -/** - * Force-increment the reference count on a shared box. If used - * carelessly, this can leak the box. - */ -#[inline] -pub unsafe fn bump_box_refcount(t: @T) { forget(t); } - /** * Transform a value of one type into a value of another type. * Both types must have the same size and alignment. @@ -72,13 +52,13 @@ pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T { /// Coerce an immutable reference to be mutable. #[inline] -pub unsafe fn transmute_mut_unsafe>(ptr: P) -> *mut T { +pub unsafe fn transmute_mut_unsafe(ptr: *T) -> *mut T { transmute(ptr) } /// Coerce an immutable reference to be mutable. #[inline] -pub unsafe fn transmute_immut_unsafe>(ptr: P) -> *T { +pub unsafe fn transmute_immut_unsafe(ptr: *mut T) -> *T { transmute(ptr) } @@ -106,43 +86,32 @@ pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T { transmute_region(ptr) } - -/**************************************************************************** - * Tests - ****************************************************************************/ +/// Casts the value at `src` to U. The two types must have the same length. +#[inline] +pub unsafe fn transmute_copy(src: &T) -> U { + let mut dest: U = intrinsics::uninit(); + let dest_ptr: *mut u8 = transmute(&mut dest); + let src_ptr: *u8 = transmute(src); + intrinsics::copy_nonoverlapping_memory(dest_ptr, src_ptr, intrinsics::size_of::()); + dest +} #[cfg(test)] mod tests { - use cast::{bump_box_refcount, transmute}; - use unstable::raw; + use super::*; #[test] fn test_transmute_copy() { - assert_eq!(1u, unsafe { ::cast::transmute_copy(&1) }); - } - - #[test] - fn test_bump_managed_refcount() { - unsafe { - let managed = @~"box box box"; // refcount 1 - bump_box_refcount(managed); // refcount 2 - let ptr: *int = transmute(managed); // refcount 2 - let _box1: @~str = ::cast::transmute_copy(&ptr); - let _box2: @~str = ::cast::transmute_copy(&ptr); - assert!(*_box1 == ~"box box box"); - assert!(*_box2 == ~"box box box"); - // Will destroy _box1 and _box2. Without the bump, this would - // use-after-free. With too many bumps, it would leak. - } + assert_eq!(1u, unsafe { transmute_copy(&1) }); } #[test] fn test_transmute() { unsafe { - let x = @100u8; - let x: *raw::Box = transmute(x); - assert!((*x).data == 100); - let _x: @int = transmute(x); + let x = ~100u8; + let x: *u8 = transmute(x); + assert!(*x == 100); + let _x: ~u8 = transmute(x); } } diff --git a/src/libstd/unstable/intrinsics.rs b/src/libprim/intrinsics.rs similarity index 99% rename from src/libstd/unstable/intrinsics.rs rename to src/libprim/intrinsics.rs index 067826f04dc83..ad6e459de162f 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libprim/intrinsics.rs @@ -43,7 +43,7 @@ A quick refresher on memory ordering: // This is needed to prevent duplicate lang item definitions. #[cfg(test)] -pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor, TypeId}; +pub use realprim::intrinsics::{TyDesc, Opaque, TyVisitor, TypeId}; pub type GlueFn = extern "Rust" fn(*i8); @@ -502,10 +502,9 @@ extern "rust-intrinsic" { /// `TypeId` represents a globally unique identifier for a type #[lang="type_id"] // This needs to be kept in lockstep with the code in trans/intrinsic.rs and // middle/lang_items.rs -#[deriving(Eq, IterBytes)] #[cfg(not(test))] pub struct TypeId { - priv t: u64, + t: u64, } #[cfg(not(test))] diff --git a/src/libstd/kinds.rs b/src/libprim/kinds.rs similarity index 97% rename from src/libstd/kinds.rs rename to src/libprim/kinds.rs index 51e9e9b386474..5be6e06478d20 100644 --- a/src/libstd/kinds.rs +++ b/src/libprim/kinds.rs @@ -89,7 +89,6 @@ pub mod marker { /// (for example, `S<&'static int>` is a subtype of `S<&'a int>` /// for some lifetime `'a`, but not the other way around). #[lang="covariant_type"] - #[deriving(Eq,Clone)] pub struct CovariantType; /// A marker type whose type parameter `T` is considered to be @@ -130,7 +129,6 @@ pub mod marker { /// function requires arguments of type `T`, it must also accept /// arguments of type `U`, hence such a conversion is safe. #[lang="contravariant_type"] - #[deriving(Eq,Clone)] pub struct ContravariantType; /// A marker type whose type parameter `T` is considered to be @@ -154,7 +152,6 @@ pub mod marker { /// never written, but in fact `Cell` uses unsafe code to achieve /// interior mutability. #[lang="invariant_type"] - #[deriving(Eq,Clone)] pub struct InvariantType; /// As `CovariantType`, but for lifetime parameters. Using @@ -174,7 +171,6 @@ pub mod marker { /// For more information about variance, refer to this Wikipedia /// article . #[lang="covariant_lifetime"] - #[deriving(Eq,Clone)] pub struct CovariantLifetime<'a>; /// As `ContravariantType`, but for lifetime parameters. Using @@ -190,7 +186,6 @@ pub mod marker { /// For more information about variance, refer to this Wikipedia /// article . #[lang="contravariant_lifetime"] - #[deriving(Eq,Clone)] pub struct ContravariantLifetime<'a>; /// As `InvariantType`, but for lifetime parameters. Using @@ -201,7 +196,6 @@ pub mod marker { /// and this pointer is itself stored in an inherently mutable /// location (such as a `Cell`). #[lang="invariant_lifetime"] - #[deriving(Eq,Clone)] pub struct InvariantLifetime<'a>; /// A type which is considered "not freezable", meaning that @@ -209,7 +203,6 @@ pub mod marker { /// context or it is the referent of an `&T` pointer. This is /// typically embedded in other types, such as `Cell`. #[lang="no_freeze_bound"] - #[deriving(Eq,Clone)] pub struct NoFreeze; /// A type which is considered "not sendable", meaning that it cannot @@ -217,19 +210,16 @@ pub mod marker { /// typically embedded in other types, such as `Gc`, to ensure that /// their instances remain thread-local. #[lang="no_send_bound"] - #[deriving(Eq,Clone)] pub struct NoSend; /// A type which is considered "not POD", meaning that it is not /// implicitly copyable. This is typically embedded in other types to /// ensure that they are never copied, even if they lack a destructor. #[lang="no_pod_bound"] - #[deriving(Eq,Clone)] pub struct NoPod; /// A type which is considered managed by the GC. This is typically /// embedded in other types. #[lang="managed_bound"] - #[deriving(Eq,Clone)] pub struct Managed; } diff --git a/src/libprim/lib.rs b/src/libprim/lib.rs new file mode 100644 index 0000000000000..8bd4e668f566e --- /dev/null +++ b/src/libprim/lib.rs @@ -0,0 +1,42 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[crate_id = "prim#0.10-pre"]; +#[license = "MIT/ASL2"]; +#[crate_type = "rlib"]; +#[crate_type = "dylib"]; +#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png", + html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_root_url = "http://static.rust-lang.org/doc/master")]; + +#[no_std]; +#[feature(globs)]; +#[feature(phase)]; +#[feature(macro_rules)]; +#[feature(managed_boxes)]; + +#[cfg(test)] #[phase(syntax)] extern mod std; + +#[cfg(test)] extern mod realprim = "prim"; +#[cfg(test)] extern mod std; +#[cfg(test)] extern mod rustuv; +#[cfg(test)] extern mod green; +#[cfg(test)] extern mod native; + +#[cfg(test)] pub use kinds = realprim::kinds; + +pub mod cast; +pub mod intrinsics; +#[cfg(not(test))] pub mod kinds; +pub mod mem; +pub mod ptr; +pub mod raw; +pub mod util; +pub mod tuple; diff --git a/src/libstd/mem.rs b/src/libprim/mem.rs similarity index 99% rename from src/libstd/mem.rs rename to src/libprim/mem.rs index c4a546f71c315..f834636b4e697 100644 --- a/src/libstd/mem.rs +++ b/src/libprim/mem.rs @@ -10,7 +10,7 @@ //! Functions relating to memory layout -use unstable::intrinsics; +use intrinsics; /// Returns the size of a type #[inline] diff --git a/src/libstd/ptr.rs b/src/libprim/ptr.rs similarity index 51% rename from src/libstd/ptr.rs rename to src/libprim/ptr.rs index dcb6d2719d907..105632d62b6c6 100644 --- a/src/libstd/ptr.rs +++ b/src/libprim/ptr.rs @@ -10,16 +10,7 @@ //! Unsafe pointer utility functions -use cast; -use clone::Clone; -#[cfg(not(test))] -use cmp::Equiv; -use iter::{range, Iterator}; -use option::{Option, Some, None}; -use unstable::intrinsics; -use util::swap; - -#[cfg(not(test))] use cmp::{Eq, Ord}; +use intrinsics; /// Calculate the offset from a pointer. /// The `count` argument is in units of T; e.g. a `count` of 3 @@ -43,21 +34,6 @@ pub unsafe fn mut_offset(ptr: *mut T, count: int) -> *mut T { pub unsafe fn buf_len(buf: **T) -> uint { position(buf, |i| *i == null()) } - -impl Clone for *T { - #[inline] - fn clone(&self) -> *T { - *self - } -} - -impl Clone for *mut T { - #[inline] - fn clone(&self) -> *mut T { - *self - } -} - /// Return the first offset `i` such that `f(buf[i]) == true`. #[inline] pub unsafe fn position(buf: *T, f: |&T| -> bool) -> uint { @@ -91,8 +67,8 @@ pub fn is_not_null>(ptr: P) -> bool { ptr.is_not_null() } * and destination may overlap. */ #[inline] -pub unsafe fn copy_memory>(dst: *mut T, src: P, count: uint) { - intrinsics::copy_memory(dst, cast::transmute_immut_unsafe(src), count) +pub unsafe fn copy_memory(dst: *mut T, src: *T, count: uint) { + intrinsics::copy_memory(dst, src, count) } /** @@ -102,10 +78,10 @@ pub unsafe fn copy_memory>(dst: *mut T, src: P, count: uint) { * and destination may *not* overlap. */ #[inline] -pub unsafe fn copy_nonoverlapping_memory>(dst: *mut T, - src: P, - count: uint) { - intrinsics::copy_nonoverlapping_memory(dst, cast::transmute_immut_unsafe(src), count) +pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, + src: *T, + count: uint) { + intrinsics::copy_nonoverlapping_memory(dst, src, count) } /** @@ -136,13 +112,13 @@ pub unsafe fn swap_ptr(x: *mut T, y: *mut T) { let t: *mut T = &mut tmp; // Perform the swap - copy_nonoverlapping_memory(t, x, 1); - copy_memory(x, y, 1); // `x` and `y` may overlap - copy_nonoverlapping_memory(y, t, 1); + copy_nonoverlapping_memory(t, &*x, 1); + copy_memory(x, &*y, 1); // `x` and `y` may overlap + copy_nonoverlapping_memory(y, &*t, 1); // y and t now point to the same thing, but we need to completely forget `tmp` // because it's no longer relevant. - cast::forget(tmp); + intrinsics::forget(tmp); } /** @@ -151,7 +127,7 @@ pub unsafe fn swap_ptr(x: *mut T, y: *mut T) { */ #[inline] pub unsafe fn replace_ptr(dest: *mut T, mut src: T) -> T { - swap(cast::transmute(dest), &mut src); // cannot overlap + swap_ptr(dest, &mut src); src } @@ -192,51 +168,12 @@ pub fn to_mut_unsafe_ptr(thing: &mut T) -> *mut T { thing as *mut T } -/** - Given a **T (pointer to an array of pointers), - iterate through each *T, up to the provided `len`, - passing to the provided callback function - - SAFETY NOTE: Pointer-arithmetic. Dragons be here. -*/ -pub unsafe fn array_each_with_len(arr: **T, len: uint, cb: |*T|) { - debug!("array_each_with_len: before iterate"); - if arr as uint == 0 { - fail!("ptr::array_each_with_len failure: arr input is null pointer"); - } - //let start_ptr = *arr; - for e in range(0, len) { - let n = offset(arr, e as int); - cb(*n); - } - debug!("array_each_with_len: after iterate"); -} - -/** - Given a null-pointer-terminated **T (pointer to - an array of pointers), iterate through each *T, - passing to the provided callback function - - SAFETY NOTE: This will only work with a null-terminated - pointer array. Barely less-dodgy Pointer Arithmetic. - Dragons be here. -*/ -pub unsafe fn array_each(arr: **T, cb: |*T|) { - if arr as uint == 0 { - fail!("ptr::array_each_with_len failure: arr input is null pointer"); - } - let len = buf_len(arr); - debug!("array_each inferred len: {}", len); - array_each_with_len(arr, len, cb); -} - #[allow(missing_doc)] pub trait RawPtr { fn null() -> Self; fn is_null(&self) -> bool; fn is_not_null(&self) -> bool; fn to_uint(&self) -> uint; - unsafe fn to_option(&self) -> Option<&T>; unsafe fn offset(self, count: int) -> Self; } @@ -258,23 +195,6 @@ impl RawPtr for *T { #[inline] fn to_uint(&self) -> uint { *self as uint } - /// - /// Returns `None` if the pointer is null, or else returns the value wrapped - /// in `Some`. - /// - /// # Safety Notes - /// - /// While this method is useful for null-safety, it is important to note - /// that this is still an unsafe operation because the returned value could - /// be pointing to invalid memory. - /// - #[inline] - unsafe fn to_option(&self) -> Option<&T> { - if self.is_null() { None } else { - Some(cast::transmute(*self)) - } - } - /// Calculates the offset from a pointer. The offset *must* be in-bounds of /// the object, or one-byte-past-the-end. #[inline] @@ -299,23 +219,6 @@ impl RawPtr for *mut T { #[inline] fn to_uint(&self) -> uint { *self as uint } - /// - /// Returns `None` if the pointer is null, or else returns the value wrapped - /// in `Some`. - /// - /// # Safety Notes - /// - /// While this method is useful for null-safety, it is important to note - /// that this is still an unsafe operation because the returned value could - /// be pointing to invalid memory. - /// - #[inline] - unsafe fn to_option(&self) -> Option<&T> { - if self.is_null() { None } else { - Some(cast::transmute(*self)) - } - } - /// Calculates the offset from a pointer. The offset *must* be in-bounds of /// the object, or one-byte-past-the-end. An arithmetic overflow is also /// undefined behaviour. @@ -326,134 +229,15 @@ impl RawPtr for *mut T { unsafe fn offset(self, count: int) -> *mut T { mut_offset(self, count) } } -// Equality for pointers -#[cfg(not(test))] -impl Eq for *T { - #[inline] - fn eq(&self, other: &*T) -> bool { - *self == *other - } - #[inline] - fn ne(&self, other: &*T) -> bool { !self.eq(other) } -} - -#[cfg(not(test))] -impl Eq for *mut T { - #[inline] - fn eq(&self, other: &*mut T) -> bool { - *self == *other - } - #[inline] - fn ne(&self, other: &*mut T) -> bool { !self.eq(other) } -} - -// Equivalence for pointers -#[cfg(not(test))] -impl Equiv<*mut T> for *T { - fn equiv(&self, other: &*mut T) -> bool { - self.to_uint() == other.to_uint() - } -} - -#[cfg(not(test))] -impl Equiv<*T> for *mut T { - fn equiv(&self, other: &*T) -> bool { - self.to_uint() == other.to_uint() - } -} - -// Equality for extern "C" fn pointers -#[cfg(not(test))] -mod externfnpointers { - use cast; - use cmp::Eq; - - impl<_R> Eq for extern "C" fn() -> _R { - #[inline] - fn eq(&self, other: &extern "C" fn() -> _R) -> bool { - let self_: *() = unsafe { cast::transmute(*self) }; - let other_: *() = unsafe { cast::transmute(*other) }; - self_ == other_ - } - #[inline] - fn ne(&self, other: &extern "C" fn() -> _R) -> bool { - !self.eq(other) - } - } - macro_rules! fnptreq( - ($($p:ident),*) => { - impl<_R,$($p),*> Eq for extern "C" fn($($p),*) -> _R { - #[inline] - fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool { - let self_: *() = unsafe { cast::transmute(*self) }; - let other_: *() = unsafe { cast::transmute(*other) }; - self_ == other_ - } - #[inline] - fn ne(&self, other: &extern "C" fn($($p),*) -> _R) -> bool { - !self.eq(other) - } - } - } - ) - fnptreq!(A) - fnptreq!(A,B) - fnptreq!(A,B,C) - fnptreq!(A,B,C,D) - fnptreq!(A,B,C,D,E) -} - -// Comparison for pointers -#[cfg(not(test))] -impl Ord for *T { - #[inline] - fn lt(&self, other: &*T) -> bool { - *self < *other - } - #[inline] - fn le(&self, other: &*T) -> bool { - *self <= *other - } - #[inline] - fn ge(&self, other: &*T) -> bool { - *self >= *other - } - #[inline] - fn gt(&self, other: &*T) -> bool { - *self > *other - } -} - -#[cfg(not(test))] -impl Ord for *mut T { - #[inline] - fn lt(&self, other: &*mut T) -> bool { - *self < *other - } - #[inline] - fn le(&self, other: &*mut T) -> bool { - *self <= *other - } - #[inline] - fn ge(&self, other: &*mut T) -> bool { - *self >= *other - } - #[inline] - fn gt(&self, other: &*mut T) -> bool { - *self > *other - } -} - #[cfg(test)] pub mod ptr_tests { use super::*; - use prelude::*; + use std::prelude::*; - use c_str::ToCStr; - use cast; - use libc; - use str; - use vec::{ImmutableVector, MutableVector}; + use std::c_str::ToCStr; + use std::cast; + use std::libc; + use std::vec::{ImmutableVector, MutableVector}; #[test] fn test() { @@ -494,13 +278,11 @@ pub mod ptr_tests { #[test] fn test_position() { - use libc::c_char; - "hello".with_c_str(|p| { unsafe { - assert!(2u == position(p, |c| *c == 'l' as c_char)); - assert!(4u == position(p, |c| *c == 'o' as c_char)); - assert!(5u == position(p, |c| *c == 0 as c_char)); + assert!(2u == position(p, |c| *c == 'l' as libc::c_char)); + assert!(4u == position(p, |c| *c == 'o' as libc::c_char)); + assert!(5u == position(p, |c| *c == 0 as libc::c_char)); } }) } @@ -538,23 +320,6 @@ pub mod ptr_tests { assert!(mq.is_not_null()); } - #[test] - fn test_to_option() { - unsafe { - let p: *int = null(); - assert_eq!(p.to_option(), None); - - let q: *int = &2; - assert_eq!(q.to_option().unwrap(), &2); - - let p: *mut int = mut_null(); - assert_eq!(p.to_option(), None); - - let q: *mut int = &mut 2; - assert_eq!(q.to_option().unwrap(), &2); - } - } - #[test] fn test_ptr_addition() { unsafe { @@ -605,94 +370,6 @@ pub mod ptr_tests { } } - #[test] - fn test_ptr_array_each_with_len() { - unsafe { - let one = "oneOne".to_c_str(); - let two = "twoTwo".to_c_str(); - let three = "threeThree".to_c_str(); - let arr = ~[ - one.with_ref(|buf| buf), - two.with_ref(|buf| buf), - three.with_ref(|buf| buf), - ]; - let expected_arr = [ - one, two, three - ]; - - let mut ctr = 0; - let mut iteration_count = 0; - array_each_with_len(arr.as_ptr(), arr.len(), |e| { - let actual = str::raw::from_c_str(e); - let expected = expected_arr[ctr].with_ref(|buf| { - str::raw::from_c_str(buf) - }); - debug!( - "test_ptr_array_each_with_len e: {}, a: {}", - expected, actual); - assert_eq!(actual, expected); - ctr += 1; - iteration_count += 1; - }); - assert_eq!(iteration_count, 3u); - } - } - - #[test] - fn test_ptr_array_each() { - unsafe { - let one = "oneOne".to_c_str(); - let two = "twoTwo".to_c_str(); - let three = "threeThree".to_c_str(); - let arr = ~[ - one.with_ref(|buf| buf), - two.with_ref(|buf| buf), - three.with_ref(|buf| buf), - // fake a null terminator - null(), - ]; - let expected_arr = [ - one, two, three - ]; - - let arr_ptr = arr.as_ptr(); - let mut ctr = 0; - let mut iteration_count = 0; - array_each(arr_ptr, |e| { - let actual = str::raw::from_c_str(e); - let expected = expected_arr[ctr].with_ref(|buf| { - str::raw::from_c_str(buf) - }); - debug!( - "test_ptr_array_each e: {}, a: {}", - expected, actual); - assert_eq!(actual, expected); - ctr += 1; - iteration_count += 1; - }); - assert_eq!(iteration_count, 3); - } - } - - #[test] - #[should_fail] - fn test_ptr_array_each_with_len_null_ptr() { - unsafe { - array_each_with_len(0 as **libc::c_char, 1, |e| { - str::raw::from_c_str(e); - }); - } - } - #[test] - #[should_fail] - fn test_ptr_array_each_null_ptr() { - unsafe { - array_each(0 as **libc::c_char, |e| { - str::raw::from_c_str(e); - }); - } - } - #[test] fn test_set_memory() { let mut xs = [0u8, ..20]; diff --git a/src/libstd/unstable/raw.rs b/src/libprim/raw.rs similarity index 98% rename from src/libstd/unstable/raw.rs rename to src/libprim/raw.rs index 63208b3f2d707..506129fb70fa1 100644 --- a/src/libstd/unstable/raw.rs +++ b/src/libprim/raw.rs @@ -9,7 +9,7 @@ // except according to those terms. use cast; -use unstable::intrinsics::TyDesc; +use intrinsics::TyDesc; /// The representation of a Rust managed box pub struct Box { diff --git a/src/libprim/tuple.rs b/src/libprim/tuple.rs new file mode 100644 index 0000000000000..5d8f8a1d2b04c --- /dev/null +++ b/src/libprim/tuple.rs @@ -0,0 +1,202 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +macro_rules! tuple_extensions { + ($( + ($move_trait:ident, $immutable_trait:ident) { + $(($get_fn:ident, $get_ref_fn:ident) -> $T:ident { + $move_pattern:pat, $ref_pattern:pat => $ret:expr + })+ + } + )+) => { + $( + pub trait $move_trait<$($T),+> { + $(fn $get_fn(self) -> $T;)+ + } + + impl<$($T),+> $move_trait<$($T),+> for ($($T,)+) { + $( + #[inline] + fn $get_fn(self) -> $T { + let $move_pattern = self; + $ret + } + )+ + } + + pub trait $immutable_trait<$($T),+> { + $(fn $get_ref_fn<'a>(&'a self) -> &'a $T;)+ + } + + impl<$($T),+> $immutable_trait<$($T),+> for ($($T,)+) { + $( + #[inline] + fn $get_ref_fn<'a>(&'a self) -> &'a $T { + let $ref_pattern = *self; + $ret + } + )+ + } + )+ + } + +} + +tuple_extensions! { + (Tuple1, ImmutableTuple1) { + (n0, n0_ref) -> A { (a,), (ref a,) => a } + } + + (Tuple2, ImmutableTuple2) { + (n0, n0_ref) -> A { (a,_), (ref a,_) => a } + (n1, n1_ref) -> B { (_,b), (_,ref b) => b } + } + + (Tuple3, ImmutableTuple3) { + (n0, n0_ref) -> A { (a,_,_), (ref a,_,_) => a } + (n1, n1_ref) -> B { (_,b,_), (_,ref b,_) => b } + (n2, n2_ref) -> C { (_,_,c), (_,_,ref c) => c } + } + + (Tuple4, ImmutableTuple4) { + (n0, n0_ref) -> A { (a,_,_,_), (ref a,_,_,_) => a } + (n1, n1_ref) -> B { (_,b,_,_), (_,ref b,_,_) => b } + (n2, n2_ref) -> C { (_,_,c,_), (_,_,ref c,_) => c } + (n3, n3_ref) -> D { (_,_,_,d), (_,_,_,ref d) => d } + } + + (Tuple5, ImmutableTuple5) { + (n0, n0_ref) -> A { (a,_,_,_,_), (ref a,_,_,_,_) => a } + (n1, n1_ref) -> B { (_,b,_,_,_), (_,ref b,_,_,_) => b } + (n2, n2_ref) -> C { (_,_,c,_,_), (_,_,ref c,_,_) => c } + (n3, n3_ref) -> D { (_,_,_,d,_), (_,_,_,ref d,_) => d } + (n4, n4_ref) -> E { (_,_,_,_,e), (_,_,_,_,ref e) => e } + } + + (Tuple6, ImmutableTuple6) { + (n0, n0_ref) -> A { (a,_,_,_,_,_), (ref a,_,_,_,_,_) => a } + (n1, n1_ref) -> B { (_,b,_,_,_,_), (_,ref b,_,_,_,_) => b } + (n2, n2_ref) -> C { (_,_,c,_,_,_), (_,_,ref c,_,_,_) => c } + (n3, n3_ref) -> D { (_,_,_,d,_,_), (_,_,_,ref d,_,_) => d } + (n4, n4_ref) -> E { (_,_,_,_,e,_), (_,_,_,_,ref e,_) => e } + (n5, n5_ref) -> F { (_,_,_,_,_,f), (_,_,_,_,_,ref f) => f } + } + + (Tuple7, ImmutableTuple7) { + (n0, n0_ref) -> A { (a,_,_,_,_,_,_), (ref a,_,_,_,_,_,_) => a } + (n1, n1_ref) -> B { (_,b,_,_,_,_,_), (_,ref b,_,_,_,_,_) => b } + (n2, n2_ref) -> C { (_,_,c,_,_,_,_), (_,_,ref c,_,_,_,_) => c } + (n3, n3_ref) -> D { (_,_,_,d,_,_,_), (_,_,_,ref d,_,_,_) => d } + (n4, n4_ref) -> E { (_,_,_,_,e,_,_), (_,_,_,_,ref e,_,_) => e } + (n5, n5_ref) -> F { (_,_,_,_,_,f,_), (_,_,_,_,_,ref f,_) => f } + (n6, n6_ref) -> G { (_,_,_,_,_,_,g), (_,_,_,_,_,_,ref g) => g } + } + + (Tuple8, ImmutableTuple8) { + (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_) => a } + (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_) => b } + (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_), (_,_,ref c,_,_,_,_,_) => c } + (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_), (_,_,_,ref d,_,_,_,_) => d } + (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_), (_,_,_,_,ref e,_,_,_) => e } + (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_), (_,_,_,_,_,ref f,_,_) => f } + (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_), (_,_,_,_,_,_,ref g,_) => g } + (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h), (_,_,_,_,_,_,_,ref h) => h } + } + + (Tuple9, ImmutableTuple9) { + (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_,_) => a } + (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_,_) => b } + (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_,_), (_,_,ref c,_,_,_,_,_,_) => c } + (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_,_), (_,_,_,ref d,_,_,_,_,_) => d } + (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_,_), (_,_,_,_,ref e,_,_,_,_) => e } + (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_,_), (_,_,_,_,_,ref f,_,_,_) => f } + (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_,_), (_,_,_,_,_,_,ref g,_,_) => g } + (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h,_), (_,_,_,_,_,_,_,ref h,_) => h } + (n8, n8_ref) -> I { (_,_,_,_,_,_,_,_,i), (_,_,_,_,_,_,_,_,ref i) => i } + } + + (Tuple10, ImmutableTuple10) { + (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_,_,_) => a } + (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_,_,_) => b } + (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_,_,_), (_,_,ref c,_,_,_,_,_,_,_) => c } + (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_,_,_), (_,_,_,ref d,_,_,_,_,_,_) => d } + (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_,_,_), (_,_,_,_,ref e,_,_,_,_,_) => e } + (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_,_,_), (_,_,_,_,_,ref f,_,_,_,_) => f } + (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_,_,_), (_,_,_,_,_,_,ref g,_,_,_) => g } + (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h,_,_), (_,_,_,_,_,_,_,ref h,_,_) => h } + (n8, n8_ref) -> I { (_,_,_,_,_,_,_,_,i,_), (_,_,_,_,_,_,_,_,ref i,_) => i } + (n9, n9_ref) -> J { (_,_,_,_,_,_,_,_,_,j), (_,_,_,_,_,_,_,_,_,ref j) => j } + } + + (Tuple11, ImmutableTuple11) { + (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_,_,_,_) => a } + (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_,_,_,_) => b } + (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_,_,_,_), (_,_,ref c,_,_,_,_,_,_,_,_) => c } + (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_,_,_,_), (_,_,_,ref d,_,_,_,_,_,_,_) => d } + (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_,_,_,_), (_,_,_,_,ref e,_,_,_,_,_,_) => e } + (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_,_,_,_), (_,_,_,_,_,ref f,_,_,_,_,_) => f } + (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_,_,_,_), (_,_,_,_,_,_,ref g,_,_,_,_) => g } + (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h,_,_,_), (_,_,_,_,_,_,_,ref h,_,_,_) => h } + (n8, n8_ref) -> I { (_,_,_,_,_,_,_,_,i,_,_), (_,_,_,_,_,_,_,_,ref i,_,_) => i } + (n9, n9_ref) -> J { (_,_,_,_,_,_,_,_,_,j,_), (_,_,_,_,_,_,_,_,_,ref j,_) => j } + (n10, n10_ref) -> K { (_,_,_,_,_,_,_,_,_,_,k), (_,_,_,_,_,_,_,_,_,_,ref k) => k } + } + + (Tuple12, ImmutableTuple12) { + (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_,_,_,_,_) => a } + (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_,_,_,_,_) => b } + (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_,_,_,_,_), (_,_,ref c,_,_,_,_,_,_,_,_,_) => c } + (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_,_,_,_,_), (_,_,_,ref d,_,_,_,_,_,_,_,_) => d } + (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_,_,_,_,_), (_,_,_,_,ref e,_,_,_,_,_,_,_) => e } + (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_,_,_,_,_), (_,_,_,_,_,ref f,_,_,_,_,_,_) => f } + (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_,_,_,_,_), (_,_,_,_,_,_,ref g,_,_,_,_,_) => g } + (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h,_,_,_,_), (_,_,_,_,_,_,_,ref h,_,_,_,_) => h } + (n8, n8_ref) -> I { (_,_,_,_,_,_,_,_,i,_,_,_), (_,_,_,_,_,_,_,_,ref i,_,_,_) => i } + (n9, n9_ref) -> J { (_,_,_,_,_,_,_,_,_,j,_,_), (_,_,_,_,_,_,_,_,_,ref j,_,_) => j } + (n10, n10_ref) -> K { (_,_,_,_,_,_,_,_,_,_,k,_), (_,_,_,_,_,_,_,_,_,_,ref k,_) => k } + (n11, n11_ref) -> L { (_,_,_,_,_,_,_,_,_,_,_,l), (_,_,_,_,_,_,_,_,_,_,_,ref l) => l } + } +} + + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_n_tuple() { + let t = (0u8, 1u16, 2u32, 3u64, 4u, 5i8, 6i16, 7i32, 8i64, 9i, 10f32, 11f64); + assert_eq!(t.n0(), 0u8); + assert_eq!(t.n1(), 1u16); + assert_eq!(t.n2(), 2u32); + assert_eq!(t.n3(), 3u64); + assert_eq!(t.n4(), 4u); + assert_eq!(t.n5(), 5i8); + assert_eq!(t.n6(), 6i16); + assert_eq!(t.n7(), 7i32); + assert_eq!(t.n8(), 8i64); + assert_eq!(t.n9(), 9i); + assert_eq!(t.n10(), 10f32); + assert_eq!(t.n11(), 11f64); + + assert_eq!(t.n0_ref(), &0u8); + assert_eq!(t.n1_ref(), &1u16); + assert_eq!(t.n2_ref(), &2u32); + assert_eq!(t.n3_ref(), &3u64); + assert_eq!(t.n4_ref(), &4u); + assert_eq!(t.n5_ref(), &5i8); + assert_eq!(t.n6_ref(), &6i16); + assert_eq!(t.n7_ref(), &7i32); + assert_eq!(t.n8_ref(), &8i64); + assert_eq!(t.n9_ref(), &9i); + assert_eq!(t.n10_ref(), &10f32); + assert_eq!(t.n11_ref(), &11f64); + } +} \ No newline at end of file diff --git a/src/libprim/util.rs b/src/libprim/util.rs new file mode 100644 index 0000000000000..cebe4866e8db1 --- /dev/null +++ b/src/libprim/util.rs @@ -0,0 +1,70 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use cast; +use intrinsics; +use ptr; + +/** + * Swap the values at two mutable locations of the same type, without + * deinitialising or copying either one. + */ +#[inline] +pub fn swap(x: &mut T, y: &mut T) { + unsafe { + // Give ourselves some scratch space to work with + let mut tmp: T = intrinsics::uninit(); + let t: *mut T = &mut tmp; + + // Perform the swap, `&mut` pointers never alias + let x_raw: *mut T = x; + let y_raw: *mut T = y; + ptr::copy_nonoverlapping_memory(t, &*x_raw, 1); + ptr::copy_nonoverlapping_memory(x, &*y_raw, 1); + ptr::copy_nonoverlapping_memory(y, &*t, 1); + + // y and t now point to the same thing, but we need to completely forget `tmp` + // because it's no longer relevant. + cast::forget(tmp); + } +} + +/** + * Replace the value at a mutable location with a new one, returning the old + * value, without deinitialising or copying either one. + */ +#[inline] +pub fn replace(dest: &mut T, mut src: T) -> T { + swap(dest, &mut src); + src +} + + +#[cfg(test)] +mod tests { + use super::{swap, replace}; + + #[test] + fn test_swap() { + let mut x = 31337; + let mut y = 42; + swap(&mut x, &mut y); + assert_eq!(x, 42); + assert_eq!(y, 31337); + } + + #[test] + fn test_replace() { + let mut x = 1; + let y = replace(&mut x, 2); + assert!(x == 2); + assert!(y == 1); + } +} \ No newline at end of file diff --git a/src/libstd/clone.rs b/src/libstd/clone.rs index e5e79b4386a56..1ae6bbd0b1cf9 100644 --- a/src/libstd/clone.rs +++ b/src/libstd/clone.rs @@ -22,6 +22,7 @@ the `clone` method. */ use std::kinds::Freeze; +use prim::kinds::marker; /// A common trait for cloning an object. pub trait Clone { @@ -41,6 +42,20 @@ pub trait Clone { } } +impl Clone for *T { + #[inline] + fn clone(&self) -> *T { + *self + } +} + +impl Clone for *mut T { + #[inline] + fn clone(&self) -> *mut T { + *self + } +} + impl Clone for ~T { /// Return a copy of the owned box. #[inline] @@ -211,6 +226,56 @@ extern_fn_deep_clone!(A, B, C, D, E, F) extern_fn_deep_clone!(A, B, C, D, E, F, G) extern_fn_deep_clone!(A, B, C, D, E, F, G, H) +impl Clone for marker::CovariantType { + #[inline] + fn clone(&self) -> marker::CovariantType { *self } +} + +impl Clone for marker::ContravariantType { + #[inline] + fn clone(&self) -> marker::ContravariantType { *self } +} + +impl Clone for marker::InvariantType { + #[inline] + fn clone(&self) -> marker::InvariantType { *self } +} + +impl<'a> Clone for marker::CovariantLifetime<'a> { + #[inline] + fn clone(&self) -> marker::CovariantLifetime<'a> { *self } +} + +impl<'a> Clone for marker::ContravariantLifetime<'a> { + #[inline] + fn clone(&self) -> marker::ContravariantLifetime<'a> { *self } +} + +impl<'a> Clone for marker::InvariantLifetime<'a> { + #[inline] + fn clone(&self) -> marker::InvariantLifetime<'a> { *self } +} + +impl Clone for marker::NoFreeze { + #[inline] + fn clone(&self) -> marker::NoFreeze { *self } +} + +impl Clone for marker::NoSend { + #[inline] + fn clone(&self) -> marker::NoSend { *self } +} + +impl Clone for marker::NoPod { + #[inline] + fn clone(&self) -> marker::NoPod { marker::NoPod } +} + +impl Clone for marker::Managed { + #[inline] + fn clone(&self) -> marker::Managed { *self } +} + #[test] fn test_owned_clone() { let a = ~5i; diff --git a/src/libstd/cmp.rs b/src/libstd/cmp.rs index 1283aba9729b9..a293ebdc8075f 100644 --- a/src/libstd/cmp.rs +++ b/src/libstd/cmp.rs @@ -22,6 +22,11 @@ and `Eq` to overload the `==` and `!=` operators. #[allow(missing_doc)]; +use cast; +use kinds::marker; +use prim::intrinsics::TypeId; +use ptr::RawPtr; + /** * Trait for values that can be compared for equality and inequality. * @@ -41,6 +46,66 @@ pub trait Eq { fn ne(&self, other: &Self) -> bool { !self.eq(other) } } +impl Eq for TypeId { + fn eq(&self, other: &TypeId) -> bool { + self.t == other.t + } +} + +impl Eq for *T { + #[inline] + fn eq(&self, other: &*T) -> bool { + *self == *other + } + #[inline] + fn ne(&self, other: &*T) -> bool { !self.eq(other) } +} + +impl Eq for *mut T { + #[inline] + fn eq(&self, other: &*mut T) -> bool { + *self == *other + } + #[inline] + fn ne(&self, other: &*mut T) -> bool { !self.eq(other) } +} + +impl<_R> Eq for extern "C" fn() -> _R { + #[inline] + fn eq(&self, other: &extern "C" fn() -> _R) -> bool { + let self_: *() = unsafe { cast::transmute(*self) }; + let other_: *() = unsafe { cast::transmute(*other) }; + self_ == other_ + } + #[inline] + fn ne(&self, other: &extern "C" fn() -> _R) -> bool { + !self.eq(other) + } +} + +macro_rules! fnptreq( + ($($p:ident),*) => { + impl<_R,$($p),*> Eq for extern "C" fn($($p),*) -> _R { + #[inline] + fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool { + let self_: *() = unsafe { cast::transmute(*self) }; + let other_: *() = unsafe { cast::transmute(*other) }; + self_ == other_ + } + #[inline] + fn ne(&self, other: &extern "C" fn($($p),*) -> _R) -> bool { + !self.eq(other) + } + } + } +) + +fnptreq!(A) +fnptreq!(A,B) +fnptreq!(A,B,C) +fnptreq!(A,B,C,D) +fnptreq!(A,B,C,D,E) + /// Trait for equality comparisons where `a == b` and `a != b` are strict inverses. pub trait TotalEq { fn equals(&self, other: &Self) -> bool; @@ -171,6 +236,44 @@ pub trait Ord { fn ge(&self, other: &Self) -> bool { !self.lt(other) } } +impl Ord for *T { + #[inline] + fn lt(&self, other: &*T) -> bool { + *self < *other + } + #[inline] + fn le(&self, other: &*T) -> bool { + *self <= *other + } + #[inline] + fn ge(&self, other: &*T) -> bool { + *self >= *other + } + #[inline] + fn gt(&self, other: &*T) -> bool { + *self > *other + } +} + +impl Ord for *mut T { + #[inline] + fn lt(&self, other: &*mut T) -> bool { + *self < *other + } + #[inline] + fn le(&self, other: &*mut T) -> bool { + *self <= *other + } + #[inline] + fn ge(&self, other: &*mut T) -> bool { + *self >= *other + } + #[inline] + fn gt(&self, other: &*mut T) -> bool { + *self > *other + } +} + /// The equivalence relation. Two values may be equivalent even if they are /// of different types. The most common use case for this relation is /// container types; e.g. it is often desirable to be able to use `&str` @@ -179,6 +282,18 @@ pub trait Equiv { fn equiv(&self, other: &T) -> bool; } +impl Equiv<*mut T> for *T { + fn equiv(&self, other: &*mut T) -> bool { + self.to_uint() == other.to_uint() + } +} + +impl Equiv<*T> for *mut T { + fn equiv(&self, other: &*T) -> bool { + self.to_uint() == other.to_uint() + } +} + #[inline] pub fn min(v1: T, v2: T) -> T { if v1 < v2 { v1 } else { v2 } @@ -189,6 +304,56 @@ pub fn max(v1: T, v2: T) -> T { if v1 > v2 { v1 } else { v2 } } +impl Eq for marker::CovariantType { + #[inline] + fn eq(&self, _other: &marker::CovariantType) -> bool { true } +} + +impl Eq for marker::ContravariantType { + #[inline] + fn eq(&self, _other: &marker::ContravariantType) -> bool { true } +} + +impl Eq for marker::InvariantType { + #[inline] + fn eq(&self, _other: &marker::InvariantType) -> bool { true } +} + +impl<'a> Eq for marker::CovariantLifetime<'a> { + #[inline] + fn eq(&self, _other: &marker::CovariantLifetime<'a>) -> bool { true } +} + +impl<'a> Eq for marker::ContravariantLifetime<'a> { + #[inline] + fn eq(&self, _other: &marker::ContravariantLifetime<'a>) -> bool { true } +} + +impl<'a> Eq for marker::InvariantLifetime<'a> { + #[inline] + fn eq(&self, _other: &marker::InvariantLifetime<'a>) -> bool { true } +} + +impl Eq for marker::NoFreeze { + #[inline] + fn eq(&self, _other: &marker::NoFreeze) -> bool { true } +} + +impl Eq for marker::NoSend { + #[inline] + fn eq(&self, _other: &marker::NoSend) -> bool { true } +} + +impl Eq for marker::NoPod { + #[inline] + fn eq(&self, _other: &marker::NoPod) -> bool { true } +} + +impl Eq for marker::Managed { + #[inline] + fn eq(&self, _other: &marker::Managed) -> bool { true } +} + #[cfg(test)] mod test { use super::lexical_ordering; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index adce11fed2dad..215534d0470bc 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -61,6 +61,8 @@ #[deny(missing_doc)]; #[allow(unknown_features)]; +extern mod prim; + // When testing libstd, bring in libuv as the I/O backend so tests can print // things and all of the std::io tests have an I/O interface to run on top // of @@ -73,10 +75,14 @@ // Make std testable by not duplicating lang items. See #2912 #[cfg(test)] extern mod realstd = "std"; -#[cfg(test)] pub use kinds = realstd::kinds; #[cfg(test)] pub use ops = realstd::ops; #[cfg(test)] pub use cmp = realstd::cmp; +pub use prim::cast; +pub use prim::kinds; +pub use prim::mem; +pub use prim::ptr; + mod macros; mod rtdeps; @@ -119,7 +125,6 @@ pub mod str; pub mod ascii; pub mod send_str; -pub mod ptr; pub mod owned; pub mod managed; mod reference; @@ -129,7 +134,6 @@ pub mod gc; /* Core language traits */ -#[cfg(not(test))] pub mod kinds; #[cfg(not(test))] pub mod ops; #[cfg(not(test))] pub mod cmp; @@ -175,14 +179,12 @@ pub mod io; pub mod path; pub mod rand; pub mod run; -pub mod cast; pub mod fmt; pub mod cleanup; #[deprecated] pub mod condition; pub mod logging; pub mod util; -pub mod mem; /* Unsupported interfaces */ diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 457d58ae46405..d91f25a364568 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -145,6 +145,49 @@ fn with_env_lock(f: || -> T) -> T { } } +/** + Given a **T (pointer to an array of pointers), + iterate through each *T, up to the provided `len`, + passing to the provided callback function + + SAFETY NOTE: Pointer-arithmetic. Dragons be here. +*/ +unsafe fn array_each_with_len(arr: **T, len: uint, cb: |*T|) { + use ptr::offset; + + debug!("array_each_with_len: before iterate"); + if arr as uint == 0 { + fail!("ptr::array_each_with_len failure: arr input is null pointer"); + } + //let start_ptr = *arr; + for e in range(0, len) { + let n = offset(arr, e as int); + cb(*n); + } + debug!("array_each_with_len: after iterate"); +} + +/** + Given a null-pointer-terminated **T (pointer to + an array of pointers), iterate through each *T, + passing to the provided callback function + + SAFETY NOTE: This will only work with a null-terminated + pointer array. Barely less-dodgy Pointer Arithmetic. + Dragons be here. +*/ +unsafe fn array_each(arr: **T, cb: |*T|) { + use ptr::buf_len; + + if arr as uint == 0 { + fail!("ptr::array_each_with_len failure: arr input is null pointer"); + } + let len = buf_len(arr); + debug!("array_each inferred len: {}", len); + array_each_with_len(arr, len, cb); +} + + /// Returns a vector of (variable, value) pairs for all the environment /// variables of the current process. pub fn env() -> ~[(~str,~str)] { @@ -181,7 +224,7 @@ pub fn env() -> ~[(~str,~str)] { os::last_os_error()); } let mut result = ~[]; - ptr::array_each(environ, |e| { + array_each(environ, |e| { let env_pair = str::raw::from_c_str(e); debug!("get_env_pairs: {}", env_pair); result.push(env_pair); @@ -1301,11 +1344,15 @@ mod tests { use prelude::*; use c_str::ToCStr; use option; + use libc; use os::{env, getcwd, getenv, make_absolute, args}; use os::{setenv, unsetenv}; use os; + use ptr::null; use rand::Rng; use rand; + use str; + use super::{array_each, array_each_with_len}; #[test] @@ -1546,4 +1593,92 @@ mod tests { } // More recursive_mkdir tests are in extra::tempfile + + #[test] + fn test_ptr_array_each_with_len() { + unsafe { + let one = "oneOne".to_c_str(); + let two = "twoTwo".to_c_str(); + let three = "threeThree".to_c_str(); + let arr = ~[ + one.with_ref(|buf| buf), + two.with_ref(|buf| buf), + three.with_ref(|buf| buf), + ]; + let expected_arr = [ + one, two, three + ]; + + let mut ctr = 0; + let mut iteration_count = 0; + array_each_with_len(arr.as_ptr(), arr.len(), |e| { + let actual = str::raw::from_c_str(e); + let expected = expected_arr[ctr].with_ref(|buf| { + str::raw::from_c_str(buf) + }); + debug!( + "test_ptr_array_each_with_len e: {}, a: {}", + expected, actual); + assert_eq!(actual, expected); + ctr += 1; + iteration_count += 1; + }); + assert_eq!(iteration_count, 3u); + } + } + + #[test] + fn test_ptr_array_each() { + unsafe { + let one = "oneOne".to_c_str(); + let two = "twoTwo".to_c_str(); + let three = "threeThree".to_c_str(); + let arr = ~[ + one.with_ref(|buf| buf), + two.with_ref(|buf| buf), + three.with_ref(|buf| buf), + // fake a null terminator + null(), + ]; + let expected_arr = [ + one, two, three + ]; + + let arr_ptr = arr.as_ptr(); + let mut ctr = 0; + let mut iteration_count = 0; + array_each(arr_ptr, |e| { + let actual = str::raw::from_c_str(e); + let expected = expected_arr[ctr].with_ref(|buf| { + str::raw::from_c_str(buf) + }); + debug!( + "test_ptr_array_each e: {}, a: {}", + expected, actual); + assert_eq!(actual, expected); + ctr += 1; + iteration_count += 1; + }); + assert_eq!(iteration_count, 3); + } + } + + #[test] + #[should_fail] + fn test_ptr_array_each_with_len_null_ptr() { + unsafe { + array_each_with_len(0 as **libc::c_char, 1, |e| { + str::raw::from_c_str(e); + }); + } + } + #[test] + #[should_fail] + fn test_ptr_array_each_null_ptr() { + unsafe { + array_each(0 as **libc::c_char, |e| { + str::raw::from_c_str(e); + }); + } + } } diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs index 4c545de73b48b..ed03a4b39a56a 100644 --- a/src/libstd/to_bytes.rs +++ b/src/libstd/to_bytes.rs @@ -18,6 +18,7 @@ use cast; use container::Container; use iter::Iterator; use option::{None, Option, Some}; +use prim::intrinsics::TypeId; use rc::Rc; use str::{Str, StrSlice}; use vec::{Vector, ImmutableVector}; @@ -54,6 +55,13 @@ pub trait IterBytes { fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool; } +impl IterBytes for TypeId { + #[inline] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + self.t.iter_bytes(lsb0, f) + } +} + impl IterBytes for bool { #[inline] fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs index 33d23df242ce2..f093fc5977288 100644 --- a/src/libstd/tuple.rs +++ b/src/libstd/tuple.rs @@ -16,6 +16,14 @@ use clone::Clone; #[cfg(not(test))] use cmp::*; #[cfg(not(test))] use default::Default; +pub use prim::tuple::{ImmutableTuple1, ImmutableTuple2, ImmutableTuple3, ImmutableTuple4}; +pub use prim::tuple::{ImmutableTuple5, ImmutableTuple6, ImmutableTuple7, ImmutableTuple8}; +pub use prim::tuple::{ImmutableTuple9, ImmutableTuple10, ImmutableTuple11, ImmutableTuple12}; +pub use prim::tuple::{Tuple1, Tuple2, Tuple3, Tuple4}; +pub use prim::tuple::{Tuple5, Tuple6, Tuple7, Tuple8}; +pub use prim::tuple::{Tuple9, Tuple10, Tuple11, Tuple12}; + + /// Method extensions to pairs where both types satisfy the `Clone` bound pub trait CloneableTuple { /// Return the first element of self @@ -80,40 +88,12 @@ impl ImmutableTuple for (T, U) { macro_rules! tuple_impls { ($( - ($move_trait:ident, $immutable_trait:ident) { - $(($get_fn:ident, $get_ref_fn:ident) -> $T:ident { - $move_pattern:pat, $ref_pattern:pat => $ret:expr - })+ + { + $(($get_ref_fn:ident) -> $T:ident; + )+ } )+) => { $( - pub trait $move_trait<$($T),+> { - $(fn $get_fn(self) -> $T;)+ - } - - impl<$($T),+> $move_trait<$($T),+> for ($($T,)+) { - $( - #[inline] - fn $get_fn(self) -> $T { - let $move_pattern = self; - $ret - } - )+ - } - - pub trait $immutable_trait<$($T),+> { - $(fn $get_ref_fn<'a>(&'a self) -> &'a $T;)+ - } - - impl<$($T),+> $immutable_trait<$($T),+> for ($($T,)+) { - $( - #[inline] - fn $get_ref_fn<'a>(&'a self) -> &'a $T { - let $ref_pattern = *self; - $ret - } - )+ - } impl<$($T:Clone),+> Clone for ($($T,)+) { fn clone(&self) -> ($($T,)+) { @@ -204,118 +184,118 @@ macro_rules! lexical_cmp { tuple_impls! { - (Tuple1, ImmutableTuple1) { - (n0, n0_ref) -> A { (a,), (ref a,) => a } + { + (n0_ref) -> A; } - (Tuple2, ImmutableTuple2) { - (n0, n0_ref) -> A { (a,_), (ref a,_) => a } - (n1, n1_ref) -> B { (_,b), (_,ref b) => b } + { + (n0_ref) -> A; + (n1_ref) -> B; } - (Tuple3, ImmutableTuple3) { - (n0, n0_ref) -> A { (a,_,_), (ref a,_,_) => a } - (n1, n1_ref) -> B { (_,b,_), (_,ref b,_) => b } - (n2, n2_ref) -> C { (_,_,c), (_,_,ref c) => c } + { + (n0_ref) -> A; + (n1_ref) -> B; + (n2_ref) -> C; } - (Tuple4, ImmutableTuple4) { - (n0, n0_ref) -> A { (a,_,_,_), (ref a,_,_,_) => a } - (n1, n1_ref) -> B { (_,b,_,_), (_,ref b,_,_) => b } - (n2, n2_ref) -> C { (_,_,c,_), (_,_,ref c,_) => c } - (n3, n3_ref) -> D { (_,_,_,d), (_,_,_,ref d) => d } + { + (n0_ref) -> A; + (n1_ref) -> B; + (n2_ref) -> C; + (n3_ref) -> D; } - (Tuple5, ImmutableTuple5) { - (n0, n0_ref) -> A { (a,_,_,_,_), (ref a,_,_,_,_) => a } - (n1, n1_ref) -> B { (_,b,_,_,_), (_,ref b,_,_,_) => b } - (n2, n2_ref) -> C { (_,_,c,_,_), (_,_,ref c,_,_) => c } - (n3, n3_ref) -> D { (_,_,_,d,_), (_,_,_,ref d,_) => d } - (n4, n4_ref) -> E { (_,_,_,_,e), (_,_,_,_,ref e) => e } + { + (n0_ref) -> A; + (n1_ref) -> B; + (n2_ref) -> C; + (n3_ref) -> D; + (n4_ref) -> E; } - (Tuple6, ImmutableTuple6) { - (n0, n0_ref) -> A { (a,_,_,_,_,_), (ref a,_,_,_,_,_) => a } - (n1, n1_ref) -> B { (_,b,_,_,_,_), (_,ref b,_,_,_,_) => b } - (n2, n2_ref) -> C { (_,_,c,_,_,_), (_,_,ref c,_,_,_) => c } - (n3, n3_ref) -> D { (_,_,_,d,_,_), (_,_,_,ref d,_,_) => d } - (n4, n4_ref) -> E { (_,_,_,_,e,_), (_,_,_,_,ref e,_) => e } - (n5, n5_ref) -> F { (_,_,_,_,_,f), (_,_,_,_,_,ref f) => f } + { + (n0_ref) -> A; + (n1_ref) -> B; + (n2_ref) -> C; + (n3_ref) -> D; + (n4_ref) -> E; + (n5_ref) -> F; } - (Tuple7, ImmutableTuple7) { - (n0, n0_ref) -> A { (a,_,_,_,_,_,_), (ref a,_,_,_,_,_,_) => a } - (n1, n1_ref) -> B { (_,b,_,_,_,_,_), (_,ref b,_,_,_,_,_) => b } - (n2, n2_ref) -> C { (_,_,c,_,_,_,_), (_,_,ref c,_,_,_,_) => c } - (n3, n3_ref) -> D { (_,_,_,d,_,_,_), (_,_,_,ref d,_,_,_) => d } - (n4, n4_ref) -> E { (_,_,_,_,e,_,_), (_,_,_,_,ref e,_,_) => e } - (n5, n5_ref) -> F { (_,_,_,_,_,f,_), (_,_,_,_,_,ref f,_) => f } - (n6, n6_ref) -> G { (_,_,_,_,_,_,g), (_,_,_,_,_,_,ref g) => g } + { + (n0_ref) -> A; + (n1_ref) -> B; + (n2_ref) -> C; + (n3_ref) -> D; + (n4_ref) -> E; + (n5_ref) -> F; + (n6_ref) -> G; } - (Tuple8, ImmutableTuple8) { - (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_) => a } - (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_) => b } - (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_), (_,_,ref c,_,_,_,_,_) => c } - (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_), (_,_,_,ref d,_,_,_,_) => d } - (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_), (_,_,_,_,ref e,_,_,_) => e } - (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_), (_,_,_,_,_,ref f,_,_) => f } - (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_), (_,_,_,_,_,_,ref g,_) => g } - (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h), (_,_,_,_,_,_,_,ref h) => h } + { + (n0_ref) -> A; + (n1_ref) -> B; + (n2_ref) -> C; + (n3_ref) -> D; + (n4_ref) -> E; + (n5_ref) -> F; + (n6_ref) -> G; + (n7_ref) -> H; } - (Tuple9, ImmutableTuple9) { - (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_,_) => a } - (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_,_) => b } - (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_,_), (_,_,ref c,_,_,_,_,_,_) => c } - (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_,_), (_,_,_,ref d,_,_,_,_,_) => d } - (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_,_), (_,_,_,_,ref e,_,_,_,_) => e } - (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_,_), (_,_,_,_,_,ref f,_,_,_) => f } - (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_,_), (_,_,_,_,_,_,ref g,_,_) => g } - (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h,_), (_,_,_,_,_,_,_,ref h,_) => h } - (n8, n8_ref) -> I { (_,_,_,_,_,_,_,_,i), (_,_,_,_,_,_,_,_,ref i) => i } + { + (n0_ref) -> A; + (n1_ref) -> B; + (n2_ref) -> C; + (n3_ref) -> D; + (n4_ref) -> E; + (n5_ref) -> F; + (n6_ref) -> G; + (n7_ref) -> H; + (n8_ref) -> I; } - (Tuple10, ImmutableTuple10) { - (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_,_,_) => a } - (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_,_,_) => b } - (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_,_,_), (_,_,ref c,_,_,_,_,_,_,_) => c } - (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_,_,_), (_,_,_,ref d,_,_,_,_,_,_) => d } - (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_,_,_), (_,_,_,_,ref e,_,_,_,_,_) => e } - (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_,_,_), (_,_,_,_,_,ref f,_,_,_,_) => f } - (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_,_,_), (_,_,_,_,_,_,ref g,_,_,_) => g } - (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h,_,_), (_,_,_,_,_,_,_,ref h,_,_) => h } - (n8, n8_ref) -> I { (_,_,_,_,_,_,_,_,i,_), (_,_,_,_,_,_,_,_,ref i,_) => i } - (n9, n9_ref) -> J { (_,_,_,_,_,_,_,_,_,j), (_,_,_,_,_,_,_,_,_,ref j) => j } + { + (n0_ref) -> A; + (n1_ref) -> B; + (n2_ref) -> C; + (n3_ref) -> D; + (n4_ref) -> E; + (n5_ref) -> F; + (n6_ref) -> G; + (n7_ref) -> H; + (n8_ref) -> I; + (n9_ref) -> J; } - (Tuple11, ImmutableTuple11) { - (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_,_,_,_) => a } - (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_,_,_,_) => b } - (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_,_,_,_), (_,_,ref c,_,_,_,_,_,_,_,_) => c } - (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_,_,_,_), (_,_,_,ref d,_,_,_,_,_,_,_) => d } - (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_,_,_,_), (_,_,_,_,ref e,_,_,_,_,_,_) => e } - (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_,_,_,_), (_,_,_,_,_,ref f,_,_,_,_,_) => f } - (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_,_,_,_), (_,_,_,_,_,_,ref g,_,_,_,_) => g } - (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h,_,_,_), (_,_,_,_,_,_,_,ref h,_,_,_) => h } - (n8, n8_ref) -> I { (_,_,_,_,_,_,_,_,i,_,_), (_,_,_,_,_,_,_,_,ref i,_,_) => i } - (n9, n9_ref) -> J { (_,_,_,_,_,_,_,_,_,j,_), (_,_,_,_,_,_,_,_,_,ref j,_) => j } - (n10, n10_ref) -> K { (_,_,_,_,_,_,_,_,_,_,k), (_,_,_,_,_,_,_,_,_,_,ref k) => k } + { + (n0_ref) -> A; + (n1_ref) -> B; + (n2_ref) -> C; + (n3_ref) -> D; + (n4_ref) -> E; + (n5_ref) -> F; + (n6_ref) -> G; + (n7_ref) -> H; + (n8_ref) -> I; + (n9_ref) -> J; + (n10_ref) -> K; } - (Tuple12, ImmutableTuple12) { - (n0, n0_ref) -> A { (a,_,_,_,_,_,_,_,_,_,_,_), (ref a,_,_,_,_,_,_,_,_,_,_,_) => a } - (n1, n1_ref) -> B { (_,b,_,_,_,_,_,_,_,_,_,_), (_,ref b,_,_,_,_,_,_,_,_,_,_) => b } - (n2, n2_ref) -> C { (_,_,c,_,_,_,_,_,_,_,_,_), (_,_,ref c,_,_,_,_,_,_,_,_,_) => c } - (n3, n3_ref) -> D { (_,_,_,d,_,_,_,_,_,_,_,_), (_,_,_,ref d,_,_,_,_,_,_,_,_) => d } - (n4, n4_ref) -> E { (_,_,_,_,e,_,_,_,_,_,_,_), (_,_,_,_,ref e,_,_,_,_,_,_,_) => e } - (n5, n5_ref) -> F { (_,_,_,_,_,f,_,_,_,_,_,_), (_,_,_,_,_,ref f,_,_,_,_,_,_) => f } - (n6, n6_ref) -> G { (_,_,_,_,_,_,g,_,_,_,_,_), (_,_,_,_,_,_,ref g,_,_,_,_,_) => g } - (n7, n7_ref) -> H { (_,_,_,_,_,_,_,h,_,_,_,_), (_,_,_,_,_,_,_,ref h,_,_,_,_) => h } - (n8, n8_ref) -> I { (_,_,_,_,_,_,_,_,i,_,_,_), (_,_,_,_,_,_,_,_,ref i,_,_,_) => i } - (n9, n9_ref) -> J { (_,_,_,_,_,_,_,_,_,j,_,_), (_,_,_,_,_,_,_,_,_,ref j,_,_) => j } - (n10, n10_ref) -> K { (_,_,_,_,_,_,_,_,_,_,k,_), (_,_,_,_,_,_,_,_,_,_,ref k,_) => k } - (n11, n11_ref) -> L { (_,_,_,_,_,_,_,_,_,_,_,l), (_,_,_,_,_,_,_,_,_,_,_,ref l) => l } + { + (n0_ref) -> A; + (n1_ref) -> B; + (n2_ref) -> C; + (n3_ref) -> D; + (n4_ref) -> E; + (n5_ref) -> F; + (n6_ref) -> G; + (n7_ref) -> H; + (n8_ref) -> I; + (n9_ref) -> J; + (n10_ref) -> K; + (n11_ref) -> L; } } @@ -346,37 +326,6 @@ mod tests { assert_eq!(a.first(), b.first()); assert_eq!(a.second(), b.second()); } - - #[test] - fn test_n_tuple() { - let t = (0u8, 1u16, 2u32, 3u64, 4u, 5i8, 6i16, 7i32, 8i64, 9i, 10f32, 11f64); - assert_eq!(t.n0(), 0u8); - assert_eq!(t.n1(), 1u16); - assert_eq!(t.n2(), 2u32); - assert_eq!(t.n3(), 3u64); - assert_eq!(t.n4(), 4u); - assert_eq!(t.n5(), 5i8); - assert_eq!(t.n6(), 6i16); - assert_eq!(t.n7(), 7i32); - assert_eq!(t.n8(), 8i64); - assert_eq!(t.n9(), 9i); - assert_eq!(t.n10(), 10f32); - assert_eq!(t.n11(), 11f64); - - assert_eq!(t.n0_ref(), &0u8); - assert_eq!(t.n1_ref(), &1u16); - assert_eq!(t.n2_ref(), &2u32); - assert_eq!(t.n3_ref(), &3u64); - assert_eq!(t.n4_ref(), &4u); - assert_eq!(t.n5_ref(), &5i8); - assert_eq!(t.n6_ref(), &6i16); - assert_eq!(t.n7_ref(), &7i32); - assert_eq!(t.n8_ref(), &8i64); - assert_eq!(t.n9_ref(), &9i); - assert_eq!(t.n10_ref(), &10f32); - assert_eq!(t.n11_ref(), &11f64); - } - #[test] fn test_tuple_cmp() { let (small, big) = ((1u, 2u, 3u), (3u, 2u, 1u)); diff --git a/src/libstd/unstable/mod.rs b/src/libstd/unstable/mod.rs index 87870ef033142..5c655e9b6c5dc 100644 --- a/src/libstd/unstable/mod.rs +++ b/src/libstd/unstable/mod.rs @@ -13,16 +13,17 @@ use prelude::*; use libc::uintptr_t; +pub use prim::intrinsics; +pub use prim::raw; + pub mod dynamic_lib; pub mod finally; -pub mod intrinsics; pub mod simd; #[cfg(not(test))] pub mod lang; pub mod sync; pub mod mutex; -pub mod raw; pub mod stack; /** diff --git a/src/libstd/util.rs b/src/libstd/util.rs index 06c7923bfeda1..017b6974639ff 100644 --- a/src/libstd/util.rs +++ b/src/libstd/util.rs @@ -10,49 +10,14 @@ //! Miscellaneous helpers for common patterns -use cast; -use ptr; use prelude::*; -use unstable::intrinsics; + +pub use prim::util::{swap, replace}; /// The identity function. #[inline] pub fn id(x: T) -> T { x } -/** - * Swap the values at two mutable locations of the same type, without - * deinitialising or copying either one. - */ -#[inline] -pub fn swap(x: &mut T, y: &mut T) { - unsafe { - // Give ourselves some scratch space to work with - let mut tmp: T = intrinsics::uninit(); - let t: *mut T = &mut tmp; - - // Perform the swap, `&mut` pointers never alias - let x_raw: *mut T = x; - let y_raw: *mut T = y; - ptr::copy_nonoverlapping_memory(t, x_raw, 1); - ptr::copy_nonoverlapping_memory(x, y_raw, 1); - ptr::copy_nonoverlapping_memory(y, t, 1); - - // y and t now point to the same thing, but we need to completely forget `tmp` - // because it's no longer relevant. - cast::forget(tmp); - } -} - -/** - * Replace the value at a mutable location with a new one, returning the old - * value, without deinitialising or copying either one. - */ -#[inline] -pub fn replace(dest: &mut T, mut src: T) -> T { - swap(dest, &mut src); - src -} - /// A non-copyable dummy type. #[deriving(Eq, TotalEq, Ord, TotalOrd)] #[unsafe_no_drop_flag] diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 607b30c000bd5..8f7f9710c5b05 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1549,7 +1549,7 @@ impl OwnedVector for ~[T] { let p = self.as_mut_ptr().offset(i as int); // Shift everything over to make space. (Duplicating the // `i`th element into two consecutive places.) - ptr::copy_memory(p.offset(1), p, len - i); + ptr::copy_memory(p.offset(1), &*p, len - i); // Write it in, overwriting the first copy of the `i`th // element. intrinsics::move_val_init(&mut *p, x); @@ -1568,7 +1568,7 @@ impl OwnedVector for ~[T] { let ret = Some(ptr::read_ptr(ptr as *T)); // Shift everything down to fill in that spot. - ptr::copy_memory(ptr, ptr.offset(1), len - i - 1); + ptr::copy_memory(ptr, &*ptr.offset(1), len - i - 1); self.set_len(len - 1); ret @@ -1863,7 +1863,7 @@ fn merge_sort(v: &mut [T], compare: |&T, &T| -> Ordering) { // that case, `i == j` so we don't copy. The // `.offset(j)` is always in bounds. ptr::copy_memory(buf_dat.offset(j + 1), - buf_dat.offset(j), + &*buf_dat.offset(j), i - j as uint); ptr::copy_nonoverlapping_memory(buf_dat.offset(j), read_ptr, 1); } @@ -1913,11 +1913,11 @@ fn merge_sort(v: &mut [T], compare: |&T, &T| -> Ordering) { if left == right_start { // the number remaining in this run. let elems = (right_end as uint - right as uint) / mem::size_of::(); - ptr::copy_nonoverlapping_memory(out, right, elems); + ptr::copy_nonoverlapping_memory(out, &*right, elems); break; } else if right == right_end { let elems = (right_start as uint - left as uint) / mem::size_of::(); - ptr::copy_nonoverlapping_memory(out, left, elems); + ptr::copy_nonoverlapping_memory(out, &*left, elems); break; } @@ -1931,7 +1931,7 @@ fn merge_sort(v: &mut [T], compare: |&T, &T| -> Ordering) { } else { step(&mut left) }; - ptr::copy_nonoverlapping_memory(out, to_copy, 1); + ptr::copy_nonoverlapping_memory(out, &*to_copy, 1); step(&mut out); } } @@ -1945,7 +1945,7 @@ fn merge_sort(v: &mut [T], compare: |&T, &T| -> Ordering) { // write the result to `v` in one go, so that there are never two copies // of the same object in `v`. unsafe { - ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), buf_dat, len); + ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), &*buf_dat, len); } // increment the pointer, returning the old pointer.