Skip to content

Commit 94214fa

Browse files
authored
Merge pull request #77 from yegorvk/missing-methods-frozen-indexmap-indexset
Add some missing methods to `FrozenIndexMap` and `FrozenIndexSet`
2 parents ab1beef + 1ae1448 commit 94214fa

File tree

2 files changed

+118
-40
lines changed

2 files changed

+118
-40
lines changed

src/index_map.rs

Lines changed: 74 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::borrow::Borrow;
21
use std::cell::{Cell, UnsafeCell};
32
use std::collections::hash_map::RandomState;
43
use std::hash::{BuildHasher, Hash};
@@ -8,6 +7,8 @@ use std::ops::Index;
87
use indexmap::IndexMap;
98
use stable_deref_trait::StableDeref;
109

10+
pub use indexmap::Equivalent;
11+
1112
/// Append-only version of `indexmap::IndexMap` where
1213
/// insertion does not require mutable access
1314
pub struct FrozenIndexMap<K, V, S = RandomState> {
@@ -41,10 +42,6 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
4142
///
4243
/// Existing values are never overwritten.
4344
///
44-
/// The key may be any borrowed form of the map's key type, but
45-
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
46-
/// the key type.
47-
///
4845
/// # Example
4946
/// ```
5047
/// use elsa::index_map::FrozenIndexMap;
@@ -72,10 +69,6 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
7269
///
7370
/// Existing values are never overwritten.
7471
///
75-
/// The key may be any borrowed form of the map's key type, but
76-
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
77-
/// the key type.
78-
///
7972
/// # Example
8073
/// ```
8174
/// use elsa::index_map::FrozenIndexMap;
@@ -97,10 +90,9 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
9790
}
9891

9992
/// Returns a reference to the value corresponding to the key.
100-
///
101-
/// The key may be any borrowed form of the map's key type, but
102-
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
103-
/// the key type.
93+
///
94+
/// # Arguments
95+
/// * `k` may be any type that implements [`Equivalent<K>`].
10496
///
10597
/// # Examples
10698
///
@@ -112,10 +104,9 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
112104
/// assert_eq!(map.get(&1), Some(&"a"));
113105
/// assert_eq!(map.get(&2), None);
114106
/// ```
115-
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V::Target>
107+
pub fn get<Q>(&self, k: &Q) -> Option<&V::Target>
116108
where
117-
K: Borrow<Q>,
118-
Q: Hash + Eq,
109+
Q: ?Sized + Hash + Equivalent<K>,
119110
{
120111
assert!(!self.in_use.get());
121112
self.in_use.set(true);
@@ -127,11 +118,36 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
127118
ret
128119
}
129120

130-
/// Returns a reference to the key-value mapping corresponding to an index.
121+
/// Returns the index corresponding to the key
122+
///
123+
/// # Arguments
124+
/// * `k` may be any type that implements [`Equivalent<K>`].
125+
///
126+
/// # Examples
131127
///
132-
/// The key may be any borrowed form of the map's key type, but
133-
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
134-
/// the key type.
128+
/// ```
129+
/// use elsa::index_map::FrozenIndexMap;
130+
///
131+
/// let map = FrozenIndexMap::new();
132+
/// map.insert(1, Box::new("a"));
133+
/// assert_eq!(map.get_index_of(&1), Some(0));
134+
/// assert_eq!(map.get_index_of(&2), None);
135+
/// ```
136+
pub fn get_index_of<Q>(&self, k: &Q) -> Option<usize>
137+
where
138+
Q: ?Sized + Hash + Equivalent<K>,
139+
{
140+
assert!(!self.in_use.get());
141+
self.in_use.set(true);
142+
let ret = unsafe {
143+
let map = self.map.get();
144+
(*map).get_index_of(k)
145+
};
146+
self.in_use.set(false);
147+
ret
148+
}
149+
150+
/// Returns a reference to the key-value mapping corresponding to an index.
135151
///
136152
/// # Examples
137153
///
@@ -158,11 +174,40 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
158174
ret
159175
}
160176

