1use super::{Bucket, Entries, IndexSet, IntoIter, Iter};
2use crate::util::try_simplify_range;
3
4use alloc::boxed::Box;
5use alloc::vec::Vec;
6use core::cmp::Ordering;
7use core::fmt;
8use core::hash::{Hash, Hasher};
9use core::ops::{self, Bound, Index, RangeBounds};
10
11/// A dynamically-sized slice of values in an `IndexSet`.
12///
13/// This supports indexed operations much like a `[T]` slice,
14/// but not any hashed operations on the values.
15///
16/// Unlike `IndexSet`, `Slice` does consider the order for `PartialEq`
17/// and `Eq`, and it also implements `PartialOrd`, `Ord`, and `Hash`.
18#[repr(transparent)]
19pub struct Slice<T> {
20 pub(crate) entries: [Bucket<T>],
21}
22
23// SAFETY: `Slice<T>` is a transparent wrapper around `[Bucket<T>]`,
24// and reference lifetimes are bound together in function signatures.
25#[allow(unsafe_code)]
26impl<T> Slice<T> {
27 pub(super) fn from_slice(entries: &[Bucket<T>]) -> &Self {
28 unsafe { &*(entries as *const [Bucket<T>] as *const Self) }
29 }
30
31 pub(super) fn from_boxed(entries: Box<[Bucket<T>]>) -> Box<Self> {
32 unsafe { Box::from_raw(Box::into_raw(entries) as *mut Self) }
33 }
34
35 fn into_boxed(self: Box<Self>) -> Box<[Bucket<T>]> {
36 unsafe { Box::from_raw(Box::into_raw(self) as *mut [Bucket<T>]) }
37 }
38}
39
40impl<T> Slice<T> {
41 pub(crate) fn into_entries(self: Box<Self>) -> Vec<Bucket<T>> {
42 self.into_boxed().into_vec()
43 }
44
45 /// Return the number of elements in the set slice.
46 pub fn len(&self) -> usize {
47 self.entries.len()
48 }
49
50 /// Returns true if the set slice contains no elements.
51 pub fn is_empty(&self) -> bool {
52 self.entries.is_empty()
53 }
54
55 /// Get a value by index.
56 ///
57 /// Valid indices are *0 <= index < self.len()*
58 pub fn get_index(&self, index: usize) -> Option<&T> {
59 self.entries.get(index).map(Bucket::key_ref)
60 }
61
62 /// Returns a slice of values in the given range of indices.
63 ///
64 /// Valid indices are *0 <= index < self.len()*
65 pub fn get_range<R: RangeBounds<usize>>(&self, range: R) -> Option<&Self> {
66 let range = try_simplify_range(range, self.entries.len())?;
67 self.entries.get(range).map(Self::from_slice)
68 }
69
70 /// Get the first value.
71 pub fn first(&self) -> Option<&T> {
72 self.entries.first().map(Bucket::key_ref)
73 }
74
75 /// Get the last value.
76 pub fn last(&self) -> Option<&T> {
77 self.entries.last().map(Bucket::key_ref)
78 }
79
80 /// Divides one slice into two at an index.
81 ///
82 /// ***Panics*** if `index > len`.
83 pub fn split_at(&self, index: usize) -> (&Self, &Self) {
84 let (first, second) = self.entries.split_at(index);
85 (Self::from_slice(first), Self::from_slice(second))
86 }
87
88 /// Returns the first value and the rest of the slice,
89 /// or `None` if it is empty.
90 pub fn split_first(&self) -> Option<(&T, &Self)> {
91 if let [first, rest @ ..] = &self.entries {
92 Some((&first.key, Self::from_slice(rest)))
93 } else {
94 None
95 }
96 }
97
98 /// Returns the last value and the rest of the slice,
99 /// or `None` if it is empty.
100 pub fn split_last(&self) -> Option<(&T, &Self)> {
101 if let [rest @ .., last] = &self.entries {
102 Some((&last.key, Self::from_slice(rest)))
103 } else {
104 None
105 }
106 }
107
108 /// Return an iterator over the values of the set slice.
109 pub fn iter(&self) -> Iter<'_, T> {
110 Iter::new(&self.entries)
111 }
112}
113
114impl<'a, T> IntoIterator for &'a Slice<T> {
115 type IntoIter = Iter<'a, T>;
116 type Item = &'a T;
117
118 fn into_iter(self) -> Self::IntoIter {
119 self.iter()
120 }
121}
122
123impl<T> IntoIterator for Box<Slice<T>> {
124 type IntoIter = IntoIter<T>;
125 type Item = T;
126
127 fn into_iter(self) -> Self::IntoIter {
128 IntoIter::new(self.into_entries())
129 }
130}
131
132impl<T> Default for &'_ Slice<T> {
133 fn default() -> Self {
134 Slice::from_slice(&[])
135 }
136}
137
138impl<T> Default for Box<Slice<T>> {
139 fn default() -> Self {
140 Slice::from_boxed(entries:Box::default())
141 }
142}
143
144impl<T: Clone> Clone for Box<Slice<T>> {
145 fn clone(&self) -> Self {
146 Slice::from_boxed(self.entries.to_vec().into_boxed_slice())
147 }
148}
149
150impl<T: Copy> From<&Slice<T>> for Box<Slice<T>> {
151 fn from(slice: &Slice<T>) -> Self {
152 Slice::from_boxed(entries:Box::from(&slice.entries))
153 }
154}
155
156impl<T: fmt::Debug> fmt::Debug for Slice<T> {
157 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158 f.debug_list().entries(self).finish()
159 }
160}
161
162impl<T: PartialEq> PartialEq for Slice<T> {
163 fn eq(&self, other: &Self) -> bool {
164 self.len() == other.len() && self.iter().eq(other)
165 }
166}
167
168impl<T: Eq> Eq for Slice<T> {}
169
170impl<T: PartialOrd> PartialOrd for Slice<T> {
171 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
172 self.iter().partial_cmp(other)
173 }
174}
175
176impl<T: Ord> Ord for Slice<T> {
177 fn cmp(&self, other: &Self) -> Ordering {
178 self.iter().cmp(other)
179 }
180}
181
182impl<T: Hash> Hash for Slice<T> {
183 fn hash<H: Hasher>(&self, state: &mut H) {
184 self.len().hash(state);
185 for value: &T in self {
186 value.hash(state);
187 }
188 }
189}
190
191impl<T> Index<usize> for Slice<T> {
192 type Output = T;
193
194 fn index(&self, index: usize) -> &Self::Output {
195 &self.entries[index].key
196 }
197}
198
199// We can't have `impl<I: RangeBounds<usize>> Index<I>` because that conflicts with `Index<usize>`.
200// Instead, we repeat the implementations for all the core range types.
201macro_rules! impl_index {
202 ($($range:ty),*) => {$(
203 impl<T, S> Index<$range> for IndexSet<T, S> {
204 type Output = Slice<T>;
205
206 fn index(&self, range: $range) -> &Self::Output {
207 Slice::from_slice(&self.as_entries()[range])
208 }
209 }
210
211 impl<T> Index<$range> for Slice<T> {
212 type Output = Self;
213
214 fn index(&self, range: $range) -> &Self::Output {
215 Slice::from_slice(&self.entries[range])
216 }
217 }
218 )*}
219}
220impl_index!(
221 ops::Range<usize>,
222 ops::RangeFrom<usize>,
223 ops::RangeFull,
224 ops::RangeInclusive<usize>,
225 ops::RangeTo<usize>,
226 ops::RangeToInclusive<usize>,
227 (Bound<usize>, Bound<usize>)
228);
229
230#[cfg(test)]
231mod tests {
232 use super::*;
233 use alloc::vec::Vec;
234
235 #[test]
236 fn slice_index() {
237 fn check(vec_slice: &[i32], set_slice: &Slice<i32>, sub_slice: &Slice<i32>) {
238 assert_eq!(set_slice as *const _, sub_slice as *const _);
239 itertools::assert_equal(vec_slice, set_slice);
240 }
241
242 let vec: Vec<i32> = (0..10).map(|i| i * i).collect();
243 let set: IndexSet<i32> = vec.iter().cloned().collect();
244 let slice = set.as_slice();
245
246 // RangeFull
247 check(&vec[..], &set[..], &slice[..]);
248
249 for i in 0usize..10 {
250 // Index
251 assert_eq!(vec[i], set[i]);
252 assert_eq!(vec[i], slice[i]);
253
254 // RangeFrom
255 check(&vec[i..], &set[i..], &slice[i..]);
256
257 // RangeTo
258 check(&vec[..i], &set[..i], &slice[..i]);
259
260 // RangeToInclusive
261 check(&vec[..=i], &set[..=i], &slice[..=i]);
262
263 // (Bound<usize>, Bound<usize>)
264 let bounds = (Bound::Excluded(i), Bound::Unbounded);
265 check(&vec[i + 1..], &set[bounds], &slice[bounds]);
266
267 for j in i..=10 {
268 // Range
269 check(&vec[i..j], &set[i..j], &slice[i..j]);
270 }
271
272 for j in i..10 {
273 // RangeInclusive
274 check(&vec[i..=j], &set[i..=j], &slice[i..=j]);
275 }
276 }
277 }
278}
279