Crate generic_static_cache

Source
Expand description

Quoting the Rust Reference:

“A static item defined in a generic scope (for example in a blanket or default implementation) will result in exactly one static item being defined, as if the static definition was pulled out of the current scope into the module. There will not be one item per monomorphization.”

One way to work around this is to use a HashMap<TypeId,Data>. This is a simple & usually the best solution. If lookup performance is important, you can skip hashing the TypeId for minor gains as it already contains a good-quality hash. This is implemented in TypeIdMap.

This crate aims to further fully remove the lookup by allocating the storage using inline assembly.

Supported targets are x86-64 and aarch64. On other targets, the generic_static macro falls back to a hashmap and most other functionality is unavailable.

Additionally, different compilation units may access different instances of the data!

This crate requires the following unstable features: asm_const and (on unsupported targets) const_collections_with_hasher.

§Examples

Static variables in a generic context:

#![feature(const_collections_with_hasher)]
fn get_and_inc<T>() -> i32 {
    generic_static!{
        static COUNTER: &AtomicI32 = &AtomicI32::new(1);
    }
    COUNTER.fetch_add(1, Ordering::Relaxed)
}
assert_eq!(get_and_inc::<bool>(), 1);
assert_eq!(get_and_inc::<bool>(), 2);
assert_eq!(get_and_inc::<String>(), 1);
assert_eq!(get_and_inc::<bool>(), 3);

Associating data with a type:

#[derive(Copy, Clone, Eq, PartialEq)]
struct Metadata(&'static str);

struct Cat;
struct Bomb;

use generic_static_cache::{get, init};
init::<Cat, _>(Metadata("nya!")).unwrap();
init::<Bomb, _>(Metadata("boom!")).unwrap();

assert_eq!(get::<Cat, _>(), Some(Metadata("nya!")));
assert_eq!(get::<Bomb, _>(), Some(Metadata("boom!")));

Macros§

generic_static
Declare a static variable that is not shared across different monomorphizations of the containing functions. Its type must be a shared reference to a type that implements Sync.

Structs§

AlreadyInitialized

Functions§

direct
Access data associated with Type without indirection. Requires interior mutability to be useful. This data is independent of the data accessed via get/init/get_or_init.
get
Access the Data-storage of type Type. Each Type can hold data for multiple different instantiations of Data.
get_or_init
Initialize & access the Data-storage of type Type. Each Type can hold data for multiple different instantiations of Data.
init
Initialize the Data-storage of type Type. Each Type can hold data for multiple different instantiations of Data.

Type Aliases§

TypeIdMap
Fast type map suitable for all platforms.