macro_rules! get_or_init_thread_local {
($init:expr, $with:expr) => { ... };
}Expand description
Same as the get_or_init! macro but using thread local storage. Similar to the thread_local! macro API, we use a closure that yields a mutable reference to your struct. The closure ensures the reference cannot escape to a different thread.
ยงExample
use num_traits::{One, Zero};
use std::cell::Cell;
use std::ops::AddAssign;
fn generic_call_counter<T: Zero + One + Copy + AddAssign + Send + 'static>() -> T {
let mut output = T::zero();
generic_singleton::get_or_init_thread_local!(|| Cell::new(T::zero()), |count_cell| {
let mut count = count_cell.get();
count += T::one();
count_cell.set(count);
output = count;
});
output
}
fn main() {
// Works with usize
assert_eq!(generic_call_counter::<usize>(), 1);
assert_eq!(generic_call_counter::<usize>(), 2);
assert_eq!(generic_call_counter::<usize>(), 3);
// Works with i32
assert_eq!(generic_call_counter::<i32>(), 1);
assert_eq!(generic_call_counter::<i32>(), 2);
assert_eq!(generic_call_counter::<i32>(), 3);
// Works with f32
assert_eq!(generic_call_counter::<f32>(), 1.0);
assert_eq!(generic_call_counter::<f32>(), 2.0);
assert_eq!(generic_call_counter::<f32>(), 3.0);
}