use std::{thread, mem};
trait FnBox {
fn call_box(self: Box<Self>);
}
impl<F: FnOnce()> FnBox for F {
fn call_box(self: Box<Self>) { (*self)() }
}
unsafe fn spawn_unsafe<'a, F: FnOnce() + Send + 'a>(func: F) -> thread::JoinHandle<()> {
let closure: Box<FnBox + 'a> = Box::new(func);
let closure: Box<FnBox + Send> = mem::transmute(closure);
thread::spawn(move || closure.call_box())
}
fn spawn_double<F: Fn() + Sync + Send>(func: F) {
let handle;
unsafe {
handle = spawn_unsafe(|| func());
}
func();
handle.join().unwrap();
}
#[allow(dead_code)]
pub fn multiply<F: Fn() + Sync + Send + 'static>(func: F) {
spawn_double(|| spawn_double(|| acid(|| func())));
}
#[allow(dead_code)]
pub fn acid<F: FnOnce()>(func: F) {
let mut vec = vec!["something", "yep", "yup"];
let mut _v = vec![Box::new(2), Box::new(5)];
let mut bx = Box::new(2389);
let abc = Box::new("abc");
vec.shrink_to_fit();
vec.extend(["lol", "lulz"].iter());
vec.shrink_to_fit();
vec.extend(["we", "are"].iter());
func();
*bx = 500;
vec.push("heyaya");
*bx = 55;
assert_eq!(vec, ["something", "yep", "yup", "lol", "lulz", "we", "are", "heyaya"]);
assert_eq!(*bx, 55);
assert_eq!(*abc, "abc");
}