// 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 pointer type for heap allocation. //! //! `Box`, casually referred to as a 'box', provides the simplest form of heap allocation in //! Rust. Boxes provide ownership for this allocation, and drop their contents when they go out of //! scope. //! //! Boxes are useful in two situations: recursive data structures, and occasionally when returning //! data. [The Pointer chapter of the Book](../../../book/pointers.html#best-practices-1) explains //! these cases in detail. //! //! # Examples //! //! Creating a box: //! //! ``` //! let x = Box::new(5); //! ``` //! //! Creating a recursive data structure: //! //! ``` //! #[derive(Show)] //! enum List { //! Cons(T, Box>), //! Nil, //! } //! //! fn main() { //! let list: List = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil)))); //! println!("{:?}", list); //! } //! ``` //! //! This will print `Cons(1i32, Box(Cons(2i32, Box(Nil))))`. #![stable] use core::any::Any; use core::clone::Clone; use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering}; use core::default::Default; use core::error::{Error, FromError}; use core::fmt; use core::hash::{self, Hash}; use core::iter::Iterator; use core::marker::Sized; use core::mem; use core::ops::{Deref, DerefMut}; use core::option::Option; use core::ptr::Unique; use core::raw::TraitObject; use core::result::Result::{Ok, Err}; use core::result::Result; /// A value that represents the 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() { /// let foo = box(HEAP) 5; /// let foo = box 5; /// } /// ``` #[lang = "exchange_heap"] #[unstable = "may be renamed; uncertain about custom allocator design"] pub static HEAP: () = (); /// A pointer type for heap allocation. /// /// See the [module-level documentation](../../std/boxed/index.html) for more. #[lang = "owned_box"] #[stable] pub struct Box(Unique); impl Box { /// Allocates memory on the heap and then moves `x` into it. /// /// # Examples /// /// ``` /// let x = Box::new(5); /// ``` #[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 new box with a `clone()` of this box's contents. /// /// # Examples /// /// ``` /// let x = Box::new(5); /// let y = x.clone(); /// ``` #[inline] fn clone(&self) -> Box { box {(**self).clone()} } /// Copies `source`'s contents into `self` without creating a new allocation. /// /// # Examples /// /// ``` /// let x = Box::new(5); /// let mut y = Box::new(10); /// /// y.clone_from(&x); /// /// assert_eq!(*y, 5); /// ``` #[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 {} impl> Hash for Box { #[inline] fn hash(&self, state: &mut S) { (**self).hash(state); } } /// Extension methods for an owning `Any` trait object. #[unstable = "this trait will likely disappear once compiler bugs blocking \ a direct impl on `Box` have been fixed "] // FIXME(#18737): this should be a direct impl on `Box`. If you're // removing this please make sure that you can downcase on // `Box` as well as `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>; } #[stable] 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::, TraitObject>(self); // Extract the data pointer Ok(mem::transmute(to.data)) } } else { Err(self) } } } #[stable] impl fmt::Display for Box { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&**self, f) } } #[stable] impl fmt::Debug for Box { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&**self, f) } } #[stable] impl fmt::Debug 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 } } // FIXME(#21363) remove `old_impl_check` when bug is fixed #[old_impl_check] impl<'a, T> Iterator for Box + 'a> { type Item = T; fn next(&mut self) -> Option { (**self).next() } fn size_hint(&self) -> (usize, Option) { (**self).size_hint() } } impl<'a, E: Error + 'a> FromError for Box { fn from_error(err: E) -> Box { Box::new(err) } }