Deprecate [T]::rotate in favor of [T]::rotate_{left,right}.
Background ========== Slices currently have an unstable [`rotate`] method which rotates elements in the slice to the _left_ N positions. [Here][tracking] is the tracking issue for this unstable feature. ```rust let mut a = ['a', 'b' ,'c', 'd', 'e', 'f']; a.rotate(2); assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']); ``` Proposal ======== Deprecate the [`rotate`] method and introduce `rotate_left` and `rotate_right` methods. ```rust let mut a = ['a', 'b' ,'c', 'd', 'e', 'f']; a.rotate_left(2); assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']); ``` ```rust let mut a = ['a', 'b' ,'c', 'd', 'e', 'f']; a.rotate_right(2); assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']); ``` Justification ============= I used this method today for my first time and (probably because I’m a naive westerner who reads LTR) was surprised when the docs mentioned that elements get rotated in a left-ward direction. I was in a situation where I needed to shift elements in a right-ward direction and had to context switch from the main problem I was working on and think how much to rotate left in order to accomplish the right-ward rotation I needed. Ruby’s `Array.rotate` shifts left-ward, Python’s `deque.rotate` shifts right-ward. Both of their implementations allow passing negative numbers to shift in the opposite direction respectively. Introducing `rotate_left` and `rotate_right` would: - remove ambiguity about direction (alleviating need to read docs 😉) - make it easier for people who need to rotate right [`rotate`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rotate [tracking]: https://github.com/rust-lang/rust/issues/41891
This commit is contained in:
@@ -494,37 +494,72 @@ fn test_sort_stability() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rotate() {
|
||||
fn test_rotate_left() {
|
||||
let expected: Vec<_> = (0..13).collect();
|
||||
let mut v = Vec::new();
|
||||
|
||||
// no-ops
|
||||
v.clone_from(&expected);
|
||||
v.rotate(0);
|
||||
v.rotate_left(0);
|
||||
assert_eq!(v, expected);
|
||||
v.rotate(expected.len());
|
||||
v.rotate_left(expected.len());
|
||||
assert_eq!(v, expected);
|
||||
let mut zst_array = [(), (), ()];
|
||||
zst_array.rotate(2);
|
||||
zst_array.rotate_left(2);
|
||||
|
||||
// happy path
|
||||
v = (5..13).chain(0..5).collect();
|
||||
v.rotate(8);
|
||||
v.rotate_left(8);
|
||||
assert_eq!(v, expected);
|
||||
|
||||
let expected: Vec<_> = (0..1000).collect();
|
||||
|
||||
// small rotations in large slice, uses ptr::copy
|
||||
v = (2..1000).chain(0..2).collect();
|
||||
v.rotate(998);
|
||||
v.rotate_left(998);
|
||||
assert_eq!(v, expected);
|
||||
v = (998..1000).chain(0..998).collect();
|
||||
v.rotate(2);
|
||||
v.rotate_left(2);
|
||||
assert_eq!(v, expected);
|
||||
|
||||
// non-small prime rotation, has a few rounds of swapping
|
||||
v = (389..1000).chain(0..389).collect();
|
||||
v.rotate(1000-389);
|
||||
v.rotate_left(1000-389);
|
||||
assert_eq!(v, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rotate_right() {
|
||||
let expected: Vec<_> = (0..13).collect();
|
||||
let mut v = Vec::new();
|
||||
|
||||
// no-ops
|
||||
v.clone_from(&expected);
|
||||
v.rotate_right(0);
|
||||
assert_eq!(v, expected);
|
||||
v.rotate_right(expected.len());
|
||||
assert_eq!(v, expected);
|
||||
let mut zst_array = [(), (), ()];
|
||||
zst_array.rotate_right(2);
|
||||
|
||||
// happy path
|
||||
v = (5..13).chain(0..5).collect();
|
||||
v.rotate_right(5);
|
||||
assert_eq!(v, expected);
|
||||
|
||||
let expected: Vec<_> = (0..1000).collect();
|
||||
|
||||
// small rotations in large slice, uses ptr::copy
|
||||
v = (2..1000).chain(0..2).collect();
|
||||
v.rotate_right(2);
|
||||
assert_eq!(v, expected);
|
||||
v = (998..1000).chain(0..998).collect();
|
||||
v.rotate_right(998);
|
||||
assert_eq!(v, expected);
|
||||
|
||||
// non-small prime rotation, has a few rounds of swapping
|
||||
v = (389..1000).chain(0..389).collect();
|
||||
v.rotate_right(389);
|
||||
assert_eq!(v, expected);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user