Skip to content

Instantly share code, notes, and snippets.

@hamzamuric
Created January 3, 2024 02:17
Show Gist options
  • Save hamzamuric/4619c07d721d350fb9eb7e71fe944e68 to your computer and use it in GitHub Desktop.
Save hamzamuric/4619c07d721d350fb9eb7e71fe944e68 to your computer and use it in GitHub Desktop.
#![feature(fn_traits, unboxed_closures, tuple_trait)]
use std::marker::Tuple;
pub struct Once<F> {
f: Option<F>,
}
impl<Args: Tuple, F: FnOnce<Args, Output = ()>> FnMut<Args> for Once<F> {
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output {
if let Some(f) = self.f.take() {
f.call_once(args)
}
}
}
impl<Args: Tuple, F: FnOnce<Args, Output = ()>> FnOnce<Args> for Once<F> {
type Output = ();
extern "rust-call" fn call_once(self, args: Args) -> Self::Output {
if let Some(f) = self.f {
f.call_once(args)
}
}
}
pub fn once<Args: Tuple, F: FnOnce<Args>>(f: F) -> Once<F> {
Once { f: Some(f) }
}
fn foo(a: i32, b: i32) {
println!("{a} {b}");
}
fn main() {
let mut f = once(foo);
f(1, 2);
f(3, 4);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment