Skip to content

Commit 1231fec

Browse files
committed
Add Deque::{swap, swap_unchecked, swap_remove_front, swap_remove_back}
1 parent f09c219 commit 1231fec

File tree

2 files changed

+159
-2
lines changed

2 files changed

+159
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3434
- Added `QueueView`, the `!Sized` version of `Queue`.
3535
- Added `SortedLinkedListView`, the `!Sized` version of `SortedLinkedList`.
3636
- Added implementation of `Borrow` and `BorrowMut` for `String` and `Vec`.
37+
- Added `Deque::{swap, swap_unchecked, swap_remove_front, swap_remove_back}`.
3738

3839
### Changed
3940

src/deque.rs

Lines changed: 158 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,14 @@ impl<T, const N: usize> Deque<T, N> {
162162

163163
/// Returns the maximum number of elements the deque can hold.
164164
///
165-
/// This method is not available on a `DequeView`, use [`storage_len`](DequeInner::storage_capacity) instead
165+
/// This method is not available on a `DequeView`, use [`storage_capacity`](DequeInner::storage_capacity) instead.
166166
pub const fn capacity(&self) -> usize {
167167
N
168168
}
169169

170170
/// Returns the number of elements currently in the deque.
171171
///
172-
/// This method is not available on a `DequeView`, use [`storage_len`](DequeInner::storage_len) instead
172+
/// This method is not available on a `DequeView`, use [`storage_len`](DequeInner::storage_len) instead.
173173
pub const fn len(&self) -> usize {
174174
if self.full {
175175
N
@@ -650,6 +650,7 @@ impl<T, S: Storage> DequeInner<T, S> {
650650
self.full = true;
651651
}
652652
}
653+
653654
/// Returns a reference to the element at the given index.
654655
///
655656
/// Index 0 is the front of the `Deque`.
@@ -706,6 +707,75 @@ impl<T, S: Storage> DequeInner<T, S> {
706707
.assume_init_mut()
707708
}
708709

710+
/// Swaps elements at indices `i` and `j`.
711+
///
712+
/// # Panics
713+
///
714+
/// Panics if either `i` or `j` are out of bounds.
715+
pub fn swap(&mut self, i: usize, j: usize) {
716+
let len = self.storage_len();
717+
assert!(i < len);
718+
assert!(j < len);
719+
unsafe { self.swap_unchecked(i, j) }
720+
}
721+
722+
/// Swaps elements at indices `i` and `j` without checking that they exist.
723+
///
724+
/// # Safety
725+
///
726+
/// Elements at indexes `i` and `j` must exist (i.e. `i < self.len()` and `j < self.len()`).
727+
pub unsafe fn swap_unchecked(&mut self, i: usize, j: usize) {
728+
debug_assert!(i < self.storage_len());
729+
debug_assert!(j < self.storage_len());
730+
let idx_i = self.to_physical_index(i);
731+
let idx_j = self.to_physical_index(j);
732+
733+
let buffer = self.buffer.borrow_mut();
734+
let ptr_i = buffer.get_unchecked_mut(idx_i).as_mut_ptr();
735+
let ptr_j = buffer.get_unchecked_mut(idx_j).as_mut_ptr();
736+
ptr::swap(ptr_i, ptr_j);
737+
}
738+
739+
/// Removes an element from anywhere in the deque and returns it, replacing it with the first
740+
/// element.
741+
///
742+
/// This does not preserve ordering, but is *O*(1).
743+
///
744+
/// Returns `None` if `index` is out of bounds.
745+
///
746+
/// Element at index 0 is the front of the queue.
747+
pub fn swap_remove_front(&mut self, index: usize) -> Option<T> {
748+
let len = self.storage_len();
749+
if len > 0 && index < len {
750+
Some(unsafe {
751+
self.swap_unchecked(index, 0);
752+
self.pop_front_unchecked()
753+
})
754+
} else {
755+
None
756+
}
757+
}
758+
759+
/// Removes an element from anywhere in the deque and returns it, replacing it with the last
760+
/// element.
761+
///
762+
/// This does not preserve ordering, but is *O*(1).
763+
///
764+
/// Returns `None` if `index` is out of bounds.
765+
///
766+
/// Element at index 0 is the front of the queue.
767+
pub fn swap_remove_back(&mut self, index: usize) -> Option<T> {
768+
let len = self.storage_len();
769+
if len > 0 && index < len {
770+
Some(unsafe {
771+
self.swap_unchecked(index, len - 1);
772+
self.pop_back_unchecked()
773+
})
774+
} else {
775+
None
776+
}
777+
}
778+
709779
fn to_physical_index(&self, index: usize) -> usize {
710780
let mut res = self.front + index;
711781
if res >= self.storage_capacity() {
@@ -1283,4 +1353,90 @@ mod tests {
12831353
assert_eq!(q.pop_front(), Some(43));
12841354
assert_eq!(q.pop_front(), None);
12851355
}
1356+
1357+
#[test]
1358+
fn swap() {
1359+
let mut q: Deque<i32, 4> = Deque::new();
1360+
q.push_back(40).unwrap();
1361+
q.push_back(41).unwrap();
1362+
q.push_back(42).unwrap();
1363+
q.pop_front().unwrap();
1364+
q.push_back(43).unwrap();
1365+
assert_eq!(*q.get(0).unwrap(), 41);
1366+
assert_eq!(*q.get(1).unwrap(), 42);
1367+
assert_eq!(*q.get(2).unwrap(), 43);
1368+
1369+
q.swap(0, 1);
1370+
assert_eq!(*q.get(0).unwrap(), 42);
1371+
assert_eq!(*q.get(1).unwrap(), 41);
1372+
assert_eq!(*q.get(2).unwrap(), 43);
1373+
1374+
q.swap(1, 2);
1375+
assert_eq!(*q.get(0).unwrap(), 42);
1376+
assert_eq!(*q.get(1).unwrap(), 43);
1377+
assert_eq!(*q.get(2).unwrap(), 41);
1378+
1379+
q.swap(1, 1);
1380+
assert_eq!(*q.get(0).unwrap(), 42);
1381+
assert_eq!(*q.get(1).unwrap(), 43);
1382+
assert_eq!(*q.get(2).unwrap(), 41);
1383+
}
1384+
1385+
#[test]
1386+
fn swap_remove_front() {
1387+
let mut q: Deque<i32, 4> = Deque::new();
1388+
q.push_back(40).unwrap();
1389+
q.push_back(41).unwrap();
1390+
q.push_back(42).unwrap();
1391+
q.push_back(43).unwrap();
1392+
1393+
assert_eq!(q.swap_remove_front(2), Some(42));
1394+
assert_eq!(q.swap_remove_front(1), Some(40));
1395+
assert_eq!(q.swap_remove_front(0), Some(41));
1396+
assert_eq!(q.swap_remove_front(1), None);
1397+
assert_eq!(q.swap_remove_front(4), None);
1398+
assert_eq!(q.swap_remove_front(6), None);
1399+
assert_eq!(q.swap_remove_front(0), Some(43));
1400+
}
1401+
1402+
#[test]
1403+
fn swap_remove_back() {
1404+
let mut q: Deque<i32, 4> = Deque::new();
1405+
q.push_back(40).unwrap();
1406+
q.push_back(41).unwrap();
1407+
q.push_back(42).unwrap();
1408+
q.push_back(43).unwrap();
1409+
q.pop_front().unwrap();
1410+
q.push_back(44).unwrap();
1411+
1412+
assert_eq!(q.swap_remove_back(1), Some(42));
1413+
assert_eq!(q.swap_remove_front(1), Some(44));
1414+
assert_eq!(q.swap_remove_front(0), Some(41));
1415+
assert_eq!(q.swap_remove_front(1), None);
1416+
assert_eq!(q.swap_remove_front(4), None);
1417+
assert_eq!(q.swap_remove_front(6), None);
1418+
assert_eq!(q.swap_remove_front(0), Some(43));
1419+
}
1420+
1421+
#[test]
1422+
#[should_panic = "i < len"]
1423+
fn swap_i_out_of_bounds() {
1424+
let mut q: Deque<i32, 4> = Deque::new();
1425+
q.push_back(40).unwrap();
1426+
q.push_back(41).unwrap();
1427+
q.push_back(42).unwrap();
1428+
q.pop_front().unwrap();
1429+
q.swap(2, 0);
1430+
}
1431+
1432+
#[test]
1433+
#[should_panic = "j < len"]
1434+
fn swap_j_out_of_bounds() {
1435+
let mut q: Deque<i32, 4> = Deque::new();
1436+
q.push_back(40).unwrap();
1437+
q.push_back(41).unwrap();
1438+
q.push_back(42).unwrap();
1439+
q.pop_front().unwrap();
1440+
q.swap(0, 2);
1441+
}
12861442
}

0 commit comments

Comments
 (0)