From e0ede9c6b3894851b800a323757857eba07943b5 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Thu, 10 Jul 2014 14:19:17 -0700 Subject: Stabilization for `owned` (now `boxed`) and `cell` This PR is the outcome of the library stabilization meeting for the `liballoc::owned` and `libcore::cell` modules. Aside from the stability attributes, there are a few breaking changes: * The `owned` modules is now named `boxed`, to better represent its contents. (`box` was unavailable, since it's a keyword.) This will help avoid the misconception that `Box` plays a special role wrt ownership. * The `AnyOwnExt` extension trait is renamed to `BoxAny`, and its `move` method is renamed to `downcast`, in both cases to improve clarity. * The recently-added `AnySendOwnExt` extension trait is removed; it was not being used and is unnecessary. [breaking-change] --- src/liballoc/boxed.rs | 180 ++++++++++++++++++++++++++++++++++++++++++++ src/liballoc/lib.rs | 14 +++- src/liballoc/owned.rs | 201 -------------------------------------------------- 3 files changed, 190 insertions(+), 205 deletions(-) create mode 100644 src/liballoc/boxed.rs delete mode 100644 src/liballoc/owned.rs (limited to 'src/liballoc') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs new file mode 100644 index 00000000000..56506d798d9 --- /dev/null +++ b/src/liballoc/boxed.rs @@ -0,0 +1,180 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A unique pointer type + +use core::any::{Any, AnyRefExt}; +use core::clone::Clone; +use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering}; +use core::default::Default; +use core::fmt; +use core::intrinsics; +use core::mem; +use core::option::Option; +use core::raw::TraitObject; +use core::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: +/// +/// use std::boxed::HEAP; +/// +/// # struct Bar; +/// # impl Bar { fn new(_a: int) { } } +/// let foo = box(HEAP) Bar::new(2); +/// let foo = box Bar::new(2); +#[lang = "exchange_heap"] +#[experimental = "may be renamed; uncertain about custom allocator design"] +pub static HEAP: () = (); + +/// A type that represents a uniquely-owned value. +#[lang = "owned_box"] +#[unstable = "custom allocators will add an additional type parameter (with default)"] +pub struct Box(*mut T); + +impl Default for Box { + fn default() -> Box { box Default::default() } +} + +#[unstable] +impl Clone for Box { + /// Return a copy of the owned box. + #[inline] + fn clone(&self) -> Box { box {(**self).clone()} } + + /// Perform copy-assignment from `source` by reusing the existing allocation. + #[inline] + fn clone_from(&mut self, source: &Box) { + (**self).clone_from(&(**source)); + } +} + +impl PartialEq for Box { + #[inline] + fn eq(&self, other: &Box) -> bool { *(*self) == *(*other) } + #[inline] + fn ne(&self, other: &Box) -> bool { *(*self) != *(*other) } +} +impl PartialOrd for Box { + #[inline] + fn partial_cmp(&self, other: &Box) -> Option { + (**self).partial_cmp(*other) + } + #[inline] + fn lt(&self, other: &Box) -> bool { *(*self) < *(*other) } + #[inline] + fn le(&self, other: &Box) -> bool { *(*self) <= *(*other) } + #[inline] + fn ge(&self, other: &Box) -> bool { *(*self) >= *(*other) } + #[inline] + fn gt(&self, other: &Box) -> bool { *(*self) > *(*other) } +} +impl Ord for Box { + #[inline] + fn cmp(&self, other: &Box) -> Ordering { (**self).cmp(*other) } +} +impl Eq for Box {} + +/// Extension methods for an owning `Any` trait object +#[unstable = "post-DST, the signature of `downcast` will change to take `Box`"] +pub trait BoxAny { + /// Returns the boxed value if it is of type `T`, or + /// `Err(Self)` if it isn't. + fn downcast(self) -> Result, Self>; + + /// Deprecated; this method has been renamed to `downcast`. + #[deprecated = "use downcast instead"] + fn move(self) -> Result, Self> { + self.downcast::() + } +} + +impl BoxAny for Box { + #[inline] + fn downcast(self) -> Result, Box> { + if self.is::() { + unsafe { + // Get the raw representation of the trait object + let to: TraitObject = + *mem::transmute::<&Box, &TraitObject>(&self); + + // Prevent destructor on self being run + intrinsics::forget(self); + + // Extract the data pointer + Ok(mem::transmute(to.data)) + } + } else { + Err(self) + } + } +} + +impl fmt::Show for Box { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + (**self).fmt(f) + } +} + +impl fmt::Show for Box { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad("Box") + } +} + +#[cfg(test)] +mod test { + #[test] + fn test_owned_clone() { + let a = box 5i; + let b: Box = a.clone(); + assert!(a == b); + } + + #[test] + fn any_move() { + let a = box 8u as Box; + let b = box Test as Box; + + match a.downcast::() { + Ok(a) => { assert!(a == box 8u); } + Err(..) => fail!() + } + match b.downcast::() { + Ok(a) => { assert!(a == box Test); } + Err(..) => fail!() + } + + let a = box 8u as Box; + let b = box Test as Box; + + assert!(a.downcast::>().is_err()); + assert!(b.downcast::>().is_err()); + } + + #[test] + fn test_show() { + let a = box 8u as Box; + let b = box Test as Box; + let a_str = a.to_str(); + let b_str = b.to_str(); + assert_eq!(a_str.as_slice(), "Box"); + assert_eq!(b_str.as_slice(), "Box"); + + let a = &8u as &Any; + let b = &Test as &Any; + let s = format!("{}", a); + assert_eq!(s.as_slice(), "&Any"); + let s = format!("{}", b); + assert_eq!(s.as_slice(), "&Any"); + } +} diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 80b6cee2a9d..6ae91f38971 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -21,11 +21,11 @@ //! //! Currently, there are four major definitions in this library. //! -//! ## Owned pointers +//! ## Boxed values //! -//! The [`Box`](owned/index.html) type is the core owned pointer type in rust. +//! The [`Box`](boxed/index.html) type is the core owned pointer type in rust. //! There can only be one owner of a `Box`, and the owner can decide to mutate -//! the contents. +//! the contents, which live on the heap. //! //! This type can be sent among tasks efficiently as the size of a `Box` value //! is just a pointer. Tree-like data structures are often built on owned @@ -82,6 +82,12 @@ extern crate libc; #[cfg(test)] #[phase(plugin, link)] extern crate std; #[cfg(test)] #[phase(plugin, link)] extern crate log; +// The deprecated name of the boxed module + +#[deprecated = "use boxed instead"] +#[cfg(not(test))] +pub use owned = boxed; + // Heaps provided for low-level allocation strategies pub mod heap; @@ -91,7 +97,7 @@ pub mod util; // Primitive types using the heaps above #[cfg(not(test))] -pub mod owned; +pub mod boxed; pub mod arc; pub mod rc; diff --git a/src/liballoc/owned.rs b/src/liballoc/owned.rs deleted file mode 100644 index addec396bbe..00000000000 --- a/src/liballoc/owned.rs +++ /dev/null @@ -1,201 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A unique pointer type - -use core::any::{Any, AnyRefExt}; -use core::clone::Clone; -use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering}; -use core::default::Default; -use core::fmt; -use core::intrinsics; -use core::kinds::Send; -use core::mem; -use core::option::Option; -use core::raw::TraitObject; -use core::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: -/// -/// use std::owned::HEAP; -/// -/// # struct Bar; -/// # impl Bar { fn new(_a: int) { } } -/// let foo = box(HEAP) Bar::new(2); -/// let foo = box Bar::new(2); -#[lang="exchange_heap"] -pub static HEAP: () = (); - -/// A type that represents a uniquely-owned value. -#[lang="owned_box"] -pub struct Box(*mut T); - -impl Default for Box { - fn default() -> Box { box Default::default() } -} - -#[unstable] -impl Clone for Box { - /// Return a copy of the owned box. - #[inline] - fn clone(&self) -> Box { box {(**self).clone()} } - - /// Perform copy-assignment from `source` by reusing the existing allocation. - #[inline] - fn clone_from(&mut self, source: &Box) { - (**self).clone_from(&(**source)); - } -} - -// box pointers -impl PartialEq for Box { - #[inline] - fn eq(&self, other: &Box) -> bool { *(*self) == *(*other) } - #[inline] - fn ne(&self, other: &Box) -> bool { *(*self) != *(*other) } -} -impl PartialOrd for Box { - #[inline] - fn partial_cmp(&self, other: &Box) -> Option { - (**self).partial_cmp(*other) - } - #[inline] - fn lt(&self, other: &Box) -> bool { *(*self) < *(*other) } - #[inline] - fn le(&self, other: &Box) -> bool { *(*self) <= *(*other) } - #[inline] - fn ge(&self, other: &Box) -> bool { *(*self) >= *(*other) } - #[inline] - fn gt(&self, other: &Box) -> bool { *(*self) > *(*other) } -} -impl Ord for Box { - #[inline] - fn cmp(&self, other: &Box) -> Ordering { (**self).cmp(*other) } -} -impl Eq for Box {} - -/// 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(self) -> Result, Self>; -} - -impl AnyOwnExt for Box { - #[inline] - fn move(self) -> Result, Box> { - if self.is::() { - unsafe { - // Get the raw representation of the trait object - let to: TraitObject = - *mem::transmute::<&Box, &TraitObject>(&self); - - // Prevent destructor on self being run - intrinsics::forget(self); - - // Extract the data pointer - Ok(mem::transmute(to.data)) - } - } else { - Err(self) - } - } -} - -/// Extension methods for an owning `Any+Send` trait object -pub trait AnySendOwnExt { - /// Returns the boxed value if it is of type `T`, or - /// `Err(Self)` if it isn't. - fn move_send(self) -> Result, Self>; -} - -impl AnySendOwnExt for Box { - #[inline] - fn move_send(self) -> Result, Box> { - if self.is::() { - unsafe { - // Get the raw representation of the trait object - let to: TraitObject = - *mem::transmute::<&Box, &TraitObject>(&self); - - // Prevent destructor on self being run - intrinsics::forget(self); - - // Extract the data pointer - Ok(mem::transmute(to.data)) - } - } else { - Err(self) - } - } -} - -impl fmt::Show for Box { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - (**self).fmt(f) - } -} - -impl fmt::Show for Box { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad("Box") - } -} - -#[cfg(test)] -mod test { - #[test] - fn test_owned_clone() { - let a = box 5i; - let b: Box = a.clone(); - assert!(a == b); - } - - #[test] - fn any_move() { - let a = box 8u as Box; - let b = box Test as Box; - - match a.move::() { - Ok(a) => { assert!(a == box 8u); } - Err(..) => fail!() - } - match b.move::() { - Ok(a) => { assert!(a == box Test); } - Err(..) => fail!() - } - - let a = box 8u as Box; - let b = box Test as Box; - - assert!(a.move::>().is_err()); - assert!(b.move::>().is_err()); - } - - #[test] - fn test_show() { - let a = box 8u as Box; - let b = box Test as Box; - let a_str = a.to_str(); - let b_str = b.to_str(); - assert_eq!(a_str.as_slice(), "Box"); - assert_eq!(b_str.as_slice(), "Box"); - - let a = &8u as &Any; - let b = &Test as &Any; - let s = format!("{}", a); - assert_eq!(s.as_slice(), "&Any"); - let s = format!("{}", b); - assert_eq!(s.as_slice(), "&Any"); - } -} -- cgit 1.4.1-3-g733a5