X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fliballoc%2Fboxed.rs;h=2801cf38cb75529d94912551a60a5eab51597235;hb=82dcec7ee4a8a71fdfb8e8771ae6785261ec1d5b;hp=bbf5d7a6042f2e4540899310d07933a273572d21;hpb=a3f6273795363c29f3b70c9fa1229c3ed5c14afd;p=rust.git diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index bbf5d7a6042..2801cf38cb7 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -300,3 +300,74 @@ fn next_back(&mut self) -> Option { (**self).next_back() } #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for Box {} + +/// `FnBox` is a version of the `FnOnce` intended for use with boxed +/// closure objects. The idea is that where one would normally store a +/// `Box` in a data structure, you should use +/// `Box`. The two traits behave essentially the same, except +/// that a `FnBox` closure can only be called if it is boxed. (Note +/// that `FnBox` may be deprecated in the future if `Box` +/// closures become directly usable.) +/// +/// ### Example +/// +/// Here is a snippet of code which creates a hashmap full of boxed +/// once closures and then removes them one by one, calling each +/// closure as it is removed. Note that the type of the closures +/// stored in the map is `Box i32>` and not `Box i32>`. +/// +/// ``` +/// #![feature(core)] +/// +/// use std::boxed::FnBox; +/// use std::collections::HashMap; +/// +/// fn make_map() -> HashMap i32>> { +/// let mut map: HashMap i32>> = HashMap::new(); +/// map.insert(1, Box::new(|| 22)); +/// map.insert(2, Box::new(|| 44)); +/// map +/// } +/// +/// fn main() { +/// let mut map = make_map(); +/// for i in &[1, 2] { +/// let f = map.remove(&i).unwrap(); +/// assert_eq!(f(), i * 22); +/// } +/// } +/// ``` +#[rustc_paren_sugar] +#[unstable(feature = "core", reason = "Newly introduced")] +pub trait FnBox { + type Output; + + fn call_box(self: Box, args: A) -> Self::Output; +} + +impl FnBox for F + where F: FnOnce +{ + type Output = F::Output; + + fn call_box(self: Box, args: A) -> F::Output { + self.call_once(args) + } +} + +impl<'a,A,R> FnOnce for Box+'a> { + type Output = R; + + extern "rust-call" fn call_once(self, args: A) -> R { + self.call_box(args) + } +} + +impl<'a,A,R> FnOnce for Box+Send+'a> { + type Output = R; + + extern "rust-call" fn call_once(self, args: A) -> R { + self.call_box(args) + } +}