Skip to content

Commit 0ebca23

Browse files
authored
Merge pull request #508 from honzasp/deque-swap
Add `Deque::{swap, swap_unchecked, swap_remove_front, swap_remove_back}`
2 parents 69add42 + 7967074 commit 0ebca23

File tree

2 files changed

+160
-2
lines changed

2 files changed

+160
-2
lines changed

CHANGELOG.md

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

4243
### Changed
4344

src/deque.rs

Lines changed: 159 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,76 @@ 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 buffer_ptr = buffer.as_mut_ptr();
735+
let ptr_i = buffer_ptr.add(idx_i);
736+
let ptr_j = buffer_ptr.add(idx_j);
737+
ptr::swap(ptr_i, ptr_j);
738+
}
739+
740+
/// Removes an element from anywhere in the deque and returns it, replacing it with the first
741+
/// element.
742+
///
743+
/// This does not preserve ordering, but is *O*(1).
744+
///
745+
/// Returns `None` if `index` is out of bounds.
746+
///
747+
/// Element at index 0 is the front of the queue.
748+
pub fn swap_remove_front(&mut self, index: usize) -> Option<T> {
749+
let len = self.storage_len();
750+
if len > 0 && index < len {
751+
Some(unsafe {
752+
self.swap_unchecked(index, 0);
753+
self.pop_front_unchecked()
754+
})
755+
} else {
756+
None
757+
}
758+
}
759+
760+
/// Removes an element from anywhere in the deque and returns it, replacing it with the last
761+
/// element.
762+
///
763+
/// This does not preserve ordering, but is *O*(1).
764+
///
765+
/// Returns `None` if `index` is out of bounds.
766+
///
767+
/// Element at index 0 is the front of the queue.
768+
pub fn swap_remove_back(&mut self, index: usize) -> Option<T> {
769+
let len = self.storage_len();
770+
if len > 0 && index < len {
771+
Some(unsafe {
772+
self.swap_unchecked(index, len - 1);
773+
self.pop_back_unchecked()
774+
})
775+
} else {
776+
None
777+
}
778+
}
779+
709780
fn to_physical_index(&self, index: usize) -> usize {
710781
let mut res = self.front + index;
711782
if res >= self.storage_capacity() {
@@ -1283,4 +1354,90 @@ mod tests {
12831354
assert_eq!(q.pop_front(), Some(43));
12841355
assert_eq!(q.pop_front(), None);
12851356
}
1357+
1358+
#[test]
1359+
fn swap() {
1360+
let mut q: Deque<i32, 4> = Deque::new();
1361+
q.push_back(40).unwrap();
1362+
q.push_back(41).unwrap();
1363+
q.push_back(42).unwrap();
1364+
q.pop_front().unwrap();
1365+
q.push_back(43).unwrap();
1366+
assert_eq!(*q.get(0).unwrap(), 41);
1367+
assert_eq!(*q.get(1).unwrap(), 42);
1368+
assert_eq!(*q.get(2).unwrap(), 43);
1369+
1370+
q.swap(0, 1);
1371+
assert_eq!(*q.get(0).unwrap(), 42);
1372+
assert_eq!(*q.get(1).unwrap(), 41);
1373+
assert_eq!(*q.get(2).unwrap(), 43);
1374+
1375+
q.swap(1, 2);
1376+
assert_eq!(*q.get(0).unwrap(), 42);
1377+
assert_eq!(*q.get(1).unwrap(), 43);
1378+
assert_eq!(*q.get(2).unwrap(), 41);
1379+
1380+
q.swap(1, 1);
1381+
assert_eq!(*q.get(0).unwrap(), 42);
1382+
assert_eq!(*q.get(1).unwrap(), 43);
1383+
assert_eq!(*q.get(2).unwrap(), 41);
1384+
}
1385+
1386+
#[test]
1387+
fn swap_remove_front() {
1388+
let mut q: Deque<i32, 4> = Deque::new();
1389+
q.push_back(40).unwrap();
1390+
q.push_back(41).unwrap();
1391+
q.push_back(42).unwrap();
1392+
q.push_back(43).unwrap();
1393+
1394+
assert_eq!(q.swap_remove_front(2), Some(42));
1395+
assert_eq!(q.swap_remove_front(1), Some(40));
1396+
assert_eq!(q.swap_remove_front(0), Some(41));
1397+
assert_eq!(q.swap_remove_front(1), None);
1398+
assert_eq!(q.swap_remove_front(4), None);
1399+
assert_eq!(q.swap_remove_front(6), None);
1400+
assert_eq!(q.swap_remove_front(0), Some(43));
1401+
}
1402+
1403+
#[test]
1404+
fn swap_remove_back() {
1405+
let mut q: Deque<i32, 4> = Deque::new();
1406+
q.push_back(40).unwrap();
1407+
q.push_back(41).unwrap();
1408+
q.push_back(42).unwrap();
1409+
q.push_back(43).unwrap();
1410+
q.pop_front().unwrap();
1411+
q.push_back(44).unwrap();
1412+
1413+
assert_eq!(q.swap_remove_back(1), Some(42));
1414+
assert_eq!(q.swap_remove_front(1), Some(44));
1415+
assert_eq!(q.swap_remove_front(0), Some(41));
1416+
assert_eq!(q.swap_remove_front(1), None);
1417+
assert_eq!(q.swap_remove_front(4), None);
1418+
assert_eq!(q.swap_remove_front(6), None);
1419+
assert_eq!(q.swap_remove_front(0), Some(43));
1420+
}
1421+
1422+
#[test]
1423+
#[should_panic = "i < len"]
1424+
fn swap_i_out_of_bounds() {
1425+
let mut q: Deque<i32, 4> = Deque::new();
1426+
q.push_back(40).unwrap();
1427+
q.push_back(41).unwrap();
1428+
q.push_back(42).unwrap();
1429+
q.pop_front().unwrap();
1430+
q.swap(2, 0);
1431+
}
1432+
1433+
#[test]
1434+
#[should_panic = "j < len"]
1435+
fn swap_j_out_of_bounds() {
1436+
let mut q: Deque<i32, 4> = Deque::new();
1437+
q.push_back(40).unwrap();
1438+
q.push_back(41).unwrap();
1439+
q.push_back(42).unwrap();
1440+
q.pop_front().unwrap();
1441+
q.swap(0, 2);
1442+
}
12861443
}

0 commit comments

Comments
 (0)