| 1 | use super::{ |
| 2 | Bucket, Entries, IndexMap, IntoIter, IntoKeys, IntoValues, Iter, IterMut, Keys, Values, |
| 3 | ValuesMut, |
| 4 | }; |
| 5 | use crate::util::{slice_eq, try_simplify_range}; |
| 6 | use crate::GetDisjointMutError; |
| 7 | |
| 8 | use alloc::boxed::Box; |
| 9 | use alloc::vec::Vec; |
| 10 | use core::cmp::Ordering; |
| 11 | use core::fmt; |
| 12 | use core::hash::{Hash, Hasher}; |
| 13 | use core::ops::{self, Bound, Index, IndexMut, RangeBounds}; |
| 14 | |
| 15 | /// A dynamically-sized slice of key-value pairs in an [`IndexMap`]. |
| 16 | /// |
| 17 | /// This supports indexed operations much like a `[(K, V)]` slice, |
| 18 | /// but not any hashed operations on the map keys. |
| 19 | /// |
| 20 | /// Unlike `IndexMap`, `Slice` does consider the order for [`PartialEq`] |
| 21 | /// and [`Eq`], and it also implements [`PartialOrd`], [`Ord`], and [`Hash`]. |
| 22 | #[repr (transparent)] |
| 23 | pub struct Slice<K, V> { |
| 24 | pub(crate) entries: [Bucket<K, V>], |
| 25 | } |
| 26 | |
| 27 | // SAFETY: `Slice<K, V>` is a transparent wrapper around `[Bucket<K, V>]`, |
| 28 | // and reference lifetimes are bound together in function signatures. |
| 29 | #[allow (unsafe_code)] |
| 30 | impl<K, V> Slice<K, V> { |
| 31 | pub(super) const fn from_slice(entries: &[Bucket<K, V>]) -> &Self { |
| 32 | unsafe { &*(entries as *const [Bucket<K, V>] as *const Self) } |
| 33 | } |
| 34 | |
| 35 | pub(super) fn from_mut_slice(entries: &mut [Bucket<K, V>]) -> &mut Self { |
| 36 | unsafe { &mut *(entries as *mut [Bucket<K, V>] as *mut Self) } |
| 37 | } |
| 38 | |
| 39 | pub(super) fn from_boxed(entries: Box<[Bucket<K, V>]>) -> Box<Self> { |
| 40 | unsafe { Box::from_raw(Box::into_raw(entries) as *mut Self) } |
| 41 | } |
| 42 | |
| 43 | fn into_boxed(self: Box<Self>) -> Box<[Bucket<K, V>]> { |
| 44 | unsafe { Box::from_raw(Box::into_raw(self) as *mut [Bucket<K, V>]) } |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | impl<K, V> Slice<K, V> { |
| 49 | pub(crate) fn into_entries(self: Box<Self>) -> Vec<Bucket<K, V>> { |
| 50 | self.into_boxed().into_vec() |
| 51 | } |
| 52 | |
| 53 | /// Returns an empty slice. |
| 54 | pub const fn new<'a>() -> &'a Self { |
| 55 | Self::from_slice(&[]) |
| 56 | } |
| 57 | |
| 58 | /// Returns an empty mutable slice. |
| 59 | pub fn new_mut<'a>() -> &'a mut Self { |
| 60 | Self::from_mut_slice(&mut []) |
| 61 | } |
| 62 | |
| 63 | /// Return the number of key-value pairs in the map slice. |
| 64 | #[inline ] |
| 65 | pub const fn len(&self) -> usize { |
| 66 | self.entries.len() |
| 67 | } |
| 68 | |
| 69 | /// Returns true if the map slice contains no elements. |
| 70 | #[inline ] |
| 71 | pub const fn is_empty(&self) -> bool { |
| 72 | self.entries.is_empty() |
| 73 | } |
| 74 | |
| 75 | /// Get a key-value pair by index. |
| 76 | /// |
| 77 | /// Valid indices are `0 <= index < self.len()`. |
| 78 | pub fn get_index(&self, index: usize) -> Option<(&K, &V)> { |
| 79 | self.entries.get(index).map(Bucket::refs) |
| 80 | } |
| 81 | |
| 82 | /// Get a key-value pair by index, with mutable access to the value. |
| 83 | /// |
| 84 | /// Valid indices are `0 <= index < self.len()`. |
| 85 | pub fn get_index_mut(&mut self, index: usize) -> Option<(&K, &mut V)> { |
| 86 | self.entries.get_mut(index).map(Bucket::ref_mut) |
| 87 | } |
| 88 | |
| 89 | /// Returns a slice of key-value pairs in the given range of indices. |
| 90 | /// |
| 91 | /// Valid indices are `0 <= index < self.len()`. |
| 92 | pub fn get_range<R: RangeBounds<usize>>(&self, range: R) -> Option<&Self> { |
| 93 | let range = try_simplify_range(range, self.entries.len())?; |
| 94 | self.entries.get(range).map(Slice::from_slice) |
| 95 | } |
| 96 | |
| 97 | /// Returns a mutable slice of key-value pairs in the given range of indices. |
| 98 | /// |
| 99 | /// Valid indices are `0 <= index < self.len()`. |
| 100 | pub fn get_range_mut<R: RangeBounds<usize>>(&mut self, range: R) -> Option<&mut Self> { |
| 101 | let range = try_simplify_range(range, self.entries.len())?; |
| 102 | self.entries.get_mut(range).map(Slice::from_mut_slice) |
| 103 | } |
| 104 | |
| 105 | /// Get the first key-value pair. |
| 106 | pub fn first(&self) -> Option<(&K, &V)> { |
| 107 | self.entries.first().map(Bucket::refs) |
| 108 | } |
| 109 | |
| 110 | /// Get the first key-value pair, with mutable access to the value. |
| 111 | pub fn first_mut(&mut self) -> Option<(&K, &mut V)> { |
| 112 | self.entries.first_mut().map(Bucket::ref_mut) |
| 113 | } |
| 114 | |
| 115 | /// Get the last key-value pair. |
| 116 | pub fn last(&self) -> Option<(&K, &V)> { |
| 117 | self.entries.last().map(Bucket::refs) |
| 118 | } |
| 119 | |
| 120 | /// Get the last key-value pair, with mutable access to the value. |
| 121 | pub fn last_mut(&mut self) -> Option<(&K, &mut V)> { |
| 122 | self.entries.last_mut().map(Bucket::ref_mut) |
| 123 | } |
| 124 | |
| 125 | /// Divides one slice into two at an index. |
| 126 | /// |
| 127 | /// ***Panics*** if `index > len`. |
| 128 | pub fn split_at(&self, index: usize) -> (&Self, &Self) { |
| 129 | let (first, second) = self.entries.split_at(index); |
| 130 | (Self::from_slice(first), Self::from_slice(second)) |
| 131 | } |
| 132 | |
| 133 | /// Divides one mutable slice into two at an index. |
| 134 | /// |
| 135 | /// ***Panics*** if `index > len`. |
| 136 | pub fn split_at_mut(&mut self, index: usize) -> (&mut Self, &mut Self) { |
| 137 | let (first, second) = self.entries.split_at_mut(index); |
| 138 | (Self::from_mut_slice(first), Self::from_mut_slice(second)) |
| 139 | } |
| 140 | |
| 141 | /// Returns the first key-value pair and the rest of the slice, |
| 142 | /// or `None` if it is empty. |
| 143 | pub fn split_first(&self) -> Option<((&K, &V), &Self)> { |
| 144 | if let [first, rest @ ..] = &self.entries { |
| 145 | Some((first.refs(), Self::from_slice(rest))) |
| 146 | } else { |
| 147 | None |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | /// Returns the first key-value pair and the rest of the slice, |
| 152 | /// with mutable access to the value, or `None` if it is empty. |
| 153 | pub fn split_first_mut(&mut self) -> Option<((&K, &mut V), &mut Self)> { |
| 154 | if let [first, rest @ ..] = &mut self.entries { |
| 155 | Some((first.ref_mut(), Self::from_mut_slice(rest))) |
| 156 | } else { |
| 157 | None |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | /// Returns the last key-value pair and the rest of the slice, |
| 162 | /// or `None` if it is empty. |
| 163 | pub fn split_last(&self) -> Option<((&K, &V), &Self)> { |
| 164 | if let [rest @ .., last] = &self.entries { |
| 165 | Some((last.refs(), Self::from_slice(rest))) |
| 166 | } else { |
| 167 | None |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | /// Returns the last key-value pair and the rest of the slice, |
| 172 | /// with mutable access to the value, or `None` if it is empty. |
| 173 | pub fn split_last_mut(&mut self) -> Option<((&K, &mut V), &mut Self)> { |
| 174 | if let [rest @ .., last] = &mut self.entries { |
| 175 | Some((last.ref_mut(), Self::from_mut_slice(rest))) |
| 176 | } else { |
| 177 | None |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | /// Return an iterator over the key-value pairs of the map slice. |
| 182 | pub fn iter(&self) -> Iter<'_, K, V> { |
| 183 | Iter::new(&self.entries) |
| 184 | } |
| 185 | |
| 186 | /// Return an iterator over the key-value pairs of the map slice. |
| 187 | pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { |
| 188 | IterMut::new(&mut self.entries) |
| 189 | } |
| 190 | |
| 191 | /// Return an iterator over the keys of the map slice. |
| 192 | pub fn keys(&self) -> Keys<'_, K, V> { |
| 193 | Keys::new(&self.entries) |
| 194 | } |
| 195 | |
| 196 | /// Return an owning iterator over the keys of the map slice. |
| 197 | pub fn into_keys(self: Box<Self>) -> IntoKeys<K, V> { |
| 198 | IntoKeys::new(self.into_entries()) |
| 199 | } |
| 200 | |
| 201 | /// Return an iterator over the values of the map slice. |
| 202 | pub fn values(&self) -> Values<'_, K, V> { |
| 203 | Values::new(&self.entries) |
| 204 | } |
| 205 | |
| 206 | /// Return an iterator over mutable references to the the values of the map slice. |
| 207 | pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> { |
| 208 | ValuesMut::new(&mut self.entries) |
| 209 | } |
| 210 | |
| 211 | /// Return an owning iterator over the values of the map slice. |
| 212 | pub fn into_values(self: Box<Self>) -> IntoValues<K, V> { |
| 213 | IntoValues::new(self.into_entries()) |
| 214 | } |
| 215 | |
| 216 | /// Search over a sorted map for a key. |
| 217 | /// |
| 218 | /// Returns the position where that key is present, or the position where it can be inserted to |
| 219 | /// maintain the sort. See [`slice::binary_search`] for more details. |
| 220 | /// |
| 221 | /// Computes in **O(log(n))** time, which is notably less scalable than looking the key up in |
| 222 | /// the map this is a slice from using [`IndexMap::get_index_of`], but this can also position |
| 223 | /// missing keys. |
| 224 | pub fn binary_search_keys(&self, x: &K) -> Result<usize, usize> |
| 225 | where |
| 226 | K: Ord, |
| 227 | { |
| 228 | self.binary_search_by(|p, _| p.cmp(x)) |
| 229 | } |
| 230 | |
| 231 | /// Search over a sorted map with a comparator function. |
| 232 | /// |
| 233 | /// Returns the position where that value is present, or the position where it can be inserted |
| 234 | /// to maintain the sort. See [`slice::binary_search_by`] for more details. |
| 235 | /// |
| 236 | /// Computes in **O(log(n))** time. |
| 237 | #[inline ] |
| 238 | pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize> |
| 239 | where |
| 240 | F: FnMut(&'a K, &'a V) -> Ordering, |
| 241 | { |
| 242 | self.entries.binary_search_by(move |a| f(&a.key, &a.value)) |
| 243 | } |
| 244 | |
| 245 | /// Search over a sorted map with an extraction function. |
| 246 | /// |
| 247 | /// Returns the position where that value is present, or the position where it can be inserted |
| 248 | /// to maintain the sort. See [`slice::binary_search_by_key`] for more details. |
| 249 | /// |
| 250 | /// Computes in **O(log(n))** time. |
| 251 | #[inline ] |
| 252 | pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize> |
| 253 | where |
| 254 | F: FnMut(&'a K, &'a V) -> B, |
| 255 | B: Ord, |
| 256 | { |
| 257 | self.binary_search_by(|k, v| f(k, v).cmp(b)) |
| 258 | } |
| 259 | |
| 260 | /// Returns the index of the partition point of a sorted map according to the given predicate |
| 261 | /// (the index of the first element of the second partition). |
| 262 | /// |
| 263 | /// See [`slice::partition_point`] for more details. |
| 264 | /// |
| 265 | /// Computes in **O(log(n))** time. |
| 266 | #[must_use ] |
| 267 | pub fn partition_point<P>(&self, mut pred: P) -> usize |
| 268 | where |
| 269 | P: FnMut(&K, &V) -> bool, |
| 270 | { |
| 271 | self.entries |
| 272 | .partition_point(move |a| pred(&a.key, &a.value)) |
| 273 | } |
| 274 | |
| 275 | /// Get an array of `N` key-value pairs by `N` indices |
| 276 | /// |
| 277 | /// Valid indices are *0 <= index < self.len()* and each index needs to be unique. |
| 278 | pub fn get_disjoint_mut<const N: usize>( |
| 279 | &mut self, |
| 280 | indices: [usize; N], |
| 281 | ) -> Result<[(&K, &mut V); N], GetDisjointMutError> { |
| 282 | let indices = indices.map(Some); |
| 283 | let key_values = self.get_disjoint_opt_mut(indices)?; |
| 284 | Ok(key_values.map(Option::unwrap)) |
| 285 | } |
| 286 | |
| 287 | #[allow (unsafe_code)] |
| 288 | pub(crate) fn get_disjoint_opt_mut<const N: usize>( |
| 289 | &mut self, |
| 290 | indices: [Option<usize>; N], |
| 291 | ) -> Result<[Option<(&K, &mut V)>; N], GetDisjointMutError> { |
| 292 | // SAFETY: Can't allow duplicate indices as we would return several mutable refs to the same data. |
| 293 | let len = self.len(); |
| 294 | for i in 0..N { |
| 295 | if let Some(idx) = indices[i] { |
| 296 | if idx >= len { |
| 297 | return Err(GetDisjointMutError::IndexOutOfBounds); |
| 298 | } else if indices[..i].contains(&Some(idx)) { |
| 299 | return Err(GetDisjointMutError::OverlappingIndices); |
| 300 | } |
| 301 | } |
| 302 | } |
| 303 | |
| 304 | let entries_ptr = self.entries.as_mut_ptr(); |
| 305 | let out = indices.map(|idx_opt| { |
| 306 | match idx_opt { |
| 307 | Some(idx) => { |
| 308 | // SAFETY: The base pointer is valid as it comes from a slice and the reference is always |
| 309 | // in-bounds & unique as we've already checked the indices above. |
| 310 | let kv = unsafe { (*(entries_ptr.add(idx))).ref_mut() }; |
| 311 | Some(kv) |
| 312 | } |
| 313 | None => None, |
| 314 | } |
| 315 | }); |
| 316 | |
| 317 | Ok(out) |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | impl<'a, K, V> IntoIterator for &'a Slice<K, V> { |
| 322 | type IntoIter = Iter<'a, K, V>; |
| 323 | type Item = (&'a K, &'a V); |
| 324 | |
| 325 | fn into_iter(self) -> Self::IntoIter { |
| 326 | self.iter() |
| 327 | } |
| 328 | } |
| 329 | |
| 330 | impl<'a, K, V> IntoIterator for &'a mut Slice<K, V> { |
| 331 | type IntoIter = IterMut<'a, K, V>; |
| 332 | type Item = (&'a K, &'a mut V); |
| 333 | |
| 334 | fn into_iter(self) -> Self::IntoIter { |
| 335 | self.iter_mut() |
| 336 | } |
| 337 | } |
| 338 | |
| 339 | impl<K, V> IntoIterator for Box<Slice<K, V>> { |
| 340 | type IntoIter = IntoIter<K, V>; |
| 341 | type Item = (K, V); |
| 342 | |
| 343 | fn into_iter(self) -> Self::IntoIter { |
| 344 | IntoIter::new(self.into_entries()) |
| 345 | } |
| 346 | } |
| 347 | |
| 348 | impl<K, V> Default for &'_ Slice<K, V> { |
| 349 | fn default() -> Self { |
| 350 | Slice::from_slice(&[]) |
| 351 | } |
| 352 | } |
| 353 | |
| 354 | impl<K, V> Default for &'_ mut Slice<K, V> { |
| 355 | fn default() -> Self { |
| 356 | Slice::from_mut_slice(&mut []) |
| 357 | } |
| 358 | } |
| 359 | |
| 360 | impl<K, V> Default for Box<Slice<K, V>> { |
| 361 | fn default() -> Self { |
| 362 | Slice::from_boxed(entries:Box::default()) |
| 363 | } |
| 364 | } |
| 365 | |
| 366 | impl<K: Clone, V: Clone> Clone for Box<Slice<K, V>> { |
| 367 | fn clone(&self) -> Self { |
| 368 | Slice::from_boxed(self.entries.to_vec().into_boxed_slice()) |
| 369 | } |
| 370 | } |
| 371 | |
| 372 | impl<K: Copy, V: Copy> From<&Slice<K, V>> for Box<Slice<K, V>> { |
| 373 | fn from(slice: &Slice<K, V>) -> Self { |
| 374 | Slice::from_boxed(entries:Box::from(&slice.entries)) |
| 375 | } |
| 376 | } |
| 377 | |
| 378 | impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Slice<K, V> { |
| 379 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 380 | f.debug_list().entries(self).finish() |
| 381 | } |
| 382 | } |
| 383 | |
| 384 | impl<K, V, K2, V2> PartialEq<Slice<K2, V2>> for Slice<K, V> |
| 385 | where |
| 386 | K: PartialEq<K2>, |
| 387 | V: PartialEq<V2>, |
| 388 | { |
| 389 | fn eq(&self, other: &Slice<K2, V2>) -> bool { |
| 390 | slice_eq(&self.entries, &other.entries, |b1: &Bucket, b2: &Bucket| { |
| 391 | b1.key == b2.key && b1.value == b2.value |
| 392 | }) |
| 393 | } |
| 394 | } |
| 395 | |
| 396 | impl<K, V, K2, V2> PartialEq<[(K2, V2)]> for Slice<K, V> |
| 397 | where |
| 398 | K: PartialEq<K2>, |
| 399 | V: PartialEq<V2>, |
| 400 | { |
| 401 | fn eq(&self, other: &[(K2, V2)]) -> bool { |
| 402 | slice_eq(&self.entries, right:other, |b: &Bucket, t: &(K2, V2)| b.key == t.0 && b.value == t.1) |
| 403 | } |
| 404 | } |
| 405 | |
| 406 | impl<K, V, K2, V2> PartialEq<Slice<K2, V2>> for [(K, V)] |
| 407 | where |
| 408 | K: PartialEq<K2>, |
| 409 | V: PartialEq<V2>, |
| 410 | { |
| 411 | fn eq(&self, other: &Slice<K2, V2>) -> bool { |
| 412 | slice_eq(self, &other.entries, |t: &(K, V), b: &Bucket| t.0 == b.key && t.1 == b.value) |
| 413 | } |
| 414 | } |
| 415 | |
| 416 | impl<K, V, K2, V2, const N: usize> PartialEq<[(K2, V2); N]> for Slice<K, V> |
| 417 | where |
| 418 | K: PartialEq<K2>, |
| 419 | V: PartialEq<V2>, |
| 420 | { |
| 421 | fn eq(&self, other: &[(K2, V2); N]) -> bool { |
| 422 | <Self as PartialEq<[_]>>::eq(self, other) |
| 423 | } |
| 424 | } |
| 425 | |
| 426 | impl<K, V, const N: usize, K2, V2> PartialEq<Slice<K2, V2>> for [(K, V); N] |
| 427 | where |
| 428 | K: PartialEq<K2>, |
| 429 | V: PartialEq<V2>, |
| 430 | { |
| 431 | fn eq(&self, other: &Slice<K2, V2>) -> bool { |
| 432 | <[_] as PartialEq<_>>::eq(self, other) |
| 433 | } |
| 434 | } |
| 435 | |
| 436 | impl<K: Eq, V: Eq> Eq for Slice<K, V> {} |
| 437 | |
| 438 | impl<K: PartialOrd, V: PartialOrd> PartialOrd for Slice<K, V> { |
| 439 | fn partial_cmp(&self, other: &Self) -> Option<Ordering> { |
| 440 | self.iter().partial_cmp(other) |
| 441 | } |
| 442 | } |
| 443 | |
| 444 | impl<K: Ord, V: Ord> Ord for Slice<K, V> { |
| 445 | fn cmp(&self, other: &Self) -> Ordering { |
| 446 | self.iter().cmp(other) |
| 447 | } |
| 448 | } |
| 449 | |
| 450 | impl<K: Hash, V: Hash> Hash for Slice<K, V> { |
| 451 | fn hash<H: Hasher>(&self, state: &mut H) { |
| 452 | self.len().hash(state); |
| 453 | for (key: &K, value: &V) in self { |
| 454 | key.hash(state); |
| 455 | value.hash(state); |
| 456 | } |
| 457 | } |
| 458 | } |
| 459 | |
| 460 | impl<K, V> Index<usize> for Slice<K, V> { |
| 461 | type Output = V; |
| 462 | |
| 463 | fn index(&self, index: usize) -> &V { |
| 464 | &self.entries[index].value |
| 465 | } |
| 466 | } |
| 467 | |
| 468 | impl<K, V> IndexMut<usize> for Slice<K, V> { |
| 469 | fn index_mut(&mut self, index: usize) -> &mut V { |
| 470 | &mut self.entries[index].value |
| 471 | } |
| 472 | } |
| 473 | |
| 474 | // We can't have `impl<I: RangeBounds<usize>> Index<I>` because that conflicts |
| 475 | // both upstream with `Index<usize>` and downstream with `Index<&Q>`. |
| 476 | // Instead, we repeat the implementations for all the core range types. |
| 477 | macro_rules! impl_index { |
| 478 | ($($range:ty),*) => {$( |
| 479 | impl<K, V, S> Index<$range> for IndexMap<K, V, S> { |
| 480 | type Output = Slice<K, V>; |
| 481 | |
| 482 | fn index(&self, range: $range) -> &Self::Output { |
| 483 | Slice::from_slice(&self.as_entries()[range]) |
| 484 | } |
| 485 | } |
| 486 | |
| 487 | impl<K, V, S> IndexMut<$range> for IndexMap<K, V, S> { |
| 488 | fn index_mut(&mut self, range: $range) -> &mut Self::Output { |
| 489 | Slice::from_mut_slice(&mut self.as_entries_mut()[range]) |
| 490 | } |
| 491 | } |
| 492 | |
| 493 | impl<K, V> Index<$range> for Slice<K, V> { |
| 494 | type Output = Slice<K, V>; |
| 495 | |
| 496 | fn index(&self, range: $range) -> &Self { |
| 497 | Self::from_slice(&self.entries[range]) |
| 498 | } |
| 499 | } |
| 500 | |
| 501 | impl<K, V> IndexMut<$range> for Slice<K, V> { |
| 502 | fn index_mut(&mut self, range: $range) -> &mut Self { |
| 503 | Self::from_mut_slice(&mut self.entries[range]) |
| 504 | } |
| 505 | } |
| 506 | )*} |
| 507 | } |
| 508 | impl_index!( |
| 509 | ops::Range<usize>, |
| 510 | ops::RangeFrom<usize>, |
| 511 | ops::RangeFull, |
| 512 | ops::RangeInclusive<usize>, |
| 513 | ops::RangeTo<usize>, |
| 514 | ops::RangeToInclusive<usize>, |
| 515 | (Bound<usize>, Bound<usize>) |
| 516 | ); |
| 517 | |
| 518 | #[cfg (test)] |
| 519 | mod tests { |
| 520 | use super::*; |
| 521 | |
| 522 | #[test ] |
| 523 | fn slice_index() { |
| 524 | fn check( |
| 525 | vec_slice: &[(i32, i32)], |
| 526 | map_slice: &Slice<i32, i32>, |
| 527 | sub_slice: &Slice<i32, i32>, |
| 528 | ) { |
| 529 | assert_eq!(map_slice as *const _, sub_slice as *const _); |
| 530 | itertools::assert_equal( |
| 531 | vec_slice.iter().copied(), |
| 532 | map_slice.iter().map(|(&k, &v)| (k, v)), |
| 533 | ); |
| 534 | itertools::assert_equal(vec_slice.iter().map(|(k, _)| k), map_slice.keys()); |
| 535 | itertools::assert_equal(vec_slice.iter().map(|(_, v)| v), map_slice.values()); |
| 536 | } |
| 537 | |
| 538 | let vec: Vec<(i32, i32)> = (0..10).map(|i| (i, i * i)).collect(); |
| 539 | let map: IndexMap<i32, i32> = vec.iter().cloned().collect(); |
| 540 | let slice = map.as_slice(); |
| 541 | |
| 542 | // RangeFull |
| 543 | check(&vec[..], &map[..], &slice[..]); |
| 544 | |
| 545 | for i in 0usize..10 { |
| 546 | // Index |
| 547 | assert_eq!(vec[i].1, map[i]); |
| 548 | assert_eq!(vec[i].1, slice[i]); |
| 549 | assert_eq!(map[&(i as i32)], map[i]); |
| 550 | assert_eq!(map[&(i as i32)], slice[i]); |
| 551 | |
| 552 | // RangeFrom |
| 553 | check(&vec[i..], &map[i..], &slice[i..]); |
| 554 | |
| 555 | // RangeTo |
| 556 | check(&vec[..i], &map[..i], &slice[..i]); |
| 557 | |
| 558 | // RangeToInclusive |
| 559 | check(&vec[..=i], &map[..=i], &slice[..=i]); |
| 560 | |
| 561 | // (Bound<usize>, Bound<usize>) |
| 562 | let bounds = (Bound::Excluded(i), Bound::Unbounded); |
| 563 | check(&vec[i + 1..], &map[bounds], &slice[bounds]); |
| 564 | |
| 565 | for j in i..=10 { |
| 566 | // Range |
| 567 | check(&vec[i..j], &map[i..j], &slice[i..j]); |
| 568 | } |
| 569 | |
| 570 | for j in i..10 { |
| 571 | // RangeInclusive |
| 572 | check(&vec[i..=j], &map[i..=j], &slice[i..=j]); |
| 573 | } |
| 574 | } |
| 575 | } |
| 576 | |
| 577 | #[test ] |
| 578 | fn slice_index_mut() { |
| 579 | fn check_mut( |
| 580 | vec_slice: &[(i32, i32)], |
| 581 | map_slice: &mut Slice<i32, i32>, |
| 582 | sub_slice: &mut Slice<i32, i32>, |
| 583 | ) { |
| 584 | assert_eq!(map_slice, sub_slice); |
| 585 | itertools::assert_equal( |
| 586 | vec_slice.iter().copied(), |
| 587 | map_slice.iter_mut().map(|(&k, &mut v)| (k, v)), |
| 588 | ); |
| 589 | itertools::assert_equal( |
| 590 | vec_slice.iter().map(|&(_, v)| v), |
| 591 | map_slice.values_mut().map(|&mut v| v), |
| 592 | ); |
| 593 | } |
| 594 | |
| 595 | let vec: Vec<(i32, i32)> = (0..10).map(|i| (i, i * i)).collect(); |
| 596 | let mut map: IndexMap<i32, i32> = vec.iter().cloned().collect(); |
| 597 | let mut map2 = map.clone(); |
| 598 | let slice = map2.as_mut_slice(); |
| 599 | |
| 600 | // RangeFull |
| 601 | check_mut(&vec[..], &mut map[..], &mut slice[..]); |
| 602 | |
| 603 | for i in 0usize..10 { |
| 604 | // IndexMut |
| 605 | assert_eq!(&mut map[i], &mut slice[i]); |
| 606 | |
| 607 | // RangeFrom |
| 608 | check_mut(&vec[i..], &mut map[i..], &mut slice[i..]); |
| 609 | |
| 610 | // RangeTo |
| 611 | check_mut(&vec[..i], &mut map[..i], &mut slice[..i]); |
| 612 | |
| 613 | // RangeToInclusive |
| 614 | check_mut(&vec[..=i], &mut map[..=i], &mut slice[..=i]); |
| 615 | |
| 616 | // (Bound<usize>, Bound<usize>) |
| 617 | let bounds = (Bound::Excluded(i), Bound::Unbounded); |
| 618 | check_mut(&vec[i + 1..], &mut map[bounds], &mut slice[bounds]); |
| 619 | |
| 620 | for j in i..=10 { |
| 621 | // Range |
| 622 | check_mut(&vec[i..j], &mut map[i..j], &mut slice[i..j]); |
| 623 | } |
| 624 | |
| 625 | for j in i..10 { |
| 626 | // RangeInclusive |
| 627 | check_mut(&vec[i..=j], &mut map[i..=j], &mut slice[i..=j]); |
| 628 | } |
| 629 | } |
| 630 | } |
| 631 | } |
| 632 | |