Skip to content

Commit 7f9883d

Browse files
committed
Add unstable VecDeque::rotate_{left|right}
1 parent bcf920f commit 7f9883d

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed

src/liballoc/collections/vec_deque.rs

+102
Original file line numberDiff line numberDiff line change
@@ -1927,6 +1927,108 @@ impl<T> VecDeque<T> {
19271927
self.truncate(new_len);
19281928
}
19291929
}
1930+
1931+
/// Rotates the double-ended queue `mid` places to the left.
1932+
///
1933+
/// Equivalently,
1934+
/// - Rotates item `mid` into the first position.
1935+
/// - Pops the first `mid` items and pushes them to the end.
1936+
/// - Rotates `len() - mid` places to the right.
1937+
///
1938+
/// # Panics
1939+
///
1940+
/// If `mid` is greater than `len()`. Note that `mid == len()`
1941+
/// does _not_ panic and is a no-op rotation.
1942+
///
1943+
/// # Complexity
1944+
///
1945+
/// Takes `O(min(mid, len() - mid))` time and no extra space.
1946+
///
1947+
/// # Examples
1948+
///
1949+
/// ```
1950+
/// #![feature(vecdeque_rotate)]
1951+
///
1952+
/// use std::collections::VecDeque;
1953+
///
1954+
/// let mut buf: VecDeque<_> = (0..10).collect();
1955+
///
1956+
/// buf.rotate_left(3);
1957+
/// assert_eq!(buf, [3, 4, 5, 6, 7, 8, 9, 0, 1, 2]);
1958+
///
1959+
/// for i in 1..10 {
1960+
/// assert_eq!(i * 3 % 10, buf[0]);
1961+
/// buf.rotate_left(3);
1962+
/// }
1963+
/// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
1964+
/// ```
1965+
#[unstable(feature = "vecdeque_rotate", issue = "56686")]
1966+
pub fn rotate_left(&mut self, mid: usize) {
1967+
assert!(mid <= self.len());
1968+
let k = self.len() - mid;
1969+
if mid <= k {
1970+
unsafe { self.rotate_left_inner(mid) }
1971+
} else {
1972+
unsafe { self.rotate_right_inner(k) }
1973+
}
1974+
}
1975+
1976+
/// Rotates the double-ended queue `k` places to the right.
1977+
///
1978+
/// Equivalently,
1979+
/// - Rotates the first item into position `k`.
1980+
/// - Pops the last `k` items and pushes them to the front.
1981+
/// - Rotates `len() - k` places to the left.
1982+
///
1983+
/// # Panics
1984+
///
1985+
/// If `k` is greater than `len()`. Note that `k == len()`
1986+
/// does _not_ panic and is a no-op rotation.
1987+
///
1988+
/// # Complexity
1989+
///
1990+
/// Takes `O(min(k, len() - k))` time and no extra space.
1991+
///
1992+
/// # Examples
1993+
///
1994+
/// ```
1995+
/// #![feature(vecdeque_rotate)]
1996+
///
1997+
/// use std::collections::VecDeque;
1998+
///
1999+
/// let mut buf: VecDeque<_> = (0..10).collect();
2000+
///
2001+
/// buf.rotate_right(3);
2002+
/// assert_eq!(buf, [7, 8, 9, 0, 1, 2, 3, 4, 5, 6]);
2003+
///
2004+
/// for i in 1..10 {
2005+
/// assert_eq!(0, buf[i * 3 % 10]);
2006+
/// buf.rotate_right(3);
2007+
/// }
2008+
/// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
2009+
/// ```
2010+
#[unstable(feature = "vecdeque_rotate", issue = "56686")]
2011+
pub fn rotate_right(&mut self, k: usize) {
2012+
assert!(k <= self.len());
2013+
let mid = self.len() - k;
2014+
if k <= mid {
2015+
unsafe { self.rotate_right_inner(k) }
2016+
} else {
2017+
unsafe { self.rotate_left_inner(mid) }
2018+
}
2019+
}
2020+
2021+
unsafe fn rotate_left_inner(&mut self, mid: usize) {
2022+
self.wrap_copy(self.head, self.tail, mid);
2023+
self.head = self.wrap_add(self.head, mid);
2024+
self.tail = self.wrap_add(self.tail, mid);
2025+
}
2026+
2027+
unsafe fn rotate_right_inner(&mut self, k: usize) {
2028+
self.head = self.wrap_sub(self.head, k);
2029+
self.tail = self.wrap_sub(self.tail, k);
2030+
self.wrap_copy(self.tail, self.head, k);
2031+
}
19302032
}
19312033

19322034
impl<T: Clone> VecDeque<T> {

0 commit comments

Comments
 (0)