Rust does NOT monomorphize it's [static generic items]. This means you cannot
use a generic static item in a generic function. You'll get the following
error:
text
error[E0401]: can't use generic parameters from outer function
That's pretty frustrating when you want to write a singleton pattern that rely's on a generic parameter. This crate allows for this pattern with minimal runtime overhead.
generic_singleton
uses [anymap] behind the scenes to store a map of each
generic type. The first time you hit the get_or_init
macro we initialize the
singleton. Subsequent calls to get_or_init
will retrieve the singleton from
the map.
```rust use std::{ops::AddAssign, sync::RwLock};
use num_traits::{One, Zero};
fn genericcallcounter
fn main() {
// Works with usize
asserteq!(genericcallcounter::
// 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);
} ```
The example shown above has a drawback of requiring an RwLock
to ensure
synchronisation around the inner [AnyMap]. In single-threaded situations we can
remove this lock and provide mutable references directly using the
get_or_init_thread_local!
macro. This comes at the cost of ergonomics,
requiring you to express your logic in a closure rather than simply returning a
reference.