Skip to main content

AnyInterner

Struct AnyInterner 

Source
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

Source

pub fn of<K: 'static>() -> Self

Source§

impl<S: BuildHasher> AnyInterner<S>

Source

pub fn with_hasher<K: 'static>(hash_builder: S) -> Self

Source

pub fn len(&self) -> usize

Returns number of values the interner contains.

Source

pub fn is_empty(&self) -> bool

Returns true if the interner is empty.

Source

pub unsafe fn intern<K>(&self, value: K) -> Interned<'_, K>
where K: Hash + Eq + 'static,

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.

Source

pub unsafe fn intern_with<K, Q, F>( &self, key: &Q, make_value: F, ) -> Interned<'_, K>
where K: Borrow<Q> + 'static, Q: Hash + Eq + ?Sized, F: FnOnce() -> 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.

Source

pub unsafe fn get<K, Q>(&self, key: &Q) -> Option<Interned<'_, K>>
where K: Borrow<Q> + 'static, Q: Hash + Eq + ?Sized,

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.

Source

pub fn is_type_of<K: 'static>(&self) -> bool

Returns true if the interner contains values of the given type.

Source

pub fn clear(&mut self)

Removes all items in the interner.

Although the interner support interior mutability, clear method requires mutable access to the interner to invalidate all Interneds referencing the interner.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.