Add (unstable) FnBox trait as a nicer replacement for `Thunk`. The doc

comment includes a test that also shows how it can be used.
This commit is contained in:
Niko Matsakis 2015-04-01 10:11:46 -04:00
parent d528aa9960
commit ed63d32651
2 changed files with 76 additions and 0 deletions

View File

@ -355,3 +355,78 @@ impl<'a, 'b> From<&'b str> for Box<Error + Send + 'a> {
}
}
}
/// `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<FnOnce()>` in a data structure, you should use
/// `Box<FnBox()>`. 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<FnOnce()>`
/// 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<FnBox() -> i32>` and not `Box<FnOnce()
/// -> i32>`.
///
/// ```
/// #![feature(core)]
///
/// use std::boxed::FnBox;
/// use std::collections::HashMap;
///
/// fn make_map() -> HashMap<i32, Box<FnBox() -> i32>> {
/// let mut map: HashMap<i32, Box<FnBox() -> 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);
/// }
/// }
/// ```
#[cfg(not(stage0))]
#[rustc_paren_sugar]
#[unstable(feature = "core", reason = "Newly introduced")]
pub trait FnBox<A> {
type Output;
extern "rust-call" fn call_box(self: Box<Self>, args: A) -> Self::Output;
}
#[cfg(not(stage0))]
impl<A,F> FnBox<A> for F
where F: FnOnce<A>
{
type Output = F::Output;
extern "rust-call" fn call_box(self: Box<F>, args: A) -> F::Output {
self.call_once(args)
}
}
#[cfg(not(stage0))]
impl<A,R> FnOnce<A> for Box<FnBox<A,Output=R>> {
type Output = R;
extern "rust-call" fn call_once(self, args: A) -> R {
self.call_box(args)
}
}
#[cfg(not(stage0))]
impl<A,R> FnOnce<A> for Box<FnBox<A,Output=R>+Send> {
type Output = R;
extern "rust-call" fn call_once(self, args: A) -> R {
self.call_box(args)
}
}

View File

@ -243,6 +243,7 @@ mod uint_macros;
#[path = "num/f64.rs"] pub mod f64;
pub mod ascii;
pub mod thunk;
/* Common traits */