Skip to content

Commit 18c1a30

Browse files
committed
Add dynamically-sized slices of maps and sets
1 parent 223d4c0 commit 18c1a30

File tree

4 files changed

+521
-3
lines changed

4 files changed

+521
-3
lines changed

src/map.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
//! pairs is independent of the hash values of the keys.
33
44
mod core;
5+
mod slice;
56

7+
pub use self::slice::Slice;
68
pub use crate::mutable_keys::MutableKeys;
79

810
#[cfg(feature = "rayon")]

src/map/slice.rs

+319
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
use super::{Bucket, Entries, IndexMap, Iter, IterMut, Keys, Values, ValuesMut};
2+
3+
use core::cmp::Ordering;
4+
use core::fmt;
5+
use core::hash::{Hash, Hasher};
6+
use core::ops::{self, Index, IndexMut};
7+
8+
/// A dynamically-sized slice of key-value pairs in an `IndexMap`.
9+
///
10+
/// This supports indexed operations much like a `[(K, V)]` slice,
11+
/// but not any hashed operations on the map keys.
12+
///
13+
/// Unlike `IndexMap`, `Slice` does consider the order for `PartialEq`
14+
/// and `Eq`, and it also implements `PartialOrd`, `Ord`, and `Hash`.
15+
#[repr(transparent)]
16+
pub struct Slice<K, V> {
17+
entries: [Bucket<K, V>],
18+
}
19+
20+
#[allow(unsafe_code)]
21+
impl<K, V> Slice<K, V> {
22+
fn from_slice(entries: &[Bucket<K, V>]) -> &Self {
23+
// SAFETY: `Slice<K, V>` is a transparent wrapper around `[Bucket<K, V>]`,
24+
// and the lifetimes are bound together by this function's signature.
25+
unsafe { &*(entries as *const [Bucket<K, V>] as *const Self) }
26+
}
27+
28+
fn from_mut_slice(entries: &mut [Bucket<K, V>]) -> &mut Self {
29+
// SAFETY: `Slice<K, V>` is a transparent wrapper around `[Bucket<K, V>]`,
30+
// and the lifetimes are bound together by this function's signature.
31+
unsafe { &mut *(entries as *mut [Bucket<K, V>] as *mut Self) }
32+
}
33+
}
34+
35+
impl<K, V, S> IndexMap<K, V, S> {
36+
/// Returns a slice of all the entries in the map.
37+
pub fn as_slice(&self) -> &Slice<K, V> {
38+
Slice::from_slice(self.as_entries())
39+
}
40+
41+
/// Returns a mutable slice of all the entries in the map.
42+
pub fn as_mut_slice(&mut self) -> &mut Slice<K, V> {
43+
Slice::from_mut_slice(self.as_entries_mut())
44+
}
45+
}
46+
47+
impl<'a, K, V> Iter<'a, K, V> {
48+
/// Returns a slice of the remaining entries in the iterator.
49+
pub fn as_slice(&self) -> &'a Slice<K, V> {
50+
Slice::from_slice(self.iter.as_slice())
51+
}
52+
}
53+
54+
impl<'a, K, V> IterMut<'a, K, V> {
55+
/// Returns a slice of the remaining entries in the iterator.
56+
///
57+
/// To avoid creating `&mut` references that alias, this is forced to consume the iterator.
58+
pub fn into_slice(self) -> &'a mut Slice<K, V> {
59+
Slice::from_mut_slice(self.iter.into_slice())
60+
}
61+
}
62+
63+
impl<K, V> Slice<K, V> {
64+
/// Return the number of key-value pairs in the map slice.
65+
#[inline]
66+
pub fn len(&self) -> usize {
67+
self.entries.len()
68+
}
69+
70+
/// Returns true if the map slice contains no elements.
71+
#[inline]
72+
pub fn is_empty(&self) -> bool {
73+
self.entries.is_empty()
74+
}
75+
76+
/// Get a key-value pair by index.
77+
///
78+
/// Valid indices are *0 <= index < self.len()*
79+
pub fn get_index(&self, index: usize) -> Option<(&K, &V)> {
80+
self.entries.get(index).map(Bucket::refs)
81+
}
82+
83+
/// Get a key-value pair by index, with mutable access to the value.
84+
///
85+
/// Valid indices are *0 <= index < self.len()*
86+
pub fn get_index_mut(&mut self, index: usize) -> Option<(&K, &mut V)> {
87+
// NB: we're not returning `&mut K` like `IndexMap::get_index_mut`,
88+
// because that was a mistake that should have required `MutableKeys`.
89+
self.entries.get_mut(index).map(Bucket::ref_mut)
90+
}
91+
92+
/// Get the first key-value pair.
93+
pub fn first(&self) -> Option<(&K, &V)> {
94+
self.entries.first().map(Bucket::refs)
95+
}
96+
97+
/// Get the first key-value pair, with mutable access to the value.
98+
pub fn first_mut(&mut self) -> Option<(&K, &mut V)> {
99+
self.entries.first_mut().map(Bucket::ref_mut)
100+
}
101+
102+
/// Get the last key-value pair.
103+
pub fn last(&self) -> Option<(&K, &V)> {
104+
self.entries.last().map(Bucket::refs)
105+
}
106+
107+
/// Get the last key-value pair, with mutable access to the value.
108+
pub fn last_mut(&mut self) -> Option<(&K, &mut V)> {
109+
self.entries.last_mut().map(Bucket::ref_mut)
110+
}
111+
112+
/// Divides one slice into two at an index.
113+
///
114+
/// ***Panics*** if `index > len`.
115+
pub fn split_at(&self, index: usize) -> (&Self, &Self) {
116+
let (first, second) = self.entries.split_at(index);
117+
(Self::from_slice(first), Self::from_slice(second))
118+
}
119+
120+
/// Divides one mutable slice into two at an index.
121+
///
122+
/// ***Panics*** if `index > len`.
123+
pub fn split_at_mut(&mut self, index: usize) -> (&mut Self, &mut Self) {
124+
let (first, second) = self.entries.split_at_mut(index);
125+
(Self::from_mut_slice(first), Self::from_mut_slice(second))
126+
}
127+
128+
/// Returns the first key-value pair and the rest of the slice,
129+
/// or `None` if it is empty.
130+
pub fn split_first(&self) -> Option<((&K, &V), &Self)> {
131+
if let Some((first, rest)) = self.entries.split_first() {
132+
Some((first.refs(), Self::from_slice(rest)))
133+
} else {
134+
None
135+
}
136+
}
137+
138+
/// Returns the first key-value pair and the rest of the slice,
139+
/// with mutable access to the value, or `None` if it is empty.
140+
pub fn split_first_mut(&mut self) -> Option<((&K, &mut V), &mut Self)> {
141+
if let Some((first, rest)) = self.entries.split_first_mut() {
142+
Some((first.ref_mut(), Self::from_mut_slice(rest)))
143+
} else {
144+
None
145+
}
146+
}
147+
148+
/// Returns the last key-value pair and the rest of the slice,
149+
/// or `None` if it is empty.
150+
pub fn split_last(&self) -> Option<((&K, &V), &Self)> {
151+
if let Some((last, rest)) = self.entries.split_last() {
152+
Some((last.refs(), Self::from_slice(rest)))
153+
} else {
154+
None
155+
}
156+
}
157+
158+
/// Returns the last key-value pair and the rest of the slice,
159+
/// with mutable access to the value, or `None` if it is empty.
160+
pub fn split_last_mut(&mut self) -> Option<((&K, &mut V), &mut Self)> {
161+
if let Some((last, rest)) = self.entries.split_last_mut() {
162+
Some((last.ref_mut(), Self::from_mut_slice(rest)))
163+
} else {
164+
None
165+
}
166+
}
167+
168+
/// Return an iterator over the key-value pairs of the map slice.
169+
pub fn iter(&self) -> Iter<'_, K, V> {
170+
Iter {
171+
iter: self.entries.iter(),
172+
}
173+
}
174+
175+
/// Return an iterator over the key-value pairs of the map slice.
176+
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
177+
IterMut {
178+
iter: self.entries.iter_mut(),
179+
}
180+
}
181+
182+
/// Return an iterator over the keys of the map slice.
183+
pub fn keys(&self) -> Keys<'_, K, V> {
184+
Keys {
185+
iter: self.entries.iter(),
186+
}
187+
}
188+
189+
/// Return an iterator over the values of the map slice.
190+
pub fn values(&self) -> Values<'_, K, V> {
191+
Values {
192+
iter: self.entries.iter(),
193+
}
194+
}
195+
196+
/// Return an iterator over mutable references to the the values of the map slice.
197+
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
198+
ValuesMut {
199+
iter: self.entries.iter_mut(),
200+
}
201+
}
202+
}
203+
204+
impl<'a, K, V> IntoIterator for &'a Slice<K, V> {
205+
type IntoIter = Iter<'a, K, V>;
206+
type Item = (&'a K, &'a V);
207+
208+
fn into_iter(self) -> Self::IntoIter {
209+
self.iter()
210+
}
211+
}
212+
213+
impl<'a, K, V> IntoIterator for &'a mut Slice<K, V> {
214+
type IntoIter = IterMut<'a, K, V>;
215+
type Item = (&'a K, &'a mut V);
216+
217+
fn into_iter(self) -> Self::IntoIter {
218+
self.iter_mut()
219+
}
220+
}
221+
222+
impl<K, V> Default for &'_ Slice<K, V> {
223+
fn default() -> Self {
224+
Slice::from_slice(&[])
225+
}
226+
}
227+
228+
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Slice<K, V> {
229+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
230+
f.debug_list().entries(self).finish()
231+
}
232+
}
233+
234+
impl<K: PartialEq, V: PartialEq> PartialEq for Slice<K, V> {
235+
fn eq(&self, other: &Self) -> bool {
236+
self.len() == other.len() && self.iter().eq(other)
237+
}
238+
}
239+
240+
impl<K: Eq, V: Eq> Eq for Slice<K, V> {}
241+
242+
impl<K: PartialOrd, V: PartialOrd> PartialOrd for Slice<K, V> {
243+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
244+
self.iter().partial_cmp(other)
245+
}
246+
}
247+
248+
impl<K: Ord, V: Ord> Ord for Slice<K, V> {
249+
fn cmp(&self, other: &Self) -> Ordering {
250+
self.iter().cmp(other)
251+
}
252+
}
253+
254+
impl<K: Hash, V: Hash> Hash for Slice<K, V> {
255+
fn hash<H: Hasher>(&self, state: &mut H) {
256+
self.len().hash(state);
257+
for (key, value) in self {
258+
key.hash(state);
259+
value.hash(state);
260+
}
261+
}
262+
}
263+
264+
impl<K, V> Index<usize> for Slice<K, V> {
265+
type Output = V;
266+
267+
fn index(&self, index: usize) -> &V {
268+
&self.entries[index].value
269+
}
270+
}
271+
272+
impl<K, V> IndexMut<usize> for Slice<K, V> {
273+
fn index_mut(&mut self, index: usize) -> &mut V {
274+
&mut self.entries[index].value
275+
}
276+
}
277+
278+
// We can't have `impl<I: RangeBounds<usize>> Index<I>` because that conflicts
279+
// both upstream with `Index<usize>` and downstream with `Index<&Q>`.
280+
// Instead, we repeat the implementations for all the core range types.
281+
macro_rules! impl_index {
282+
($($range:ty),*) => {$(
283+
impl<K, V, S> Index<$range> for IndexMap<K, V, S> {
284+
type Output = Slice<K, V>;
285+
286+
fn index(&self, range: $range) -> &Self::Output {
287+
Slice::from_slice(&self.as_entries()[range])
288+
}
289+
}
290+
291+
impl<K, V, S> IndexMut<$range> for IndexMap<K, V, S> {
292+
fn index_mut(&mut self, range: $range) -> &mut Self::Output {
293+
Slice::from_mut_slice(&mut self.as_entries_mut()[range])
294+
}
295+
}
296+
297+
impl<K, V> Index<$range> for Slice<K, V> {
298+
type Output = Slice<K, V>;
299+
300+
fn index(&self, range: $range) -> &Self {
301+
Self::from_slice(&self.entries[range])
302+
}
303+
}
304+
305+
impl<K, V> IndexMut<$range> for Slice<K, V> {
306+
fn index_mut(&mut self, range: $range) -> &mut Self {
307+
Self::from_mut_slice(&mut self.entries[range])
308+
}
309+
}
310+
)*}
311+
}
312+
impl_index!(
313+
ops::Range<usize>,
314+
ops::RangeFrom<usize>,
315+
ops::RangeFull,
316+
ops::RangeInclusive<usize>,
317+
ops::RangeTo<usize>,
318+
ops::RangeToInclusive<usize>
319+
);

