this repo has no description
at main 1068 lines 33 kB view raw
1#![cfg_attr(not(test), no_std)] 2// #![no_std] 3 4use core::borrow::{Borrow, BorrowMut}; 5use core::error::Error; 6use core::hash::{Hash, Hasher}; 7use core::mem::MaybeUninit; 8use core::ops::{Bound, Deref, DerefMut, RangeBounds}; 9use core::ptr::NonNull; 10use core::{cmp, fmt, mem, ptr, slice}; 11 12pub struct CapacityError<T>(pub T); 13 14impl<T> Error for CapacityError<T> {} 15 16impl<T> fmt::Display for CapacityError<T> { 17 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 18 f.write_str("insufficient capacity") 19 } 20} 21 22impl<T> fmt::Debug for CapacityError<T> { 23 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 24 write!(f, "CapacityError: insufficient capacity") 25 } 26} 27 28/// A vector with a fixed capacity. 29/// 30/// The `ArrayVec` is a vector backed by a fixed size array. Elements are stored inline in the vector 31/// itself (rather than on the heap) making `ArrayVec` suitable to be allocated on the stack or 32/// used in `const` contexts. 33/// 34/// The maximum capacity of the vector is determined by the `CAP` generic parameter, attempting to 35/// insert more elements than `CAP` will always fail. 36pub struct ArrayVec<T, const CAP: usize> { 37 len: usize, 38 data: [MaybeUninit<T>; CAP], 39} 40 41impl<T, const CAP: usize> Default for ArrayVec<T, CAP> { 42 fn default() -> Self { 43 Self::new() 44 } 45} 46 47impl<T, const CAP: usize> Drop for ArrayVec<T, CAP> { 48 fn drop(&mut self) { 49 self.clear(); 50 } 51} 52 53impl<T, const CAP: usize> ArrayVec<T, CAP> { 54 /// Create a new empty `ArrayVec`. 55 /// 56 /// The maximum capacity is given by the generic parameter `CAP`. 57 #[inline] 58 pub const fn new() -> Self { 59 Self { 60 data: [const { MaybeUninit::uninit() }; CAP], 61 len: 0, 62 } 63 } 64 65 /// Returns the number of elements in the `ArrayVec`. 66 #[inline(always)] 67 pub const fn len(&self) -> usize { 68 self.len 69 } 70 71 /// Returns `true` if the `ArrayVec` is empty, `false` otherwise. 72 #[inline] 73 pub const fn is_empty(&self) -> bool { 74 self.len() == 0 75 } 76 77 /// Returns the capacity of the `ArrayVec`. 78 #[inline(always)] 79 pub const fn capacity(&self) -> usize { 80 CAP 81 } 82 83 /// Returns `true` if the `ArrayVec` is completely filled to its capacity, `false` otherwise. 84 pub const fn is_full(&self) -> bool { 85 self.len() == self.capacity() 86 } 87 88 /// Returns the capacity left in the `ArrayVec`. 89 pub const fn remaining_capacity(&self) -> usize { 90 self.capacity() - self.len() 91 } 92 93 /// Returns a raw pointer to the vector’s buffer. 94 pub const fn as_ptr(&self) -> *const T { 95 self.data.as_ptr().cast() 96 } 97 98 /// Returns a raw mutable pointer to the vector’s buffer. 99 pub const fn as_mut_ptr(&mut self) -> *mut T { 100 self.data.as_mut_ptr().cast() 101 } 102 103 /// Extracts a slice containing the entire vector. 104 pub const fn as_slice(&self) -> &[T] { 105 // SAFETY: `slice::from_raw_parts` requires 106 // 1. pointee is a contiguous, aligned buffer of size `len` containing properly-initialized `T`s. 107 // 2. Data must not be mutated for the returned lifetime. 108 // 3. Further, `len * size_of::<T>` <= `isize::MAX`, and allocation does not "wrap" through overflowing memory addresses. 109 // 110 // The ArrayVec API guarantees properly-initialized items within 0..len 111 // and the backing store being a Rust array guarantees correct alignment and contiguity. 112 // 3. Is also guaranteed by construction (can't express a type that's too large) and we 113 // since we borrow self here 2. is upheld as well. 114 unsafe { slice::from_raw_parts(self.as_ptr(), self.len) } 115 } 116 117 /// Extracts a mutable slice of the entire vector. 118 pub const fn as_mut_slice(&mut self) -> &mut [T] { 119 // SAFETY: `slice::from_raw_parts` requires 120 // 1. pointee is a contiguous, aligned buffer of size `len` containing properly-initialized `T`s. 121 // 2. Data must not be mutated for the returned lifetime. 122 // 3. Further, `len * size_of::<T>` <= `isize::MAX`, and allocation does not "wrap" through overflowing memory addresses. 123 // 124 // The ArrayVec API guarantees properly-initialized items within 0..len 125 // and the backing store being a Rust array guarantees correct alignment and contiguity. 126 // 3. Is also guaranteed by construction (can't express a type that's too large) and we 127 // since we borrow self here 2. is upheld as well. 128 unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) } 129 } 130 131 /// Push `element` to the end of the vector. 132 /// 133 /// # Panics 134 /// 135 /// Panics if the `ArrayVec` is full. 136 pub fn push(&mut self, element: T) { 137 self.try_push(element).unwrap(); 138 } 139 140 /// Push `element` to the end of the vector. 141 /// 142 /// # Errors 143 /// 144 /// Returns `Err(CapacityError)` with the element if the `ArrayVec` is full. 145 pub const fn try_push(&mut self, element: T) -> Result<(), CapacityError<T>> { 146 if self.len() < CAP { 147 // Safety: we have checked the capacity above 148 unsafe { 149 self.push_unchecked(element); 150 } 151 Ok(()) 152 } else { 153 Err(CapacityError(element)) 154 } 155 } 156 157 /// Push `element` to the end of the vector, without doing bounds checking. 158 /// 159 /// # Safety 160 /// 161 /// Calling this method with on an already full vector is *[undefined behavior]*. 162 /// The caller has to ensure that `self.len() < self.capacity()`. 163 #[track_caller] 164 pub const unsafe fn push_unchecked(&mut self, element: T) { 165 let len = self.len(); 166 debug_assert!(len < CAP); 167 self.data[len].write(element); 168 self.len += 1; 169 } 170 171 /// Removes the last element from a vector and returns it, or [`None`] if it 172 /// is empty. 173 /// 174 /// # Time complexity 175 /// 176 /// Takes *O*(1) time. 177 #[inline] 178 pub const fn pop(&mut self) -> Option<T> { 179 if self.len == 0 { 180 None 181 } else { 182 // Safety: we have checked `len` is NOT zero above, which means there 183 // must be at least one element in the vec at the `len - 1` index. 184 unsafe { 185 self.len -= 1; 186 core::hint::assert_unchecked(self.len < self.capacity()); 187 Some(ptr::read(self.as_ptr().add(self.len()))) 188 } 189 } 190 } 191 192 /// Remove all elements in the vector. 193 pub fn clear(&mut self) { 194 let len = self.len; 195 self.len = 0; 196 for elt in self.data.iter_mut().take(len) { 197 // Safety: ArrayVec API guarantees properly-initialized items within 0..len 198 unsafe { MaybeUninit::assume_init_drop(elt) }; 199 } 200 } 201 202 /// Retains only the elements specified by the predicate. 203 pub fn retain<F>(&mut self, mut f: F) 204 where 205 F: FnMut(&mut T) -> bool, 206 { 207 // The implementation below is taken from std::vec::Vec 208 209 let original_len = self.len(); 210 self.len = 0; 211 212 struct BackshiftOnDrop<'a, T, const CAP: usize> { 213 v: &'a mut ArrayVec<T, CAP>, 214 processed_len: usize, 215 deleted_cnt: usize, 216 original_len: usize, 217 } 218 219 impl<T, const CAP: usize> Drop for BackshiftOnDrop<'_, T, CAP> { 220 fn drop(&mut self) { 221 if self.deleted_cnt > 0 { 222 // Safety: Trailing unchecked items must be valid since we never touch them. 223 unsafe { 224 ptr::copy( 225 self.v.as_ptr().add(self.processed_len), 226 self.v 227 .as_mut_ptr() 228 .add(self.processed_len - self.deleted_cnt), 229 self.original_len - self.processed_len, 230 ); 231 } 232 } 233 self.v.len = self.original_len - self.deleted_cnt; 234 } 235 } 236 237 let mut g = BackshiftOnDrop { 238 v: self, 239 processed_len: 0, 240 deleted_cnt: 0, 241 original_len, 242 }; 243 244 #[inline(always)] 245 fn process_one<F: FnMut(&mut T) -> bool, T, const CAP: usize, const DELETED: bool>( 246 f: &mut F, 247 g: &mut BackshiftOnDrop<'_, T, CAP>, 248 ) -> bool { 249 // Safety: Unchecked element must be valid. 250 let cur = unsafe { g.v.as_mut_ptr().add(g.processed_len) }; 251 // Safety: Unchecked element must be valid. 252 if !f(unsafe { cur.as_mut().unwrap() }) { 253 g.processed_len += 1; 254 g.deleted_cnt += 1; 255 // Safety: We never touch this element again after dropped. 256 unsafe { ptr::drop_in_place(cur) }; 257 return false; 258 } 259 if DELETED { 260 // Safety: `deleted_cnt` > 0, so the hole slot must not overlap with current element. 261 // We use copy for move, and never touch this element again. 262 unsafe { 263 let hole_slot = cur.sub(g.deleted_cnt); 264 ptr::copy_nonoverlapping(cur, hole_slot, 1); 265 } 266 } 267 g.processed_len += 1; 268 true 269 } 270 271 // Stage 1: Nothing was deleted. 272 while g.processed_len != original_len { 273 if !process_one::<F, T, CAP, false>(&mut f, &mut g) { 274 break; 275 } 276 } 277 278 // Stage 2: Some elements were deleted. 279 while g.processed_len != original_len { 280 process_one::<F, T, CAP, true>(&mut f, &mut g); 281 } 282 283 drop(g); 284 } 285 286 /// Removes the subslice indicated by the given range from the vector, 287 /// returning a double-ended iterator over the removed subslice. 288 /// 289 /// If the iterator is dropped before being fully consumed, 290 /// it drops the remaining removed elements. 291 /// 292 /// The returned iterator keeps a mutable borrow on the vector to optimize 293 /// its implementation. 294 /// 295 /// # Panics 296 /// 297 /// Panics if the starting point is greater than the end point or if 298 /// the end point is greater than the length of the vector. 299 /// 300 /// # Leaking 301 /// 302 /// If the returned iterator goes out of scope without being dropped (due to 303 /// [`mem::forget`], for example), the vector may have lost and leaked 304 /// elements arbitrarily, including elements outside the range. 305 pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, CAP> 306 where 307 R: RangeBounds<usize>, 308 { 309 // Memory safety 310 // 311 // When the Drain is first created, it shortens the length of 312 // the source vector to make sure no uninitialized or moved-from elements 313 // are accessible at all if the Drain's destructor never gets to run. 314 // 315 // Drain will ptr::read out the values to remove. 316 // When finished, remaining tail of the vec is copied back to cover 317 // the hole, and the vector length is restored to the new length. 318 319 let len = self.len(); 320 let start = match range.start_bound() { 321 Bound::Unbounded => 0, 322 Bound::Included(&i) => i, 323 Bound::Excluded(&i) => i.saturating_add(1), 324 }; 325 let end = match range.end_bound() { 326 Bound::Excluded(&j) => j, 327 Bound::Included(&j) => j.saturating_add(1), 328 Bound::Unbounded => len, 329 }; 330 331 // set our length to start, to be safe in case Drain is leaked 332 self.len = start; 333 // Safety: ArrayVec API guarantees properly-initialized items within 0..len 334 // Note: we do this unsafe slicing here because we also need to mutably borrow self (for backshifting the tail) 335 let range_slice = unsafe { slice::from_raw_parts(self.as_ptr().add(start), end - start) }; 336 337 Drain { 338 tail_start: end, 339 tail_len: len - end, 340 iter: range_slice.iter(), 341 #[expect(clippy::ref_as_ptr, reason = "passing &mut self to a function would invalidate the slice iterator")] 342 // Safety: We have a &mut to self, so creating a pointer from it is always safe. 343 vec: unsafe { NonNull::new_unchecked(self as *mut _) }, 344 } 345 } 346 347 /// Shortens the vector, keeping the first `len` elements and dropping 348 /// the rest 349 pub fn truncate(&mut self, new_len: usize) { 350 let len = self.len(); 351 if new_len < len { 352 // Safety: ArrayVec API guarantees properly-initialized items within 0..len 353 // we have checked that new_len is less than len so all elements within 0..new_len must be 354 // initialized 355 unsafe { 356 self.len = new_len; 357 let tail = slice::from_raw_parts_mut(self.as_mut_ptr().add(new_len), len - new_len); 358 ptr::drop_in_place(tail); 359 } 360 } 361 } 362 363 /// Returns the remaining spare capacity of the vector as a slice of 364 /// `MaybeUninit<T>`. 365 pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] { 366 let len = self.len(); 367 &mut self.data[len..] 368 } 369 370 /// Extend the `ArrayVec` with elements from the provided slice 371 /// 372 /// # Panics 373 /// 374 /// Panics if the `ArrayVec` does not have enough capacity to accommodate 375 /// the elements. 376 pub fn extend_from_slice(&mut self, slice: &[T]) 377 where 378 T: Clone, 379 { 380 self.try_extend_from_slice(slice).unwrap(); 381 } 382 383 /// Extend the `ArrayVec` with elements from the provided slice 384 /// 385 /// # Errors 386 /// 387 /// Returns a `CapacityError` if the `ArrayVec` does not have enough capacity to accommodate 388 /// the elements. 389 pub fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), CapacityError<()>> 390 where 391 T: Clone, 392 { 393 if self.remaining_capacity() < other.len() { 394 return Err(CapacityError(())); 395 } 396 397 for (element, slot) in other.iter().cloned().zip(self.spare_capacity_mut()) { 398 slot.write(element); 399 } 400 self.len += other.len(); 401 402 Ok(()) 403 } 404} 405 406impl<T, const CAP: usize> fmt::Debug for ArrayVec<T, CAP> 407where 408 T: fmt::Debug, 409{ 410 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 411 (**self).fmt(f) 412 } 413} 414 415impl<T, const CAP: usize> Clone for ArrayVec<T, CAP> 416where 417 T: Clone, 418{ 419 fn clone(&self) -> Self { 420 self.iter().cloned().collect() 421 } 422 423 fn clone_from(&mut self, rhs: &Self) { 424 // recursive case for the common prefix 425 let prefix = cmp::min(self.len(), rhs.len()); 426 self[..prefix].clone_from_slice(&rhs[..prefix]); 427 428 if prefix < self.len() { 429 // rhs was shorter 430 self.truncate(prefix); 431 } else { 432 let rhs_elems = &rhs[self.len()..]; 433 self.extend_from_slice(rhs_elems); 434 } 435 } 436} 437 438impl<T, const CAP: usize> Deref for ArrayVec<T, CAP> { 439 type Target = [T]; 440 #[inline] 441 fn deref(&self) -> &Self::Target { 442 self.as_slice() 443 } 444} 445 446impl<T, const CAP: usize> DerefMut for ArrayVec<T, CAP> { 447 #[inline] 448 fn deref_mut(&mut self) -> &mut Self::Target { 449 self.as_mut_slice() 450 } 451} 452 453impl<T, const CAP: usize> Hash for ArrayVec<T, CAP> 454where 455 T: Hash, 456{ 457 fn hash<H: Hasher>(&self, state: &mut H) { 458 Hash::hash(&**self, state); 459 } 460} 461 462impl<T, const CAP: usize> PartialEq for ArrayVec<T, CAP> 463where 464 T: PartialEq, 465{ 466 fn eq(&self, other: &Self) -> bool { 467 **self == **other 468 } 469} 470 471impl<T, const CAP: usize> PartialEq<[T]> for ArrayVec<T, CAP> 472where 473 T: PartialEq, 474{ 475 fn eq(&self, other: &[T]) -> bool { 476 **self == *other 477 } 478} 479 480impl<T, const CAP: usize> Eq for ArrayVec<T, CAP> where T: Eq {} 481 482impl<T, const CAP: usize> Borrow<[T]> for ArrayVec<T, CAP> { 483 fn borrow(&self) -> &[T] { 484 self 485 } 486} 487 488impl<T, const CAP: usize> BorrowMut<[T]> for ArrayVec<T, CAP> { 489 fn borrow_mut(&mut self) -> &mut [T] { 490 self 491 } 492} 493 494impl<T, const CAP: usize> AsRef<[T]> for ArrayVec<T, CAP> { 495 fn as_ref(&self) -> &[T] { 496 self 497 } 498} 499 500impl<T, const CAP: usize> AsMut<[T]> for ArrayVec<T, CAP> { 501 fn as_mut(&mut self) -> &mut [T] { 502 self 503 } 504} 505 506impl<T, const CAP: usize> PartialOrd for ArrayVec<T, CAP> 507where 508 T: PartialOrd, 509{ 510 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { 511 (**self).partial_cmp(other) 512 } 513 514 fn lt(&self, other: &Self) -> bool { 515 (**self).lt(other) 516 } 517 518 fn le(&self, other: &Self) -> bool { 519 (**self).le(other) 520 } 521 522 fn ge(&self, other: &Self) -> bool { 523 (**self).ge(other) 524 } 525 526 fn gt(&self, other: &Self) -> bool { 527 (**self).gt(other) 528 } 529} 530 531impl<T, const CAP: usize> Ord for ArrayVec<T, CAP> 532where 533 T: Ord, 534{ 535 fn cmp(&self, other: &Self) -> cmp::Ordering { 536 (**self).cmp(other) 537 } 538} 539 540/// Create an `ArrayVec` from an iterator. 541/// 542/// ***Panics*** if the number of elements in the iterator exceeds the arrayvec's capacity. 543impl<T, const CAP: usize> FromIterator<T> for ArrayVec<T, CAP> { 544 /// Create an `ArrayVec` from an iterator. 545 /// 546 /// ***Panics*** if the number of elements in the iterator exceeds the arrayvec's capacity. 547 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self { 548 let mut array = ArrayVec::new(); 549 for element in iter { 550 array.push(element); 551 } 552 array 553 } 554} 555 556impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a ArrayVec<T, CAP> { 557 type Item = &'a T; 558 type IntoIter = slice::Iter<'a, T>; 559 fn into_iter(self) -> Self::IntoIter { 560 self.iter() 561 } 562} 563 564impl<'a, T: 'a, const CAP: usize> IntoIterator for &'a mut ArrayVec<T, CAP> { 565 type Item = &'a mut T; 566 type IntoIter = slice::IterMut<'a, T>; 567 fn into_iter(self) -> Self::IntoIter { 568 self.iter_mut() 569 } 570} 571 572impl<T, const CAP: usize> IntoIterator for ArrayVec<T, CAP> { 573 type Item = T; 574 type IntoIter = IntoIter<T, CAP>; 575 fn into_iter(self) -> IntoIter<T, CAP> { 576 IntoIter { 577 index: 0, 578 vec: self, 579 } 580 } 581} 582 583pub struct IntoIter<T, const CAP: usize> { 584 index: usize, 585 vec: ArrayVec<T, CAP>, 586} 587 588impl<T, const CAP: usize> Drop for IntoIter<T, CAP> { 589 fn drop(&mut self) { 590 let len = self.vec.len(); 591 self.vec.len = 0; 592 for elt in &mut self.vec.data[self.index..len] { 593 // Safety: ArrayVec API guarantees properly-initialized items within 0..len 594 unsafe { MaybeUninit::assume_init_drop(elt) }; 595 } 596 } 597} 598 599impl<T, const CAP: usize> fmt::Debug for IntoIter<T, CAP> 600where 601 T: fmt::Debug, 602{ 603 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 604 f.debug_list().entries(&self.vec[self.index..]).finish() 605 } 606} 607 608impl<T, const CAP: usize> Iterator for IntoIter<T, CAP> { 609 type Item = T; 610 611 fn next(&mut self) -> Option<Self::Item> { 612 if self.vec.is_empty() || self.index >= self.vec.len { 613 None 614 } else { 615 let elt = mem::replace(&mut self.vec.data[self.index], MaybeUninit::uninit()); 616 self.index += 1; 617 // Safety: ArrayVec API guarantees properly-initialized items within 0..len 618 Some(unsafe { MaybeUninit::assume_init(elt) }) 619 } 620 } 621 622 fn size_hint(&self) -> (usize, Option<usize>) { 623 (self.vec.len(), Some(self.vec.len())) 624 } 625} 626 627impl<T, const CAP: usize> DoubleEndedIterator for IntoIter<T, CAP> { 628 fn next_back(&mut self) -> Option<Self::Item> { 629 if self.vec.is_empty() || self.index >= self.vec.len { 630 None 631 } else { 632 let elt = mem::replace(&mut self.vec.data[self.vec.len - 1], MaybeUninit::uninit()); 633 self.vec.len -= 1; 634 // Safety: ArrayVec API guarantees properly-initialized items within 0..len 635 Some(unsafe { MaybeUninit::assume_init(elt) }) 636 } 637 } 638} 639 640impl<T, const CAP: usize> ExactSizeIterator for IntoIter<T, CAP> {} 641 642/// A draining iterator for `ArrayVec`. 643pub struct Drain<'a, T, const CAP: usize> { 644 /// Index of tail to preserve 645 tail_start: usize, 646 /// Length of tail 647 tail_len: usize, 648 /// Current remaining range to remove 649 iter: slice::Iter<'a, T>, 650 vec: NonNull<ArrayVec<T, CAP>>, 651} 652 653impl<T, const CAP: usize> Iterator for Drain<'_, T, CAP> { 654 type Item = T; 655 656 fn next(&mut self) -> Option<Self::Item> { 657 self.iter.next().map(|elt| { 658 // Safety: ArrayVec API guarantees properly-initialized items within 0..len 659 unsafe { ptr::read(ptr::from_ref(elt)) } 660 }) 661 } 662 663 fn size_hint(&self) -> (usize, Option<usize>) { 664 self.iter.size_hint() 665 } 666} 667 668impl<T, const CAP: usize> DoubleEndedIterator for Drain<'_, T, CAP> { 669 fn next_back(&mut self) -> Option<Self::Item> { 670 self.iter.next_back().map(|elt| { 671 // Safety: ArrayVec API guarantees properly-initialized items within 0..len 672 unsafe { ptr::read(ptr::from_ref(elt)) } 673 }) 674 } 675} 676 677impl<T, const CAP: usize> ExactSizeIterator for Drain<'_, T, CAP> {} 678 679impl<T, const CAP: usize> Drop for Drain<'_, T, CAP> { 680 fn drop(&mut self) { 681 /// Fill the drained range by backshifting the "tail" (elements after the drained range). 682 /// 683 /// We do this in a drop guard so that no matter what happens, even if T's drop panics 684 /// we leave an ArrayVec without uninitialized holes behind. 685 struct DropGuard<'r, 'a, T, const CAP: usize>(&'r mut Drain<'a, T, CAP>); 686 687 impl<'r, 'a, T, const CAP: usize> Drop for DropGuard<'r, 'a, T, CAP> { 688 fn drop(&mut self) { 689 if self.0.tail_len > 0 { 690 // Safety: See ArrayVec::drain comment 691 unsafe { 692 let source_vec = self.0.vec.as_mut(); 693 694 // memmove back untouched tail, update to new length 695 let start = source_vec.len(); 696 let tail = self.0.tail_start; 697 if tail != start { 698 // as_mut_ptr creates a &mut, invalidating other pointers. 699 // This pattern avoids calling it with a pointer already present. 700 let ptr = source_vec.as_mut_ptr(); 701 let src = ptr.add(tail); 702 let dst = ptr.add(start); 703 ptr::copy(src, dst, self.0.tail_len); 704 } 705 source_vec.len = start + self.0.tail_len; 706 } 707 } 708 } 709 } 710 711 let guard = DropGuard(self); 712 713 // drain the iterator and drop its elements 714 for _ in guard.0.by_ref() {} 715 // while let Some(_) = guard.0.next() {} 716 } 717} 718 719#[cfg(test)] 720mod tests { 721 use super::*; 722 723 #[test] 724 fn new_creates_empty_vec() { 725 let vec: ArrayVec<i32, 10> = ArrayVec::new(); 726 assert_eq!(vec.len(), 0); 727 assert!(vec.is_empty()); 728 assert_eq!(vec.capacity(), 10); 729 } 730 731 #[test] 732 fn default_creates_empty_vec() { 733 let vec: ArrayVec<i32, 10> = ArrayVec::default(); 734 assert_eq!(vec.len(), 0); 735 assert!(vec.is_empty()); 736 } 737 738 #[test] 739 fn push_increases_length() { 740 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 741 vec.push(1); 742 assert_eq!(vec.len(), 1); 743 vec.push(2); 744 assert_eq!(vec.len(), 2); 745 } 746 747 #[test] 748 #[should_panic] 749 fn push_panics_when_full() { 750 let mut vec: ArrayVec<i32, 2> = ArrayVec::new(); 751 vec.push(1); 752 vec.push(2); 753 vec.push(3); 754 } 755 756 #[test] 757 fn try_push_succeeds_when_not_full() { 758 let mut vec: ArrayVec<i32, 2> = ArrayVec::new(); 759 assert!(vec.try_push(1).is_ok()); 760 assert!(vec.try_push(2).is_ok()); 761 } 762 763 #[test] 764 fn try_push_fails_when_full() { 765 let mut vec: ArrayVec<i32, 2> = ArrayVec::new(); 766 vec.push(1); 767 vec.push(2); 768 let result = vec.try_push(3); 769 assert!(result.is_err()); 770 assert_eq!(result.unwrap_err().0, 3); 771 } 772 773 #[test] 774 fn is_full_returns_true_when_at_capacity() { 775 let mut vec: ArrayVec<i32, 2> = ArrayVec::new(); 776 assert!(!vec.is_full()); 777 vec.push(1); 778 assert!(!vec.is_full()); 779 vec.push(2); 780 assert!(vec.is_full()); 781 } 782 783 #[test] 784 fn as_slice_returns_valid_slice() { 785 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 786 vec.push(1); 787 vec.push(2); 788 vec.push(3); 789 let slice = vec.as_slice(); 790 assert_eq!(slice, &[1, 2, 3]); 791 } 792 793 #[test] 794 fn as_mut_slice_allows_modification() { 795 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 796 vec.push(1); 797 vec.push(2); 798 let slice = vec.as_mut_slice(); 799 slice[0] = 10; 800 assert_eq!(vec.as_slice(), &[10, 2]); 801 } 802 #[test] 803 fn clear_removes_all_elements() { 804 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 805 vec.push(1); 806 vec.push(2); 807 vec.push(3); 808 vec.clear(); 809 assert_eq!(vec.len(), 0); 810 assert!(vec.is_empty()); 811 } 812 813 #[test] 814 fn retain_keeps_matching_elements() { 815 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 816 vec.push(1); 817 vec.push(2); 818 vec.push(3); 819 vec.push(4); 820 vec.retain(|x| *x % 2 == 0); 821 assert_eq!(vec.as_slice(), &[2, 4]); 822 } 823 824 #[test] 825 fn clone_from_updates_to_match_source() { 826 let mut vec1: ArrayVec<i32, 10> = ArrayVec::new(); 827 vec1.push(1); 828 vec1.push(2); 829 let mut vec2: ArrayVec<i32, 10> = ArrayVec::new(); 830 vec2.push(3); 831 vec2.push(4); 832 vec2.push(5); 833 vec2.clone_from(&vec1); 834 assert_eq!(vec2.as_slice(), &[1, 2]); 835 } 836 837 #[test] 838 fn try_extend_from_slice_succeeds_with_capacity() { 839 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 840 vec.push(1); 841 assert!(vec.try_extend_from_slice(&[2, 3]).is_ok()); 842 assert_eq!(vec.as_slice(), &[1, 2, 3]); 843 } 844 845 #[test] 846 fn try_extend_from_slice_fails_without_capacity() { 847 let mut vec: ArrayVec<i32, 3> = ArrayVec::new(); 848 vec.push(1); 849 let result = vec.try_extend_from_slice(&[2, 3, 4]); 850 assert!(result.is_err()); 851 } 852 853 #[test] 854 fn extend_from_slice_adds_elements() { 855 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 856 vec.push(1); 857 vec.extend_from_slice(&[2, 3, 4]); 858 assert_eq!(vec.as_slice(), &[1, 2, 3, 4]); 859 } 860 861 #[test] 862 #[should_panic] 863 fn extend_from_slice_panics_when_insufficient_capacity() { 864 let mut vec: ArrayVec<i32, 3> = ArrayVec::new(); 865 vec.push(1); 866 vec.extend_from_slice(&[2, 3, 4]); 867 } 868 869 #[test] 870 fn truncate_removes_trailing_elements() { 871 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 872 vec.push(1); 873 vec.push(2); 874 vec.push(3); 875 vec.push(4); 876 vec.truncate(2); 877 assert_eq!(vec.len(), 2); 878 assert_eq!(vec.as_slice(), &[1, 2]); 879 } 880 881 #[test] 882 fn drain_removes_elements_in_range() { 883 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 884 vec.extend_from_slice(&[1, 2, 3, 4, 5]); 885 let drained: Vec<_> = vec.drain(1..3).collect(); 886 assert_eq!(drained, &[2, 3]); 887 assert_eq!(vec.as_slice(), &[1, 4, 5]); 888 } 889 890 #[test] 891 fn drain_calls_drop_on_remaining_elements() { 892 use core::sync::atomic::{AtomicUsize, Ordering}; 893 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0); 894 895 struct DropCounter; 896 impl Drop for DropCounter { 897 fn drop(&mut self) { 898 DROP_COUNT.fetch_add(1, Ordering::SeqCst); 899 } 900 } 901 902 { 903 let mut vec: ArrayVec<DropCounter, 5> = ArrayVec::new(); 904 vec.push(DropCounter); 905 vec.push(DropCounter); 906 vec.push(DropCounter); 907 let mut drain = vec.drain(0..2); 908 drain.next(); // consume one element 909 // Drop drain without consuming all elements 910 drop(drain); 911 912 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 2); 913 } 914 // All 3 elements should be dropped: 1 consumed, 1 remaining in drain, 1 in vec 915 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3); 916 } 917 918 #[test] 919 fn drain_restores_tail_on_early_drop() { 920 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 921 vec.extend_from_slice(&[1, 2, 3, 4, 5]); 922 assert_eq!(vec.len(), 5); 923 { 924 let mut drain = vec.drain(1..3); 925 drain.next(); // consume one element (2) 926 // drain is dropped here without consuming all elements 927 } 928 // Tail should be restored: [1, 4, 5] 929 assert_eq!(vec.as_slice(), &[1, 4, 5]); 930 } 931 932 #[test] 933 fn drain_empty_range() { 934 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 935 vec.extend_from_slice(&[1, 2, 3]); 936 assert_eq!(vec.len(), 3); 937 let drained: Vec<_> = vec.drain(1..1).collect(); 938 assert_eq!(drained.len(), 0); 939 assert_eq!(vec.as_slice(), &[1, 2, 3]); 940 } 941 942 #[test] 943 fn drain_full_range() { 944 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 945 vec.extend_from_slice(&[1, 2, 3, 4]); 946 assert_eq!(vec.len(), 4); 947 let drained: Vec<_> = vec.drain(..).collect(); 948 assert_eq!(drained, &[1, 2, 3, 4]); 949 assert_eq!(vec.len(), 0); 950 assert!(vec.is_empty()); 951 } 952 953 #[test] 954 fn drain_double_ended() { 955 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 956 vec.extend_from_slice(&[1, 2, 3, 4, 5]); 957 assert_eq!(vec.len(), 5); 958 let mut drain = vec.drain(1..4); 959 assert_eq!(drain.next(), Some(2)); 960 assert_eq!(drain.next_back(), Some(4)); 961 assert_eq!(drain.next(), Some(3)); 962 assert_eq!(drain.next(), None); 963 drop(drain); 964 assert_eq!(vec.as_slice(), &[1, 5]); 965 } 966 967 #[test] 968 fn into_iter_consumes_all_elements() { 969 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 970 vec.extend_from_slice(&[1, 2, 3, 4, 5]); 971 let collected: Vec<_> = vec.into_iter().collect(); 972 assert_eq!(collected, &[1, 2, 3, 4, 5]); 973 } 974 975 #[test] 976 fn into_iter_empty_vec() { 977 let vec: ArrayVec<i32, 10> = ArrayVec::new(); 978 let collected: Vec<_> = vec.into_iter().collect(); 979 assert_eq!(collected.len(), 0); 980 } 981 982 #[test] 983 fn into_iter_double_ended() { 984 let mut vec: ArrayVec<i32, 10> = ArrayVec::new(); 985 vec.extend_from_slice(&[1, 2, 3, 4, 5]); 986 let mut iter = vec.into_iter(); 987 assert_eq!(iter.next(), Some(1)); 988 assert_eq!(iter.next_back(), Some(5)); 989 assert_eq!(iter.next(), Some(2)); 990 assert_eq!(iter.next_back(), Some(4)); 991 assert_eq!(iter.next(), Some(3)); 992 assert_eq!(iter.next(), None); 993 assert_eq!(iter.next_back(), None); 994 } 995 996 #[test] 997 fn into_iter_panic_in_drop() { 998 use core::sync::atomic::{AtomicUsize, Ordering}; 999 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0); 1000 1001 enum DropEl { 1002 Count, 1003 Panic, 1004 } 1005 1006 impl Drop for DropEl { 1007 fn drop(&mut self) { 1008 match *self { 1009 DropEl::Count => { 1010 DROP_COUNT.fetch_add(1, Ordering::SeqCst); 1011 } 1012 DropEl::Panic => { 1013 panic!("Oh no"); 1014 } 1015 } 1016 } 1017 } 1018 1019 let mut vec: ArrayVec<DropEl, 5> = ArrayVec::new(); 1020 vec.push(DropEl::Count); 1021 vec.push(DropEl::Panic); 1022 vec.push(DropEl::Count); 1023 1024 let mut iter = vec.into_iter(); 1025 iter.next(); 1026 let _ = std::panic::catch_unwind(|| drop(iter)); 1027 1028 // Note we don't see enough drop counts, essentially every element after the panic is leaked 1029 // but at least we don't access uninitialized elements and trigger UB 1030 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1); 1031 } 1032 1033 #[test] 1034 fn drain_panic_in_drop() { 1035 use core::sync::atomic::{AtomicUsize, Ordering}; 1036 static DROP_COUNT: AtomicUsize = AtomicUsize::new(0); 1037 1038 enum DropEl { 1039 Count, 1040 Panic, 1041 } 1042 1043 impl Drop for DropEl { 1044 fn drop(&mut self) { 1045 match *self { 1046 DropEl::Count => { 1047 DROP_COUNT.fetch_add(1, Ordering::SeqCst); 1048 } 1049 DropEl::Panic => { 1050 panic!("Oh no"); 1051 } 1052 } 1053 } 1054 } 1055 1056 let mut vec: ArrayVec<DropEl, 5> = ArrayVec::new(); 1057 vec.push(DropEl::Count); 1058 vec.push(DropEl::Panic); 1059 vec.push(DropEl::Count); 1060 1061 let drain = vec.drain(1..2); 1062 assert_eq!(drain.len(), 1); 1063 let _ = std::panic::catch_unwind(|| drop(drain)); 1064 assert_eq!(vec.len(), 2); 1065 drop(vec); 1066 assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 2); 1067 } 1068}