pub struct AnyInterner<S = FxBuildHasher> { /* private fields */ }Expand description
A type-erased interner for storing and deduplicating values of a single type.
This interner is simply a wrapper of AnyInternSet with interior mutability. If you need a
collection of interners for various types like a hash map of interners, then consider using the
AnyInterSet with a container providing interior mutability such as [ManualMutex].
§Examples
use any_intern::AnyInterner;
#[derive(PartialEq, Eq, Hash, Debug)]
struct A(u32);
let interner = AnyInterner::of::<A>();
unsafe {
let a1 = interner.intern(A(42));
let a2 = interner.intern(A(42));
assert_eq!(a1, a2); // Same value, same reference
let a3 = interner.intern(A(99));
assert_ne!(a1, a3); // Different values, different references
}§Safety
Many methods in AnyInterner are marked as unsafe because they rely on the caller to ensure
that the correct type is used when interacting with the interner. Using an incorrect type can
lead to undefined behavior.
Implementations§
Source§impl AnyInterner
impl AnyInterner
Source§impl<S: BuildHasher> AnyInterner<S>
impl<S: BuildHasher> AnyInterner<S>
pub fn with_hasher<K: 'static>(hash_builder: S) -> Self
Sourcepub unsafe fn intern<K>(&self, value: K) -> Interned<'_, K>
pub unsafe fn intern<K>(&self, value: K) -> Interned<'_, K>
Stores a value in the interner, returning a reference to the interned value.
This method inserts the given value into the interner if it does not already exist. If the value already exists, a reference to the existing value is returned.
§Examples
use any_intern::AnyInterner;
#[derive(PartialEq, Eq, Hash, Debug)]
struct A(u32);
let interner = AnyInterner::of::<A>();
unsafe {
let a1 = interner.intern(A(42));
let a2 = interner.intern(A(42));
assert_eq!(a1, a2); // Same value, same reference
assert_eq!(a1.raw().as_ptr(), a2.raw().as_ptr());
}§Safety
Undefined behavior if incorrect type K is given.
Sourcepub unsafe fn intern_with<K, Q, F>(
&self,
key: &Q,
make_value: F,
) -> Interned<'_, K>
pub unsafe fn intern_with<K, Q, F>( &self, key: &Q, make_value: F, ) -> Interned<'_, K>
Stores a value in the interner, creating it only if it does not already exist.
This method allows you to provide a key and a closure to generate the value. If the key already exists in the interner, the closure is not called, and a reference to the existing value is returned. If the key does not exist, the closure is called to create the value, which is then stored in the interner.
This method is useful when the value is expensive to compute, as it avoids unnecessary computation if the value already exists.
§Examples
use any_intern::AnyInterner;
#[derive(PartialEq, Eq, Hash, Debug)]
struct A(i32);
impl std::borrow::Borrow<i32> for A {
fn borrow(&self) -> &i32 {
&self.0
}
}
let interner = AnyInterner::of::<A>();
unsafe {
let a = interner.intern_with(&42, || A(42));
assert_eq!(interner.len(), 1);
assert_eq!(*a, A(42));
let b = interner.intern_with(&42, || A(99)); // Closure is not called
assert_eq!(interner.len(), 1);
assert_eq!(*b, A(42));
let c = interner.intern_with(&43, || A(43));
assert_eq!(interner.len(), 2);
assert_eq!(*c, A(43));
}§Safety
Undefined behavior if incorrect type K is given.
Sourcepub unsafe fn get<K, Q>(&self, key: &Q) -> Option<Interned<'_, K>>
pub unsafe fn get<K, Q>(&self, key: &Q) -> Option<Interned<'_, K>>
Retrieves a reference to a value in the interner based on the provided key.
This method checks if a value corresponding to the given key exists in the interner. If it
exists, a reference to the interned value is returned. Otherwise, None is returned.
§Eaxmples
use any_intern::AnyInterner;
let interner = AnyInterner::of::<i32>();
unsafe {
interner.intern(42);
assert_eq!(interner.get::<i32, _>(&42).as_deref(), Some(&42));
assert!(interner.get::<i32, _>(&99).is_none());
}§Safety
Undefined behavior if incorrect type K is given.
Sourcepub fn is_type_of<K: 'static>(&self) -> bool
pub fn is_type_of<K: 'static>(&self) -> bool
Returns true if the interner contains values of the given type.