@@ -355,3 +355,78 @@ impl<'a, 'b> From<&'b str> for Box<Error + Send + 'a> {
355
355
}
356
356
}
357
357
}
358
+
359
+ /// `FnBox` is a version of the `FnOnce` intended for use with boxed
360
+ /// closure objects. The idea is that where one would normally store a
361
+ /// `Box<FnOnce()>` in a data structure, you should use
362
+ /// `Box<FnBox()>`. The two traits behave essentially the same, except
363
+ /// that a `FnBox` closure can only be called if it is boxed. (Note
364
+ /// that `FnBox` may be deprecated in the future if `Box<FnOnce()>`
365
+ /// closures become directly usable.)
366
+ ///
367
+ /// ### Example
368
+ ///
369
+ /// Here is a snippet of code which creates a hashmap full of boxed
370
+ /// once closures and then removes them one by one, calling each
371
+ /// closure as it is removed. Note that the type of the closures
372
+ /// stored in the map is `Box<FnBox() -> i32>` and not `Box<FnOnce()
373
+ /// -> i32>`.
374
+ ///
375
+ /// ```
376
+ /// #![feature(core)]
377
+ ///
378
+ /// use std::boxed::FnBox;
379
+ /// use std::collections::HashMap;
380
+ ///
381
+ /// fn make_map() -> HashMap<i32, Box<FnBox() -> i32>> {
382
+ /// let mut map: HashMap<i32, Box<FnBox() -> i32>> = HashMap::new();
383
+ /// map.insert(1, Box::new(|| 22));
384
+ /// map.insert(2, Box::new(|| 44));
385
+ /// map
386
+ /// }
387
+ ///
388
+ /// fn main() {
389
+ /// let mut map = make_map();
390
+ /// for i in &[1, 2] {
391
+ /// let f = map.remove(&i).unwrap();
392
+ /// assert_eq!(f(), i * 22);
393
+ /// }
394
+ /// }
395
+ /// ```
396
+ #[ cfg( not( stage0) ) ]
397
+ #[ rustc_paren_sugar]
398
+ #[ unstable( feature = "core" , reason = "Newly introduced" ) ]
399
+ pub trait FnBox < A > {
400
+ type Output ;
401
+
402
+ extern "rust-call" fn call_box ( self : Box < Self > , args : A ) -> Self :: Output ;
403
+ }
404
+
405
+ #[ cfg( not( stage0) ) ]
406
+ impl < A , F > FnBox < A > for F
407
+ where F : FnOnce < A >
408
+ {
409
+ type Output = F :: Output ;
410
+
411
+ extern "rust-call" fn call_box ( self : Box < F > , args : A ) -> F :: Output {
412
+ self . call_once ( args)
413
+ }
414
+ }
415
+
416
+ #[ cfg( not( stage0) ) ]
417
+ impl < A , R > FnOnce < A > for Box < FnBox < A , Output =R > > {
418
+ type Output = R ;
419
+
420
+ extern "rust-call" fn call_once ( self , args : A ) -> R {
421
+ self . call_box ( args)
422
+ }
423
+ }
424
+
425
+ #[ cfg( not( stage0) ) ]
426
+ impl < A , R > FnOnce < A > for Box < FnBox < A , Output =R > +Send > {
427
+ type Output = R ;
428
+
429
+ extern "rust-call" fn call_once ( self , args : A ) -> R {
430
+ self . call_box ( args)
431
+ }
432
+ }
0 commit comments