Skip to content

Commit fe321d2

Browse files
committed
Add dynamically-sized slices of maps and sets
1 parent ddc2088 commit fe321d2

File tree

4 files changed

+523
-3
lines changed

4 files changed

+523
-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

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

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)