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/// Declare a structure with a default BuildHasher.
26#[cfg(any(test, feature = "std", feature = "ahash"))]
27macro_rules! declare_structs {
28    {
29        $(
30        $(#[$meta:meta])*
31        pub struct $name:ident < $($param:ident),* ,?S > ( $($members:tt)+ );
32        )*
33    } => {
34        $(
35        $(#[$meta])*
36        pub struct $name < $($param),* , S = RandomState > ( $($members)+ );
37        )*
38    }
39}
40
41/// Declare a structure _wihtout_ a default BuildHasher
42#[cfg(not(any(test, feature = "std", feature = "ahash")))]
43macro_rules! declare_structs {
44    {
45        $(
46        $(#[$meta:meta])*
47        pub struct $name:ident < $($param:ident),* ,?S > ( $($members:tt)+ );
48        )*
49    } => {
50        $(
51        $(#[$meta])*
52        pub struct $name < $($param),* , S > ( $($members)+ );
53        )*
54    }
55}
56
57declare_structs! {
58/// A hash map with weak keys, hashed on key value.
59///
60/// When a weak pointer expires, its mapping is lazily removed.
61#[derive(Clone)]
62pub struct WeakKeyHashMap<K, V, ?S>(inner::Table<inner::WeakK<K>, inner::Owned<V>, S>);
63
64/// A hash map with weak keys, hashed on key pointer.
65///
66/// When a weak pointer expires, its mapping is lazily removed.
67///
68/// # Examples
69///
70/// ```
71/// use weak_table::PtrWeakKeyHashMap;
72/// use std::rc::{Rc, Weak};
73/// # fn x() {
74/// # type PtrWeakKeyHashMap<T, U> = weak_table::PtrWeakKeyHashMap<T, U, ahash::RandomState>;
75///
76/// type Table = PtrWeakKeyHashMap<Weak<str>, usize>;
77///
78/// let mut map = Table::default();
79/// let a = Rc::<str>::from("hello");
80/// let b = Rc::<str>::from("hello");
81///
82/// map.insert(a.clone(), 5);
83///
84/// assert_eq!( map.get(&a), Some(&5) );
85/// assert_eq!( map.get(&b), None );
86///
87/// map.insert(b.clone(), 7);
88///
89/// assert_eq!( map.get(&a), Some(&5) );
90/// assert_eq!( map.get(&b), Some(&7) );
91/// }
92/// x();
93/// ```
94#[derive(Clone)]
95pub struct PtrWeakKeyHashMap<K, V,?S>(WeakKeyHashMap<by_ptr::ByPtr<K>, V, S>);
96
97/// A hash map with weak values.
98///
99/// When a weak pointer expires, its mapping is lazily removed.
100#[derive(Clone)]
101pub struct WeakValueHashMap<K, V, ?S>(
102    inner::Table<inner::Owned<K>, inner::WeakV<V>, S>,
103);
104
105/// A hash map with weak keys and weak values, hashed on key value.
106///
107/// When a weak pointer expires, its mapping is lazily removed.
108#[derive(Clone)]
109pub struct WeakWeakHashMap<K, V, ?S>(
110    inner::Table<inner::WeakK<K>, inner::WeakV<V>, S>,
111);
112
113/// A hash map with weak keys and weak values, hashed on key pointer.
114///
115/// When a weak pointer expires, its mapping is lazily removed.
116#[derive(Clone)]
117pub struct PtrWeakWeakHashMap<K, V, ?S>(WeakWeakHashMap<by_ptr::ByPtr<K>, V, S>);
118
119/// A hash set with weak elements, hashed on element value.
120///
121/// When a weak pointer expires, its mapping is lazily removed.
122#[derive(Clone)]
123pub struct WeakHashSet<T, ?S>(WeakKeyHashMap<T, (), S>);
124
125/// A hash set with weak elements, hashed on element pointer.
126///
127/// When a weak pointer expires, its mapping is lazily removed.
128#[derive(Clone)]
129pub struct PtrWeakHashSet<T, ?S>(PtrWeakKeyHashMap<T, (), S>);
130}
131
132/// An error that can occur during a `try_reserve` method.
133#[derive(Clone, Debug)]
134#[non_exhaustive]
135pub enum TryReserveError {
136    /// The amount of memory that we would need to allocate
137    /// would have been greater than the maximum (typically `isize::MAX).
138    CapacityOverflow,
139
140    /// We were unable to allocate memory to grow the table or set.
141    AllocError {
142        /// The memory layout that we were unable to allocate.
143        layout: Layout,
144    },
145}
146
147impl TryReserveError {
148    /// Construct a TryReserveError from the hashbrown equivalent.
149    ///
150    /// (For implementation hiding purposes, this is not a public `From`
151    /// implementation.)
152    #[allow(clippy::needless_pass_by_value)]
153    pub(crate) fn from_hashbrown(error: hashbrown::TryReserveError) -> Self {
154        match error {
155            hashbrown::TryReserveError::CapacityOverflow => TryReserveError::CapacityOverflow,
156            hashbrown::TryReserveError::AllocError { layout } => {
157                TryReserveError::AllocError { layout }
158            }
159        }
160    }
161}
162impl Display for TryReserveError {
163    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
164        match self {
165            TryReserveError::CapacityOverflow => write!(
166                f,
167                "Allocation failed: arithmetic overflow in capacity calculation"
168            ),
169            TryReserveError::AllocError { .. } => {
170                write!(f, "Allocation failed: memory allocator returned an error")
171            }
172        }
173    }
174}
175#[cfg(feature = "std")]
176impl Error for TryReserveError {}