// Copyright 2012-2015 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. #![stable] use core::any::Any; use core::clone::Clone; use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering}; use core::default::Default; use core::fmt; use core::hash::{self, Hash}; use core::marker::Sized; use core::mem; use core::option::Option; use core::ptr::Unique; use core::raw::TraitObject; use core::result::Result; use core::result::Result::{Ok, Err}; use core::ops::{Deref, DerefMut}; /// 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: /// /// ```rust /// #![feature(box_syntax)] /// use std::boxed::HEAP; /// /// fn main() { /// # 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"] #[stable] pub struct Box(Unique); impl Box { /// Moves `x` into a freshly allocated box on the global exchange heap. #[stable] pub fn new(x: T) -> Box { box x } } #[stable] impl Default for Box { #[stable] fn default() -> Box { box Default::default() } } #[stable] impl Default for Box<[T]> { #[stable] fn default() -> Box<[T]> { box [] } } #[stable] impl Clone for Box { /// Returns a copy of the owned box. #[inline] fn clone(&self) -> Box { box {(**self).clone()} } /// Performs copy-assignment from `source` by reusing the existing allocation. #[inline] fn clone_from(&mut self, source: &Box) { (**self).clone_from(&(**source)); } } #[stable] impl PartialEq for Box { #[inline] fn eq(&self, other: &Box) -> bool { PartialEq::eq(&**self, &**other) } #[inline] fn ne(&self, other: &Box) -> bool { PartialEq::ne(&**self, &**other) } } #[stable] impl PartialOrd for Box { #[inline] fn partial_cmp(&self, other: &Box) -> Option { PartialOrd::partial_cmp(&**self, &**other) } #[inline] fn lt(&self, other: &Box) -> bool { PartialOrd::lt(&**self, &**other) } #[inline] fn le(&self, other: &Box) -> bool { PartialOrd::le(&**self, &**other) } #[inline] fn ge(&self, other: &Box) -> bool { PartialOrd::ge(&**self, &**other) } #[inline] fn gt(&self, other: &Box) -> bool { PartialOrd::gt(&**self, &**other) } } #[stable] impl Ord for Box { #[inline] fn cmp(&self, other: &Box) -> Ordering { Ord::cmp(&**self, &**other) } } #[stable] impl Eq for Box {} #[cfg(stage0)] impl> Hash for Box { #[inline] fn hash(&self, state: &mut S) { (**self).hash(state); } } #[cfg(not(stage0))] impl> Hash for Box { #[inline] fn hash(&self, state: &mut S) { (**self).hash(state); } } /// Extension methods for an owning `Any` trait object. #[unstable = "post-DST and coherence changes, this will not be a trait but \ rather a direct `impl` on `Box`"] pub trait BoxAny { /// Returns the boxed value if it is of type `T`, or /// `Err(Self)` if it isn't. #[stable] fn downcast(self) -> Result, Self>; } impl BoxAny for Box { #[inline] #[unstable = "method may be renamed with respect to other downcasting \ methods"] fn downcast(self) -> Result, Box> { if self.is::() { unsafe { // Get the raw representation of the trait object let to: TraitObject = mem::transmute::, TraitObject>(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 { write!(f, "Box({:?})", &**self) } } #[stable] impl fmt::String for Box { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::String::fmt(&**self, f) } } impl fmt::Show for Box { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.pad("Box") } } #[stable] impl Deref for Box { type Target = T; fn deref(&self) -> &T { &**self } } #[stable] impl DerefMut for Box { fn deref_mut(&mut self) -> &mut T { &mut **self } } #[cfg(test)] mod test { #[test] fn test_owned_clone() { let a = Box::new(5i); let b: Box = a.clone(); assert!(a == b); } #[test] fn any_move() { let a = Box::new(8u) as Box; let b = Box::new(Test) as Box; match a.downcast::() { Ok(a) => { assert!(a == Box::new(8u)); } Err(..) => panic!() } match b.downcast::() { Ok(a) => { assert!(a == Box::new(Test)); } Err(..) => panic!() } let a = Box::new(8u) as Box; let b = Box::new(Test) as Box; assert!(a.downcast::>().is_err()); assert!(b.downcast::>().is_err()); } #[test] fn test_show() { let a = Box::new(8u) as Box; let b = Box::new(Test) as Box; let a_str = a.to_str(); let b_str = b.to_str(); assert_eq!(a_str, "Box"); assert_eq!(b_str, "Box"); let a = &8u as &Any; let b = &Test as &Any; let s = format!("{}", a); assert_eq!(s, "&Any"); let s = format!("{}", b); assert_eq!(s, "&Any"); } #[test] fn deref() { fn homura>(_: T) { } homura(Box::new(765i32)); } }