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:
parent
d528aa9960
commit
ed63d32651
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -243,6 +243,7 @@ mod uint_macros;
|
||||||
#[path = "num/f64.rs"] pub mod f64;
|
#[path = "num/f64.rs"] pub mod f64;
|
||||||
|
|
||||||
pub mod ascii;
|
pub mod ascii;
|
||||||
|
|
||||||
pub mod thunk;
|
pub mod thunk;
|
||||||
|
|
||||||
/* Common traits */
|
/* Common traits */
|
||||||
|
|
Loading…
Reference in New Issue