Skip to content

Commit 1d3f8a3

Browse files
committed
Cleanup code, fix typo and remove unncessary bound checks
This commit: - makes insert_unchecked_keep_len private - replaces `if let`s with `match`es - gives better names to the raw pointers - compresses the 3 bound checks into 1 inside force_insert - fixes the "Exmaples" typo - makes swap_remove_unchecked's implementation prettier
1 parent e57c1e5 commit 1d3f8a3

File tree

1 file changed

+29
-43
lines changed

1 file changed

+29
-43
lines changed

src/lib.rs

Lines changed: 29 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ impl<T, const N: usize> ArrayVec<T, { N }> {
280280
/// The item cannot be inserted at an index greater than the
281281
/// vector's length or greater or equal to the maximum capacity `N`.
282282
///
283-
/// # Exmaples
283+
/// # Examples
284284
///
285285
/// When the vector's not full, [`ArrayVec::force_insert`] acts like
286286
/// [`ArrayVec::insert`]:
@@ -313,18 +313,13 @@ impl<T, const N: usize> ArrayVec<T, { N }> {
313313
pub fn force_insert(&mut self, index: usize, item: T) -> Option<T> {
314314
let len = self.len();
315315

316-
// bound checks
317-
if index > len {
318-
out_of_bounds!("force_insert", index, len);
319-
}
320-
321316
let result;
322317

323-
if self.is_full() {
324-
// bound checks (here: N == len)
325-
if index >= N {
326-
out_of_bounds!("force_insert", index, len);
327-
}
318+
if index > len || index == N {
319+
// Failed bound checks.
320+
out_of_bounds!("force_insert", index, len);
321+
} else if self.is_full() {
322+
// The last item must be removed to perform the insertion.
328323

329324
unsafe {
330325
// Store the last item before it's removed.
@@ -335,17 +330,12 @@ impl<T, const N: usize> ArrayVec<T, { N }> {
335330
self.insert_unchecked_keep_len(index, item, len - 1);
336331
}
337332
} else {
338-
// bound checks
339-
if index > len {
340-
out_of_bounds!("force_insert", index, len);
341-
}
342-
343333
// Since nothing's going to be removed, the vector's size
344334
// is going to be increased and nothing will be returned.
345335
unsafe {
346336
self.insert_unchecked(index, item, len);
347-
result = None;
348337
}
338+
result = None;
349339
}
350340

351341
result
@@ -380,20 +370,20 @@ impl<T, const N: usize> ArrayVec<T, { N }> {
380370
/// 3 previously mentioned conditions yourself before calling this
381371
/// method. You also need to increment the vector's length afterward
382372
/// yourself.
383-
pub unsafe fn insert_unchecked_keep_len(
373+
unsafe fn insert_unchecked_keep_len(
384374
&mut self,
385375
index: usize,
386376
item: T,
387377
len: usize,
388378
) {
389-
// The spot to put the Vec::new(new value);
390-
let p = self.as_mut_ptr().add(index);
379+
// The spot to put the new value at.
380+
let ptr_index = self.as_mut_ptr().add(index);
391381
// Shift everything over to make space. (Duplicating the
392382
// `index`th element into two consecutive places.)
393-
ptr::copy(p, p.add(1), len - index);
383+
ptr::copy(ptr_index, ptr_index.add(1), len - index);
394384
// Write it in, overwriting the first copy of the `index`th
395385
// element.
396-
ptr::write(p, item);
386+
ptr::write(ptr_index, item);
397387
}
398388

399389
/// Remove the value contained at `index` and return it.
@@ -414,10 +404,9 @@ impl<T, const N: usize> ArrayVec<T, { N }> {
414404
/// assert_eq!(&vector, [4, 2].as_ref());
415405
/// ```
416406
pub fn remove(&mut self, index: usize) -> T {
417-
if let Some(item) = self.try_remove(index) {
418-
item
419-
} else {
420-
out_of_bounds!("remove", index, self.len());
407+
match self.try_remove(index) {
408+
Some(item) => item,
409+
None => out_of_bounds!("remove", index, self.len()),
421410
}
422411
}
423412

@@ -455,11 +444,11 @@ impl<T, const N: usize> ArrayVec<T, { N }> {
455444
let len = self.len();
456445

457446
// Where the value to remove is.
458-
let p = self.as_mut_ptr().add(index);
447+
let ptr_index = self.as_mut_ptr().add(index);
459448
// Read the value before sending it to the other world.
460-
let item = ptr::read(p);
449+
let item = ptr::read(ptr_index);
461450
// Shift every value after the removed one to the left.
462-
ptr::copy(p.add(1), p, len - index - 1);
451+
ptr::copy(ptr_index.add(1), ptr_index, len - index - 1);
463452
// We removed an item, so the length should be decremented.
464453
self.set_len(len - 1);
465454

@@ -492,10 +481,9 @@ impl<T, const N: usize> ArrayVec<T, { N }> {
492481
/// assert_eq!(vector.len(), 0);
493482
/// ```
494483
pub fn swap_remove(&mut self, index: usize) -> T {
495-
if let Some(item) = self.try_swap_remove(index) {
496-
item
497-
} else {
498-
out_of_bounds!("swap_remove", index, self.len());
484+
match self.try_swap_remove(index) {
485+
Some(item) => item,
486+
None => out_of_bounds!("swap_remove", index, self.len()),
499487
}
500488
}
501489

@@ -537,18 +525,16 @@ impl<T, const N: usize> ArrayVec<T, { N }> {
537525
/// The index must be in bounds.
538526
pub unsafe fn swap_remove_unchecked(&mut self, index: usize) -> T {
539527
let new_len = self.len() - 1;
540-
let p = self.as_mut_ptr();
541-
let p_item = p.add(index);
528+
let ptr_vec_start = self.as_mut_ptr();
529+
let ptr_index = ptr_vec_start.add(index);
542530

543531
// Read the item from its pointer.
544-
let item = ptr::read(p_item);
545-
546-
// Check `index` isn't the last item's index.
547-
if new_len != index {
548-
// Replace the item at `index` with the last item.
549-
ptr::copy_nonoverlapping(p.add(new_len), p_item, 1);
550-
}
551-
532+
let item = ptr::read(ptr_index);
533+
// Read the last item from its pointer.
534+
let last_item = ptr::read(ptr_vec_start.add(new_len));
535+
// Replace the item at `index` with the last item without calling
536+
// `drop`.
537+
ptr::write(ptr_index, last_item);
552538
// Resize the vector so that the last item gets ignored.
553539
self.set_len(new_len);
554540

0 commit comments

Comments
 (0)