diff options
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/lib.rs | 8 | ||||
| -rw-r--r-- | src/libstd/owned.rs | 101 | ||||
| -rw-r--r-- | src/libstd/rt/task.rs | 3 | ||||
| -rw-r--r-- | src/libstd/task.rs | 5 |
4 files changed, 111 insertions, 6 deletions
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 34ed7933c39..a37f9a516fd 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -133,14 +133,16 @@ extern crate core; #[cfg(test)] pub use ops = realstd::ops; #[cfg(test)] pub use cmp = realstd::cmp; #[cfg(test)] pub use ty = realstd::ty; -#[cfg(test)] pub use owned = realstd::owned; +#[cfg(not(stage0), test)] pub use owned = realstd::owned; #[cfg(not(test))] pub use cmp = core::cmp; #[cfg(not(test))] pub use kinds = core::kinds; #[cfg(not(test))] pub use ops = core::ops; -#[cfg(not(test))] pub use owned = core::owned; #[cfg(not(test))] pub use ty = core::ty; +#[cfg(stage0, test)] pub use owned = realstd::owned; +#[cfg(stage0, not(test))] pub use owned = core::owned; + pub use core::any; pub use core::bool; pub use core::cell; @@ -207,6 +209,8 @@ pub mod ascii; pub mod rc; pub mod gc; +#[cfg(not(stage0), not(test))] +pub mod owned; /* Common traits */ diff --git a/src/libstd/owned.rs b/src/libstd/owned.rs new file mode 100644 index 00000000000..3af12c5154c --- /dev/null +++ b/src/libstd/owned.rs @@ -0,0 +1,101 @@ +// Copyright 2012 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. + +//! Operations on unique pointer types + +use any::{Any, AnyRefExt}; +use clone::Clone; +use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering}; +use default::Default; +use intrinsics; +use mem; +use raw::TraitObject; +use result::{Ok, Err, Result}; + +/// A value that represents the global exchange heap. This is the default +/// place that the `box` keyword allocates into when no place is supplied. +/// +/// The following two examples are equivalent: +/// +/// let foo = box(HEAP) Bar::new(...); +/// let foo = box Bar::new(...); +#[lang="exchange_heap"] +pub static HEAP: () = (); + +/// A type that represents a uniquely-owned value. +#[lang="owned_box"] +pub struct Box<T>(*T); + +impl<T: Default> Default for Box<T> { + fn default() -> Box<T> { box Default::default() } +} + +impl<T: Clone> Clone for Box<T> { + /// Return a copy of the owned box. + #[inline] + fn clone(&self) -> Box<T> { box {(**self).clone()} } + + /// Perform copy-assignment from `source` by reusing the existing allocation. + #[inline] + fn clone_from(&mut self, source: &Box<T>) { + (**self).clone_from(&(**source)); + } +} + +// box pointers +impl<T:Eq> Eq for Box<T> { + #[inline] + fn eq(&self, other: &Box<T>) -> bool { *(*self) == *(*other) } + #[inline] + fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) } +} +impl<T:Ord> Ord for Box<T> { + #[inline] + fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) } + #[inline] + fn le(&self, other: &Box<T>) -> bool { *(*self) <= *(*other) } + #[inline] + fn ge(&self, other: &Box<T>) -> bool { *(*self) >= *(*other) } + #[inline] + fn gt(&self, other: &Box<T>) -> bool { *(*self) > *(*other) } +} +impl<T: TotalOrd> TotalOrd for Box<T> { + #[inline] + fn cmp(&self, other: &Box<T>) -> Ordering { (**self).cmp(*other) } +} +impl<T: TotalEq> TotalEq for Box<T> {} + +/// Extension methods for an owning `Any` trait object +pub trait AnyOwnExt { + /// Returns the boxed value if it is of type `T`, or + /// `Err(Self)` if it isn't. + fn move<T: 'static>(self) -> Result<Box<T>, Self>; +} + +impl AnyOwnExt for Box<Any> { + #[inline] + fn move<T: 'static>(self) -> Result<Box<T>, Box<Any>> { + if self.is::<T>() { + unsafe { + // Get the raw representation of the trait object + let to: TraitObject = + *mem::transmute::<&Box<Any>, &TraitObject>(&self); + + // Prevent destructor on self being run + intrinsics::forget(self); + + // Extract the data pointer + Ok(mem::transmute(to.data)) + } + } else { + Err(self) + } + } +} diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index cd0445056b2..31a20145306 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -13,7 +13,6 @@ //! local storage, and logging. Even a 'freestanding' Rust would likely want //! to implement this. -use any::AnyOwnExt; use cleanup; use clone::Clone; use comm::Sender; @@ -24,7 +23,7 @@ use local_data; use mem; use ops::Drop; use option::{Option, Some, None}; -use owned::Box; +use owned::{AnyOwnExt, Box}; use prelude::drop; use result::{Result, Ok, Err}; use rt::Runtime; diff --git a/src/libstd/task.rs b/src/libstd/task.rs index 2f7b31ae31d..7fb61c29112 100644 --- a/src/libstd/task.rs +++ b/src/libstd/task.rs @@ -47,10 +47,11 @@ use rt::local::Local; use rt::task::Task; use str::{Str, SendStr, IntoMaybeOwned}; -#[cfg(test)] use any::{AnyOwnExt, AnyRefExt}; +#[cfg(test)] use any::AnyRefExt; +#[cfg(test)] use owned::AnyOwnExt; +#[cfg(test)] use realstd::result::ResultUnwrap; #[cfg(test)] use result; #[cfg(test)] use str::StrAllocating; -#[cfg(test)] use realstd::result::ResultUnwrap; /// Indicates the manner in which a task exited. /// |
