diff options
Diffstat (limited to 'src/libcore')
35 files changed, 1420 insertions, 911 deletions
diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs index e2bce1bd0f0..9f59f1d8fe4 100644 --- a/src/libcore/at_vec.rs +++ b/src/libcore/at_vec.rs @@ -12,9 +12,8 @@ use cast::transmute; use kinds::Copy; -use iter; +use old_iter; use option::Option; -use ptr::addr_of; use sys; use uint; use vec; @@ -40,8 +39,7 @@ pub mod rustrt { #[inline(always)] pub fn capacity<T>(v: @[T]) -> uint { unsafe { - let repr: **raw::VecRepr = - ::cast::transmute(addr_of(&v)); + let repr: **raw::VecRepr = transmute(&v); (**repr).unboxed.alloc / sys::size_of::<T>() } } @@ -125,7 +123,7 @@ pub fn map<T, U>(v: &[T], f: &fn(x: &T) -> U) -> @[U] { * Creates an immutable vector of size `n_elts` and initializes the elements * to the value returned by the function `op`. */ -pub fn from_fn<T>(n_elts: uint, op: iter::InitOp<T>) -> @[T] { +pub fn from_fn<T>(n_elts: uint, op: old_iter::InitOp<T>) -> @[T] { do build_sized(n_elts) |push| { let mut i: uint = 0u; while i < n_elts { push(op(i)); i += 1u; } @@ -187,13 +185,12 @@ pub mod traits {} pub mod raw { use at_vec::{capacity, rustrt}; - use cast::transmute; + use cast::{transmute, transmute_copy}; use libc; - use unstable::intrinsics::{move_val_init}; - use ptr::addr_of; use ptr; use sys; use uint; + use unstable::intrinsics::{move_val_init}; use vec; pub type VecRepr = vec::raw::VecRepr; @@ -208,18 +205,17 @@ pub mod raw { */ #[inline(always)] pub unsafe fn set_len<T>(v: @[T], new_len: uint) { - let repr: **mut VecRepr = ::cast::transmute(addr_of(&v)); + let repr: **mut VecRepr = transmute(&v); (**repr).unboxed.fill = new_len * sys::size_of::<T>(); } #[inline(always)] pub unsafe fn push<T>(v: &mut @[T], initval: T) { - let repr: **VecRepr = ::cast::reinterpret_cast(&v); + let repr: **VecRepr = transmute_copy(&v); let fill = (**repr).unboxed.fill; if (**repr).unboxed.alloc > fill { push_fast(v, initval); - } - else { + } else { push_slow(v, initval); } } @@ -229,7 +225,7 @@ pub mod raw { let repr: **mut VecRepr = ::cast::transmute(v); let fill = (**repr).unboxed.fill; (**repr).unboxed.fill += sys::size_of::<T>(); - let p = addr_of(&((**repr).unboxed.data)); + let p = &((**repr).unboxed.data); let p = ptr::offset(p, fill) as *mut T; move_val_init(&mut(*p), initval); } diff --git a/src/libcore/cast.rs b/src/libcore/cast.rs index 1d214f402f5..6fb737d3770 100644 --- a/src/libcore/cast.rs +++ b/src/libcore/cast.rs @@ -10,21 +10,56 @@ //! Unsafe casting functions +use sys; +use unstable; + pub mod rusti { #[abi = "rust-intrinsic"] #[link_name = "rusti"] pub extern "rust-intrinsic" { fn forget<T>(+x: T); + + #[cfg(stage0)] fn reinterpret_cast<T, U>(&&e: T) -> U; + + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn transmute<T,U>(e: T) -> U; } } /// Casts the value at `src` to U. The two types must have the same length. #[inline(always)] +#[cfg(stage0)] pub unsafe fn reinterpret_cast<T, U>(src: &T) -> U { rusti::reinterpret_cast(*src) } +/// Unsafely copies and casts the value at `src` to U, even if the value is +/// noncopyable. The two types must have the same length. +#[inline(always)] +#[cfg(stage0)] +pub unsafe fn transmute_copy<T, U>(src: &T) -> U { + rusti::reinterpret_cast(*src) +} + +#[inline(always)] +#[cfg(stage1)] +#[cfg(stage2)] +#[cfg(stage3)] +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 * @@ -53,12 +88,21 @@ pub unsafe fn bump_box_refcount<T>(t: @T) { forget(t); } * assert!(transmute("L") == ~[76u8, 0u8]); */ #[inline(always)] +#[cfg(stage0)] pub unsafe fn transmute<L, G>(thing: L) -> G { let newthing: G = reinterpret_cast(&thing); forget(thing); newthing } +#[inline(always)] +#[cfg(stage1)] +#[cfg(stage2)] +#[cfg(stage3)] +pub unsafe fn transmute<L, G>(thing: L) -> G { + rusti::transmute(thing) +} + /// Coerce an immutable reference to be mutable. #[inline(always)] pub unsafe fn transmute_mut<'a,T>(ptr: &'a T) -> &'a mut T { transmute(ptr) } @@ -112,11 +156,20 @@ pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T { #[cfg(test)] mod tests { - use cast::{bump_box_refcount, reinterpret_cast, transmute}; + use cast::{bump_box_refcount, transmute}; #[test] + #[cfg(stage0)] fn test_reinterpret_cast() { - assert!(1u == unsafe { reinterpret_cast(&1) }); + assert!(1u == unsafe { ::cast::reinterpret_cast(&1) }); + } + + #[test] + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn test_transmute_copy() { + assert!(1u == unsafe { ::cast::transmute_copy(&1) }); } #[test] @@ -125,8 +178,8 @@ mod tests { let box = @~"box box box"; // refcount 1 bump_box_refcount(box); // refcount 2 let ptr: *int = transmute(box); // refcount 2 - let _box1: @~str = reinterpret_cast(&ptr); - let _box2: @~str = reinterpret_cast(&ptr); + 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 diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index 2656115dca2..50a3bba049b 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -327,6 +327,7 @@ impl<T: Owned> ::clone::Clone for SharedChan<T> { #[allow(non_camel_case_types)] pub mod oneshot { priv use core::kinds::Owned; + use ptr::to_unsafe_ptr; pub fn init<T: Owned>() -> (client::Oneshot<T>, server::Oneshot<T>) { pub use core::pipes::HasBuffer; @@ -341,7 +342,7 @@ pub mod oneshot { do ::core::pipes::entangle_buffer(buffer) |buffer, data| { { data.Oneshot.set_buffer(buffer); - ::ptr::addr_of(&(data.Oneshot)) + to_unsafe_ptr(&data.Oneshot) } } } @@ -394,24 +395,55 @@ pub mod oneshot { } /// The send end of a oneshot pipe. -pub type ChanOne<T> = oneshot::client::Oneshot<T>; +pub struct ChanOne<T> { + contents: oneshot::client::Oneshot<T> +} + +impl<T> ChanOne<T> { + pub fn new(contents: oneshot::client::Oneshot<T>) -> ChanOne<T> { + ChanOne { + contents: contents + } + } +} + /// The receive end of a oneshot pipe. -pub type PortOne<T> = oneshot::server::Oneshot<T>; +pub struct PortOne<T> { + contents: oneshot::server::Oneshot<T> +} + +impl<T> PortOne<T> { + pub fn new(contents: oneshot::server::Oneshot<T>) -> PortOne<T> { + PortOne { + contents: contents + } + } +} /// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair. pub fn oneshot<T: Owned>() -> (PortOne<T>, ChanOne<T>) { let (chan, port) = oneshot::init(); - (port, chan) + (PortOne::new(port), ChanOne::new(chan)) } pub impl<T: Owned> PortOne<T> { fn recv(self) -> T { recv_one(self) } fn try_recv(self) -> Option<T> { try_recv_one(self) } + fn unwrap(self) -> oneshot::server::Oneshot<T> { + match self { + PortOne { contents: s } => s + } + } } pub impl<T: Owned> ChanOne<T> { fn send(self, data: T) { send_one(self, data) } fn try_send(self, data: T) -> bool { try_send_one(self, data) } + fn unwrap(self) -> oneshot::client::Oneshot<T> { + match self { + ChanOne { contents: s } => s + } + } } /** @@ -419,33 +451,47 @@ pub impl<T: Owned> ChanOne<T> { * closed. */ pub fn recv_one<T: Owned>(port: PortOne<T>) -> T { - let oneshot::send(message) = recv(port); - message + match port { + PortOne { contents: port } => { + let oneshot::send(message) = recv(port); + message + } + } } /// Receive a message from a oneshot pipe unless the connection was closed. pub fn try_recv_one<T: Owned> (port: PortOne<T>) -> Option<T> { - let message = try_recv(port); - - if message.is_none() { None } - else { - let oneshot::send(message) = message.unwrap(); - Some(message) + match port { + PortOne { contents: port } => { + let message = try_recv(port); + + if message.is_none() { + None + } else { + let oneshot::send(message) = message.unwrap(); + Some(message) + } + } } } /// Send a message on a oneshot pipe, failing if the connection was closed. pub fn send_one<T: Owned>(chan: ChanOne<T>, data: T) { - oneshot::client::send(chan, data); + match chan { + ChanOne { contents: chan } => oneshot::client::send(chan, data), + } } /** * Send a message on a oneshot pipe, or return false if the connection was * closed. */ -pub fn try_send_one<T: Owned>(chan: ChanOne<T>, data: T) - -> bool { - oneshot::client::try_send(chan, data).is_some() +pub fn try_send_one<T: Owned>(chan: ChanOne<T>, data: T) -> bool { + match chan { + ChanOne { contents: chan } => { + oneshot::client::try_send(chan, data).is_some() + } + } } @@ -519,11 +565,11 @@ mod test { #[test] fn test_oneshot() { - let (c, p) = oneshot::init(); + let (p, c) = oneshot(); - oneshot::client::send(c, ()); + c.send(()); - recv_one(p) + p.recv() } #[test] diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 158da9a12fc..f9a56f613d5 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -99,13 +99,15 @@ pub use container::{Container, Mutable}; pub use vec::{CopyableVector, ImmutableVector}; pub use vec::{ImmutableEqVector, ImmutableCopyableVector}; pub use vec::{OwnedVector, OwnedCopyableVector, MutableVector}; -pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter}; -pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times}; -pub use iter::{ExtendedMutableIter}; +pub use old_iter::{BaseIter, ExtendedIter, EqIter, CopyableIter}; +pub use old_iter::{CopyableOrderedIter, CopyableNonstrictIter}; +pub use old_iter::{ExtendedMutableIter}; +pub use iter::Times; pub use num::{Num, NumCast}; -pub use num::{Orderable, Signed, Unsigned, Integer}; -pub use num::{Round, Fractional, Real, RealExt}; +pub use num::{Orderable, Signed, Unsigned, Round}; +pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic}; +pub use num::{Integer, Fractional, Real, RealExt}; pub use num::{Bitwise, BitCount, Bounded}; pub use num::{Primitive, Int, Float}; @@ -188,6 +190,7 @@ pub mod from_str; #[path = "num/num.rs"] pub mod num; pub mod iter; +pub mod old_iter; pub mod iterator; pub mod to_str; pub mod to_bytes; diff --git a/src/libcore/flate.rs b/src/libcore/flate.rs index 5c4181c10cf..c3518cc8b6e 100644 --- a/src/libcore/flate.rs +++ b/src/libcore/flate.rs @@ -53,7 +53,7 @@ pub fn deflate_bytes(bytes: &const [u8]) -> ~[u8] { let res = rustrt::tdefl_compress_mem_to_heap(b as *c_void, len as size_t, - ptr::addr_of(&outsz), + &outsz, lz_norm); assert!(res as int != 0); let out = vec::raw::from_buf_raw(res as *u8, @@ -71,7 +71,7 @@ pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] { let res = rustrt::tinfl_decompress_mem_to_heap(b as *c_void, len as size_t, - ptr::addr_of(&outsz), + &outsz, 0); assert!(res as int != 0); let out = vec::raw::from_buf_raw(res as *u8, diff --git a/src/libcore/gc.rs b/src/libcore/gc.rs index a6bae3c7663..0d0a98359d1 100644 --- a/src/libcore/gc.rs +++ b/src/libcore/gc.rs @@ -338,7 +338,7 @@ pub fn cleanup_stack_for_failure() { // own stack roots on the stack anyway. let sentinel_box = ~0; let sentinel: **Word = if expect_sentinel() { - cast::transmute(ptr::addr_of(&sentinel_box)) + cast::transmute(&sentinel_box) } else { ptr::null() }; diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index d2be0416371..41f4f34dc19 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -16,9 +16,9 @@ use container::{Container, Mutable, Map, Set}; use cmp::{Eq, Equiv}; use hash::Hash; -use iter::BaseIter; +use old_iter::BaseIter; use hash::Hash; -use iter; +use old_iter; use option::{None, Option, Some}; use rand::RngUtil; use rand; @@ -757,12 +757,12 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> { /// Return true if the set has no elements in common with `other`. /// This is equivalent to checking for an empty intersection. fn is_disjoint(&self, other: &HashSet<T>) -> bool { - iter::all(self, |v| !other.contains(v)) + old_iter::all(self, |v| !other.contains(v)) } /// Return true if the set is a subset of another fn is_subset(&self, other: &HashSet<T>) -> bool { - iter::all(self, |v| other.contains(v)) + old_iter::all(self, |v| other.contains(v)) } /// Return true if the set is a superset of another diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 3dcca0e06c2..7476531ef94 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -8,369 +8,124 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! +/*! Composable internal iterators -The iteration traits and common implementation +Internal iterators are functions implementing the protocol used by the `for` loop. -*/ - -use cmp::{Eq, Ord}; -use kinds::Copy; -use option::{None, Option, Some}; -use vec; +An internal iterator takes `fn(...) -> bool` as a parameter, with returning `false` used to signal +breaking out of iteration. The adaptors in the module work with any such iterator, not just ones +tied to specific traits. For example: -/// A function used to initialize the elements of a sequence -pub type InitOp<'self,T> = &'self fn(uint) -> T; - -pub trait BaseIter<A> { - fn each(&self, blk: &fn(v: &A) -> bool); - fn size_hint(&self) -> Option<uint>; -} +~~~~ +use core::iter::iter_to_vec; +println(iter_to_vec(|f| uint::range(0, 20, f)).to_str()); +~~~~ -pub trait ReverseIter<A>: BaseIter<A> { - fn each_reverse(&self, blk: &fn(&A) -> bool); -} +An external iterator object implementing the interface in the `iterator` module can be used as an +internal iterator by calling the `advance` method. For example: -pub trait MutableIter<A>: BaseIter<A> { - fn each_mut(&mut self, blk: &fn(&mut A) -> bool); -} +~~~~ +use core::iterator::*; -pub trait ExtendedIter<A> { - fn eachi(&self, blk: &fn(uint, v: &A) -> bool); - fn all(&self, blk: &fn(&A) -> bool) -> bool; - fn any(&self, blk: &fn(&A) -> bool) -> bool; - fn foldl<B>(&self, b0: B, blk: &fn(&B, &A) -> B) -> B; - fn position(&self, f: &fn(&A) -> bool) -> Option<uint>; - fn map_to_vec<B>(&self, op: &fn(&A) -> B) -> ~[B]; - fn flat_map_to_vec<B,IB: BaseIter<B>>(&self, op: &fn(&A) -> IB) -> ~[B]; +let xs = [0u, 1, 2, 3, 4, 5]; +let ys = [30, 40, 50, 60]; +let mut it = xs.iter().chain(ys.iter()); +for it.advance |&x: &uint| { + println(x.to_str()); } +~~~~ -pub trait ExtendedMutableIter<A> { - fn eachi_mut(&mut self, blk: &fn(uint, &mut A) -> bool); -} +Internal iterators provide a subset of the functionality of an external iterator. It's not possible +to interleave them to implement algorithms like `zip`, `union` and `merge`. However, they're often +much easier to implement. -pub trait EqIter<A:Eq> { - fn contains(&self, x: &A) -> bool; - fn count(&self, x: &A) -> uint; -} +*/ pub trait Times { fn times(&self, it: &fn() -> bool); } -pub trait CopyableIter<A:Copy> { - fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A]; - fn to_vec(&self) -> ~[A]; - fn find(&self, p: &fn(&A) -> bool) -> Option<A>; -} - -pub trait CopyableOrderedIter<A:Copy + Ord> { - fn min(&self) -> A; - fn max(&self) -> A; -} - -pub trait CopyableNonstrictIter<A:Copy> { - // Like "each", but copies out the value. If the receiver is mutated while - // iterating over it, the semantics must not be memory-unsafe but are - // otherwise undefined. - fn each_val(&const self, f: &fn(A) -> bool); -} - -// A trait for sequences that can be built by imperatively pushing elements -// onto them. -pub trait Buildable<A> { - /** - * Builds a buildable sequence by calling a provided function with - * an argument function that pushes an element onto the back of - * the sequence. - * This version takes an initial size for the sequence. - * - * # Arguments - * - * * size - A hint for an initial size of the sequence - * * builder - A function that will construct the sequence. It receives - * as an argument a function that will push an element - * onto the sequence being constructed. - */ - fn build_sized(size: uint, builder: &fn(push: &fn(A))) -> Self; -} - -#[inline(always)] -pub fn eachi<A,IA:BaseIter<A>>(self: &IA, blk: &fn(uint, &A) -> bool) { - let mut i = 0; - for self.each |a| { - if !blk(i, a) { break; } - i += 1; - } -} - -#[inline(always)] -pub fn all<A,IA:BaseIter<A>>(self: &IA, blk: &fn(&A) -> bool) -> bool { - for self.each |a| { - if !blk(a) { return false; } - } - return true; -} - -#[inline(always)] -pub fn any<A,IA:BaseIter<A>>(self: &IA, blk: &fn(&A) -> bool) -> bool { - for self.each |a| { - if blk(a) { return true; } - } - return false; -} - -#[inline(always)] -pub fn filter_to_vec<A:Copy,IA:BaseIter<A>>(self: &IA, - prd: &fn(&A) -> bool) - -> ~[A] { - do vec::build_sized_opt(self.size_hint()) |push| { - for self.each |a| { - if prd(a) { push(*a); } - } - } -} - -#[inline(always)] -pub fn map_to_vec<A,B,IA:BaseIter<A>>(self: &IA, op: &fn(&A) -> B) -> ~[B] { - do vec::build_sized_opt(self.size_hint()) |push| { - for self.each |a| { - push(op(a)); - } - } -} - -#[inline(always)] -pub fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(self: &IA, - op: &fn(&A) -> IB) - -> ~[B] { - do vec::build |push| { - for self.each |a| { - for op(a).each |&b| { - push(b); - } - } - } -} - -#[inline(always)] -pub fn foldl<A,B,IA:BaseIter<A>>(self: &IA, b0: B, blk: &fn(&B, &A) -> B) - -> B { - let mut b = b0; - for self.each |a| { - b = blk(&b, a); - } - b -} - -#[inline(always)] -pub fn to_vec<A:Copy,IA:BaseIter<A>>(self: &IA) -> ~[A] { - map_to_vec(self, |&x| x) -} - -#[inline(always)] -pub fn contains<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> bool { - for self.each |a| { - if *a == *x { return true; } - } - return false; -} - -#[inline(always)] -pub fn count<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> uint { - do foldl(self, 0) |count, value| { - if *value == *x { - *count + 1 - } else { - *count - } - } -} - -#[inline(always)] -pub fn position<A,IA:BaseIter<A>>(self: &IA, f: &fn(&A) -> bool) - -> Option<uint> { - let mut i = 0; - for self.each |a| { - if f(a) { return Some(i); } - i += 1; - } - return None; -} - -// note: 'rposition' would only make sense to provide with a bidirectional -// iter interface, such as would provide "reach" in addition to "each". As is, -// it would have to be implemented with foldr, which is too inefficient. - -#[inline(always)] -pub fn repeat(times: uint, blk: &fn() -> bool) { - let mut i = 0; - while i < times { - if !blk() { break } - i += 1; - } -} - -#[inline(always)] -pub fn min<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A { - match do foldl::<A,Option<A>,IA>(self, None) |a, b| { - match a { - &Some(ref a_) if *a_ < *b => { - *(a) - } - _ => Some(*b) - } - } { - Some(val) => val, - None => fail!(~"min called on empty iterator") - } -} - -#[inline(always)] -pub fn max<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A { - match do foldl::<A,Option<A>,IA>(self, None) |a, b| { - match a { - &Some(ref a_) if *a_ > *b => { - *(a) - } - _ => Some(*b) - } - } { - Some(val) => val, - None => fail!(~"max called on empty iterator") - } -} - -#[inline(always)] -pub fn find<A:Copy,IA:BaseIter<A>>(self: &IA, f: &fn(&A) -> bool) - -> Option<A> { - for self.each |i| { - if f(i) { return Some(*i) } - } - return None; -} - -// Some functions for just building - /** - * Builds a sequence by calling a provided function with an argument - * function that pushes an element to the back of a sequence. + * Transform an internal iterator into an owned vector. * - * # Arguments + * # Example: * - * * builder - A function that will construct the sequence. It receives - * as an argument a function that will push an element - * onto the sequence being constructed. + * ~~~ + * let xs = ~[1, 2, 3]; + * let ys = do iter_to_vec |f| { xs.each(|x| f(*x)) }; + * assert_eq!(xs, ys); + * ~~~ */ #[inline(always)] -pub fn build<A,B: Buildable<A>>(builder: &fn(push: &fn(A))) -> B { - Buildable::build_sized(4, builder) +pub fn iter_to_vec<T>(iter: &fn(f: &fn(T) -> bool)) -> ~[T] { + let mut v = ~[]; + for iter |x| { v.push(x) } + v } /** - * Builds a sequence by calling a provided function with an argument - * function that pushes an element to the back of the sequence. - * This version takes an initial size for the sequence. + * Return true if `predicate` is true for any values yielded by an internal iterator. * - * # Arguments + * Example: * - * * size - An option, maybe containing initial size of the sequence - * to reserve. - * * builder - A function that will construct the sequence. It receives - * as an argument a function that will push an element - * onto the sequence being constructed. + * ~~~~ + * let xs = ~[1u, 2, 3, 4, 5]; + * assert!(any(|&x: &uint| x > 2, |f| xs.each(f))); + * assert!(!any(|&x: &uint| x > 5, |f| xs.each(f))); + * ~~~~ */ #[inline(always)] -pub fn build_sized_opt<A,B: Buildable<A>>(size: Option<uint>, - builder: &fn(push: &fn(A))) -> B { - Buildable::build_sized(size.get_or_default(4), builder) -} - -// Functions that combine iteration and building - -/// Applies a function to each element of an iterable and returns the results -/// in a sequence built via `BU`. See also `map_to_vec`. -#[inline(always)] -pub fn map<T,IT: BaseIter<T>,U,BU: Buildable<U>>(v: &IT, f: &fn(&T) -> U) - -> BU { - do build_sized_opt(v.size_hint()) |push| { - for v.each() |elem| { - push(f(elem)); +pub fn any<T>(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> bool { + for iter |x| { + if predicate(x) { + return true } } + false } /** - * Creates and initializes a generic sequence from a function. + * Return true if `predicate` is true for all values yielded by an internal iterator. * - * Creates a generic sequence of size `n_elts` and initializes the elements - * to the value returned by the function `op`. - */ -#[inline(always)] -pub fn from_fn<T,BT: Buildable<T>>(n_elts: uint, op: InitOp<T>) -> BT { - do Buildable::build_sized(n_elts) |push| { - let mut i: uint = 0u; - while i < n_elts { push(op(i)); i += 1u; } - } -} - -/** - * Creates and initializes a generic sequence with some elements. + * # Example: * - * Creates an immutable vector of size `n_elts` and initializes the elements - * to the value `t`. + * ~~~~ + * assert!(all(|&x: &uint| x < 6, |f| uint::range(1, 6, f))); + * assert!(!all(|&x: &uint| x < 5, |f| uint::range(1, 6, f))); + * ~~~~ */ #[inline(always)] -pub fn from_elem<T:Copy,BT:Buildable<T>>(n_elts: uint, t: T) -> BT { - do Buildable::build_sized(n_elts) |push| { - let mut i: uint = 0; - while i < n_elts { push(t); i += 1; } +pub fn all<T>(predicate: &fn(T) -> bool, iter: &fn(f: &fn(T) -> bool)) -> bool { + for iter |x| { + if !predicate(x) { + return false + } } + true } -/// Appends two generic sequences. -#[inline(always)] -pub fn append<T:Copy,IT:BaseIter<T>,BT:Buildable<T>>(lhs: &IT, rhs: &IT) - -> BT { - let size_opt = lhs.size_hint().chain_ref( - |sz1| rhs.size_hint().map(|sz2| *sz1+*sz2)); - do build_sized_opt(size_opt) |push| { - for lhs.each |x| { push(*x); } - for rhs.each |x| { push(*x); } - } -} +#[cfg(test)] +mod tests { + use super::*; + use prelude::*; -/// Copies a generic sequence, possibly converting it to a different -/// type of sequence. -#[inline(always)] -pub fn copy_seq<T:Copy,IT:BaseIter<T>,BT:Buildable<T>>(v: &IT) -> BT { - do build_sized_opt(v.size_hint()) |push| { - for v.each |x| { push(*x); } + #[test] + fn test_iter_to_vec() { + let xs = ~[1, 2, 3]; + let ys = do iter_to_vec |f| { xs.each(|x| f(*x)) }; + assert_eq!(xs, ys); } -} -/** - * Helper function to transform an internal iterator into an owned vector. - * - * # Example: - * - * ~~~ - * let v = ~[1, 2, 3]; - * let v2 = do iter_to_vec |f| { v.each(|e| f(*e)) }; - * if v != v2 { fail!() } - * ~~~ - */ -#[inline(always)] -pub fn iter_to_vec<T>(pusher: &fn(it: &fn(T) -> bool)) -> ~[T] { - let mut v = ~[]; - let pushf = |e| {v.push(e); true}; - pusher(pushf); - v -} + #[test] + fn test_any() { + let xs = ~[1u, 2, 3, 4, 5]; + assert!(any(|&x: &uint| x > 2, |f| xs.each(f))); + assert!(!any(|&x: &uint| x > 5, |f| xs.each(f))); + } -#[test] -fn test_iter_to_vec() { - let v = ~[1, 2, 3]; - let v2 = do iter_to_vec |f| { v.each(|e| f(*e)) }; - if v != v2 { fail!() } + #[test] + fn test_all() { + assert!(all(|x: uint| x < 6, |f| uint::range(1, 6, f))); + assert!(!all(|x: uint| x < 5, |f| uint::range(1, 6, f))); + } } diff --git a/src/libcore/managed.rs b/src/libcore/managed.rs index 2bd3959acf4..debca1ead82 100644 --- a/src/libcore/managed.rs +++ b/src/libcore/managed.rs @@ -10,7 +10,7 @@ //! Operations on managed box types -use ptr; +use ptr::to_unsafe_ptr; #[cfg(notest)] use cmp::{Eq, Ord}; @@ -38,13 +38,15 @@ pub mod raw { #[inline(always)] pub fn ptr_eq<T>(a: @T, b: @T) -> bool { //! Determine if two shared boxes point to the same object - ptr::addr_of(&(*a)) == ptr::addr_of(&(*b)) + let a_ptr: *T = to_unsafe_ptr(&*a), b_ptr: *T = to_unsafe_ptr(&*b); + a_ptr == b_ptr } #[inline(always)] pub fn mut_ptr_eq<T>(a: @mut T, b: @mut T) -> bool { //! Determine if two mutable shared boxes point to the same object - ptr::addr_of(&(*a)) == ptr::addr_of(&(*b)) + let a_ptr: *T = to_unsafe_ptr(&*a), b_ptr: *T = to_unsafe_ptr(&*b); + a_ptr == b_ptr } #[cfg(notest)] diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index ada47fb597e..e687f482fa9 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -11,7 +11,6 @@ //! Operations and constants for `f32` use from_str; -use libc::c_int; use num::{Zero, One, strconv}; use prelude::*; @@ -102,8 +101,8 @@ delegate!( fn sinh(n: c_float) -> c_float = c_float_utils::sinh, fn tan(n: c_float) -> c_float = c_float_utils::tan, fn tanh(n: c_float) -> c_float = c_float_utils::tanh, - fn tgamma(n: c_float) -> c_float = c_float_utils::tgamma) - + fn tgamma(n: c_float) -> c_float = c_float_utils::tgamma +) // These are not defined inside consts:: for consistency with // the integer types @@ -368,154 +367,153 @@ impl Fractional for f32 { fn recip(&self) -> f32 { 1.0 / *self } } -impl Real for f32 { - /// Archimedes' constant +impl Algebraic for f32 { #[inline(always)] - fn pi() -> f32 { 3.14159265358979323846264338327950288 } - - /// 2.0 * pi - #[inline(always)] - fn two_pi() -> f32 { 6.28318530717958647692528676655900576 } - - /// pi / 2.0 - #[inline(always)] - fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 } - - /// pi / 3.0 - #[inline(always)] - fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 } + fn pow(&self, n: f32) -> f32 { pow(*self, n) } - /// pi / 4.0 #[inline(always)] - fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 } + fn sqrt(&self) -> f32 { sqrt(*self) } - /// pi / 6.0 #[inline(always)] - fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 } + fn rsqrt(&self) -> f32 { self.sqrt().recip() } - /// pi / 8.0 #[inline(always)] - fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 } + fn cbrt(&self) -> f32 { cbrt(*self) } - /// 1 .0/ pi #[inline(always)] - fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 } + fn hypot(&self, other: f32) -> f32 { hypot(*self, other) } +} - /// 2.0 / pi +impl Trigonometric for f32 { #[inline(always)] - fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 } + fn sin(&self) -> f32 { sin(*self) } - /// 2.0 / sqrt(pi) #[inline(always)] - fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 } + fn cos(&self) -> f32 { cos(*self) } - /// sqrt(2.0) #[inline(always)] - fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 } + fn tan(&self) -> f32 { tan(*self) } - /// 1.0 / sqrt(2.0) #[inline(always)] - fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 } + fn asin(&self) -> f32 { asin(*self) } - /// Euler's number #[inline(always)] - fn e() -> f32 { 2.71828182845904523536028747135266250 } + fn acos(&self) -> f32 { acos(*self) } - /// log2(e) #[inline(always)] - fn log2_e() -> f32 { 1.44269504088896340735992468100189214 } + fn atan(&self) -> f32 { atan(*self) } - /// log10(e) #[inline(always)] - fn log10_e() -> f32 { 0.434294481903251827651128918916605082 } + fn atan2(&self, other: f32) -> f32 { atan2(*self, other) } +} - /// log(2.0) +impl Exponential for f32 { #[inline(always)] - fn log_2() -> f32 { 0.693147180559945309417232121458176568 } + fn exp(&self) -> f32 { exp(*self) } - /// log(10.0) #[inline(always)] - fn log_10() -> f32 { 2.30258509299404568401799145468436421 } + fn exp2(&self) -> f32 { exp2(*self) } #[inline(always)] - fn pow(&self, n: f32) -> f32 { pow(*self, n) } + fn expm1(&self) -> f32 { expm1(*self) } #[inline(always)] - fn exp(&self) -> f32 { exp(*self) } + fn log(&self) -> f32 { ln(*self) } #[inline(always)] - fn exp2(&self) -> f32 { exp2(*self) } + fn log2(&self) -> f32 { log2(*self) } #[inline(always)] - fn expm1(&self) -> f32 { expm1(*self) } + fn log10(&self) -> f32 { log10(*self) } +} +impl Hyperbolic for f32 { #[inline(always)] - fn ldexp(&self, n: int) -> f32 { ldexp(*self, n as c_int) } + fn sinh(&self) -> f32 { sinh(*self) } #[inline(always)] - fn log(&self) -> f32 { ln(*self) } + fn cosh(&self) -> f32 { cosh(*self) } #[inline(always)] - fn log2(&self) -> f32 { log2(*self) } + fn tanh(&self) -> f32 { tanh(*self) } +} +impl Real for f32 { + /// Archimedes' constant #[inline(always)] - fn log10(&self) -> f32 { log10(*self) } + fn pi() -> f32 { 3.14159265358979323846264338327950288 } + /// 2.0 * pi #[inline(always)] - fn log_radix(&self) -> f32 { log_radix(*self) as f32 } + fn two_pi() -> f32 { 6.28318530717958647692528676655900576 } + /// pi / 2.0 #[inline(always)] - fn ilog_radix(&self) -> int { ilog_radix(*self) as int } + fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 } + /// pi / 3.0 #[inline(always)] - fn sqrt(&self) -> f32 { sqrt(*self) } + fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 } + /// pi / 4.0 #[inline(always)] - fn rsqrt(&self) -> f32 { self.sqrt().recip() } + fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 } + /// pi / 6.0 #[inline(always)] - fn cbrt(&self) -> f32 { cbrt(*self) } + fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 } - /// Converts to degrees, assuming the number is in radians + /// pi / 8.0 #[inline(always)] - fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::<f32>()) } + fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 } - /// Converts to radians, assuming the number is in degrees + /// 1 .0/ pi #[inline(always)] - fn to_radians(&self) -> f32 { *self * (Real::pi::<f32>() / 180.0) } + fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 } + /// 2.0 / pi #[inline(always)] - fn hypot(&self, other: f32) -> f32 { hypot(*self, other) } + fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 } + /// 2.0 / sqrt(pi) #[inline(always)] - fn sin(&self) -> f32 { sin(*self) } + fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 } + /// sqrt(2.0) #[inline(always)] - fn cos(&self) -> f32 { cos(*self) } + fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 } + /// 1.0 / sqrt(2.0) #[inline(always)] - fn tan(&self) -> f32 { tan(*self) } + fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 } + /// Euler's number #[inline(always)] - fn asin(&self) -> f32 { asin(*self) } + fn e() -> f32 { 2.71828182845904523536028747135266250 } + /// log2(e) #[inline(always)] - fn acos(&self) -> f32 { acos(*self) } + fn log2_e() -> f32 { 1.44269504088896340735992468100189214 } + /// log10(e) #[inline(always)] - fn atan(&self) -> f32 { atan(*self) } + fn log10_e() -> f32 { 0.434294481903251827651128918916605082 } + /// log(2.0) #[inline(always)] - fn atan2(&self, other: f32) -> f32 { atan2(*self, other) } + fn log_2() -> f32 { 0.693147180559945309417232121458176568 } + /// log(10.0) #[inline(always)] - fn sinh(&self) -> f32 { sinh(*self) } + fn log_10() -> f32 { 2.30258509299404568401799145468436421 } + /// Converts to degrees, assuming the number is in radians #[inline(always)] - fn cosh(&self) -> f32 { cosh(*self) } + fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::<f32>()) } + /// Converts to radians, assuming the number is in degrees #[inline(always)] - fn tanh(&self) -> f32 { tanh(*self) } + fn to_radians(&self) -> f32 { *self * (Real::pi::<f32>() / 180.0) } } impl Bounded for f32 { diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 07a29652e94..d00e6ae2c0d 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -109,7 +109,8 @@ delegate!( fn jn(i: c_int, n: c_double) -> c_double = c_double_utils::jn, fn y0(n: c_double) -> c_double = c_double_utils::y0, fn y1(n: c_double) -> c_double = c_double_utils::y1, - fn yn(i: c_int, n: c_double) -> c_double = c_double_utils::yn) + fn yn(i: c_int, n: c_double) -> c_double = c_double_utils::yn +) // FIXME (#1433): obtain these in a different way @@ -378,154 +379,153 @@ impl Fractional for f64 { fn recip(&self) -> f64 { 1.0 / *self } } -impl Real for f64 { - /// Archimedes' constant +impl Algebraic for f64 { #[inline(always)] - fn pi() -> f64 { 3.14159265358979323846264338327950288 } - - /// 2.0 * pi - #[inline(always)] - fn two_pi() -> f64 { 6.28318530717958647692528676655900576 } - - /// pi / 2.0 - #[inline(always)] - fn frac_pi_2() -> f64 { 1.57079632679489661923132169163975144 } + fn pow(&self, n: f64) -> f64 { pow(*self, n) } - /// pi / 3.0 #[inline(always)] - fn frac_pi_3() -> f64 { 1.04719755119659774615421446109316763 } - - /// pi / 4.0 - #[inline(always)] - fn frac_pi_4() -> f64 { 0.785398163397448309615660845819875721 } + fn sqrt(&self) -> f64 { sqrt(*self) } - /// pi / 6.0 #[inline(always)] - fn frac_pi_6() -> f64 { 0.52359877559829887307710723054658381 } + fn rsqrt(&self) -> f64 { self.sqrt().recip() } - /// pi / 8.0 #[inline(always)] - fn frac_pi_8() -> f64 { 0.39269908169872415480783042290993786 } + fn cbrt(&self) -> f64 { cbrt(*self) } - /// 1.0 / pi #[inline(always)] - fn frac_1_pi() -> f64 { 0.318309886183790671537767526745028724 } + fn hypot(&self, other: f64) -> f64 { hypot(*self, other) } +} - /// 2.0 / pi +impl Trigonometric for f64 { #[inline(always)] - fn frac_2_pi() -> f64 { 0.636619772367581343075535053490057448 } + fn sin(&self) -> f64 { sin(*self) } - /// 2.0 / sqrt(pi) #[inline(always)] - fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517 } + fn cos(&self) -> f64 { cos(*self) } - /// sqrt(2.0) #[inline(always)] - fn sqrt2() -> f64 { 1.41421356237309504880168872420969808 } + fn tan(&self) -> f64 { tan(*self) } - /// 1.0 / sqrt(2.0) #[inline(always)] - fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039 } + fn asin(&self) -> f64 { asin(*self) } - /// Euler's number #[inline(always)] - fn e() -> f64 { 2.71828182845904523536028747135266250 } + fn acos(&self) -> f64 { acos(*self) } - /// log2(e) #[inline(always)] - fn log2_e() -> f64 { 1.44269504088896340735992468100189214 } + fn atan(&self) -> f64 { atan(*self) } - /// log10(e) #[inline(always)] - fn log10_e() -> f64 { 0.434294481903251827651128918916605082 } + fn atan2(&self, other: f64) -> f64 { atan2(*self, other) } +} - /// log(2.0) +impl Exponential for f64 { #[inline(always)] - fn log_2() -> f64 { 0.693147180559945309417232121458176568 } + fn exp(&self) -> f64 { exp(*self) } - /// log(10.0) #[inline(always)] - fn log_10() -> f64 { 2.30258509299404568401799145468436421 } + fn exp2(&self) -> f64 { exp2(*self) } #[inline(always)] - fn pow(&self, n: f64) -> f64 { pow(*self, n) } + fn expm1(&self) -> f64 { expm1(*self) } #[inline(always)] - fn exp(&self) -> f64 { exp(*self) } + fn log(&self) -> f64 { ln(*self) } #[inline(always)] - fn exp2(&self) -> f64 { exp2(*self) } + fn log2(&self) -> f64 { log2(*self) } #[inline(always)] - fn expm1(&self) -> f64 { expm1(*self) } + fn log10(&self) -> f64 { log10(*self) } +} +impl Hyperbolic for f64 { #[inline(always)] - fn ldexp(&self, n: int) -> f64 { ldexp(*self, n as c_int) } + fn sinh(&self) -> f64 { sinh(*self) } #[inline(always)] - fn log(&self) -> f64 { ln(*self) } + fn cosh(&self) -> f64 { cosh(*self) } #[inline(always)] - fn log2(&self) -> f64 { log2(*self) } + fn tanh(&self) -> f64 { tanh(*self) } +} +impl Real for f64 { + /// Archimedes' constant #[inline(always)] - fn log10(&self) -> f64 { log10(*self) } + fn pi() -> f64 { 3.14159265358979323846264338327950288 } + /// 2.0 * pi #[inline(always)] - fn log_radix(&self) -> f64 { log_radix(*self) } + fn two_pi() -> f64 { 6.28318530717958647692528676655900576 } + /// pi / 2.0 #[inline(always)] - fn ilog_radix(&self) -> int { ilog_radix(*self) as int } + fn frac_pi_2() -> f64 { 1.57079632679489661923132169163975144 } + /// pi / 3.0 #[inline(always)] - fn sqrt(&self) -> f64 { sqrt(*self) } + fn frac_pi_3() -> f64 { 1.04719755119659774615421446109316763 } + /// pi / 4.0 #[inline(always)] - fn rsqrt(&self) -> f64 { self.sqrt().recip() } + fn frac_pi_4() -> f64 { 0.785398163397448309615660845819875721 } + /// pi / 6.0 #[inline(always)] - fn cbrt(&self) -> f64 { cbrt(*self) } + fn frac_pi_6() -> f64 { 0.52359877559829887307710723054658381 } - /// Converts to degrees, assuming the number is in radians + /// pi / 8.0 #[inline(always)] - fn to_degrees(&self) -> f64 { *self * (180.0 / Real::pi::<f64>()) } + fn frac_pi_8() -> f64 { 0.39269908169872415480783042290993786 } - /// Converts to radians, assuming the number is in degrees + /// 1.0 / pi #[inline(always)] - fn to_radians(&self) -> f64 { *self * (Real::pi::<f64>() / 180.0) } + fn frac_1_pi() -> f64 { 0.318309886183790671537767526745028724 } + /// 2.0 / pi #[inline(always)] - fn hypot(&self, other: f64) -> f64 { hypot(*self, other) } + fn frac_2_pi() -> f64 { 0.636619772367581343075535053490057448 } + /// 2.0 / sqrt(pi) #[inline(always)] - fn sin(&self) -> f64 { sin(*self) } + fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517 } + /// sqrt(2.0) #[inline(always)] - fn cos(&self) -> f64 { cos(*self) } + fn sqrt2() -> f64 { 1.41421356237309504880168872420969808 } + /// 1.0 / sqrt(2.0) #[inline(always)] - fn tan(&self) -> f64 { tan(*self) } + fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039 } + /// Euler's number #[inline(always)] - fn asin(&self) -> f64 { asin(*self) } + fn e() -> f64 { 2.71828182845904523536028747135266250 } + /// log2(e) #[inline(always)] - fn acos(&self) -> f64 { acos(*self) } + fn log2_e() -> f64 { 1.44269504088896340735992468100189214 } + /// log10(e) #[inline(always)] - fn atan(&self) -> f64 { atan(*self) } + fn log10_e() -> f64 { 0.434294481903251827651128918916605082 } + /// log(2.0) #[inline(always)] - fn atan2(&self, other: f64) -> f64 { atan2(*self, other) } + fn log_2() -> f64 { 0.693147180559945309417232121458176568 } + /// log(10.0) #[inline(always)] - fn sinh(&self) -> f64 { sinh(*self) } + fn log_10() -> f64 { 2.30258509299404568401799145468436421 } + /// Converts to degrees, assuming the number is in radians #[inline(always)] - fn cosh(&self) -> f64 { cosh(*self) } + fn to_degrees(&self) -> f64 { *self * (180.0 / Real::pi::<f64>()) } + /// Converts to radians, assuming the number is in degrees #[inline(always)] - fn tanh(&self) -> f64 { tanh(*self) } + fn to_radians(&self) -> f64 { *self * (Real::pi::<f64>() / 180.0) } } impl RealExt for f64 { diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs index ef0adee884b..3aa8848cdbe 100644 --- a/src/libcore/num/float.rs +++ b/src/libcore/num/float.rs @@ -453,154 +453,195 @@ impl Fractional for float { fn recip(&self) -> float { 1.0 / *self } } -impl Real for float { - /// Archimedes' constant - #[inline(always)] - fn pi() -> float { 3.14159265358979323846264338327950288 } - - /// 2.0 * pi - #[inline(always)] - fn two_pi() -> float { 6.28318530717958647692528676655900576 } - - /// pi / 2.0 - #[inline(always)] - fn frac_pi_2() -> float { 1.57079632679489661923132169163975144 } - - /// pi / 3.0 +impl Algebraic for float { #[inline(always)] - fn frac_pi_3() -> float { 1.04719755119659774615421446109316763 } + fn pow(&self, n: float) -> float { + (*self as f64).pow(n as f64) as float + } - /// pi / 4.0 #[inline(always)] - fn frac_pi_4() -> float { 0.785398163397448309615660845819875721 } + fn sqrt(&self) -> float { + (*self as f64).sqrt() as float + } - /// pi / 6.0 #[inline(always)] - fn frac_pi_6() -> float { 0.52359877559829887307710723054658381 } + fn rsqrt(&self) -> float { + (*self as f64).rsqrt() as float + } - /// pi / 8.0 #[inline(always)] - fn frac_pi_8() -> float { 0.39269908169872415480783042290993786 } + fn cbrt(&self) -> float { + (*self as f64).cbrt() as float + } - /// 1.0 / pi #[inline(always)] - fn frac_1_pi() -> float { 0.318309886183790671537767526745028724 } + fn hypot(&self, other: float) -> float { + (*self as f64).hypot(other as f64) as float + } +} - /// 2.0 / pi +impl Trigonometric for float { #[inline(always)] - fn frac_2_pi() -> float { 0.636619772367581343075535053490057448 } + fn sin(&self) -> float { + (*self as f64).sin() as float + } - /// 2 .0/ sqrt(pi) #[inline(always)] - fn frac_2_sqrtpi() -> float { 1.12837916709551257389615890312154517 } + fn cos(&self) -> float { + (*self as f64).cos() as float + } - /// sqrt(2.0) #[inline(always)] - fn sqrt2() -> float { 1.41421356237309504880168872420969808 } + fn tan(&self) -> float { + (*self as f64).tan() as float + } - /// 1.0 / sqrt(2.0) #[inline(always)] - fn frac_1_sqrt2() -> float { 0.707106781186547524400844362104849039 } + fn asin(&self) -> float { + (*self as f64).asin() as float + } - /// Euler's number #[inline(always)] - fn e() -> float { 2.71828182845904523536028747135266250 } + fn acos(&self) -> float { + (*self as f64).acos() as float + } - /// log2(e) #[inline(always)] - fn log2_e() -> float { 1.44269504088896340735992468100189214 } + fn atan(&self) -> float { + (*self as f64).atan() as float + } - /// log10(e) #[inline(always)] - fn log10_e() -> float { 0.434294481903251827651128918916605082 } + fn atan2(&self, other: float) -> float { + (*self as f64).atan2(other as f64) as float + } +} - /// log(2.0) +impl Exponential for float { #[inline(always)] - fn log_2() -> float { 0.693147180559945309417232121458176568 } + fn exp(&self) -> float { + (*self as f64).exp() as float + } - /// log(10.0) #[inline(always)] - fn log_10() -> float { 2.30258509299404568401799145468436421 } + fn exp2(&self) -> float { + (*self as f64).exp2() as float + } #[inline(always)] - fn pow(&self, n: float) -> float { pow(*self as f64, n as f64) as float } + fn expm1(&self) -> float { + (*self as f64).expm1() as float + } #[inline(always)] - fn exp(&self) -> float { exp(*self as f64) as float } + fn log(&self) -> float { + (*self as f64).log() as float + } #[inline(always)] - fn exp2(&self) -> float { exp2(*self as f64) as float } + fn log2(&self) -> float { + (*self as f64).log2() as float + } #[inline(always)] - fn expm1(&self) -> float { expm1(*self as f64) as float } + fn log10(&self) -> float { + (*self as f64).log10() as float + } +} +impl Hyperbolic for float { #[inline(always)] - fn ldexp(&self, n: int) -> float { ldexp(*self as f64, n as c_int) as float } + fn sinh(&self) -> float { + (*self as f64).sinh() as float + } #[inline(always)] - fn log(&self) -> float { ln(*self as f64) as float } + fn cosh(&self) -> float { + (*self as f64).cosh() as float + } #[inline(always)] - fn log2(&self) -> float { log2(*self as f64) as float } + fn tanh(&self) -> float { + (*self as f64).tanh() as float + } +} +impl Real for float { + /// Archimedes' constant #[inline(always)] - fn log10(&self) -> float { log10(*self as f64) as float } + fn pi() -> float { 3.14159265358979323846264338327950288 } + /// 2.0 * pi #[inline(always)] - fn log_radix(&self) -> float { log_radix(*self as f64) as float } + fn two_pi() -> float { 6.28318530717958647692528676655900576 } + /// pi / 2.0 #[inline(always)] - fn ilog_radix(&self) -> int { ilog_radix(*self as f64) as int } + fn frac_pi_2() -> float { 1.57079632679489661923132169163975144 } + /// pi / 3.0 #[inline(always)] - fn sqrt(&self) -> float { sqrt(*self) } + fn frac_pi_3() -> float { 1.04719755119659774615421446109316763 } + /// pi / 4.0 #[inline(always)] - fn rsqrt(&self) -> float { self.sqrt().recip() } + fn frac_pi_4() -> float { 0.785398163397448309615660845819875721 } + /// pi / 6.0 #[inline(always)] - fn cbrt(&self) -> float { cbrt(*self as f64) as float } + fn frac_pi_6() -> float { 0.52359877559829887307710723054658381 } - /// Converts to degrees, assuming the number is in radians + /// pi / 8.0 #[inline(always)] - fn to_degrees(&self) -> float { *self * (180.0 / Real::pi::<float>()) } + fn frac_pi_8() -> float { 0.39269908169872415480783042290993786 } - /// Converts to radians, assuming the number is in degrees + /// 1.0 / pi #[inline(always)] - fn to_radians(&self) -> float { *self * (Real::pi::<float>() / 180.0) } + fn frac_1_pi() -> float { 0.318309886183790671537767526745028724 } + /// 2.0 / pi #[inline(always)] - fn hypot(&self, other: float) -> float { hypot(*self as f64, other as f64) as float } + fn frac_2_pi() -> float { 0.636619772367581343075535053490057448 } + /// 2 .0/ sqrt(pi) #[inline(always)] - fn sin(&self) -> float { sin(*self) } + fn frac_2_sqrtpi() -> float { 1.12837916709551257389615890312154517 } + /// sqrt(2.0) #[inline(always)] - fn cos(&self) -> float { cos(*self) } + fn sqrt2() -> float { 1.41421356237309504880168872420969808 } + /// 1.0 / sqrt(2.0) #[inline(always)] - fn tan(&self) -> float { tan(*self) } + fn frac_1_sqrt2() -> float { 0.707106781186547524400844362104849039 } + /// Euler's number #[inline(always)] - fn asin(&self) -> float { asin(*self as f64) as float } + fn e() -> float { 2.71828182845904523536028747135266250 } + /// log2(e) #[inline(always)] - fn acos(&self) -> float { acos(*self as f64) as float } + fn log2_e() -> float { 1.44269504088896340735992468100189214 } + /// log10(e) #[inline(always)] - fn atan(&self) -> float { atan(*self) } + fn log10_e() -> float { 0.434294481903251827651128918916605082 } + /// log(2.0) #[inline(always)] - fn atan2(&self, other: float) -> float { atan2(*self as f64, other as f64) as float } + fn log_2() -> float { 0.693147180559945309417232121458176568 } + /// log(10.0) #[inline(always)] - fn sinh(&self) -> float { sinh(*self as f64) as float } + fn log_10() -> float { 2.30258509299404568401799145468436421 } + /// Converts to degrees, assuming the number is in radians #[inline(always)] - fn cosh(&self) -> float { cosh(*self as f64) as float } + fn to_degrees(&self) -> float { (*self as f64).to_degrees() as float } + /// Converts to radians, assuming the number is in degrees #[inline(always)] - fn tanh(&self) -> float { tanh(*self as f64) as float } + fn to_radians(&self) -> float { (*self as f64).to_radians() as float } } impl RealExt for float { diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs index 08df820a73d..ec38a32c039 100644 --- a/src/libcore/num/int-template.rs +++ b/src/libcore/num/int-template.rs @@ -406,11 +406,11 @@ impl Integer for T { /// Returns `true` if the number can be divided by `other` without leaving a remainder #[inline(always)] - fn divisible_by(&self, other: &T) -> bool { *self % *other == 0 } + fn is_multiple_of(&self, other: &T) -> bool { *self % *other == 0 } /// Returns `true` if the number is divisible by `2` #[inline(always)] - fn is_even(&self) -> bool { self.divisible_by(&2) } + fn is_even(&self) -> bool { self.is_multiple_of(&2) } /// Returns `true` if the number is not divisible by `2` #[inline(always)] @@ -683,6 +683,42 @@ mod tests { } #[test] + fn test_multiple_of() { + assert!((6 as T).is_multiple_of(&(6 as T))); + assert!((6 as T).is_multiple_of(&(3 as T))); + assert!((6 as T).is_multiple_of(&(1 as T))); + assert!((-8 as T).is_multiple_of(&(4 as T))); + assert!((8 as T).is_multiple_of(&(-1 as T))); + assert!((-8 as T).is_multiple_of(&(-2 as T))); + } + + #[test] + fn test_even() { + assert_eq!((-4 as T).is_even(), true); + assert_eq!((-3 as T).is_even(), false); + assert_eq!((-2 as T).is_even(), true); + assert_eq!((-1 as T).is_even(), false); + assert_eq!((0 as T).is_even(), true); + assert_eq!((1 as T).is_even(), false); + assert_eq!((2 as T).is_even(), true); + assert_eq!((3 as T).is_even(), false); + assert_eq!((4 as T).is_even(), true); + } + + #[test] + fn test_odd() { + assert_eq!((-4 as T).is_odd(), false); + assert_eq!((-3 as T).is_odd(), true); + assert_eq!((-2 as T).is_odd(), false); + assert_eq!((-1 as T).is_odd(), true); + assert_eq!((0 as T).is_odd(), false); + assert_eq!((1 as T).is_odd(), true); + assert_eq!((2 as T).is_odd(), false); + assert_eq!((3 as T).is_odd(), true); + assert_eq!((4 as T).is_odd(), false); + } + + #[test] fn test_bitcount() { assert_eq!((0b010101 as T).population_count(), 3); } diff --git a/src/libcore/num/num.rs b/src/libcore/num/num.rs index 0e2669a26b6..3e43ebfef12 100644 --- a/src/libcore/num/num.rs +++ b/src/libcore/num/num.rs @@ -85,7 +85,8 @@ pub trait Integer: Num fn gcd(&self, other: &Self) -> Self; fn lcm(&self, other: &Self) -> Self; - fn divisible_by(&self, other: &Self) -> bool; + + fn is_multiple_of(&self, other: &Self) -> bool; fn is_even(&self) -> bool; fn is_odd(&self) -> bool; } @@ -105,14 +106,47 @@ pub trait Fractional: Num fn recip(&self) -> Self; } +pub trait Algebraic { + fn pow(&self, n: Self) -> Self; + fn sqrt(&self) -> Self; + fn rsqrt(&self) -> Self; + fn cbrt(&self) -> Self; + fn hypot(&self, other: Self) -> Self; +} + +pub trait Trigonometric { + fn sin(&self) -> Self; + fn cos(&self) -> Self; + fn tan(&self) -> Self; + fn asin(&self) -> Self; + fn acos(&self) -> Self; + fn atan(&self) -> Self; + fn atan2(&self, other: Self) -> Self; +} + +pub trait Exponential { + fn exp(&self) -> Self; + fn exp2(&self) -> Self; + fn expm1(&self) -> Self; + fn log(&self) -> Self; + fn log2(&self) -> Self; + fn log10(&self) -> Self; +} + +pub trait Hyperbolic: Exponential { + fn sinh(&self) -> Self; + fn cosh(&self) -> Self; + fn tanh(&self) -> Self; +} + /// /// Defines constants and methods common to real numbers /// pub trait Real: Signed - + Fractional { - // FIXME (#5527): usages of `int` should be replaced with an associated - // integer type once these are implemented - + + Fractional + + Algebraic + + Trigonometric + + Hyperbolic { // Common Constants // FIXME (#5527): These should be associated constants fn pi() -> Self; @@ -133,41 +167,9 @@ pub trait Real: Signed fn log_2() -> Self; fn log_10() -> Self; - // Exponential functions - fn pow(&self, n: Self) -> Self; - fn exp(&self) -> Self; - fn exp2(&self) -> Self; - fn expm1(&self) -> Self; - fn ldexp(&self, n: int) -> Self; - fn log(&self) -> Self; - fn log2(&self) -> Self; - fn log10(&self) -> Self; - fn log_radix(&self) -> Self; - fn ilog_radix(&self) -> int; - fn sqrt(&self) -> Self; - fn rsqrt(&self) -> Self; - fn cbrt(&self) -> Self; - // Angular conversions fn to_degrees(&self) -> Self; fn to_radians(&self) -> Self; - - // Triganomic functions - fn hypot(&self, other: Self) -> Self; - fn sin(&self) -> Self; - fn cos(&self) -> Self; - fn tan(&self) -> Self; - - // Inverse triganomic functions - fn asin(&self) -> Self; - fn acos(&self) -> Self; - fn atan(&self) -> Self; - fn atan2(&self, other: Self) -> Self; - - // Hyperbolic triganomic functions - fn sinh(&self) -> Self; - fn cosh(&self) -> Self; - fn tanh(&self) -> Self; } /// diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs index af64660ad0c..3dfdd22c42d 100644 --- a/src/libcore/num/uint-template.rs +++ b/src/libcore/num/uint-template.rs @@ -238,11 +238,11 @@ impl Integer for T { /// Returns `true` if the number can be divided by `other` without leaving a remainder #[inline(always)] - fn divisible_by(&self, other: &T) -> bool { *self % *other == 0 } + fn is_multiple_of(&self, other: &T) -> bool { *self % *other == 0 } /// Returns `true` if the number is divisible by `2` #[inline(always)] - fn is_even(&self) -> bool { self.divisible_by(&2) } + fn is_even(&self) -> bool { self.is_multiple_of(&2) } /// Returns `true` if the number is not divisible by `2` #[inline(always)] @@ -416,6 +416,31 @@ mod tests { } #[test] + fn test_multiple_of() { + assert!((6 as T).is_multiple_of(&(6 as T))); + assert!((6 as T).is_multiple_of(&(3 as T))); + assert!((6 as T).is_multiple_of(&(1 as T))); + } + + #[test] + fn test_even() { + assert_eq!((0 as T).is_even(), true); + assert_eq!((1 as T).is_even(), false); + assert_eq!((2 as T).is_even(), true); + assert_eq!((3 as T).is_even(), false); + assert_eq!((4 as T).is_even(), true); + } + + #[test] + fn test_odd() { + assert_eq!((0 as T).is_odd(), false); + assert_eq!((1 as T).is_odd(), true); + assert_eq!((2 as T).is_odd(), false); + assert_eq!((3 as T).is_odd(), true); + assert_eq!((4 as T).is_odd(), false); + } + + #[test] fn test_bitwise() { assert_eq!(0b1110 as T, (0b1100 as T).bitor(&(0b1010 as T))); assert_eq!(0b1000 as T, (0b1100 as T).bitand(&(0b1010 as T))); diff --git a/src/libcore/num/uint-template/uint.rs b/src/libcore/num/uint-template/uint.rs index 6a8567451e6..de882f1ee7a 100644 --- a/src/libcore/num/uint-template/uint.rs +++ b/src/libcore/num/uint-template/uint.rs @@ -16,9 +16,9 @@ pub use self::inst::{ }; pub mod inst { - use sys; use iter; use num::{Primitive, BitCount}; + use sys; pub type T = uint; #[allow(non_camel_case_types)] diff --git a/src/libcore/old_iter.rs b/src/libcore/old_iter.rs new file mode 100644 index 00000000000..98b847c75b4 --- /dev/null +++ b/src/libcore/old_iter.rs @@ -0,0 +1,346 @@ +// Copyright 2012-2013 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/*! + +**Deprecated** iteration traits and common implementations. + +*/ + +use cmp::{Eq, Ord}; +use kinds::Copy; +use option::{None, Option, Some}; +use vec; + +/// A function used to initialize the elements of a sequence +pub type InitOp<'self,T> = &'self fn(uint) -> T; + +pub trait BaseIter<A> { + fn each(&self, blk: &fn(v: &A) -> bool); + fn size_hint(&self) -> Option<uint>; +} + +pub trait ReverseIter<A>: BaseIter<A> { + fn each_reverse(&self, blk: &fn(&A) -> bool); +} + +pub trait MutableIter<A>: BaseIter<A> { + fn each_mut(&mut self, blk: &fn(&mut A) -> bool); +} + +pub trait ExtendedIter<A> { + fn eachi(&self, blk: &fn(uint, v: &A) -> bool); + fn all(&self, blk: &fn(&A) -> bool) -> bool; + fn any(&self, blk: &fn(&A) -> bool) -> bool; + fn foldl<B>(&self, b0: B, blk: &fn(&B, &A) -> B) -> B; + fn position(&self, f: &fn(&A) -> bool) -> Option<uint>; + fn map_to_vec<B>(&self, op: &fn(&A) -> B) -> ~[B]; + fn flat_map_to_vec<B,IB: BaseIter<B>>(&self, op: &fn(&A) -> IB) -> ~[B]; +} + +pub trait ExtendedMutableIter<A> { + fn eachi_mut(&mut self, blk: &fn(uint, &mut A) -> bool); +} + +pub trait EqIter<A:Eq> { + fn contains(&self, x: &A) -> bool; + fn count(&self, x: &A) -> uint; +} + +pub trait CopyableIter<A:Copy> { + fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A]; + fn to_vec(&self) -> ~[A]; + fn find(&self, p: &fn(&A) -> bool) -> Option<A>; +} + +pub trait CopyableOrderedIter<A:Copy + Ord> { + fn min(&self) -> A; + fn max(&self) -> A; +} + +pub trait CopyableNonstrictIter<A:Copy> { + // Like "each", but copies out the value. If the receiver is mutated while + // iterating over it, the semantics must not be memory-unsafe but are + // otherwise undefined. + fn each_val(&const self, f: &fn(A) -> bool); +} + +// A trait for sequences that can be built by imperatively pushing elements +// onto them. +pub trait Buildable<A> { + /** + * Builds a buildable sequence by calling a provided function with + * an argument function that pushes an element onto the back of + * the sequence. + * This version takes an initial size for the sequence. + * + * # Arguments + * + * * size - A hint for an initial size of the sequence + * * builder - A function that will construct the sequence. It receives + * as an argument a function that will push an element + * onto the sequence being constructed. + */ + fn build_sized(size: uint, builder: &fn(push: &fn(A))) -> Self; +} + +#[inline(always)] +pub fn eachi<A,IA:BaseIter<A>>(self: &IA, blk: &fn(uint, &A) -> bool) { + let mut i = 0; + for self.each |a| { + if !blk(i, a) { break; } + i += 1; + } +} + +#[inline(always)] +pub fn all<A,IA:BaseIter<A>>(self: &IA, blk: &fn(&A) -> bool) -> bool { + for self.each |a| { + if !blk(a) { return false; } + } + return true; +} + +#[inline(always)] +pub fn any<A,IA:BaseIter<A>>(self: &IA, blk: &fn(&A) -> bool) -> bool { + for self.each |a| { + if blk(a) { return true; } + } + return false; +} + +#[inline(always)] +pub fn filter_to_vec<A:Copy,IA:BaseIter<A>>(self: &IA, + prd: &fn(&A) -> bool) + -> ~[A] { + do vec::build_sized_opt(self.size_hint()) |push| { + for self.each |a| { + if prd(a) { push(*a); } + } + } +} + +#[inline(always)] +pub fn map_to_vec<A,B,IA:BaseIter<A>>(self: &IA, op: &fn(&A) -> B) -> ~[B] { + do vec::build_sized_opt(self.size_hint()) |push| { + for self.each |a| { + push(op(a)); + } + } +} + +#[inline(always)] +pub fn flat_map_to_vec<A,B,IA:BaseIter<A>,IB:BaseIter<B>>(self: &IA, + op: &fn(&A) -> IB) + -> ~[B] { + do vec::build |push| { + for self.each |a| { + for op(a).each |&b| { + push(b); + } + } + } +} + +#[inline(always)] +pub fn foldl<A,B,IA:BaseIter<A>>(self: &IA, b0: B, blk: &fn(&B, &A) -> B) + -> B { + let mut b = b0; + for self.each |a| { + b = blk(&b, a); + } + b +} + +#[inline(always)] +pub fn to_vec<A:Copy,IA:BaseIter<A>>(self: &IA) -> ~[A] { + map_to_vec(self, |&x| x) +} + +#[inline(always)] +pub fn contains<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> bool { + for self.each |a| { + if *a == *x { return true; } + } + return false; +} + +#[inline(always)] +pub fn count<A:Eq,IA:BaseIter<A>>(self: &IA, x: &A) -> uint { + do foldl(self, 0) |count, value| { + if *value == *x { + *count + 1 + } else { + *count + } + } +} + +#[inline(always)] +pub fn position<A,IA:BaseIter<A>>(self: &IA, f: &fn(&A) -> bool) + -> Option<uint> { + let mut i = 0; + for self.each |a| { + if f(a) { return Some(i); } + i += 1; + } + return None; +} + +// note: 'rposition' would only make sense to provide with a bidirectional +// iter interface, such as would provide "reach" in addition to "each". As is, +// it would have to be implemented with foldr, which is too inefficient. + +#[inline(always)] +pub fn repeat(times: uint, blk: &fn() -> bool) { + let mut i = 0; + while i < times { + if !blk() { break } + i += 1; + } +} + +#[inline(always)] +pub fn min<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A { + match do foldl::<A,Option<A>,IA>(self, None) |a, b| { + match a { + &Some(ref a_) if *a_ < *b => { + *(a) + } + _ => Some(*b) + } + } { + Some(val) => val, + None => fail!(~"min called on empty iterator") + } +} + +#[inline(always)] +pub fn max<A:Copy + Ord,IA:BaseIter<A>>(self: &IA) -> A { + match do foldl::<A,Option<A>,IA>(self, None) |a, b| { + match a { + &Some(ref a_) if *a_ > *b => { + *(a) + } + _ => Some(*b) + } + } { + Some(val) => val, + None => fail!(~"max called on empty iterator") + } +} + +#[inline(always)] +pub fn find<A:Copy,IA:BaseIter<A>>(self: &IA, f: &fn(&A) -> bool) + -> Option<A> { + for self.each |i| { + if f(i) { return Some(*i) } + } + return None; +} + +// Some functions for just building + +/** + * Builds a sequence by calling a provided function with an argument + * function that pushes an element to the back of a sequence. + * + * # Arguments + * + * * builder - A function that will construct the sequence. It receives + * as an argument a function that will push an element + * onto the sequence being constructed. + */ +#[inline(always)] +pub fn build<A,B: Buildable<A>>(builder: &fn(push: &fn(A))) -> B { + Buildable::build_sized(4, builder) +} + +/** + * Builds a sequence by calling a provided function with an argument + * function that pushes an element to the back of the sequence. + * This version takes an initial size for the sequence. + * + * # Arguments + * + * * size - An option, maybe containing initial size of the sequence + * to reserve. + * * builder - A function that will construct the sequence. It receives + * as an argument a function that will push an element + * onto the sequence being constructed. + */ +#[inline(always)] +pub fn build_sized_opt<A,B: Buildable<A>>(size: Option<uint>, + builder: &fn(push: &fn(A))) -> B { + Buildable::build_sized(size.get_or_default(4), builder) +} + +// Functions that combine iteration and building + +/// Applies a function to each element of an iterable and returns the results +/// in a sequence built via `BU`. See also `map_to_vec`. +#[inline(always)] +pub fn map<T,IT: BaseIter<T>,U,BU: Buildable<U>>(v: &IT, f: &fn(&T) -> U) + -> BU { + do build_sized_opt(v.size_hint()) |push| { + for v.each() |elem| { + push(f(elem)); + } + } +} + +/** + * Creates and initializes a generic sequence from a function. + * + * Creates a generic sequence of size `n_elts` and initializes the elements + * to the value returned by the function `op`. + */ +#[inline(always)] +pub fn from_fn<T,BT: Buildable<T>>(n_elts: uint, op: InitOp<T>) -> BT { + do Buildable::build_sized(n_elts) |push| { + let mut i: uint = 0u; + while i < n_elts { push(op(i)); i += 1u; } + } +} + +/** + * Creates and initializes a generic sequence with some elements. + * + * Creates an immutable vector of size `n_elts` and initializes the elements + * to the value `t`. + */ +#[inline(always)] +pub fn from_elem<T:Copy,BT:Buildable<T>>(n_elts: uint, t: T) -> BT { + do Buildable::build_sized(n_elts) |push| { + let mut i: uint = 0; + while i < n_elts { push(t); i += 1; } + } +} + +/// Appends two generic sequences. +#[inline(always)] +pub fn append<T:Copy,IT:BaseIter<T>,BT:Buildable<T>>(lhs: &IT, rhs: &IT) + -> BT { + let size_opt = lhs.size_hint().chain_ref( + |sz1| rhs.size_hint().map(|sz2| *sz1+*sz2)); + do build_sized_opt(size_opt) |push| { + for lhs.each |x| { push(*x); } + for rhs.each |x| { push(*x); } + } +} + +/// Copies a generic sequence, possibly converting it to a different +/// type of sequence. +#[inline(always)] +pub fn copy_seq<T:Copy,IT:BaseIter<T>,BT:Buildable<T>>(v: &IT) -> BT { + do build_sized_opt(v.size_hint()) |push| { + for v.each |x| { push(*x); } + } +} diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 9b7276879c1..17192b4257b 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -46,10 +46,9 @@ use ops::Add; use kinds::Copy; use util; use num::Zero; -use iter::{BaseIter, MutableIter, ExtendedIter}; -use iter; +use old_iter::{BaseIter, MutableIter, ExtendedIter}; +use old_iter; -#[cfg(test)] use ptr; #[cfg(test)] use str; /// The option type @@ -140,26 +139,26 @@ impl<T> MutableIter<T> for Option<T> { impl<A> ExtendedIter<A> for Option<A> { pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { - iter::eachi(self, blk) + old_iter::eachi(self, blk) } pub fn all(&self, blk: &fn(&A) -> bool) -> bool { - iter::all(self, blk) + old_iter::all(self, blk) } pub fn any(&self, blk: &fn(&A) -> bool) -> bool { - iter::any(self, blk) + old_iter::any(self, blk) } pub fn foldl<B>(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { - iter::foldl(self, b0, blk) + old_iter::foldl(self, b0, blk) } pub fn position(&self, f: &fn(&A) -> bool) -> Option<uint> { - iter::position(self, f) + old_iter::position(self, f) } fn map_to_vec<B>(&self, op: &fn(&A) -> B) -> ~[B] { - iter::map_to_vec(self, op) + old_iter::map_to_vec(self, op) } fn flat_map_to_vec<B,IB:BaseIter<B>>(&self, op: &fn(&A) -> IB) -> ~[B] { - iter::flat_map_to_vec(self, op) + old_iter::flat_map_to_vec(self, op) } } @@ -481,12 +480,14 @@ pub impl<T:Copy + Zero> Option<T> { #[test] fn test_unwrap_ptr() { - let x = ~0; - let addr_x = ptr::addr_of(&(*x)); - let opt = Some(x); - let y = opt.unwrap(); - let addr_y = ptr::addr_of(&(*y)); - assert!(addr_x == addr_y); + unsafe { + let x = ~0; + let addr_x: *int = ::cast::transmute(&*x); + let opt = Some(x); + let y = opt.unwrap(); + let addr_y: *int = ::cast::transmute(&*y); + assert!(addr_x == addr_y); + } } #[test] diff --git a/src/libcore/os.rs b/src/libcore/os.rs index b81209d35cf..f1962eeaa23 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -643,20 +643,22 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool { /// Returns true iff creation /// succeeded. Also creates all intermediate subdirectories /// if they don't already exist, giving all of them the same mode. + +// tjc: if directory exists but with different permissions, +// should we return false? pub fn mkdir_recursive(p: &Path, mode: c_int) -> bool { if path_is_dir(p) { return true; } - let parent = p.dir_path(); - debug!("mkdir_recursive: parent = %s", - parent.to_str()); - if parent.to_str() == ~"." - || parent.to_str() == ~"/" { // !!! + else if p.components.is_empty() { + return false; + } + else if p.components.len() == 1 { // No parent directories to create - path_is_dir(&parent) && make_dir(p, mode) + path_is_dir(p) || make_dir(p, mode) } else { - mkdir_recursive(&parent, mode) && make_dir(p, mode) + mkdir_recursive(&p.pop(), mode) && make_dir(p, mode) } } @@ -1267,6 +1269,8 @@ mod tests { use run; use str; use vec; + use libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; + #[test] pub fn last_os_error() { @@ -1490,16 +1494,16 @@ mod tests { } #[test] - fn recursive_mkdir_ok() { - use libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; + fn recursive_mkdir_slash() { + let path = Path("/"); + assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32)); + } - let root = os::tmpdir(); - let path = "xy/z/zy"; - let nested = root.push(path); - assert!(os::mkdir_recursive(&nested, (S_IRUSR | S_IWUSR | S_IXUSR) as i32)); - assert!(os::path_is_dir(&root.push("xy"))); - assert!(os::path_is_dir(&root.push("xy/z"))); - assert!(os::path_is_dir(&nested)); + #[test] + fn recursive_mkdir_empty() { + let path = Path(""); + assert!(!os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32)); } + // More recursive_mkdir tests are in std::tempfile } diff --git a/src/libcore/path.rs b/src/libcore/path.rs index edc61299af9..a87fd90f4e2 100644 --- a/src/libcore/path.rs +++ b/src/libcore/path.rs @@ -21,6 +21,11 @@ use str; use to_str::ToStr; use ascii::{AsciiCast, AsciiStr}; +#[cfg(windows)] +pub use Path = self::WindowsPath; +#[cfg(unix)] +pub use Path = self::PosixPath; + #[deriving(Clone, Eq)] pub struct WindowsPath { host: Option<~str>, @@ -44,50 +49,74 @@ pub fn PosixPath(s: &str) -> PosixPath { } pub trait GenericPath { + /// Converts a string to a Path fn from_str(&str) -> Self; + /// Returns the directory component of `self`, as a string fn dirname(&self) -> ~str; + /// Returns the file component of `self`, as a string option. + /// Returns None if `self` names a directory. fn filename(&self) -> Option<~str>; + /// Returns the stem of the file component of `self`, as a string option. + /// The stem is the slice of a filename starting at 0 and ending just before + /// the last '.' in the name. + /// Returns None if `self` names a directory. fn filestem(&self) -> Option<~str>; + /// Returns the type of the file component of `self`, as a string option. + /// The file type is the slice of a filename starting just after the last + /// '.' in the name and ending at the last index in the filename. + /// Returns None if `self` names a directory. fn filetype(&self) -> Option<~str>; + /// Returns a new path consisting of `self` with the parent directory component replaced + /// with the given string. fn with_dirname(&self, (&str)) -> Self; + /// Returns a new path consisting of `self` with the file component replaced + /// with the given string. fn with_filename(&self, (&str)) -> Self; + /// Returns a new path consisting of `self` with the file stem replaced + /// with the given string. fn with_filestem(&self, (&str)) -> Self; + /// Returns a new path consisting of `self` with the file type replaced + /// with the given string. fn with_filetype(&self, (&str)) -> Self; + /// Returns the directory component of `self`, as a new path. + /// If `self` has no parent, returns `self`. fn dir_path(&self) -> Self; + /// Returns the file component of `self`, as a new path. + /// If `self` names a directory, returns the empty path. fn file_path(&self) -> Self; + /// Returns a new Path whose parent directory is `self` and whose + /// file component is the given string. fn push(&self, (&str)) -> Self; + /// Returns a new Path consisting of the given path, made relative to `self`. fn push_rel(&self, (&Self)) -> Self; + /// Returns a new Path consisting of the path given by the given vector + /// of strings, relative to `self`. fn push_many(&self, (&[~str])) -> Self; + /// Identical to `dir_path` except in the case where `self` has only one + /// component. In this case, `pop` returns the empty path. fn pop(&self) -> Self; + /// The same as `push_rel`, except that the directory argument must not + /// contain directory separators in any of its components. fn unsafe_join(&self, (&Self)) -> Self; + /// On Unix, always returns false. On Windows, returns true iff `self`'s + /// file stem is one of: `con` `aux` `com1` `com2` `com3` `com4` + /// `lpt1` `lpt2` `lpt3` `prn` `nul` fn is_restricted(&self) -> bool; + /// Returns a new path that names the same file as `self`, without containing + /// any '.', '..', or empty components. On Windows, uppercases the drive letter + /// as well. fn normalize(&self) -> Self; + /// Returns `true` if `self` is an absolute path. fn is_absolute(&self) -> bool; } -#[cfg(windows)] -pub type Path = WindowsPath; - -#[cfg(windows)] -pub fn Path(s: &str) -> Path { - WindowsPath(s) -} - -#[cfg(unix)] -pub type Path = PosixPath; - -#[cfg(unix)] -pub fn Path(s: &str) -> Path { - PosixPath(s) -} - #[cfg(target_os = "linux")] #[cfg(target_os = "android")] mod stat { diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 2ec3afca612..95b24d20a4b 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -82,7 +82,7 @@ bounded and unbounded protocols allows for less code duplication. */ -use cast::{forget, reinterpret_cast, transmute}; +use cast::{forget, transmute, transmute_copy}; use either::{Either, Left, Right}; use kinds::Owned; use libc; @@ -95,7 +95,7 @@ use vec; static SPIN_COUNT: uint = 0; macro_rules! move_it ( - { $x:expr } => ( unsafe { let y = *ptr::addr_of(&($x)); y } ) + { $x:expr } => ( unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } ) ) #[deriving(Eq)] @@ -131,7 +131,7 @@ pub struct PacketHeader { mut state: State, mut blocked_task: *rust_task, - // This is a reinterpret_cast of a ~buffer, that can also be cast + // This is a transmute_copy of a ~buffer, that can also be cast // to a buffer_header if need be. mut buffer: *libc::c_void, } @@ -170,12 +170,12 @@ pub impl PacketHeader { // thing. You'll proobably want to forget them when you're done. unsafe fn buf_header(&self) -> ~BufferHeader { assert!(self.buffer.is_not_null()); - reinterpret_cast(&self.buffer) + transmute_copy(&self.buffer) } fn set_buffer<T:Owned>(&self, b: ~Buffer<T>) { unsafe { - self.buffer = reinterpret_cast(&b); + self.buffer = transmute_copy(&b); } } } @@ -211,14 +211,14 @@ fn unibuffer<T>() -> ~Buffer<Packet<T>> { }; unsafe { - b.data.header.buffer = reinterpret_cast(&b); + b.data.header.buffer = transmute_copy(&b); } b } pub fn packet<T>() -> *Packet<T> { let b = unibuffer(); - let p = ptr::addr_of(&(b.data)); + let p = ptr::to_unsafe_ptr(&(b.data)); // We'll take over memory management from here. unsafe { forget(b) } p @@ -229,7 +229,7 @@ pub fn entangle_buffer<T:Owned,Tstart:Owned>( init: &fn(*libc::c_void, x: &T) -> *Packet<Tstart>) -> (SendPacketBuffered<Tstart, T>, RecvPacketBuffered<Tstart, T>) { - let p = init(unsafe { reinterpret_cast(&buffer) }, &buffer.data); + let p = init(unsafe { transmute_copy(&buffer) }, &buffer.data); unsafe { forget(buffer) } (SendPacketBuffered(p), RecvPacketBuffered(p)) } @@ -305,7 +305,7 @@ impl<T> ::ops::Drop for BufferResource<T> { fn finalize(&self) { unsafe { let b = move_it!(self.buffer); - //let p = ptr::addr_of(*b); + //let p = ptr::to_unsafe_ptr(*b); //error!("drop %?", p); let old_count = intrinsics::atomic_xsub_rel(&mut b.header.ref_count, 1); //let old_count = atomic_xchng_rel(b.header.ref_count, 0); @@ -322,7 +322,7 @@ impl<T> ::ops::Drop for BufferResource<T> { } fn BufferResource<T>(b: ~Buffer<T>) -> BufferResource<T> { - //let p = ptr::addr_of(*b); + //let p = ptr::to_unsafe_ptr(*b); //error!("take %?", p); unsafe { intrinsics::atomic_xadd_acq(&mut b.header.ref_count, 1) }; @@ -336,7 +336,7 @@ pub fn send<T,Tbuffer>(p: SendPacketBuffered<T,Tbuffer>, payload: T) -> bool { let header = p.header(); let p_ = p.unwrap(); let p = unsafe { &*p_ }; - assert!(ptr::addr_of(&(p.header)) == header); + assert!(ptr::to_unsafe_ptr(&(p.header)) == header); assert!(p.payload.is_none()); p.payload = Some(payload); let old_state = swap_state_rel(&mut p.header.state, Full); @@ -356,7 +356,7 @@ pub fn send<T,Tbuffer>(p: SendPacketBuffered<T,Tbuffer>, payload: T) -> bool { unsafe { rustrt::task_signal_event( old_task, - ptr::addr_of(&(p.header)) as *libc::c_void); + ptr::to_unsafe_ptr(&(p.header)) as *libc::c_void); rustrt::rust_task_deref(old_task); } } @@ -521,7 +521,7 @@ fn sender_terminate<T:Owned>(p: *Packet<T>) { unsafe { rustrt::task_signal_event( old_task, - ptr::addr_of(&(p.header)) as *libc::c_void); + ptr::to_unsafe_ptr(&(p.header)) as *libc::c_void); rustrt::rust_task_deref(old_task); } } @@ -665,7 +665,7 @@ pub fn SendPacketBuffered<T,Tbuffer>(p: *Packet<T>) p: Some(p), buffer: unsafe { Some(BufferResource( - get_buffer(ptr::addr_of(&((*p).header))))) + get_buffer(ptr::to_unsafe_ptr(&((*p).header))))) } } } @@ -681,7 +681,7 @@ pub impl<T,Tbuffer> SendPacketBuffered<T,Tbuffer> { match self.p { Some(packet) => unsafe { let packet = &*packet; - let header = ptr::addr_of(&(packet.header)); + let header = ptr::to_unsafe_ptr(&(packet.header)); //forget(packet); header }, @@ -747,7 +747,7 @@ impl<T:Owned,Tbuffer:Owned> Selectable for RecvPacketBuffered<T, Tbuffer> { match self.p { Some(packet) => unsafe { let packet = &*packet; - let header = ptr::addr_of(&(packet.header)); + let header = ptr::to_unsafe_ptr(&(packet.header)); //forget(packet); header }, @@ -763,7 +763,7 @@ pub fn RecvPacketBuffered<T,Tbuffer>(p: *Packet<T>) p: Some(p), buffer: unsafe { Some(BufferResource( - get_buffer(ptr::addr_of(&((*p).header))))) + get_buffer(ptr::to_unsafe_ptr(&((*p).header))))) } } } @@ -885,9 +885,9 @@ mod test { #[test] fn test_oneshot() { - let (c, p) = oneshot::init(); + let (p, c) = oneshot(); - oneshot::client::send(c, ()); + c.send(()); recv_one(p) } diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 7e41f1b5b34..9a2e480ce6e 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -34,12 +34,14 @@ pub use clone::Clone; pub use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; pub use container::{Container, Mutable, Map, Set}; pub use hash::Hash; -pub use iter::{BaseIter, ReverseIter, MutableIter, ExtendedIter, EqIter}; -pub use iter::{CopyableIter, CopyableOrderedIter, CopyableNonstrictIter}; -pub use iter::{Times, ExtendedMutableIter}; +pub use old_iter::{BaseIter, ReverseIter, MutableIter, ExtendedIter, EqIter}; +pub use old_iter::{CopyableIter, CopyableOrderedIter, CopyableNonstrictIter}; +pub use old_iter::{ExtendedMutableIter}; +pub use iter::Times; pub use num::{Num, NumCast}; -pub use num::{Orderable, Signed, Unsigned, Integer}; -pub use num::{Round, Fractional, Real, RealExt}; +pub use num::{Orderable, Signed, Unsigned, Round}; +pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic}; +pub use num::{Integer, Fractional, Real, RealExt}; pub use num::{Bitwise, BitCount, Bounded}; pub use num::{Primitive, Int, Float}; pub use path::GenericPath; @@ -79,6 +81,7 @@ pub use i8; pub use int; pub use io; pub use iter; +pub use old_iter; pub use libc; pub use num; pub use ops; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 94474c3c02d..86b36834bbd 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -39,17 +39,6 @@ pub mod libc_ { } } -pub mod rusti { - #[abi = "rust-intrinsic"] - pub extern "rust-intrinsic" { - fn addr_of<T>(&&val: T) -> *T; - } -} - -/// Get an unsafe pointer to a value -#[inline(always)] -pub fn addr_of<T>(val: &T) -> *T { unsafe { rusti::addr_of(*val) } } - /// Calculate the offset from a pointer #[inline(always)] pub fn offset<T>(ptr: *T, count: uint) -> *T { @@ -130,7 +119,7 @@ pub unsafe fn set_memory<T>(dst: *mut T, c: int, count: uint) { /** Transform a region pointer - &T - to an unsafe pointer - *T. This is safe, but is implemented with an unsafe block due to - reinterpret_cast. + transmute. */ #[inline(always)] pub fn to_unsafe_ptr<T>(thing: &T) -> *T { @@ -140,7 +129,7 @@ pub fn to_unsafe_ptr<T>(thing: &T) -> *T { /** Transform a const region pointer - &const T - to a const unsafe pointer - *const T. This is safe, but is implemented with an unsafe block due to - reinterpret_cast. + transmute. */ #[inline(always)] pub fn to_const_unsafe_ptr<T>(thing: &const T) -> *const T { @@ -150,7 +139,7 @@ pub fn to_const_unsafe_ptr<T>(thing: &const T) -> *const T { /** Transform a mutable region pointer - &mut T - to a mutable unsafe pointer - *mut T. This is safe, but is implemented with an unsafe block due to - reinterpret_cast. + transmute. */ #[inline(always)] pub fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T { @@ -160,7 +149,7 @@ pub fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T { /** Cast a region pointer - &T - to a uint. This is safe, but is implemented with an unsafe block due to - reinterpret_cast. + transmute. (I couldn't think of a cutesy name for this one.) */ diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs index 52944391851..9fa099cabbf 100644 --- a/src/libcore/rand.rs +++ b/src/libcore/rand.rs @@ -53,6 +53,7 @@ pub trait Rand { } impl Rand for int { + #[inline] fn rand<R: Rng>(rng: &R) -> int { if int::bits == 32 { rng.next() as int @@ -63,30 +64,35 @@ impl Rand for int { } impl Rand for i8 { + #[inline] fn rand<R: Rng>(rng: &R) -> i8 { rng.next() as i8 } } impl Rand for i16 { + #[inline] fn rand<R: Rng>(rng: &R) -> i16 { rng.next() as i16 } } impl Rand for i32 { + #[inline] fn rand<R: Rng>(rng: &R) -> i32 { rng.next() as i32 } } impl Rand for i64 { + #[inline] fn rand<R: Rng>(rng: &R) -> i64 { (rng.next() as i64 << 32) | rng.next() as i64 } } impl Rand for uint { + #[inline] fn rand<R: Rng>(rng: &R) -> uint { if uint::bits == 32 { rng.next() as uint @@ -97,36 +103,42 @@ impl Rand for uint { } impl Rand for u8 { + #[inline] fn rand<R: Rng>(rng: &R) -> u8 { rng.next() as u8 } } impl Rand for u16 { + #[inline] fn rand<R: Rng>(rng: &R) -> u16 { rng.next() as u16 } } impl Rand for u32 { + #[inline] fn rand<R: Rng>(rng: &R) -> u32 { rng.next() } } impl Rand for u64 { + #[inline] fn rand<R: Rng>(rng: &R) -> u64 { (rng.next() as u64 << 32) | rng.next() as u64 } } impl Rand for float { + #[inline] fn rand<R: Rng>(rng: &R) -> float { rng.gen::<f64>() as float } } impl Rand for f32 { + #[inline] fn rand<R: Rng>(rng: &R) -> f32 { rng.gen::<f64>() as f32 } @@ -134,6 +146,7 @@ impl Rand for f32 { static scale : f64 = (u32::max_value as f64) + 1.0f64; impl Rand for f64 { + #[inline] fn rand<R: Rng>(rng: &R) -> f64 { let u1 = rng.next() as f64; let u2 = rng.next() as f64; @@ -144,12 +157,14 @@ impl Rand for f64 { } impl Rand for char { + #[inline] fn rand<R: Rng>(rng: &R) -> char { rng.next() as char } } impl Rand for bool { + #[inline] fn rand<R: Rng>(rng: &R) -> bool { rng.next() & 1u32 == 1u32 } @@ -163,6 +178,7 @@ macro_rules! tuple_impl { $( $tyvar : Rand ),* > Rand for ( $( $tyvar ),* , ) { + #[inline] fn rand<R: Rng>(_rng: &R) -> ( $( $tyvar ),* , ) { ( // use the $tyvar's to get the appropriate number of @@ -177,7 +193,10 @@ macro_rules! tuple_impl { } } -impl Rand for () { fn rand<R: Rng>(_: &R) -> () { () } } +impl Rand for () { + #[inline] + fn rand<R: Rng>(_: &R) -> () { () } +} tuple_impl!{A} tuple_impl!{A, B} tuple_impl!{A, B, C} @@ -190,6 +209,7 @@ tuple_impl!{A, B, C, D, E, F, G, H, I} tuple_impl!{A, B, C, D, E, F, G, H, I, J} impl<T:Rand> Rand for Option<T> { + #[inline] fn rand<R: Rng>(rng: &R) -> Option<T> { if rng.gen() { Some(rng.gen()) @@ -200,27 +220,22 @@ impl<T:Rand> Rand for Option<T> { } impl<T: Rand> Rand for ~T { + #[inline] fn rand<R: Rng>(rng: &R) -> ~T { ~rng.gen() } } impl<T: Rand> Rand for @T { + #[inline] fn rand<R: Rng>(rng: &R) -> @T { @rng.gen() } } -#[allow(non_camel_case_types)] // runtime type -pub enum rust_rng {} - #[abi = "cdecl"] pub mod rustrt { use libc::size_t; - use super::rust_rng; pub extern { unsafe fn rand_seed_size() -> size_t; unsafe fn rand_gen_seed(buf: *mut u8, sz: size_t); - unsafe fn rand_new_seeded(buf: *u8, sz: size_t) -> *rust_rng; - unsafe fn rand_next(rng: *rust_rng) -> u32; - unsafe fn rand_free(rng: *rust_rng); } } @@ -420,6 +435,7 @@ pub trait RngUtil { /// Extension methods for random number generators impl<R: Rng> RngUtil for R { /// Return a random value for a Rand type + #[inline(always)] fn gen<T: Rand>(&self) -> T { Rand::rand(self) } @@ -566,66 +582,183 @@ pub fn rng() -> IsaacRng { IsaacRng::new() } -pub struct IsaacRng { - priv rng: *rust_rng, -} +static RAND_SIZE_LEN: u32 = 8; +static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN; -impl Drop for IsaacRng { - fn finalize(&self) { - unsafe { - rustrt::rand_free(self.rng); - } - } +/// A random number generator that uses the [ISAAC +/// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29). +pub struct IsaacRng { + priv mut cnt: u32, + priv mut rsl: [u32, .. RAND_SIZE], + priv mut mem: [u32, .. RAND_SIZE], + priv mut a: u32, + priv mut b: u32, + priv mut c: u32 } pub impl IsaacRng { - priv fn from_rust_rng(rng: *rust_rng) -> IsaacRng { - IsaacRng { - rng: rng - } - } - - /// Create an ISAAC random number generator with a system specified seed + /// Create an ISAAC random number generator with a random seed. fn new() -> IsaacRng { IsaacRng::new_seeded(seed()) } - /** - * Create a random number generator using the specified seed. A generator - * constructed with a given seed will generate the same sequence of values as - * all other generators constructed with the same seed. The seed may be any - * length. - */ + /// Create an ISAAC random number generator with a seed. This can be any + /// length, although the maximum number of bytes used is 1024 and any more + /// will be silently ignored. A generator constructed with a given seed + /// will generate the same sequence of values as all other generators + /// constructed with the same seed. fn new_seeded(seed: &[u8]) -> IsaacRng { - unsafe { - do vec::as_imm_buf(seed) |p, sz| { - IsaacRng::from_rust_rng(rustrt::rand_new_seeded(p, sz as size_t)) + let mut rng = IsaacRng { + cnt: 0, + rsl: [0, .. RAND_SIZE], + mem: [0, .. RAND_SIZE], + a: 0, b: 0, c: 0 + }; + + let array_size = sys::size_of_val(&rng.rsl); + let copy_length = cmp::min(array_size, seed.len()); + + // manually create a &mut [u8] slice of randrsl to copy into. + let dest = unsafe { cast::transmute((&mut rng.rsl, array_size)) }; + vec::bytes::copy_memory(dest, seed, copy_length); + rng.init(true); + rng + } + + /// Create an ISAAC random number generator using the default + /// fixed seed. + fn new_unseeded() -> IsaacRng { + let mut rng = IsaacRng { + cnt: 0, + rsl: [0, .. RAND_SIZE], + mem: [0, .. RAND_SIZE], + a: 0, b: 0, c: 0 + }; + rng.init(false); + rng + } + + /// Initialises `self`. If `use_rsl` is true, then use the current value + /// of `rsl` as a seed, otherwise construct one algorithmically (not + /// randomly). + priv fn init(&self, use_rsl: bool) { + macro_rules! init_mut_many ( + ($( $var:ident ),* = $val:expr ) => { + let mut $( $var = $val ),*; + } + ); + init_mut_many!(a, b, c, d, e, f, g, h = 0x9e3779b9); + + + macro_rules! mix( + () => {{ + a^=b<<11; d+=a; b+=c; + b^=c>>2; e+=b; c+=d; + c^=d<<8; f+=c; d+=e; + d^=e>>16; g+=d; e+=f; + e^=f<<10; h+=e; f+=g; + f^=g>>4; a+=f; g+=h; + g^=h<<8; b+=g; h+=a; + h^=a>>9; c+=h; a+=b; + }} + ); + + for 4.times { mix!(); } + + if use_rsl { + macro_rules! memloop ( + ($arr:expr) => {{ + for u32::range_step(0, RAND_SIZE, 8) |i| { + a+=$arr[i ]; b+=$arr[i+1]; + c+=$arr[i+2]; d+=$arr[i+3]; + e+=$arr[i+4]; f+=$arr[i+5]; + g+=$arr[i+6]; h+=$arr[i+7]; + mix!(); + self.mem[i ]=a; self.mem[i+1]=b; + self.mem[i+2]=c; self.mem[i+3]=d; + self.mem[i+4]=e; self.mem[i+5]=f; + self.mem[i+6]=g; self.mem[i+7]=h; + } + }} + ); + + memloop!(self.rsl); + memloop!(self.mem); + } else { + for u32::range_step(0, RAND_SIZE, 8) |i| { + mix!(); + self.mem[i ]=a; self.mem[i+1]=b; + self.mem[i+2]=c; self.mem[i+3]=d; + self.mem[i+4]=e; self.mem[i+5]=f; + self.mem[i+6]=g; self.mem[i+7]=h; } } + + self.isaac(); } -} -impl Rng for IsaacRng { - pub fn next(&self) -> u32 { - unsafe { - return rustrt::rand_next(self.rng); + /// Refills the output buffer (`self.rsl`) + #[inline] + priv fn isaac(&self) { + self.c += 1; + // abbreviations + let mut a = self.a, b = self.b + self.c; + let mem = &mut self.mem; + let rsl = &mut self.rsl; + + static midpoint: uint = RAND_SIZE as uint / 2; + + macro_rules! ind (($x:expr) => { mem[($x >> 2) & (RAND_SIZE - 1)] }); + macro_rules! rngstep( + ($j:expr, $shift:expr) => {{ + let base = base + $j; + let mix = if $shift < 0 { + a >> -$shift as uint + } else { + a << $shift as uint + }; + + let x = mem[base + mr_offset]; + a = (a ^ mix) + mem[base + m2_offset]; + let y = ind!(x) + a + b; + mem[base + mr_offset] = y; + + b = ind!(y >> RAND_SIZE_LEN) + x; + rsl[base + mr_offset] = b; + }} + ); + + for [(0, midpoint), (midpoint, 0)].each |&(mr_offset, m2_offset)| { + for uint::range_step(0, midpoint, 4) |base| { + rngstep!(0, 13); + rngstep!(1, -6); + rngstep!(2, 2); + rngstep!(3, -16); + } } + + self.a = a; + self.b = b; + self.cnt = RAND_SIZE; } } -/// Create a new random seed for IsaacRng::new_seeded -pub fn seed() -> ~[u8] { - unsafe { - let n = rustrt::rand_seed_size() as uint; - let mut s = vec::from_elem(n, 0_u8); - do vec::as_mut_buf(s) |p, sz| { - rustrt::rand_gen_seed(p, sz as size_t) +impl Rng for IsaacRng { + #[inline(always)] + fn next(&self) -> u32 { + if self.cnt == 0 { + // make some more numbers + self.isaac(); } - s + self.cnt -= 1; + self.rsl[self.cnt] } } -struct XorShiftRng { +/// An [Xorshift random number +/// generator](http://en.wikipedia.org/wiki/Xorshift). Not suitable for +/// cryptographic purposes. +pub struct XorShiftRng { priv mut x: u32, priv mut y: u32, priv mut z: u32, @@ -633,6 +766,7 @@ struct XorShiftRng { } impl Rng for XorShiftRng { + #[inline] pub fn next(&self) -> u32 { let x = self.x; let t = x ^ (x << 11); @@ -660,7 +794,18 @@ pub impl XorShiftRng { fn new_seeded(x: u32, y: u32, z: u32, w: u32) -> XorShiftRng { XorShiftRng { x: x, y: y, z: z, w: w } } +} +/// Create a new random seed. +pub fn seed() -> ~[u8] { + unsafe { + let n = rustrt::rand_seed_size() as uint; + let mut s = vec::from_elem(n, 0_u8); + do vec::as_mut_buf(s) |p, sz| { + rustrt::rand_gen_seed(p, sz as size_t) + } + s + } } // used to make space in TLS for a random number generator @@ -671,6 +816,7 @@ fn tls_rng_state(_v: @IsaacRng) {} * seeded by the system. Intended to be used in method chaining style, ie * `task_rng().gen::<int>()`. */ +#[inline] pub fn task_rng() -> @IsaacRng { let r : Option<@IsaacRng>; unsafe { @@ -690,6 +836,7 @@ pub fn task_rng() -> @IsaacRng { // Allow direct chaining with `task_rng` impl<R: Rng> Rng for @R { + #[inline(always)] fn next(&self) -> u32 { (**self).next() } } @@ -697,8 +844,9 @@ impl<R: Rng> Rng for @R { * Returns a random value of a Rand type, using the task's random number * generator. */ +#[inline] pub fn random<T: Rand>() -> T { - task_rng().gen() + (*task_rng()).gen() } #[cfg(test)] @@ -879,6 +1027,45 @@ mod tests { (u8, i8, u16, i16, u32, i32, u64, i64), (f32, (f64, (float,)))) = random(); } + + #[test] + fn compare_isaac_implementation() { + // This is to verify that the implementation of the ISAAC rng is + // correct (i.e. matches the output of the upstream implementation, + // which is in the runtime) + use vec; + use libc::size_t; + + #[abi = "cdecl"] + mod rustrt { + use libc::size_t; + + #[allow(non_camel_case_types)] // runtime type + pub enum rust_rng {} + + pub extern { + unsafe fn rand_new_seeded(buf: *u8, sz: size_t) -> *rust_rng; + unsafe fn rand_next(rng: *rust_rng) -> u32; + unsafe fn rand_free(rng: *rust_rng); + } + } + + // run against several seeds + for 10.times { + unsafe { + let seed = super::seed(); + let rt_rng = do vec::as_imm_buf(seed) |p, sz| { + rustrt::rand_new_seeded(p, sz as size_t) + }; + let rng = IsaacRng::new_seeded(seed); + + for 10000.times { + assert_eq!(rng.next(), rustrt::rand_next(rt_rng)); + } + rustrt::rand_free(rt_rng); + } + } + } } diff --git a/src/libcore/rt/thread.rs b/src/libcore/rt/thread.rs index 910e445f47b..0f1ae09bd94 100644 --- a/src/libcore/rt/thread.rs +++ b/src/libcore/rt/thread.rs @@ -21,10 +21,10 @@ pub struct Thread { pub impl Thread { fn start(main: ~fn()) -> Thread { - fn substart(main: &fn()) -> *raw_thread { - unsafe { rust_raw_thread_start(&main) } + fn substart(main: &~fn()) -> *raw_thread { + unsafe { rust_raw_thread_start(main) } } - let raw = substart(main); + let raw = substart(&main); Thread { main: main, raw_thread: raw @@ -39,6 +39,6 @@ impl Drop for Thread { } extern { - pub unsafe fn rust_raw_thread_start(f: &(&fn())) -> *raw_thread; + pub unsafe fn rust_raw_thread_start(f: &(~fn())) -> *raw_thread; pub unsafe fn rust_raw_thread_join_delete(thread: *raw_thread); } diff --git a/src/libcore/rt/uv/mod.rs b/src/libcore/rt/uv/mod.rs index 4cbc8d70569..cb7925abdcd 100644 --- a/src/libcore/rt/uv/mod.rs +++ b/src/libcore/rt/uv/mod.rs @@ -366,14 +366,15 @@ pub fn slice_to_uv_buf(v: &[u8]) -> Buf { /// Transmute an owned vector to a Buf pub fn vec_to_uv_buf(v: ~[u8]) -> Buf { - let data = unsafe { malloc(v.len() as size_t) } as *u8; - assert!(data.is_not_null()); - do vec::as_imm_buf(v) |b, l| { - let data = data as *mut u8; - unsafe { ptr::copy_memory(data, b, l) } + unsafe { + let data = malloc(v.len() as size_t) as *u8; + assert!(data.is_not_null()); + do vec::as_imm_buf(v) |b, l| { + let data = data as *mut u8; + ptr::copy_memory(data, b, l) + } + uvll::buf_init(data, v.len()) } - let buf = unsafe { uvll::buf_init(data, v.len()) }; - return buf; } /// Transmute a Buf that was once a ~[u8] back to ~[u8] @@ -384,6 +385,7 @@ pub fn vec_from_uv_buf(buf: Buf) -> Option<~[u8]> { return Some(v); } else { // No buffer + rtdebug!("No buffer!"); return None; } } diff --git a/src/libcore/rt/uvll.rs b/src/libcore/rt/uvll.rs index b7eff217ff8..c9a696fcd15 100644 --- a/src/libcore/rt/uvll.rs +++ b/src/libcore/rt/uvll.rs @@ -252,7 +252,7 @@ pub unsafe fn async_send(async_handle: *uv_async_t) { } pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t { let out_buf = uv_buf_t { base: ptr::null(), len: 0 as size_t }; - let out_buf_ptr = ptr::addr_of(&out_buf); + let out_buf_ptr = ptr::to_unsafe_ptr(&out_buf); rust_uv_buf_init(out_buf_ptr, input, len as size_t); return out_buf; } @@ -330,7 +330,7 @@ pub unsafe fn free_base_of_buf(buf: uv_buf_t) { pub unsafe fn get_last_err_info(uv_loop: *c_void) -> ~str { let err = last_error(uv_loop); - let err_ptr = ptr::addr_of(&err); + let err_ptr = ptr::to_unsafe_ptr(&err); let err_name = str::raw::from_c_str(err_name(err_ptr)); let err_msg = str::raw::from_c_str(strerror(err_ptr)); return fmt!("LIBUV ERROR: name: %s msg: %s", @@ -339,7 +339,7 @@ pub unsafe fn get_last_err_info(uv_loop: *c_void) -> ~str { pub unsafe fn get_last_err_data(uv_loop: *c_void) -> uv_err_data { let err = last_error(uv_loop); - let err_ptr = ptr::addr_of(&err); + let err_ptr = ptr::to_unsafe_ptr(&err); let err_name = str::raw::from_c_str(err_name(err_ptr)); let err_msg = str::raw::from_c_str(strerror(err_ptr)); uv_err_data { err_name: err_name, err_msg: err_msg } diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs index be5f8989368..ebf36e4e09a 100644 --- a/src/libcore/stackwalk.rs +++ b/src/libcore/stackwalk.rs @@ -93,7 +93,10 @@ pub mod rustrt { pub mod rusti { #[abi = "rust-intrinsic"] pub extern "rust-intrinsic" { + #[cfg(stage0)] pub fn frame_address(f: &once fn(x: *u8)); + #[cfg(not(stage0))] + pub fn frame_address(+f: &once fn(x: *u8)); } } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 92c965256ce..064bffa0056 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -18,6 +18,7 @@ */ use at_vec; +use cast::transmute; use cast; use char; use clone::Clone; @@ -2045,7 +2046,7 @@ pub fn as_c_str<T>(s: &str, f: &fn(*libc::c_char) -> T) -> T { #[inline(always)] pub fn as_buf<T>(s: &str, f: &fn(*u8, uint) -> T) -> T { unsafe { - let v : *(*u8,uint) = ::cast::transmute(ptr::addr_of(&s)); + let v : *(*u8,uint) = transmute(&s); let (buf,len) = *v; f(buf, len) } diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index bdc3a17308d..8cad0a22886 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -154,7 +154,7 @@ pub fn pref_align_of_val<T>(_val: &T) -> uint { #[inline(always)] pub fn refcount<T>(t: @T) -> uint { unsafe { - let ref_ptr: *uint = cast::reinterpret_cast(&t); + let ref_ptr: *uint = cast::transmute_copy(&t); *ref_ptr - 1 } } diff --git a/src/libcore/task/local_data_priv.rs b/src/libcore/task/local_data_priv.rs index 5d1cba79c05..67bc3adeb41 100644 --- a/src/libcore/task/local_data_priv.rs +++ b/src/libcore/task/local_data_priv.rs @@ -59,9 +59,7 @@ unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap { let map_ptr = rt::rust_get_task_local_data(task); if map_ptr.is_null() { let map: TaskLocalMap = @mut ~[]; - // Use reinterpret_cast -- transmute would take map away from us also. - rt::rust_set_task_local_data( - task, cast::transmute(map)); + rt::rust_set_task_local_data(task, cast::transmute(map)); rt::rust_task_local_data_atexit(task, cleanup_task_local_map); // Also need to reference it an extra time to keep it for now. let nonmut = cast::transmute::<TaskLocalMap, @@ -77,12 +75,10 @@ unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap { } } -unsafe fn key_to_key_value<T:Durable>( - key: LocalDataKey<T>) -> *libc::c_void { - +unsafe fn key_to_key_value<T:Durable>(key: LocalDataKey<T>) -> *libc::c_void { // Keys are closures, which are (fnptr,envptr) pairs. Use fnptr. // Use reintepret_cast -- transmute would leak (forget) the closure. - let pair: (*libc::c_void, *libc::c_void) = cast::reinterpret_cast(&key); + let pair: (*libc::c_void, *libc::c_void) = cast::transmute_copy(&key); pair.first() } diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index a6c03638713..96429932b18 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -687,7 +687,7 @@ fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port let ch = ch.clone(); do spawn_unlinked { // Give middle task a chance to fail-but-not-kill-us. - for iter::repeat(16) { task::yield(); } + for old_iter::repeat(16) { task::yield(); } ch.send(()); // If killed first, grandparent hangs. } fail!(); // Shouldn't kill either (grand)parent or (grand)child. @@ -702,7 +702,7 @@ fn test_spawn_unlinked_unsup_no_fail_up() { // child unlinked fails fn test_spawn_unlinked_sup_no_fail_up() { // child unlinked fails do spawn_supervised { fail!(); } // Give child a chance to fail-but-not-kill-us. - for iter::repeat(16) { task::yield(); } + for old_iter::repeat(16) { task::yield(); } } #[test] #[should_fail] #[ignore(cfg(windows))] fn test_spawn_unlinked_sup_fail_down() { @@ -783,7 +783,7 @@ fn test_spawn_failure_propagate_grandchild() { loop { task::yield(); } } } - for iter::repeat(16) { task::yield(); } + for old_iter::repeat(16) { task::yield(); } fail!(); } @@ -795,7 +795,7 @@ fn test_spawn_failure_propagate_secondborn() { loop { task::yield(); } } } - for iter::repeat(16) { task::yield(); } + for old_iter::repeat(16) { task::yield(); } fail!(); } @@ -807,7 +807,7 @@ fn test_spawn_failure_propagate_nephew_or_niece() { loop { task::yield(); } } } - for iter::repeat(16) { task::yield(); } + for old_iter::repeat(16) { task::yield(); } fail!(); } @@ -819,7 +819,7 @@ fn test_spawn_linked_sup_propagate_sibling() { loop { task::yield(); } } } - for iter::repeat(16) { task::yield(); } + for old_iter::repeat(16) { task::yield(); } fail!(); } @@ -971,7 +971,7 @@ fn test_spawn_sched_blocking() { // Testing that a task in one scheduler can block in foreign code // without affecting other schedulers - for iter::repeat(20u) { + for old_iter::repeat(20u) { let (start_po, start_ch) = stream(); let (fin_po, fin_ch) = stream(); @@ -1028,10 +1028,10 @@ fn avoid_copying_the_body(spawnfn: &fn(v: ~fn())) { let (p, ch) = stream::<uint>(); let x = ~1; - let x_in_parent = ptr::addr_of(&(*x)) as uint; + let x_in_parent = ptr::to_unsafe_ptr(&*x) as uint; do spawnfn || { - let x_in_child = ptr::addr_of(&(*x)) as uint; + let x_in_child = ptr::to_unsafe_ptr(&*x) as uint; ch.send(x_in_child); } @@ -1088,7 +1088,7 @@ fn test_unkillable() { // We want to do this after failing do spawn_unlinked { - for iter::repeat(10) { yield() } + for old_iter::repeat(10) { yield() } ch.send(()); } @@ -1123,7 +1123,7 @@ fn test_unkillable_nested() { // We want to do this after failing do spawn_unlinked || { - for iter::repeat(10) { yield() } + for old_iter::repeat(10) { yield() } ch.send(()); } diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 43fdee67b7a..507643ea5ec 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -93,7 +93,7 @@ use util; #[cfg(test)] use task::default_task_opts; macro_rules! move_it ( - { $x:expr } => ( unsafe { let y = *ptr::addr_of(&($x)); y } ) + { $x:expr } => ( unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } ) ) type TaskSet = HashSet<*rust_task>; diff --git a/src/libcore/unstable/intrinsics.rs b/src/libcore/unstable/intrinsics.rs index a18ad173886..b58429a10aa 100644 --- a/src/libcore/unstable/intrinsics.rs +++ b/src/libcore/unstable/intrinsics.rs @@ -47,9 +47,8 @@ pub extern "rust-intrinsic" { pub fn forget<T>(_: T) -> (); // XXX: intrinsic uses legacy modes + #[cfg(stage0)] fn reinterpret_cast<T,U>(&&src: T) -> U; - // XXX: intrinsic uses legacy modes - fn addr_of<T>(&&scr: T) -> *T; pub fn needs_drop<T>() -> bool; diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 176e20f3894..86767dc5bad 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -17,8 +17,8 @@ use cast; use container::{Container, Mutable}; use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater}; use clone::Clone; -use iter::BaseIter; -use iter; +use old_iter::BaseIter; +use old_iter; #[cfg(stage1)] #[cfg(stage2)] #[cfg(stage3)] @@ -26,11 +26,11 @@ use iterator::Iterator; use kinds::Copy; use libc; use option::{None, Option, Some}; -use unstable::intrinsics; +use ptr::to_unsafe_ptr; use ptr; -use ptr::addr_of; use sys; use uint; +use unstable::intrinsics; use vec; #[cfg(notest)] use cmp::Equiv; @@ -117,7 +117,7 @@ pub fn reserve_at_least<T>(v: &mut ~[T], n: uint) { #[inline(always)] pub fn capacity<T>(v: &const ~[T]) -> uint { unsafe { - let repr: **raw::VecRepr = ::cast::transmute(v); + let repr: **raw::VecRepr = transmute(v); (**repr).unboxed.alloc / sys::nonzero_size_of::<T>() } } @@ -131,7 +131,7 @@ pub fn len<T>(v: &const [T]) -> uint { // A botch to tide us over until core and std are fully demuted. pub fn uniq_len<T>(v: &const ~[T]) -> uint { unsafe { - let v: &~[T] = ::cast::transmute(v); + let v: &~[T] = transmute(v); as_const_buf(*v, |_p, len| len) } } @@ -142,7 +142,7 @@ pub fn uniq_len<T>(v: &const ~[T]) -> uint { * Creates an immutable vector of size `n_elts` and initializes the elements * to the value returned by the function `op`. */ -pub fn from_fn<T>(n_elts: uint, op: iter::InitOp<T>) -> ~[T] { +pub fn from_fn<T>(n_elts: uint, op: old_iter::InitOp<T>) -> ~[T] { unsafe { let mut v = with_capacity(n_elts); do as_mut_buf(v) |p, _len| { @@ -280,9 +280,8 @@ pub fn slice<'r,T>(v: &'r [T], start: uint, end: uint) -> &'r [T] { assert!(end <= len(v)); do as_imm_buf(v) |p, _len| { unsafe { - ::cast::transmute( - (ptr::offset(p, start), - (end - start) * sys::nonzero_size_of::<T>())) + transmute((ptr::offset(p, start), + (end - start) * sys::nonzero_size_of::<T>())) } } } @@ -295,9 +294,8 @@ pub fn mut_slice<'r,T>(v: &'r mut [T], start: uint, end: uint) assert!(end <= v.len()); do as_mut_buf(v) |p, _len| { unsafe { - ::cast::transmute( - (ptr::mut_offset(p, start), - (end - start) * sys::nonzero_size_of::<T>())) + transmute((ptr::mut_offset(p, start), + (end - start) * sys::nonzero_size_of::<T>())) } } } @@ -310,9 +308,8 @@ pub fn const_slice<'r,T>(v: &'r const [T], start: uint, end: uint) assert!(end <= len(v)); do as_const_buf(v) |p, _len| { unsafe { - ::cast::transmute( - (ptr::const_offset(p, start), - (end - start) * sys::nonzero_size_of::<T>())) + transmute((ptr::const_offset(p, start), + (end - start) * sys::nonzero_size_of::<T>())) } } } @@ -489,14 +486,14 @@ pub fn shift<T>(v: &mut ~[T]) -> T { { let first_slice = slice(*v, 0, 1); let last_slice = slice(*v, next_ln, ln); - raw::copy_memory(::cast::transmute(last_slice), first_slice, 1); + raw::copy_memory(transmute(last_slice), first_slice, 1); } // Memcopy everything to the left one element { let init_slice = slice(*v, 0, next_ln); let tail_slice = slice(*v, 1, ln); - raw::copy_memory(::cast::transmute(init_slice), + raw::copy_memory(transmute(init_slice), tail_slice, next_ln); } @@ -626,7 +623,7 @@ pub fn swap_remove<T>(v: &mut ~[T], index: uint) -> T { #[inline(always)] pub fn push<T>(v: &mut ~[T], initval: T) { unsafe { - let repr: **raw::VecRepr = ::cast::transmute(&mut *v); + let repr: **raw::VecRepr = transmute(&mut *v); let fill = (**repr).unboxed.fill; if (**repr).unboxed.alloc > fill { push_fast(v, initval); @@ -640,10 +637,10 @@ pub fn push<T>(v: &mut ~[T], initval: T) { // This doesn't bother to make sure we have space. #[inline(always)] // really pretty please unsafe fn push_fast<T>(v: &mut ~[T], initval: T) { - let repr: **mut raw::VecRepr = ::cast::transmute(v); + let repr: **mut raw::VecRepr = transmute(v); let fill = (**repr).unboxed.fill; (**repr).unboxed.fill += sys::nonzero_size_of::<T>(); - let p = addr_of(&((**repr).unboxed.data)); + let p = to_unsafe_ptr(&((**repr).unboxed.data)); let p = ptr::offset(p, fill) as *mut T; intrinsics::move_val_init(&mut(*p), initval); } @@ -786,7 +783,7 @@ pub fn grow<T:Copy>(v: &mut ~[T], n: uint, initval: &T) { * * init_op - A function to call to retreive each appended element's * value */ -pub fn grow_fn<T>(v: &mut ~[T], n: uint, op: iter::InitOp<T>) { +pub fn grow_fn<T>(v: &mut ~[T], n: uint, op: old_iter::InitOp<T>) { let new_len = v.len() + n; reserve_at_least(&mut *v, new_len); let mut i: uint = 0u; @@ -1622,8 +1619,7 @@ pub fn as_imm_buf<T,U>(s: &[T], // instead! unsafe { - let v : *(*T,uint) = - ::cast::transmute(addr_of(&s)); + let v : *(*T,uint) = transmute(&s); let (buf,len) = *v; f(buf, len / sys::nonzero_size_of::<T>()) } @@ -1633,8 +1629,7 @@ pub fn as_imm_buf<T,U>(s: &[T], #[inline(always)] pub fn as_const_buf<T,U>(s: &const [T], f: &fn(*const T, uint) -> U) -> U { unsafe { - let v : *(*const T,uint) = - ::cast::transmute(addr_of(&s)); + let v : *(*const T,uint) = transmute(&s); let (buf,len) = *v; f(buf, len / sys::nonzero_size_of::<T>()) } @@ -1644,8 +1639,7 @@ pub fn as_const_buf<T,U>(s: &const [T], f: &fn(*const T, uint) -> U) -> U { #[inline(always)] pub fn as_mut_buf<T,U>(s: &mut [T], f: &fn(*mut T, uint) -> U) -> U { unsafe { - let v : *(*mut T,uint) = - ::cast::transmute(addr_of(&s)); + let v : *(*mut T,uint) = transmute(&s); let (buf,len) = *v; f(buf, len / sys::nonzero_size_of::<T>()) } @@ -2265,7 +2259,7 @@ pub trait OwnedVector<T> { fn consume_reverse(self, f: &fn(uint, v: T)); fn filter(self, f: &fn(t: &T) -> bool) -> ~[T]; fn partition(self, f: &fn(&T) -> bool) -> (~[T], ~[T]); - fn grow_fn(&mut self, n: uint, op: iter::InitOp<T>); + fn grow_fn(&mut self, n: uint, op: old_iter::InitOp<T>); } impl<T> OwnedVector<T> for ~[T] { @@ -2344,7 +2338,7 @@ impl<T> OwnedVector<T> for ~[T] { } #[inline] - fn grow_fn(&mut self, n: uint, op: iter::InitOp<T>) { + fn grow_fn(&mut self, n: uint, op: old_iter::InitOp<T>) { grow_fn(self, n, op); } } @@ -2429,13 +2423,13 @@ pub struct UnboxedVecRepr { /// Unsafe operations pub mod raw { + use cast::transmute; use kinds::Copy; use managed; use option::{None, Some}; - use unstable::intrinsics; - use ptr::addr_of; use ptr; use sys; + use unstable::intrinsics; use vec::{UnboxedVecRepr, as_const_buf, as_mut_buf, len, with_capacity}; /// The internal representation of a (boxed) vector @@ -2458,7 +2452,7 @@ pub mod raw { */ #[inline(always)] pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) { - let repr: **mut VecRepr = ::cast::transmute(v); + let repr: **mut VecRepr = transmute(v); (**repr).unboxed.fill = new_len * sys::nonzero_size_of::<T>(); } @@ -2473,22 +2467,22 @@ pub mod raw { */ #[inline(always)] pub unsafe fn to_ptr<T>(v: &[T]) -> *T { - let repr: **SliceRepr = ::cast::transmute(&v); - ::cast::transmute(addr_of(&((**repr).data))) + let repr: **SliceRepr = transmute(&v); + transmute(&((**repr).data)) } /** see `to_ptr()` */ #[inline(always)] pub unsafe fn to_const_ptr<T>(v: &const [T]) -> *const T { - let repr: **SliceRepr = ::cast::transmute(&v); - ::cast::transmute(addr_of(&((**repr).data))) + let repr: **SliceRepr = transmute(&v); + transmute(&((**repr).data)) } /** see `to_ptr()` */ #[inline(always)] pub unsafe fn to_mut_ptr<T>(v: &mut [T]) -> *mut T { - let repr: **SliceRepr = ::cast::transmute(&v); - ::cast::transmute(addr_of(&((**repr).data))) + let repr: **SliceRepr = transmute(&v); + transmute(&((**repr).data)) } /** @@ -2500,8 +2494,7 @@ pub mod raw { len: uint, f: &fn(v: &[T]) -> U) -> U { let pair = (p, len * sys::nonzero_size_of::<T>()); - let v : *(&'blk [T]) = - ::cast::transmute(addr_of(&pair)); + let v : *(&'blk [T]) = transmute(&pair); f(*v) } @@ -2514,8 +2507,7 @@ pub mod raw { len: uint, f: &fn(v: &mut [T]) -> U) -> U { let pair = (p, len * sys::nonzero_size_of::<T>()); - let v : *(&'blk mut [T]) = - ::cast::transmute(addr_of(&pair)); + let v : *(&'blk mut [T]) = transmute(&pair); f(*v) } @@ -2643,7 +2635,7 @@ pub mod bytes { // ITERATION TRAIT METHODS #[cfg(stage0)] -impl<'self,A> iter::BaseIter<A> for &'self [A] { +impl<'self,A> old_iter::BaseIter<A> for &'self [A] { #[inline(always)] fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) } #[inline(always)] @@ -2653,7 +2645,7 @@ impl<'self,A> iter::BaseIter<A> for &'self [A] { #[cfg(stage1)] #[cfg(stage2)] #[cfg(stage3)] -impl<'self,A> iter::BaseIter<A> for &'self [A] { +impl<'self,A> old_iter::BaseIter<A> for &'self [A] { #[inline(always)] fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) } #[inline(always)] @@ -2662,7 +2654,7 @@ impl<'self,A> iter::BaseIter<A> for &'self [A] { // FIXME(#4148): This should be redundant #[cfg(stage0)] -impl<A> iter::BaseIter<A> for ~[A] { +impl<A> old_iter::BaseIter<A> for ~[A] { #[inline(always)] fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) } #[inline(always)] @@ -2673,7 +2665,7 @@ impl<A> iter::BaseIter<A> for ~[A] { #[cfg(stage1)] #[cfg(stage2)] #[cfg(stage3)] -impl<A> iter::BaseIter<A> for ~[A] { +impl<A> old_iter::BaseIter<A> for ~[A] { #[inline(always)] fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) } #[inline(always)] @@ -2682,7 +2674,7 @@ impl<A> iter::BaseIter<A> for ~[A] { // FIXME(#4148): This should be redundant #[cfg(stage0)] -impl<A> iter::BaseIter<A> for @[A] { +impl<A> old_iter::BaseIter<A> for @[A] { #[inline(always)] fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) } #[inline(always)] @@ -2693,7 +2685,7 @@ impl<A> iter::BaseIter<A> for @[A] { #[cfg(stage1)] #[cfg(stage2)] #[cfg(stage3)] -impl<A> iter::BaseIter<A> for @[A] { +impl<A> old_iter::BaseIter<A> for @[A] { #[inline(always)] fn each<'a>(&'a self, blk: &fn(v: &'a A) -> bool) { each(*self, blk) } #[inline(always)] @@ -2701,7 +2693,7 @@ impl<A> iter::BaseIter<A> for @[A] { } #[cfg(stage0)] -impl<'self,A> iter::MutableIter<A> for &'self mut [A] { +impl<'self,A> old_iter::MutableIter<A> for &'self mut [A] { #[inline(always)] fn each_mut(&mut self, blk: &fn(v: &'self mut A) -> bool) { each_mut(*self, blk) @@ -2711,7 +2703,7 @@ impl<'self,A> iter::MutableIter<A> for &'self mut [A] { #[cfg(stage1)] #[cfg(stage2)] #[cfg(stage3)] -impl<'self,A> iter::MutableIter<A> for &'self mut [A] { +impl<'self,A> old_iter::MutableIter<A> for &'self mut [A] { #[inline(always)] fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) { each_mut(*self, blk) @@ -2720,7 +2712,7 @@ impl<'self,A> iter::MutableIter<A> for &'self mut [A] { // FIXME(#4148): This should be redundant #[cfg(stage0)] -impl<A> iter::MutableIter<A> for ~[A] { +impl<A> old_iter::MutableIter<A> for ~[A] { #[inline(always)] fn each_mut(&mut self, blk: &fn(v: &'self mut A) -> bool) { each_mut(*self, blk) @@ -2730,7 +2722,7 @@ impl<A> iter::MutableIter<A> for ~[A] { #[cfg(stage1)] #[cfg(stage2)] #[cfg(stage3)] -impl<A> iter::MutableIter<A> for ~[A] { +impl<A> old_iter::MutableIter<A> for ~[A] { #[inline(always)] fn each_mut<'a>(&'a mut self, blk: &fn(v: &'a mut A) -> bool) { each_mut(*self, blk) @@ -2738,39 +2730,39 @@ impl<A> iter::MutableIter<A> for ~[A] { } // FIXME(#4148): This should be redundant -impl<A> iter::MutableIter<A> for @mut [A] { +impl<A> old_iter::MutableIter<A> for @mut [A] { #[inline(always)] fn each_mut(&mut self, blk: &fn(v: &mut A) -> bool) { each_mut(*self, blk) } } -impl<'self,A> iter::ExtendedIter<A> for &'self [A] { +impl<'self,A> old_iter::ExtendedIter<A> for &'self [A] { pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { - iter::eachi(self, blk) + old_iter::eachi(self, blk) } pub fn all(&self, blk: &fn(&A) -> bool) -> bool { - iter::all(self, blk) + old_iter::all(self, blk) } pub fn any(&self, blk: &fn(&A) -> bool) -> bool { - iter::any(self, blk) + old_iter::any(self, blk) } pub fn foldl<B>(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { - iter::foldl(self, b0, blk) + old_iter::foldl(self, b0, blk) } pub fn position(&self, f: &fn(&A) -> bool) -> Option<uint> { - iter::position(self, f) + old_iter::position(self, f) } fn map_to_vec<B>(&self, op: &fn(&A) -> B) -> ~[B] { - iter::map_to_vec(self, op) + old_iter::map_to_vec(self, op) } fn flat_map_to_vec<B,IB:BaseIter<B>>(&self, op: &fn(&A) -> IB) -> ~[B] { - iter::flat_map_to_vec(self, op) + old_iter::flat_map_to_vec(self, op) } } -impl<'self,A> iter::ExtendedMutableIter<A> for &'self mut [A] { +impl<'self,A> old_iter::ExtendedMutableIter<A> for &'self mut [A] { #[inline(always)] pub fn eachi_mut(&mut self, blk: &fn(uint, v: &mut A) -> bool) { eachi_mut(*self, blk) @@ -2778,124 +2770,124 @@ impl<'self,A> iter::ExtendedMutableIter<A> for &'self mut [A] { } // FIXME(#4148): This should be redundant -impl<A> iter::ExtendedIter<A> for ~[A] { +impl<A> old_iter::ExtendedIter<A> for ~[A] { pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { - iter::eachi(self, blk) + old_iter::eachi(self, blk) } pub fn all(&self, blk: &fn(&A) -> bool) -> bool { - iter::all(self, blk) + old_iter::all(self, blk) } pub fn any(&self, blk: &fn(&A) -> bool) -> bool { - iter::any(self, blk) + old_iter::any(self, blk) } pub fn foldl<B>(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { - iter::foldl(self, b0, blk) + old_iter::foldl(self, b0, blk) } pub fn position(&self, f: &fn(&A) -> bool) -> Option<uint> { - iter::position(self, f) + old_iter::position(self, f) } fn map_to_vec<B>(&self, op: &fn(&A) -> B) -> ~[B] { - iter::map_to_vec(self, op) + old_iter::map_to_vec(self, op) } fn flat_map_to_vec<B,IB:BaseIter<B>>(&self, op: &fn(&A) -> IB) -> ~[B] { - iter::flat_map_to_vec(self, op) + old_iter::flat_map_to_vec(self, op) } } // FIXME(#4148): This should be redundant -impl<A> iter::ExtendedIter<A> for @[A] { +impl<A> old_iter::ExtendedIter<A> for @[A] { pub fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { - iter::eachi(self, blk) + old_iter::eachi(self, blk) } pub fn all(&self, blk: &fn(&A) -> bool) -> bool { - iter::all(self, blk) + old_iter::all(self, blk) } pub fn any(&self, blk: &fn(&A) -> bool) -> bool { - iter::any(self, blk) + old_iter::any(self, blk) } pub fn foldl<B>(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { - iter::foldl(self, b0, blk) + old_iter::foldl(self, b0, blk) } pub fn position(&self, f: &fn(&A) -> bool) -> Option<uint> { - iter::position(self, f) + old_iter::position(self, f) } fn map_to_vec<B>(&self, op: &fn(&A) -> B) -> ~[B] { - iter::map_to_vec(self, op) + old_iter::map_to_vec(self, op) } fn flat_map_to_vec<B,IB:BaseIter<B>>(&self, op: &fn(&A) -> IB) -> ~[B] { - iter::flat_map_to_vec(self, op) + old_iter::flat_map_to_vec(self, op) } } -impl<'self,A:Eq> iter::EqIter<A> for &'self [A] { - pub fn contains(&self, x: &A) -> bool { iter::contains(self, x) } - pub fn count(&self, x: &A) -> uint { iter::count(self, x) } +impl<'self,A:Eq> old_iter::EqIter<A> for &'self [A] { + pub fn contains(&self, x: &A) -> bool { old_iter::contains(self, x) } + pub fn count(&self, x: &A) -> uint { old_iter::count(self, x) } } // FIXME(#4148): This should be redundant -impl<A:Eq> iter::EqIter<A> for ~[A] { - pub fn contains(&self, x: &A) -> bool { iter::contains(self, x) } - pub fn count(&self, x: &A) -> uint { iter::count(self, x) } +impl<A:Eq> old_iter::EqIter<A> for ~[A] { + pub fn contains(&self, x: &A) -> bool { old_iter::contains(self, x) } + pub fn count(&self, x: &A) -> uint { old_iter::count(self, x) } } // FIXME(#4148): This should be redundant -impl<A:Eq> iter::EqIter<A> for @[A] { - pub fn contains(&self, x: &A) -> bool { iter::contains(self, x) } - pub fn count(&self, x: &A) -> uint { iter::count(self, x) } +impl<A:Eq> old_iter::EqIter<A> for @[A] { + pub fn contains(&self, x: &A) -> bool { old_iter::contains(self, x) } + pub fn count(&self, x: &A) -> uint { old_iter::count(self, x) } } -impl<'self,A:Copy> iter::CopyableIter<A> for &'self [A] { +impl<'self,A:Copy> old_iter::CopyableIter<A> for &'self [A] { fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { - iter::filter_to_vec(self, pred) + old_iter::filter_to_vec(self, pred) } - fn to_vec(&self) -> ~[A] { iter::to_vec(self) } + fn to_vec(&self) -> ~[A] { old_iter::to_vec(self) } pub fn find(&self, f: &fn(&A) -> bool) -> Option<A> { - iter::find(self, f) + old_iter::find(self, f) } } // FIXME(#4148): This should be redundant -impl<A:Copy> iter::CopyableIter<A> for ~[A] { +impl<A:Copy> old_iter::CopyableIter<A> for ~[A] { fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { - iter::filter_to_vec(self, pred) + old_iter::filter_to_vec(self, pred) } - fn to_vec(&self) -> ~[A] { iter::to_vec(self) } + fn to_vec(&self) -> ~[A] { old_iter::to_vec(self) } pub fn find(&self, f: &fn(&A) -> bool) -> Option<A> { - iter::find(self, f) + old_iter::find(self, f) } } // FIXME(#4148): This should be redundant -impl<A:Copy> iter::CopyableIter<A> for @[A] { +impl<A:Copy> old_iter::CopyableIter<A> for @[A] { fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { - iter::filter_to_vec(self, pred) + old_iter::filter_to_vec(self, pred) } - fn to_vec(&self) -> ~[A] { iter::to_vec(self) } + fn to_vec(&self) -> ~[A] { old_iter::to_vec(self) } pub fn find(&self, f: &fn(&A) -> bool) -> Option<A> { - iter::find(self, f) + old_iter::find(self, f) } } -impl<'self,A:Copy + Ord> iter::CopyableOrderedIter<A> for &'self [A] { - fn min(&self) -> A { iter::min(self) } - fn max(&self) -> A { iter::max(self) } +impl<'self,A:Copy + Ord> old_iter::CopyableOrderedIter<A> for &'self [A] { + fn min(&self) -> A { old_iter::min(self) } + fn max(&self) -> A { old_iter::max(self) } } // FIXME(#4148): This should be redundant -impl<A:Copy + Ord> iter::CopyableOrderedIter<A> for ~[A] { - fn min(&self) -> A { iter::min(self) } - fn max(&self) -> A { iter::max(self) } +impl<A:Copy + Ord> old_iter::CopyableOrderedIter<A> for ~[A] { + fn min(&self) -> A { old_iter::min(self) } + fn max(&self) -> A { old_iter::max(self) } } // FIXME(#4148): This should be redundant -impl<A:Copy + Ord> iter::CopyableOrderedIter<A> for @[A] { - fn min(&self) -> A { iter::min(self) } - fn max(&self) -> A { iter::max(self) } +impl<A:Copy + Ord> old_iter::CopyableOrderedIter<A> for @[A] { + fn min(&self) -> A { old_iter::min(self) } + fn max(&self) -> A { old_iter::max(self) } } -impl<'self,A:Copy> iter::CopyableNonstrictIter<A> for &'self [A] { +impl<'self,A:Copy> old_iter::CopyableNonstrictIter<A> for &'self [A] { fn each_val(&const self, f: &fn(A) -> bool) { let mut i = 0; while i < self.len() { @@ -2906,7 +2898,7 @@ impl<'self,A:Copy> iter::CopyableNonstrictIter<A> for &'self [A] { } // FIXME(#4148): This should be redundant -impl<A:Copy> iter::CopyableNonstrictIter<A> for ~[A] { +impl<A:Copy> old_iter::CopyableNonstrictIter<A> for ~[A] { fn each_val(&const self, f: &fn(A) -> bool) { let mut i = 0; while i < uniq_len(self) { @@ -2917,7 +2909,7 @@ impl<A:Copy> iter::CopyableNonstrictIter<A> for ~[A] { } // FIXME(#4148): This should be redundant -impl<A:Copy> iter::CopyableNonstrictIter<A> for @[A] { +impl<A:Copy> old_iter::CopyableNonstrictIter<A> for @[A] { fn each_val(&const self, f: &fn(A) -> bool) { let mut i = 0; while i < self.len() { |
