pub use core::slice::{from_ref, from_ref_mut};
#[unstable(feature = "slice_get_slice", issue = "35729")]
pub use core::slice::SliceIndex;
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ pub use core::slice::{ExactChunks, ExactChunksMut};
////////////////////////////////////////////////////////////////////////////////
// Basic slice extension methods
/// not divide the length of the slice, then the last chunk will
/// not have length `chunk_size`.
///
+ /// See [`exact_chunks`] for a variant of this iterator that returns chunks
+ /// of always exactly `chunk_size` elements.
+ ///
/// # Panics
///
/// Panics if `chunk_size` is 0.
core_slice::SliceExt::chunks(self, chunk_size)
}
+ /// Returns an iterator over `chunk_size` elements of the slice at a
+ /// time. The chunks are slices and do not overlap. If `chunk_size` does
+ /// not divide the length of the slice, then the last up to `chunk_size-1`
+ /// elements will be omitted.
+ ///
+ /// Due to each chunk having exactly `chunk_size` elements, the compiler
+ /// can often optimize the resulting code better than in the case of
+ /// [`chunks`].
+ ///
+ /// # Panics
+ ///
+ /// Panics if `chunk_size` is 0.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(exact_chunks)]
+ ///
+ /// let slice = ['l', 'o', 'r', 'e', 'm'];
+ /// let mut iter = slice.exact_chunks(2);
+ /// assert_eq!(iter.next().unwrap(), &['l', 'o']);
+ /// assert_eq!(iter.next().unwrap(), &['r', 'e']);
+ /// assert!(iter.next().is_none());
+ /// ```
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ #[inline]
+ pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
+ core_slice::SliceExt::exact_chunks(self, chunk_size)
+ }
+
/// Returns an iterator over `chunk_size` elements of the slice at a time.
/// The chunks are mutable slices, and do not overlap. If `chunk_size` does
/// not divide the length of the slice, then the last chunk will not
/// have length `chunk_size`.
///
+ /// See [`exact_chunks_mut`] for a variant of this iterator that returns chunks
+ /// of always exactly `chunk_size` elements.
+ ///
/// # Panics
///
/// Panics if `chunk_size` is 0.
core_slice::SliceExt::chunks_mut(self, chunk_size)
}
+ /// Returns an iterator over `chunk_size` elements of the slice at a time.
+ /// The chunks are mutable slices, and do not overlap. If `chunk_size` does
+ /// not divide the length of the slice, then the last up to `chunk_size-1`
+ /// elements will be omitted.
+ ///
+ ///
+ /// Due to each chunk having exactly `chunk_size` elements, the compiler
+ /// can often optimize the resulting code better than in the case of
+ /// [`chunks_mut`].
+ ///
+ /// # Panics
+ ///
+ /// Panics if `chunk_size` is 0.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(exact_chunks)]
+ ///
+ /// let v = &mut [0, 0, 0, 0, 0];
+ /// let mut count = 1;
+ ///
+ /// for chunk in v.exact_chunks_mut(2) {
+ /// for elem in chunk.iter_mut() {
+ /// *elem += count;
+ /// }
+ /// count += 1;
+ /// }
+ /// assert_eq!(v, &[1, 1, 2, 2, 0]);
+ /// ```
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ #[inline]
+ pub fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut<T> {
+ core_slice::SliceExt::exact_chunks_mut(self, chunk_size)
+ }
+
/// Divides one slice into two at an index.
///
/// The first will contain all indices from `[0, mid)` (excluding
core_slice::SliceExt::sort_unstable_by_key(self, f);
}
- /// Permutes the slice in-place such that `self[mid..]` moves to the
- /// beginning of the slice while `self[..mid]` moves to the end of the
- /// slice. Equivalently, rotates the slice `mid` places to the left
- /// or `k = self.len() - mid` places to the right.
+ /// Rotates the slice in-place such that the first `mid` elements of the
+ /// slice move to the end while the last `self.len() - mid` elements move to
+ /// the front. After calling `rotate_left`, the element previously at index
+ /// `mid` will become the first element in the slice.
///
- /// This is a "k-rotation", a permutation in which item `i` moves to
- /// position `i + k`, modulo the length of the slice. See _Elements
- /// of Programming_ [ยง10.4][eop].
+ /// # Panics
+ ///
+ /// This function will panic if `mid` is greater than the length of the
+ /// slice. Note that `mid == self.len()` does _not_ panic and is a no-op
+ /// rotation.
+ ///
+ /// # Complexity
+ ///
+ /// Takes linear (in `self.len()`) time.
+ ///
+ /// # Examples
///
- /// Rotation by `mid` and rotation by `k` are inverse operations.
+ /// ```
+ /// #![feature(slice_rotate)]
///
- /// [eop]: https://books.google.com/books?id=CO9ULZGINlsC&pg=PA178&q=k-rotation
+ /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+ /// a.rotate_left(2);
+ /// assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+ /// ```
+ ///
+ /// Rotating a subslice:
+ ///
+ /// ```
+ /// #![feature(slice_rotate)]
+ ///
+ /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+ /// a[1..5].rotate_left(1);
+ /// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+ /// ```
+ #[unstable(feature = "slice_rotate", issue = "41891")]
+ pub fn rotate_left(&mut self, mid: usize) {
+ core_slice::SliceExt::rotate_left(self, mid);
+ }
+
+ #[unstable(feature = "slice_rotate", issue = "41891")]
+ #[rustc_deprecated(since = "", reason = "renamed to `rotate_left`")]
+ pub fn rotate(&mut self, mid: usize) {
+ core_slice::SliceExt::rotate_left(self, mid);
+ }
+
+ /// Rotates the slice in-place such that the first `self.len() - k`
+ /// elements of the slice move to the end while the last `k` elements move
+ /// to the front. After calling `rotate_right`, the element previously at
+ /// index `self.len() - k` will become the first element in the slice.
///
/// # Panics
///
- /// This function will panic if `mid` is greater than the length of the
- /// slice. (Note that `mid == self.len()` does _not_ panic; it's a nop
- /// rotation with `k == 0`, the inverse of a rotation with `mid == 0`.)
+ /// This function will panic if `k` is greater than the length of the
+ /// slice. Note that `k == self.len()` does _not_ panic and is a no-op
+ /// rotation.
///
/// # Complexity
///
/// ```
/// #![feature(slice_rotate)]
///
- /// let mut a = [1, 2, 3, 4, 5, 6, 7];
- /// let mid = 2;
- /// a.rotate(mid);
- /// assert_eq!(&a, &[3, 4, 5, 6, 7, 1, 2]);
- /// let k = a.len() - mid;
- /// a.rotate(k);
- /// assert_eq!(&a, &[1, 2, 3, 4, 5, 6, 7]);
- ///
- /// use std::ops::Range;
- /// fn slide<T>(slice: &mut [T], range: Range<usize>, to: usize) {
- /// if to < range.start {
- /// slice[to..range.end].rotate(range.start-to);
- /// } else if to > range.end {
- /// slice[range.start..to].rotate(range.end-range.start);
- /// }
- /// }
- /// let mut v: Vec<_> = (0..10).collect();
- /// slide(&mut v, 1..4, 7);
- /// assert_eq!(&v, &[0, 4, 5, 6, 1, 2, 3, 7, 8, 9]);
- /// slide(&mut v, 6..8, 1);
- /// assert_eq!(&v, &[0, 3, 7, 4, 5, 6, 1, 2, 8, 9]);
+ /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+ /// a.rotate_right(2);
+ /// assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+ /// ```
+ ///
+ /// Rotate a subslice:
+ ///
+ /// ```
+ /// #![feature(slice_rotate)]
+ ///
+ /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+ /// a[1..5].rotate_right(1);
+ /// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
/// ```
#[unstable(feature = "slice_rotate", issue = "41891")]
- pub fn rotate(&mut self, mid: usize) {
- core_slice::SliceExt::rotate(self, mid);
+ pub fn rotate_right(&mut self, k: usize) {
+ core_slice::SliceExt::rotate_right(self, k);
}
/// Copies the elements from `src` into `self`.
/// let x = s.to_vec();
/// // Here, `s` and `x` can be modified independently.
/// ```
+ #[rustc_conversion_suggestion]
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn to_vec(&self) -> Vec<T>
}
#[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);
}
let _it = v.chunks(0);
}
+ #[test]
+ fn test_exact_chunksator() {
+ let v = &[1, 2, 3, 4, 5];
+
+ assert_eq!(v.exact_chunks(2).len(), 2);
+
+ let chunks: &[&[_]] = &[&[1, 2], &[3, 4]];
+ assert_eq!(v.exact_chunks(2).collect::<Vec<_>>(), chunks);
+ let chunks: &[&[_]] = &[&[1, 2, 3]];
+ assert_eq!(v.exact_chunks(3).collect::<Vec<_>>(), chunks);
+ let chunks: &[&[_]] = &[];
+ assert_eq!(v.exact_chunks(6).collect::<Vec<_>>(), chunks);
+
+ let chunks: &[&[_]] = &[&[3, 4], &[1, 2]];
+ assert_eq!(v.exact_chunks(2).rev().collect::<Vec<_>>(), chunks);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_exact_chunksator_0() {
+ let v = &[1, 2, 3, 4];
+ let _it = v.exact_chunks(0);
+ }
+
#[test]
fn test_reverse_part() {
let mut values = [1, 2, 3, 4, 5];
}
}
let result = [0, 0, 0, 1, 1, 1, 2];
- assert!(v == result);
+ assert_eq!(v, result);
}
#[test]
}
}
let result = [2, 2, 2, 1, 1, 1, 0];
- assert!(v == result);
+ assert_eq!(v, result);
}
#[test]
let _it = v.chunks_mut(0);
}
+ #[test]
+ fn test_mut_exact_chunks() {
+ let mut v = [0, 1, 2, 3, 4, 5, 6];
+ assert_eq!(v.exact_chunks_mut(2).len(), 3);
+ for (i, chunk) in v.exact_chunks_mut(3).enumerate() {
+ for x in chunk {
+ *x = i as u8;
+ }
+ }
+ let result = [0, 0, 0, 1, 1, 1, 6];
+ assert_eq!(v, result);
+ }
+
+ #[test]
+ fn test_mut_exact_chunks_rev() {
+ let mut v = [0, 1, 2, 3, 4, 5, 6];
+ for (i, chunk) in v.exact_chunks_mut(3).rev().enumerate() {
+ for x in chunk {
+ *x = i as u8;
+ }
+ }
+ let result = [1, 1, 1, 0, 0, 0, 6];
+ assert_eq!(v, result);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_mut_exact_chunks_0() {
+ let mut v = [1, 2, 3, 4];
+ let _it = v.exact_chunks_mut(0);
+ }
+
#[test]
fn test_mut_last() {
let mut x = [1, 2, 3, 4, 5];
#[stable(feature = "core", since = "1.6.0")]
fn chunks(&self, size: usize) -> Chunks<Self::Item>;
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ fn exact_chunks(&self, size: usize) -> ExactChunks<Self::Item>;
+
#[stable(feature = "core", since = "1.6.0")]
fn get<I>(&self, index: I) -> Option<&I::Output>
where I: SliceIndex<Self>;
#[stable(feature = "core", since = "1.6.0")]
fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<Self::Item>;
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ fn exact_chunks_mut(&mut self, size: usize) -> ExactChunksMut<Self::Item>;
+
#[stable(feature = "core", since = "1.6.0")]
fn swap(&mut self, a: usize, b: usize);
fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
#[unstable(feature = "slice_rotate", issue = "41891")]
- fn rotate(&mut self, mid: usize);
+ fn rotate_left(&mut self, mid: usize);
+
+ #[unstable(feature = "slice_rotate", issue = "41891")]
+ fn rotate_right(&mut self, k: usize);
#[stable(feature = "clone_from_slice", since = "1.7.0")]
fn clone_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Clone;
Chunks { v: self, chunk_size: chunk_size }
}
+ #[inline]
+ fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
+ assert!(chunk_size != 0);
+ let rem = self.len() % chunk_size;
+ let len = self.len() - rem;
+ ExactChunks { v: &self[..len], chunk_size: chunk_size}
+ }
+
#[inline]
fn get<I>(&self, index: I) -> Option<&I::Output>
where I: SliceIndex<[T]>
ChunksMut { v: self, chunk_size: chunk_size }
}
+ #[inline]
+ fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut<T> {
+ assert!(chunk_size != 0);
+ let rem = self.len() % chunk_size;
+ let len = self.len() - rem;
+ ExactChunksMut { v: &mut self[..len], chunk_size: chunk_size}
+ }
+
#[inline]
fn swap(&mut self, a: usize, b: usize) {
unsafe {
self.binary_search_by(|p| p.cmp(x))
}
- fn rotate(&mut self, mid: usize) {
+ fn rotate_left(&mut self, mid: usize) {
assert!(mid <= self.len());
let k = self.len() - mid;
}
}
+ fn rotate_right(&mut self, k: usize) {
+ assert!(k <= self.len());
+ let mid = self.len() - k;
+
+ unsafe {
+ let p = self.as_mut_ptr();
+ rotate::ptr_rotate(mid, p.offset(mid as isize), k);
+ }
+ }
+
#[inline]
fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
assert!(self.len() == src.len(),
fn may_have_side_effect() -> bool { false }
}
+ /// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
+ /// time).
+ ///
+ /// When the slice len is not evenly divided by the chunk size, the last
+ /// up to `chunk_size-1` elements will be omitted.
+ ///
+ /// This struct is created by the [`exact_chunks`] method on [slices].
+ ///
+ /// [`exact_chunks`]: ../../std/primitive.slice.html#method.exact_chunks
+ /// [slices]: ../../std/primitive.slice.html
+ #[derive(Debug)]
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ pub struct ExactChunks<'a, T:'a> {
+ v: &'a [T],
+ chunk_size: usize
+ }
+
+ // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ impl<'a, T> Clone for ExactChunks<'a, T> {
+ fn clone(&self) -> ExactChunks<'a, T> {
+ ExactChunks {
+ v: self.v,
+ chunk_size: self.chunk_size,
+ }
+ }
+ }
+
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ impl<'a, T> Iterator for ExactChunks<'a, T> {
+ type Item = &'a [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a [T]> {
+ if self.v.len() < self.chunk_size {
+ None
+ } else {
+ let (fst, snd) = self.v.split_at(self.chunk_size);
+ self.v = snd;
+ Some(fst)
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let n = self.v.len() / self.chunk_size;
+ (n, Some(n))
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.len()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ let (start, overflow) = n.overflowing_mul(self.chunk_size);
+ if start >= self.v.len() || overflow {
+ self.v = &[];
+ None
+ } else {
+ let (_, snd) = self.v.split_at(start);
+ self.v = snd;
+ self.next()
+ }
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<Self::Item> {
+ self.next_back()
+ }
+ }
+
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ impl<'a, T> DoubleEndedIterator for ExactChunks<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a [T]> {
+ if self.v.len() < self.chunk_size {
+ None
+ } else {
+ let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
+ self.v = fst;
+ Some(snd)
+ }
+ }
+ }
+
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ impl<'a, T> ExactSizeIterator for ExactChunks<'a, T> {
+ fn is_empty(&self) -> bool {
+ self.v.is_empty()
+ }
+ }
+
+ #[unstable(feature = "fused", issue = "35602")]
+ impl<'a, T> FusedIterator for ExactChunks<'a, T> {}
+
+ #[doc(hidden)]
+ unsafe impl<'a, T> TrustedRandomAccess for ExactChunks<'a, T> {
+ unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T] {
+ let start = i * self.chunk_size;
+ from_raw_parts(self.v.as_ptr().offset(start as isize), self.chunk_size)
+ }
+ fn may_have_side_effect() -> bool { false }
+ }
+
+ /// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
+ /// elements at a time). When the slice len is not evenly divided by the chunk
+ /// size, the last up to `chunk_size-1` elements will be omitted.
+ ///
+ /// This struct is created by the [`exact_chunks_mut`] method on [slices].
+ ///
+ /// [`exact_chunks_mut`]: ../../std/primitive.slice.html#method.exact_chunks_mut
+ /// [slices]: ../../std/primitive.slice.html
+ #[derive(Debug)]
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ pub struct ExactChunksMut<'a, T:'a> {
+ v: &'a mut [T],
+ chunk_size: usize
+ }
+
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ impl<'a, T> Iterator for ExactChunksMut<'a, T> {
+ type Item = &'a mut [T];
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a mut [T]> {
+ if self.v.len() < self.chunk_size {
+ None
+ } else {
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (head, tail) = tmp.split_at_mut(self.chunk_size);
+ self.v = tail;
+ Some(head)
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let n = self.v.len() / self.chunk_size;
+ (n, Some(n))
+ }
+
+ #[inline]
+ fn count(self) -> usize {
+ self.len()
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
+ let (start, overflow) = n.overflowing_mul(self.chunk_size);
+ if start >= self.v.len() || overflow {
+ self.v = &mut [];
+ None
+ } else {
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let (_, snd) = tmp.split_at_mut(start);
+ self.v = snd;
+ self.next()
+ }
+ }
+
+ #[inline]
+ fn last(mut self) -> Option<Self::Item> {
+ self.next_back()
+ }
+ }
+
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ impl<'a, T> DoubleEndedIterator for ExactChunksMut<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a mut [T]> {
+ if self.v.len() < self.chunk_size {
+ None
+ } else {
+ let tmp = mem::replace(&mut self.v, &mut []);
+ let tmp_len = tmp.len();
+ let (head, tail) = tmp.split_at_mut(tmp_len - self.chunk_size);
+ self.v = head;
+ Some(tail)
+ }
+ }
+ }
+
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ impl<'a, T> ExactSizeIterator for ExactChunksMut<'a, T> {
+ fn is_empty(&self) -> bool {
+ self.v.is_empty()
+ }
+ }
+
+ #[unstable(feature = "fused", issue = "35602")]
+ impl<'a, T> FusedIterator for ExactChunksMut<'a, T> {}
+
+ #[doc(hidden)]
+ unsafe impl<'a, T> TrustedRandomAccess for ExactChunksMut<'a, T> {
+ unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut [T] {
+ let start = i * self.chunk_size;
+ from_raw_parts_mut(self.v.as_mut_ptr().offset(start as isize), self.chunk_size)
+ }
+ fn may_have_side_effect() -> bool { false }
+ }
+
//
// Free functions
//
fn test_chunks_nth() {
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
let mut c = v.chunks(2);
- assert_eq!(c.nth(1).unwrap()[1], 3);
- assert_eq!(c.next().unwrap()[0], 4);
+ assert_eq!(c.nth(1).unwrap(), &[2, 3]);
+ assert_eq!(c.next().unwrap(), &[4, 5]);
let v2: &[i32] = &[0, 1, 2, 3, 4];
let mut c2 = v2.chunks(3);
- assert_eq!(c2.nth(1).unwrap()[1], 4);
+ assert_eq!(c2.nth(1).unwrap(), &[3, 4]);
assert_eq!(c2.next(), None);
}
fn test_chunks_mut_nth() {
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
let mut c = v.chunks_mut(2);
- assert_eq!(c.nth(1).unwrap()[1], 3);
- assert_eq!(c.next().unwrap()[0], 4);
+ assert_eq!(c.nth(1).unwrap(), &[2, 3]);
+ assert_eq!(c.next().unwrap(), &[4, 5]);
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
let mut c2 = v2.chunks_mut(3);
- assert_eq!(c2.nth(1).unwrap()[1], 4);
+ assert_eq!(c2.nth(1).unwrap(), &[3, 4]);
assert_eq!(c2.next(), None);
}
fn test_chunks_mut_last() {
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
let c = v.chunks_mut(2);
- assert_eq!(c.last().unwrap()[1], 5);
+ assert_eq!(c.last().unwrap(), &[4, 5]);
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
let c2 = v2.chunks_mut(2);
- assert_eq!(c2.last().unwrap()[0], 4);
+ assert_eq!(c2.last().unwrap(), &[4]);
}
#[test]
assert_eq!(v1, [13, 14, 19, 20, 14]);
}
+ #[test]
+ fn test_exact_chunks_count() {
+ let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+ let c = v.exact_chunks(3);
+ assert_eq!(c.count(), 2);
+
+ let v2: &[i32] = &[0, 1, 2, 3, 4];
+ let c2 = v2.exact_chunks(2);
+ assert_eq!(c2.count(), 2);
+
+ let v3: &[i32] = &[];
+ let c3 = v3.exact_chunks(2);
+ assert_eq!(c3.count(), 0);
+ }
+
+ #[test]
+ fn test_exact_chunks_nth() {
+ let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+ let mut c = v.exact_chunks(2);
+ assert_eq!(c.nth(1).unwrap(), &[2, 3]);
+ assert_eq!(c.next().unwrap(), &[4, 5]);
+
+ let v2: &[i32] = &[0, 1, 2, 3, 4, 5, 6];
+ let mut c2 = v2.exact_chunks(3);
+ assert_eq!(c2.nth(1).unwrap(), &[3, 4, 5]);
+ assert_eq!(c2.next(), None);
+ }
+
+ #[test]
+ fn test_exact_chunks_last() {
+ let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+ let c = v.exact_chunks(2);
+ assert_eq!(c.last().unwrap(), &[4, 5]);
+
+ let v2: &[i32] = &[0, 1, 2, 3, 4];
+ let c2 = v2.exact_chunks(2);
+ assert_eq!(c2.last().unwrap(), &[2, 3]);
+ }
+
+ #[test]
+ fn test_exact_chunks_zip() {
+ let v1: &[i32] = &[0, 1, 2, 3, 4];
+ let v2: &[i32] = &[6, 7, 8, 9, 10];
+
+ let res = v1.exact_chunks(2)
+ .zip(v2.exact_chunks(2))
+ .map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
+ .collect::<Vec<_>>();
+ assert_eq!(res, vec![14, 22]);
+ }
+
+ #[test]
+ fn test_exact_chunks_mut_count() {
+ let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+ let c = v.exact_chunks_mut(3);
+ assert_eq!(c.count(), 2);
+
+ let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
+ let c2 = v2.exact_chunks_mut(2);
+ assert_eq!(c2.count(), 2);
+
+ let v3: &mut [i32] = &mut [];
+ let c3 = v3.exact_chunks_mut(2);
+ assert_eq!(c3.count(), 0);
+ }
+
+ #[test]
+ fn test_exact_chunks_mut_nth() {
+ let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+ let mut c = v.exact_chunks_mut(2);
+ assert_eq!(c.nth(1).unwrap(), &[2, 3]);
+ assert_eq!(c.next().unwrap(), &[4, 5]);
+
+ let v2: &mut [i32] = &mut [0, 1, 2, 3, 4, 5, 6];
+ let mut c2 = v2.exact_chunks_mut(3);
+ assert_eq!(c2.nth(1).unwrap(), &[3, 4, 5]);
+ assert_eq!(c2.next(), None);
+ }
+
+ #[test]
+ fn test_exact_chunks_mut_last() {
+ let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+ let c = v.exact_chunks_mut(2);
+ assert_eq!(c.last().unwrap(), &[4, 5]);
+
+ let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
+ let c2 = v2.exact_chunks_mut(2);
+ assert_eq!(c2.last().unwrap(), &[2, 3]);
+ }
+
+ #[test]
+ fn test_exact_chunks_mut_zip() {
+ let v1: &mut [i32] = &mut [0, 1, 2, 3, 4];
+ let v2: &[i32] = &[6, 7, 8, 9, 10];
+
+ for (a, b) in v1.exact_chunks_mut(2).zip(v2.exact_chunks(2)) {
+ let sum = b.iter().sum::<i32>();
+ for v in a {
+ *v += sum;
+ }
+ }
+ assert_eq!(v1, [13, 14, 19, 20, 4]);
+ }
+
#[test]
fn test_windows_count() {
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
}
#[test]
-fn test_rotate() {
+fn test_rotate_left() {
const N: usize = 600;
let a: &mut [_] = &mut [0; N];
for i in 0..N {
a[i] = i;
}
- a.rotate(42);
+ a.rotate_left(42);
let k = N - 42;
for i in 0..N {
- assert_eq!(a[(i+k)%N], i);
+ assert_eq!(a[(i + k) % N], i);
+ }
+}
+
+#[test]
+fn test_rotate_right() {
+ const N: usize = 600;
+ let a: &mut [_] = &mut [0; N];
+ for i in 0..N {
+ a[i] = i;
+ }
+
+ a.rotate_right(42);
+
+ for i in 0..N {
+ assert_eq!(a[(i + 42) % N], i);
}
}