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