Last active
August 30, 2016 21:38
-
-
Save randomPoison/e8b9bf35611447614e373a1a00f2f22b to your computer and use it in GitHub Desktop.
Version that only uses a hand-rolled macro to do magic.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(fnbox)] | |
use std::boxed::FnBox; | |
/// Represents a single unit of work that needs doing. | |
/// | |
/// Erases type information about the work that needs to be done, reducing it | |
/// to a single function invocation. | |
struct Worker(Box<FnBox()>); | |
impl Worker { | |
/// Creates a new unit of work | |
unsafe fn new<T: 'static>(value: T, out: &mut Option<T>) -> Worker { | |
let out_ptr = out as *mut _; | |
let work_proc = move || { | |
*out_ptr = Some(value); | |
}; | |
Worker(Box::new(work_proc)) | |
} | |
} | |
fn finish_all<I: IntoIterator<Item = Worker>>(workers: I) { | |
for worker in workers { | |
worker.0(); | |
} | |
} | |
macro_rules! do_work { | |
($work_0: expr, $work_1: expr, $work_2: expr) => { | |
{ | |
let mut result_0 = None; | |
let mut result_1 = None; | |
let mut result_2 = None; | |
let worker_0 = unsafe { Worker::new($work_0, &mut result_0) }; | |
let worker_1 = unsafe { Worker::new($work_1, &mut result_1) }; | |
let worker_2 = unsafe { Worker::new($work_2, &mut result_2) }; | |
finish_all(vec![worker_0, worker_1, worker_2]); | |
(result_0.unwrap(), result_1.unwrap(), result_2.unwrap()) | |
} | |
}; | |
($work_0: expr, $work_1: expr) => { | |
{ | |
let mut result_0 = None; | |
let mut result_1 = None; | |
let worker_0 = unsafe { Worker::new($work_0, &mut result_0) }; | |
let worker_1 = unsafe { Worker::new($work_1, &mut result_1) }; | |
finish_all(vec![worker_0, worker_1]); | |
(result_0.unwrap(), result_1.unwrap()) | |
} | |
}; | |
} | |
fn main() { | |
let result = do_work!(1, true, 3.14); | |
println!("{:?}", result); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment