Skip to main content

weak_table/
lib.rs

1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(feature = "std"), no_std)]
3
4use self::compat::*;
5
6pub mod ptr_weak_hash_set;
7pub mod ptr_weak_key_hash_map;
8pub mod ptr_weak_weak_hash_map;
9pub mod traits;
10pub mod weak_hash_set;
11pub mod weak_key_hash_map;
12pub mod weak_value_hash_map;
13pub mod weak_weak_hash_map;
14
15#[cfg(test)]
16mod tests;
17
18mod by_ptr;
19mod common;
20mod compat;
21mod inner;
22mod size_policy;
23mod util;
24
25/// A hash map with weak keys, hashed on key value.
26///
27/// When a weak pointer expires, its mapping is lazily removed.
28#[derive(Clone)]
29pub struct WeakKeyHashMap<K, V, S = RandomState>(inner::Table<inner::WeakK<K>, inner::Owned<V>, S>);
30
31/// A hash map with weak keys, hashed on key pointer.
32///
33/// When a weak pointer expires, its mapping is lazily removed.
34///
35/// # Examples
36///
37/// ```
38/// use weak_table::PtrWeakKeyHashMap;
39/// use std::rc::{Rc, Weak};
40///
41/// type Table = PtrWeakKeyHashMap<Weak<str>, usize>;
42///
43/// let mut map = Table::new();
44/// let a = Rc::<str>::from("hello");
45/// let b = Rc::<str>::from("hello");
46///
47/// map.insert(a.clone(), 5);
48///
49/// assert_eq!( map.get(&a), Some(&5) );
50/// assert_eq!( map.get(&b), None );
51///
52/// map.insert(b.clone(), 7);
53///
54/// assert_eq!( map.get(&a), Some(&5) );
55/// assert_eq!( map.get(&b), Some(&7) );
56/// ```
57#[derive(Clone)]
58pub struct PtrWeakKeyHashMap<K, V, S = RandomState>(WeakKeyHashMap<by_ptr::ByPtr<K>, V, S>);
59
60/// A hash map with weak values.
61///
62/// When a weak pointer expires, its mapping is lazily removed.
63#[derive(Clone)]
64pub struct WeakValueHashMap<K, V, S = RandomState>(
65    inner::Table<inner::Owned<K>, inner::WeakV<V>, S>,
66);
67
68/// A hash map with weak keys and weak values, hashed on key value.
69///
70/// When a weak pointer expires, its mapping is lazily removed.
71#[derive(Clone)]
72pub struct WeakWeakHashMap<K, V, S = RandomState>(
73    inner::Table<inner::WeakK<K>, inner::WeakV<V>, S>,
74);
75
76/// A hash map with weak keys and weak values, hashed on key pointer.
77///
78/// When a weak pointer expires, its mapping is lazily removed.
79#[derive(Clone)]
80pub struct PtrWeakWeakHashMap<K, V, S = RandomState>(WeakWeakHashMap<by_ptr::ByPtr<K>, V, S>);
81
82/// A hash set with weak elements, hashed on element value.
83///
84/// When a weak pointer expires, its mapping is lazily removed.
85#[derive(Clone)]
86pub struct WeakHashSet<T, S = RandomState>(WeakKeyHashMap<T, (), S>);
87
88/// A hash set with weak elements, hashed on element pointer.
89///
90/// When a weak pointer expires, its mapping is lazily removed.
91#[derive(Clone)]
92pub struct PtrWeakHashSet<T, S = RandomState>(PtrWeakKeyHashMap<T, (), S>);
93
94/// An error that can occur during a `try_reserve` method.
95#[derive(Clone, Debug)]
96#[non_exhaustive]
97pub enum TryReserveError {
98    /// The amount of memory that we would need to allocate
99    /// would have been greater than the maximum (typically `isize::MAX).
100    CapacityOverflow,
101
102    /// We were unable to allocate memory to grow the table or set.
103    AllocError {
104        /// The memory layout that we were unable to allocate.
105        layout: Layout,
106    },
107}
108
109impl TryReserveError {
110    /// Construct a TryReserveError from the hashbrown equivalent.
111    ///
112    /// (For implementation hiding purposes, this is not a public `From`
113    /// implementation.)
114    #[allow(clippy::needless_pass_by_value)]
115    pub(crate) fn from_hashbrown(error: hashbrown::TryReserveError) -> Self {
116        match error {
117            hashbrown::TryReserveError::CapacityOverflow => TryReserveError::CapacityOverflow,
118            hashbrown::TryReserveError::AllocError { layout } => {
119                TryReserveError::AllocError { layout }
120            }
121        }
122    }
123}
124impl Display for TryReserveError {
125    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
126        match self {
127            TryReserveError::CapacityOverflow => write!(
128                f,
129                "Allocation failed: arithmetic overflow in capacity calculation"
130            ),
131            TryReserveError::AllocError { .. } => {
132                write!(f, "Allocation failed: memory allocator returned an error")
133            }
134        }
135    }
136}
137#[cfg(feature = "std")]
138impl Error for TryReserveError {}