177+
/// Returns a reference to the key, along with its index and a reference to its value
178+
///
179+
/// # Arguments
180+
/// * `k` may be any type that implements [`Equivalent<K>`].
181+
///
182+
/// # Examples
183+
///
184+
/// ```
185+
/// use elsa::index_map::FrozenIndexMap;
186+
///
187+
/// let map = FrozenIndexMap::new();
188+
/// map.insert("1", Box::new("a"));
189+
/// assert_eq!(map.get_full("1"), Some((0, "1", &"a")));
190+
/// assert_eq!(map.get_full("2"), None);
191+
/// ```
192+
pub fn get_full<Q>(&self, k: &Q) -> Option<(usize, &K::Target, &V::Target)>
193+
where
194+
Q: ?Sized + Hash + Equivalent<K>,
195+
K: StableDeref,
196+
{
197+
assert!(!self.in_use.get());
198+
self.in_use.set(true);
199+
let ret = unsafe {
200+
let map = self.map.get();
201+
(*map).get_full(k).map(|(i, k, v)| (i, &**k, &**v))
202+
};
203+
self.in_use.set(false);
204+
ret
205+
}
206+
161207
/// Applies a function to the owner of the value corresponding to the key (if any).
162208
///
163-
/// The key may be any borrowed form of the map's key type, but
164-
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
165-
/// the key type.
209+
/// # Arguments
210+
/// * `k` may be any type that implements [`Equivalent<K>`].
166211
///
167212
/// # Examples
168213
///
@@ -174,10 +219,9 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
174219
/// assert_eq!(map.map_get(&1, Clone::clone), Some(Box::new("a")));
175220
/// assert_eq!(map.map_get(&2, Clone::clone), None);
176221
/// ```
177-
pub fn map_get<Q: ?Sized, T, F>(&self, k: &Q, f: F) -> Option<T>
222+
pub fn map_get<Q, T, F>(&self, k: &Q, f: F) -> Option<T>
178223
where
179-
K: Borrow<Q>,
180-
Q: Hash + Eq,
224+
Q: ?Sized + Hash + Equivalent<K>,
181225
F: FnOnce(&V) -> T,
182226
{
183227
assert!(!self.in_use.get());
@@ -246,10 +290,10 @@ impl<K, V, S> From<IndexMap<K, V, S>> for FrozenIndexMap<K, V, S> {
246290
}
247291
}
248292

249-
impl<Q: ?Sized, K: Eq + Hash, V: StableDeref, S: BuildHasher> Index<&Q> for FrozenIndexMap<K, V, S>
293+
impl<Q, K, V, S> Index<&Q> for FrozenIndexMap<K, V, S>
250294
where
251-
Q: Eq + Hash,
252-
K: Eq + Hash + Borrow<Q>,
295+
Q: ?Sized + Hash + Equivalent<K>,
296+
K: Eq + Hash,
253297
V: StableDeref,
254298
S: BuildHasher,
255299
{
@@ -265,7 +309,7 @@ where
265309
/// assert_eq!(map[&1], "a");
266310
/// ```
267311
fn index(&self, idx: &Q) -> &V::Target {
268-
self.get(&idx)
312+
self.get(idx)
269313
.expect("attempted to index FrozenIndexMap with unknown key")
270314
}
271315
}

src/index_set.rs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::borrow::Borrow;
21
use std::cell::{Cell, UnsafeCell};
32
use std::collections::hash_map::RandomState;
43
use std::hash::{BuildHasher, Hash};
@@ -8,6 +7,8 @@ use std::ops::Index;
87
use indexmap::IndexSet;
98
use stable_deref_trait::StableDeref;
109