src/set.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
//! A hash set implemented using `IndexMap`
22
3+
mod slice;
4+
5+
pub use self::slice::Slice;
6+
37
#[cfg(feature = "rayon")]
48
pub use crate::rayon::set as rayon;
59

@@ -12,7 +16,7 @@ use core::fmt;
1216
use core::hash::{BuildHasher, Hash};
1317
use core::iter::{Chain, FromIterator};
1418
use core::ops::{BitAnd, BitOr, BitXor, Index, RangeBounds, Sub};
15-
use core::slice;
19+
use core::slice::Iter as SliceIter;
1620

1721
use super::{Entries, Equivalent, IndexMap};
1822

@@ -189,7 +193,7 @@ impl<T, S> IndexSet<T, S> {
189193
/// Return an iterator over the values of the set, in their order
190194
pub fn iter(&self) -> Iter<'_, T> {
191195
Iter {
192-
iter: self.map.keys().iter,
196+
iter: self.map.as_entries().iter(),
193197
}
194198
}
195199

@@ -734,7 +738,7 @@ impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
734738
/// [`IndexSet`]: struct.IndexSet.html
735739
/// [`iter`]: struct.IndexSet.html#method.iter
736740
pub struct Iter<'a, T> {
737-
iter: slice::Iter<'a, Bucket<T>>,
741+
iter: SliceIter<'a, Bucket<T>>,
738742
}
739743

740744
impl<'a, T> Iterator for Iter<'a, T> {

0 commit comments

Comments
 (0)