10+
use crate::index_map::Equivalent;
11+
1112
/// Append-only version of `indexmap::IndexSet` where
1213
/// insertion does not require mutable access
1314
pub struct FrozenIndexSet<T, S = RandomState> {
@@ -72,9 +73,9 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
7273
/// # Example
7374
/// ```
7475
/// use elsa::index_set::FrozenIndexSet;
75-
/// let map = FrozenIndexSet::new();
76-
/// assert_eq!(map.insert_full(Box::new("a")), (0, &"a"));
77-
/// assert_eq!(map.insert_full(Box::new("b")), (1, &"b"));
76+
/// let set = FrozenIndexSet::new();
77+
/// assert_eq!(set.insert_full(Box::new("a")), (0, &"a"));
78+
/// assert_eq!(set.insert_full(Box::new("b")), (1, &"b"));
7879
/// ```
7980
pub fn insert_full(&self, value: T) -> (usize, &T::Target) {
8081
assert!(!self.in_use.get());
@@ -116,6 +117,9 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
116117
// }
117118

118119
/// Returns a reference to the value passed as argument if present in the set.
120+
///
121+
/// # Arguments
122+
/// * `k` may be any type that implements [`Equivalent<T>`].
119123
///
120124
/// # Examples
121125
///
@@ -127,10 +131,9 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
127131
/// assert_eq!(set.get(&Box::new("a")), Some(&"a"));
128132
/// assert_eq!(set.get(&Box::new("b")), None);
129133
/// ```
130-
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&T::Target>
134+
pub fn get<Q>(&self, k: &Q) -> Option<&T::Target>
131135
where
132-
T: Borrow<Q>,
133-
Q: Hash + Eq,
136+
Q: ?Sized + Hash + Equivalent<T>,
134137
{
135138
assert!(!self.in_use.get());
136139
self.in_use.set(true);
@@ -142,8 +145,40 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
142145
ret
143146
}
144147

148+
/// Returns the index corresponding to the value if present in the set
149+
///
150+
/// # Arguments
151+
/// * `k` may be any type that implements [`Equivalent<T>`].
152+
///
153+
/// # Examples
154+
///
155+
/// ```
156+
/// use elsa::FrozenIndexSet;
157+
///
158+
/// let set = FrozenIndexSet::new();
159+
/// set.insert(Box::new("a"));
160+
/// assert_eq!(set.get_index_of(&Box::new("a")), Some(0));
161+
/// assert_eq!(set.get_index_of(&Box::new("b")), None);
162+
/// ```
163+
pub fn get_index_of<Q>(&self, k: &Q) -> Option<usize>
164+
where
165+
Q: ?Sized + Hash + Equivalent<T>,
166+
{
167+
assert!(!self.in_use.get());
168+
self.in_use.set(true);
169+
let ret = unsafe {
170+
let set = self.set.get();
171+
(*set).get_index_of(k)
172+
};
173+
self.in_use.set(false);
174+
ret
175+
}
176+
145177
/// Returns a reference to the value passed as argument if present in the set,
146178
/// along with its index
179+
///
180+
/// # Arguments
181+
/// * `k` may be any type that implements [`Equivalent<T>`].
147182
///
148183
/// # Examples
149184
///
@@ -155,10 +190,9 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
155190
/// assert_eq!(set.get_full(&Box::new("a")), Some((0, &"a")));
156191
/// assert_eq!(set.get_full(&Box::new("b")), None);
157192
/// ```
158-
pub fn get_full<Q: ?Sized>(&self, k: &Q) -> Option<(usize, &T::Target)>
193+
pub fn get_full<Q>(&self, k: &Q) -> Option<(usize, &T::Target)>
159194
where
160-
T: Borrow<Q>,
161-
Q: Hash + Eq,
195+
Q: ?Sized + Hash + Equivalent<T>,
162196
{
163197
assert!(!self.in_use.get());
164198
self.in_use.set(true);

0 commit comments

Comments
 (0)