Auto merge of #54580 - sdroege:rchunks, r=SimonSapin
Add slice::rchunks(), rchunks_mut(), rchunks_exact() and rchunks_exact_mut() These work exactly like the normal chunks iterators but start creating chunks from the end of the slice. ---- The new iterators were motivated by a [comment](https://github.com/rust-lang/rust/issues/47115#issuecomment-424141121) by @DutchGhost. ~~~This currently includes the commits from https://github.com/rust-lang/rust/pull/54537 to not have to rename things twice or have merge conflicts. I'll force-push a new version of the branch ones those are in master.~~~ Also the stabilization tracking issue is just some number right now. I'll create the corresponding issue once this is reviewed and otherwise mergeable. cc @DutchGhost
This commit is contained in:
commit
121320d523
@ -120,6 +120,7 @@
|
||||
#![feature(const_vec_new)]
|
||||
#![feature(slice_partition_dedup)]
|
||||
#![feature(maybe_uninit)]
|
||||
#![feature(rchunks)]
|
||||
|
||||
// Allow testing this library
|
||||
|
||||
|
@ -125,6 +125,8 @@ pub use core::slice::{from_ref, from_mut};
|
||||
pub use core::slice::SliceIndex;
|
||||
#[unstable(feature = "chunks_exact", issue = "47115")]
|
||||
pub use core::slice::{ChunksExact, ChunksExactMut};
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
pub use core::slice::{RChunks, RChunksMut, RChunksExact, RChunksExactMut};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Basic slice extension methods
|
||||
|
@ -20,6 +20,7 @@
|
||||
#![feature(try_reserve)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(chunks_exact)]
|
||||
#![feature(rchunks)]
|
||||
#![feature(repeat_generic_slice)]
|
||||
|
||||
extern crate alloc_system;
|
||||
|
@ -998,6 +998,54 @@ fn test_chunks_exactator_0() {
|
||||
let _it = v.chunks_exact(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunksator() {
|
||||
let v = &[1, 2, 3, 4, 5];
|
||||
|
||||
assert_eq!(v.rchunks(2).len(), 3);
|
||||
|
||||
let chunks: &[&[_]] = &[&[4, 5], &[2, 3], &[1]];
|
||||
assert_eq!(v.rchunks(2).collect::<Vec<_>>(), chunks);
|
||||
let chunks: &[&[_]] = &[&[3, 4, 5], &[1, 2]];
|
||||
assert_eq!(v.rchunks(3).collect::<Vec<_>>(), chunks);
|
||||
let chunks: &[&[_]] = &[&[1, 2, 3, 4, 5]];
|
||||
assert_eq!(v.rchunks(6).collect::<Vec<_>>(), chunks);
|
||||
|
||||
let chunks: &[&[_]] = &[&[1], &[2, 3], &[4, 5]];
|
||||
assert_eq!(v.rchunks(2).rev().collect::<Vec<_>>(), chunks);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_rchunksator_0() {
|
||||
let v = &[1, 2, 3, 4];
|
||||
let _it = v.rchunks(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_exactator() {
|
||||
let v = &[1, 2, 3, 4, 5];
|
||||
|
||||
assert_eq!(v.rchunks_exact(2).len(), 2);
|
||||
|
||||
let chunks: &[&[_]] = &[&[4, 5], &[2, 3]];
|
||||
assert_eq!(v.rchunks_exact(2).collect::<Vec<_>>(), chunks);
|
||||
let chunks: &[&[_]] = &[&[3, 4, 5]];
|
||||
assert_eq!(v.rchunks_exact(3).collect::<Vec<_>>(), chunks);
|
||||
let chunks: &[&[_]] = &[];
|
||||
assert_eq!(v.rchunks_exact(6).collect::<Vec<_>>(), chunks);
|
||||
|
||||
let chunks: &[&[_]] = &[&[2, 3], &[4, 5]];
|
||||
assert_eq!(v.rchunks_exact(2).rev().collect::<Vec<_>>(), chunks);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_rchunks_exactator_0() {
|
||||
let v = &[1, 2, 3, 4];
|
||||
let _it = v.rchunks_exact(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reverse_part() {
|
||||
let mut values = [1, 2, 3, 4, 5];
|
||||
@ -1205,7 +1253,7 @@ fn test_get_mut() {
|
||||
#[test]
|
||||
fn test_mut_chunks() {
|
||||
let mut v = [0, 1, 2, 3, 4, 5, 6];
|
||||
assert_eq!(v.chunks_mut(2).len(), 4);
|
||||
assert_eq!(v.chunks_mut(3).len(), 3);
|
||||
for (i, chunk) in v.chunks_mut(3).enumerate() {
|
||||
for x in chunk {
|
||||
*x = i as u8;
|
||||
@ -1237,7 +1285,7 @@ fn test_mut_chunks_0() {
|
||||
#[test]
|
||||
fn test_mut_chunks_exact() {
|
||||
let mut v = [0, 1, 2, 3, 4, 5, 6];
|
||||
assert_eq!(v.chunks_exact_mut(2).len(), 3);
|
||||
assert_eq!(v.chunks_exact_mut(3).len(), 2);
|
||||
for (i, chunk) in v.chunks_exact_mut(3).enumerate() {
|
||||
for x in chunk {
|
||||
*x = i as u8;
|
||||
@ -1266,6 +1314,70 @@ fn test_mut_chunks_exact_0() {
|
||||
let _it = v.chunks_exact_mut(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_rchunks() {
|
||||
let mut v = [0, 1, 2, 3, 4, 5, 6];
|
||||
assert_eq!(v.rchunks_mut(3).len(), 3);
|
||||
for (i, chunk) in v.rchunks_mut(3).enumerate() {
|
||||
for x in chunk {
|
||||
*x = i as u8;
|
||||
}
|
||||
}
|
||||
let result = [2, 1, 1, 1, 0, 0, 0];
|
||||
assert_eq!(v, result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_rchunks_rev() {
|
||||
let mut v = [0, 1, 2, 3, 4, 5, 6];
|
||||
for (i, chunk) in v.rchunks_mut(3).rev().enumerate() {
|
||||
for x in chunk {
|
||||
*x = i as u8;
|
||||
}
|
||||
}
|
||||
let result = [0, 1, 1, 1, 2, 2, 2];
|
||||
assert_eq!(v, result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_mut_rchunks_0() {
|
||||
let mut v = [1, 2, 3, 4];
|
||||
let _it = v.rchunks_mut(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_rchunks_exact() {
|
||||
let mut v = [0, 1, 2, 3, 4, 5, 6];
|
||||
assert_eq!(v.rchunks_exact_mut(3).len(), 2);
|
||||
for (i, chunk) in v.rchunks_exact_mut(3).enumerate() {
|
||||
for x in chunk {
|
||||
*x = i as u8;
|
||||
}
|
||||
}
|
||||
let result = [0, 1, 1, 1, 0, 0, 0];
|
||||
assert_eq!(v, result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_rchunks_exact_rev() {
|
||||
let mut v = [0, 1, 2, 3, 4, 5, 6];
|
||||
for (i, chunk) in v.rchunks_exact_mut(3).rev().enumerate() {
|
||||
for x in chunk {
|
||||
*x = i as u8;
|
||||
}
|
||||
}
|
||||
let result = [0, 0, 0, 0, 1, 1, 1];
|
||||
assert_eq!(v, result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_mut_rchunks_exact_0() {
|
||||
let mut v = [1, 2, 3, 4];
|
||||
let _it = v.rchunks_exact_mut(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_last() {
|
||||
let mut x = [1, 2, 3, 4, 5];
|
||||
|
@ -620,13 +620,15 @@ impl<T> [T] {
|
||||
Windows { v: self, 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 chunk will
|
||||
/// not have length `chunk_size`.
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
|
||||
/// beginning of the slice.
|
||||
///
|
||||
/// See [`chunks_exact`] for a variant of this iterator that returns chunks
|
||||
/// of always exactly `chunk_size` elements.
|
||||
/// The chunks are 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 [`chunks_exact`] for a variant of this iterator that returns chunks of always exactly
|
||||
/// `chunk_size` elements, and [`rchunks`] for the same iterator but starting at the end of the
|
||||
/// slice of the slice.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
@ -644,6 +646,7 @@ impl<T> [T] {
|
||||
/// ```
|
||||
///
|
||||
/// [`chunks_exact`]: #method.chunks_exact
|
||||
/// [`rchunks`]: #method.rchunks
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn chunks(&self, chunk_size: usize) -> Chunks<T> {
|
||||
@ -651,13 +654,15 @@ impl<T> [T] {
|
||||
Chunks { v: 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`.
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
|
||||
/// beginning of the slice.
|
||||
///
|
||||
/// See [`chunks_exact_mut`] for a variant of this iterator that returns chunks
|
||||
/// of always exactly `chunk_size` elements.
|
||||
/// 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 [`chunks_exact_mut`] for a variant of this iterator that returns chunks of always
|
||||
/// exactly `chunk_size` elements, and [`rchunks_mut`] for the same iterator but starting at
|
||||
/// the end of the slice of the slice.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
@ -679,6 +684,7 @@ impl<T> [T] {
|
||||
/// ```
|
||||
///
|
||||
/// [`chunks_exact_mut`]: #method.chunks_exact_mut
|
||||
/// [`rchunks_mut`]: #method.rchunks_mut
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
|
||||
@ -686,15 +692,19 @@ impl<T> [T] {
|
||||
ChunksMut { v: 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 and can be retrieved from the `remainder`
|
||||
/// function of the iterator.
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
|
||||
/// beginning of the slice.
|
||||
///
|
||||
/// Due to each chunk having exactly `chunk_size` elements, the compiler
|
||||
/// can often optimize the resulting code better than in the case of
|
||||
/// [`chunks`].
|
||||
/// 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 and can be retrieved
|
||||
/// from the `remainder` function of the iterator.
|
||||
///
|
||||
/// Due to each chunk having exactly `chunk_size` elements, the compiler can often optimize the
|
||||
/// resulting code better than in the case of [`chunks`].
|
||||
///
|
||||
/// See [`chunks`] for a variant of this iterator that also returns the remainder as a smaller
|
||||
/// chunk, and [`rchunks_exact`] for the same iterator but starting at the end of the slice of
|
||||
/// the slice.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
@ -710,9 +720,11 @@ impl<T> [T] {
|
||||
/// assert_eq!(iter.next().unwrap(), &['l', 'o']);
|
||||
/// assert_eq!(iter.next().unwrap(), &['r', 'e']);
|
||||
/// assert!(iter.next().is_none());
|
||||
/// assert_eq!(iter.remainder(), &['m']);
|
||||
/// ```
|
||||
///
|
||||
/// [`chunks`]: #method.chunks
|
||||
/// [`rchunks_exact`]: #method.rchunks_exact
|
||||
#[unstable(feature = "chunks_exact", issue = "47115")]
|
||||
#[inline]
|
||||
pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<T> {
|
||||
@ -723,15 +735,19 @@ impl<T> [T] {
|
||||
ChunksExact { v: fst, rem: snd, 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 and can be retrieved from the `into_remainder`
|
||||
/// function of the iterator.
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
|
||||
/// beginning of the slice.
|
||||
///
|
||||
/// 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`].
|
||||
/// 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 and can be
|
||||
/// retrieved from the `into_remainder` function of the iterator.
|
||||
///
|
||||
/// 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`].
|
||||
///
|
||||
/// See [`chunks_mut`] for a variant of this iterator that also returns the remainder as a
|
||||
/// smaller chunk, and [`rchunks_exact_mut`] for the same iterator but starting at the end of
|
||||
/// the slice of the slice.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
@ -755,6 +771,7 @@ impl<T> [T] {
|
||||
/// ```
|
||||
///
|
||||
/// [`chunks_mut`]: #method.chunks_mut
|
||||
/// [`rchunks_exact_mut`]: #method.rchunks_exact_mut
|
||||
#[unstable(feature = "chunks_exact", issue = "47115")]
|
||||
#[inline]
|
||||
pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<T> {
|
||||
@ -765,6 +782,170 @@ impl<T> [T] {
|
||||
ChunksExactMut { v: fst, rem: snd, chunk_size }
|
||||
}
|
||||
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
|
||||
/// of the slice.
|
||||
///
|
||||
/// The chunks are 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 [`rchunks_exact`] for a variant of this iterator that returns chunks of always exactly
|
||||
/// `chunk_size` elements, and [`chunks`] for the same iterator but starting at the beginning
|
||||
/// of the slice.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `chunk_size` is 0.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(rchunks)]
|
||||
///
|
||||
/// let slice = ['l', 'o', 'r', 'e', 'm'];
|
||||
/// let mut iter = slice.rchunks(2);
|
||||
/// assert_eq!(iter.next().unwrap(), &['e', 'm']);
|
||||
/// assert_eq!(iter.next().unwrap(), &['o', 'r']);
|
||||
/// assert_eq!(iter.next().unwrap(), &['l']);
|
||||
/// assert!(iter.next().is_none());
|
||||
/// ```
|
||||
///
|
||||
/// [`rchunks_exact`]: #method.rchunks_exact
|
||||
/// [`chunks`]: #method.chunks
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
#[inline]
|
||||
pub fn rchunks(&self, chunk_size: usize) -> RChunks<T> {
|
||||
assert!(chunk_size != 0);
|
||||
RChunks { v: self, chunk_size }
|
||||
}
|
||||
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
|
||||
/// of the slice.
|
||||
///
|
||||
/// 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 [`rchunks_exact_mut`] for a variant of this iterator that returns chunks of always
|
||||
/// exactly `chunk_size` elements, and [`chunks_mut`] for the same iterator but starting at the
|
||||
/// beginning of the slice.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `chunk_size` is 0.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(rchunks)]
|
||||
///
|
||||
/// let v = &mut [0, 0, 0, 0, 0];
|
||||
/// let mut count = 1;
|
||||
///
|
||||
/// for chunk in v.rchunks_mut(2) {
|
||||
/// for elem in chunk.iter_mut() {
|
||||
/// *elem += count;
|
||||
/// }
|
||||
/// count += 1;
|
||||
/// }
|
||||
/// assert_eq!(v, &[3, 2, 2, 1, 1]);
|
||||
/// ```
|
||||
///
|
||||
/// [`rchunks_exact_mut`]: #method.rchunks_exact_mut
|
||||
/// [`chunks_mut`]: #method.chunks_mut
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
#[inline]
|
||||
pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<T> {
|
||||
assert!(chunk_size != 0);
|
||||
RChunksMut { v: self, chunk_size }
|
||||
}
|
||||
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
|
||||
/// beginning of the slice.
|
||||
///
|
||||
/// 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 and can be retrieved
|
||||
/// from the `remainder` function of the iterator.
|
||||
///
|
||||
/// Due to each chunk having exactly `chunk_size` elements, the compiler can often optimize the
|
||||
/// resulting code better than in the case of [`chunks`].
|
||||
///
|
||||
/// See [`rchunks`] for a variant of this iterator that also returns the remainder as a smaller
|
||||
/// chunk, and [`chunks_exact`] for the same iterator but starting at the beginning of the
|
||||
/// slice of the slice.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `chunk_size` is 0.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(rchunks)]
|
||||
///
|
||||
/// let slice = ['l', 'o', 'r', 'e', 'm'];
|
||||
/// let mut iter = slice.rchunks_exact(2);
|
||||
/// assert_eq!(iter.next().unwrap(), &['e', 'm']);
|
||||
/// assert_eq!(iter.next().unwrap(), &['o', 'r']);
|
||||
/// assert!(iter.next().is_none());
|
||||
/// assert_eq!(iter.remainder(), &['l']);
|
||||
/// ```
|
||||
///
|
||||
/// [`rchunks`]: #method.rchunks
|
||||
/// [`chunks_exact`]: #method.chunks_exact
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
#[inline]
|
||||
pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<T> {
|
||||
assert!(chunk_size != 0);
|
||||
let rem = self.len() % chunk_size;
|
||||
let (fst, snd) = self.split_at(rem);
|
||||
RChunksExact { v: snd, rem: fst, chunk_size }
|
||||
}
|
||||
|
||||
/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
|
||||
/// of the slice.
|
||||
///
|
||||
/// 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 and can be
|
||||
/// retrieved from the `into_remainder` function of the iterator.
|
||||
///
|
||||
/// 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`].
|
||||
///
|
||||
/// See [`rchunks_mut`] for a variant of this iterator that also returns the remainder as a
|
||||
/// smaller chunk, and [`chunks_exact_mut`] for the same iterator but starting at the beginning
|
||||
/// of the slice of the slice.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `chunk_size` is 0.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(rchunks)]
|
||||
///
|
||||
/// let v = &mut [0, 0, 0, 0, 0];
|
||||
/// let mut count = 1;
|
||||
///
|
||||
/// for chunk in v.rchunks_exact_mut(2) {
|
||||
/// for elem in chunk.iter_mut() {
|
||||
/// *elem += count;
|
||||
/// }
|
||||
/// count += 1;
|
||||
/// }
|
||||
/// assert_eq!(v, &[0, 2, 2, 1, 1]);
|
||||
/// ```
|
||||
///
|
||||
/// [`rchunks_mut`]: #method.rchunks_mut
|
||||
/// [`chunks_exact_mut`]: #method.chunks_exact_mut
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
#[inline]
|
||||
pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<T> {
|
||||
assert!(chunk_size != 0);
|
||||
let rem = self.len() % chunk_size;
|
||||
let (fst, snd) = self.split_at_mut(rem);
|
||||
RChunksExactMut { v: snd, rem: fst, chunk_size }
|
||||
}
|
||||
|
||||
/// Divides one slice into two at an index.
|
||||
///
|
||||
/// The first will contain all indices from `[0, mid)` (excluding
|
||||
@ -3581,7 +3762,7 @@ unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {
|
||||
}
|
||||
|
||||
/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
|
||||
/// time).
|
||||
/// time), starting at the beginning of the slice.
|
||||
///
|
||||
/// When the slice len is not evenly divided by the chunk size, the last slice
|
||||
/// of the iteration will be the remainder.
|
||||
@ -3708,8 +3889,10 @@ unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {
|
||||
}
|
||||
|
||||
/// 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 slice of the iteration will be the remainder.
|
||||
/// elements at a time), starting at the beginning of the slice.
|
||||
///
|
||||
/// When the slice len is not evenly divided by the chunk size, the last slice
|
||||
/// of the iteration will be the remainder.
|
||||
///
|
||||
/// This struct is created by the [`chunks_mut`] method on [slices].
|
||||
///
|
||||
@ -3827,7 +4010,7 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
|
||||
}
|
||||
|
||||
/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
|
||||
/// time).
|
||||
/// time), starting at the beginning of the slice.
|
||||
///
|
||||
/// When the slice len is not evenly divided by the chunk size, the last
|
||||
/// up to `chunk_size-1` elements will be omitted but can be retrieved from
|
||||
@ -3941,6 +4124,7 @@ unsafe impl<T> TrustedLen for ChunksExact<'_, T> {}
|
||||
impl<T> FusedIterator for ChunksExact<'_, T> {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "chunks_exact", issue = "47115")]
|
||||
unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {
|
||||
unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T] {
|
||||
let start = i * self.chunk_size;
|
||||
@ -3950,7 +4134,7 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {
|
||||
}
|
||||
|
||||
/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
|
||||
/// elements at a time).
|
||||
/// elements at a time), starting at the beginning of the slice.
|
||||
///
|
||||
/// When the slice len is not evenly divided by the chunk size, the last up to
|
||||
/// `chunk_size-1` elements will be omitted but can be retrieved from the
|
||||
@ -4056,6 +4240,7 @@ unsafe impl<T> TrustedLen for ChunksExactMut<'_, T> {}
|
||||
impl<T> FusedIterator for ChunksExactMut<'_, T> {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "chunks_exact", issue = "47115")]
|
||||
unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
|
||||
unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut [T] {
|
||||
let start = i * self.chunk_size;
|
||||
@ -4064,6 +4249,505 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
|
||||
fn may_have_side_effect() -> bool { false }
|
||||
}
|
||||
|
||||
/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
|
||||
/// time), starting at the end of the slice.
|
||||
///
|
||||
/// When the slice len is not evenly divided by the chunk size, the last slice
|
||||
/// of the iteration will be the remainder.
|
||||
///
|
||||
/// This struct is created by the [`rchunks`] method on [slices].
|
||||
///
|
||||
/// [`rchunks`]: ../../std/primitive.slice.html#method.rchunks
|
||||
/// [slices]: ../../std/primitive.slice.html
|
||||
#[derive(Debug)]
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
pub struct RChunks<'a, T:'a> {
|
||||
v: &'a [T],
|
||||
chunk_size: usize
|
||||
}
|
||||
|
||||
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> Clone for RChunks<'a, T> {
|
||||
fn clone(&self) -> RChunks<'a, T> {
|
||||
RChunks {
|
||||
v: self.v,
|
||||
chunk_size: self.chunk_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> Iterator for RChunks<'a, T> {
|
||||
type Item = &'a [T];
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a [T]> {
|
||||
if self.v.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let chunksz = cmp::min(self.v.len(), self.chunk_size);
|
||||
let (fst, snd) = self.v.split_at(self.v.len() - chunksz);
|
||||
self.v = fst;
|
||||
Some(snd)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
if self.v.is_empty() {
|
||||
(0, Some(0))
|
||||
} else {
|
||||
let n = self.v.len() / self.chunk_size;
|
||||
let rem = self.v.len() % self.chunk_size;
|
||||
let n = if rem > 0 { n+1 } else { n };
|
||||
(n, Some(n))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn count(self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
||||
let (end, overflow) = n.overflowing_mul(self.chunk_size);
|
||||
if end >= self.v.len() || overflow {
|
||||
self.v = &[];
|
||||
None
|
||||
} else {
|
||||
// Can't underflow because of the check above
|
||||
let end = self.v.len() - end;
|
||||
let start = match end.checked_sub(self.chunk_size) {
|
||||
Some(sum) => sum,
|
||||
None => 0,
|
||||
};
|
||||
let nth = &self.v[start..end];
|
||||
self.v = &self.v[0..start];
|
||||
Some(nth)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn last(self) -> Option<Self::Item> {
|
||||
if self.v.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let rem = self.v.len() % self.chunk_size;
|
||||
let end = if rem == 0 { self.chunk_size } else { rem };
|
||||
Some(&self.v[0..end])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<&'a [T]> {
|
||||
if self.v.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let remainder = self.v.len() % self.chunk_size;
|
||||
let chunksz = if remainder != 0 { remainder } else { self.chunk_size };
|
||||
let (fst, snd) = self.v.split_at(chunksz);
|
||||
self.v = snd;
|
||||
Some(fst)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> ExactSizeIterator for RChunks<'a, T> {}
|
||||
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<'a, T> TrustedLen for RChunks<'a, T> {}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> FusedIterator for RChunks<'a, T> {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {
|
||||
unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T] {
|
||||
let end = self.v.len() - i * self.chunk_size;
|
||||
let start = match end.checked_sub(self.chunk_size) {
|
||||
None => 0,
|
||||
Some(start) => start,
|
||||
};
|
||||
from_raw_parts(self.v.as_ptr().add(start), end - start)
|
||||
}
|
||||
fn may_have_side_effect() -> bool { false }
|
||||
}
|
||||
|
||||
/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
|
||||
/// elements at a time), starting at the end of the slice.
|
||||
///
|
||||
/// When the slice len is not evenly divided by the chunk size, the last slice
|
||||
/// of the iteration will be the remainder.
|
||||
///
|
||||
/// This struct is created by the [`rchunks_mut`] method on [slices].
|
||||
///
|
||||
/// [`rchunks_mut`]: ../../std/primitive.slice.html#method.rchunks_mut
|
||||
/// [slices]: ../../std/primitive.slice.html
|
||||
#[derive(Debug)]
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
pub struct RChunksMut<'a, T:'a> {
|
||||
v: &'a mut [T],
|
||||
chunk_size: usize
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> Iterator for RChunksMut<'a, T> {
|
||||
type Item = &'a mut [T];
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a mut [T]> {
|
||||
if self.v.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let sz = cmp::min(self.v.len(), self.chunk_size);
|
||||
let tmp = mem::replace(&mut self.v, &mut []);
|
||||
let tmp_len = tmp.len();
|
||||
let (head, tail) = tmp.split_at_mut(tmp_len - sz);
|
||||
self.v = head;
|
||||
Some(tail)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
if self.v.is_empty() {
|
||||
(0, Some(0))
|
||||
} else {
|
||||
let n = self.v.len() / self.chunk_size;
|
||||
let rem = self.v.len() % self.chunk_size;
|
||||
let n = if rem > 0 { n + 1 } else { n };
|
||||
(n, Some(n))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn count(self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
|
||||
let (end, overflow) = n.overflowing_mul(self.chunk_size);
|
||||
if end >= self.v.len() || overflow {
|
||||
self.v = &mut [];
|
||||
None
|
||||
} else {
|
||||
// Can't underflow because of the check above
|
||||
let end = self.v.len() - end;
|
||||
let start = match end.checked_sub(self.chunk_size) {
|
||||
Some(sum) => sum,
|
||||
None => 0,
|
||||
};
|
||||
let tmp = mem::replace(&mut self.v, &mut []);
|
||||
let (head, tail) = tmp.split_at_mut(start);
|
||||
let (nth, _) = tail.split_at_mut(end - start);
|
||||
self.v = head;
|
||||
Some(nth)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn last(self) -> Option<Self::Item> {
|
||||
if self.v.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let rem = self.v.len() % self.chunk_size;
|
||||
let end = if rem == 0 { self.chunk_size } else { rem };
|
||||
Some(&mut self.v[0..end])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<&'a mut [T]> {
|
||||
if self.v.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let remainder = self.v.len() % self.chunk_size;
|
||||
let sz = if remainder != 0 { remainder } else { self.chunk_size };
|
||||
let tmp = mem::replace(&mut self.v, &mut []);
|
||||
let (head, tail) = tmp.split_at_mut(sz);
|
||||
self.v = tail;
|
||||
Some(head)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> ExactSizeIterator for RChunksMut<'a, T> {}
|
||||
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<'a, T> TrustedLen for RChunksMut<'a, T> {}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> FusedIterator for RChunksMut<'a, T> {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
|
||||
unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut [T] {
|
||||
let end = self.v.len() - i * self.chunk_size;
|
||||
let start = match end.checked_sub(self.chunk_size) {
|
||||
None => 0,
|
||||
Some(start) => start,
|
||||
};
|
||||
from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start)
|
||||
}
|
||||
fn may_have_side_effect() -> bool { false }
|
||||
}
|
||||
|
||||
/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
|
||||
/// time), starting at the end of the slice.
|
||||
///
|
||||
/// When the slice len is not evenly divided by the chunk size, the last
|
||||
/// up to `chunk_size-1` elements will be omitted but can be retrieved from
|
||||
/// the [`remainder`] function from the iterator.
|
||||
///
|
||||
/// This struct is created by the [`rchunks_exact`] method on [slices].
|
||||
///
|
||||
/// [`rchunks_exact`]: ../../std/primitive.slice.html#method.rchunks_exact
|
||||
/// [`remainder`]: ../../std/slice/struct.ChunksExact.html#method.remainder
|
||||
/// [slices]: ../../std/primitive.slice.html
|
||||
#[derive(Debug)]
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
pub struct RChunksExact<'a, T:'a> {
|
||||
v: &'a [T],
|
||||
rem: &'a [T],
|
||||
chunk_size: usize
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> RChunksExact<'a, T> {
|
||||
/// Return the remainder of the original slice that is not going to be
|
||||
/// returned by the iterator. The returned slice has at most `chunk_size-1`
|
||||
/// elements.
|
||||
pub fn remainder(&self) -> &'a [T] {
|
||||
self.rem
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> Clone for RChunksExact<'a, T> {
|
||||
fn clone(&self) -> RChunksExact<'a, T> {
|
||||
RChunksExact {
|
||||
v: self.v,
|
||||
rem: self.rem,
|
||||
chunk_size: self.chunk_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> Iterator for RChunksExact<'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.v.len() - self.chunk_size);
|
||||
self.v = fst;
|
||||
Some(snd)
|
||||
}
|
||||
}
|
||||
|
||||
#[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 (end, overflow) = n.overflowing_mul(self.chunk_size);
|
||||
if end >= self.v.len() || overflow {
|
||||
self.v = &[];
|
||||
None
|
||||
} else {
|
||||
let (fst, _) = self.v.split_at(self.v.len() - end);
|
||||
self.v = fst;
|
||||
self.next()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn last(mut self) -> Option<Self::Item> {
|
||||
self.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> DoubleEndedIterator for RChunksExact<'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.chunk_size);
|
||||
self.v = snd;
|
||||
Some(fst)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> ExactSizeIterator for RChunksExact<'a, T> {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.v.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<'a, T> TrustedLen for RChunksExact<'a, T> {}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> FusedIterator for RChunksExact<'a, T> {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
|
||||
unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T] {
|
||||
let end = self.v.len() - i * self.chunk_size;
|
||||
let start = end - self.chunk_size;
|
||||
from_raw_parts(self.v.as_ptr().add(start), 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), starting at the end of the slice.
|
||||
///
|
||||
/// When the slice len is not evenly divided by the chunk size, the last up to
|
||||
/// `chunk_size-1` elements will be omitted but can be retrieved from the
|
||||
/// [`into_remainder`] function from the iterator.
|
||||
///
|
||||
/// This struct is created by the [`rchunks_exact_mut`] method on [slices].
|
||||
///
|
||||
/// [`rchunks_exact_mut`]: ../../std/primitive.slice.html#method.rchunks_exact_mut
|
||||
/// [`into_remainder`]: ../../std/slice/struct.ChunksExactMut.html#method.into_remainder
|
||||
/// [slices]: ../../std/primitive.slice.html
|
||||
#[derive(Debug)]
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
pub struct RChunksExactMut<'a, T:'a> {
|
||||
v: &'a mut [T],
|
||||
rem: &'a mut [T],
|
||||
chunk_size: usize
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> RChunksExactMut<'a, T> {
|
||||
/// Return the remainder of the original slice that is not going to be
|
||||
/// returned by the iterator. The returned slice has at most `chunk_size-1`
|
||||
/// elements.
|
||||
pub fn into_remainder(self) -> &'a mut [T] {
|
||||
self.rem
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> Iterator for RChunksExactMut<'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 tmp_len = tmp.len();
|
||||
let (head, tail) = tmp.split_at_mut(tmp_len - self.chunk_size);
|
||||
self.v = head;
|
||||
Some(tail)
|
||||
}
|
||||
}
|
||||
|
||||
#[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 (end, overflow) = n.overflowing_mul(self.chunk_size);
|
||||
if end >= self.v.len() || overflow {
|
||||
self.v = &mut [];
|
||||
None
|
||||
} else {
|
||||
let tmp = mem::replace(&mut self.v, &mut []);
|
||||
let tmp_len = tmp.len();
|
||||
let (fst, _) = tmp.split_at_mut(tmp_len - end);
|
||||
self.v = fst;
|
||||
self.next()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn last(mut self) -> Option<Self::Item> {
|
||||
self.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> DoubleEndedIterator for RChunksExactMut<'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 (head, tail) = tmp.split_at_mut(self.chunk_size);
|
||||
self.v = tail;
|
||||
Some(head)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> ExactSizeIterator for RChunksExactMut<'a, T> {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.v.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<'a, T> TrustedLen for RChunksExactMut<'a, T> {}
|
||||
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
impl<'a, T> FusedIterator for RChunksExactMut<'a, T> {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "rchunks", issue = "55177")]
|
||||
unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
|
||||
unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut [T] {
|
||||
let end = self.v.len() - i * self.chunk_size;
|
||||
let start = end - self.chunk_size;
|
||||
from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size)
|
||||
}
|
||||
fn may_have_side_effect() -> bool { false }
|
||||
}
|
||||
|
||||
//
|
||||
// Free functions
|
||||
//
|
||||
|
@ -35,6 +35,7 @@
|
||||
#![feature(try_from)]
|
||||
#![feature(try_trait)]
|
||||
#![feature(chunks_exact)]
|
||||
#![feature(rchunks)]
|
||||
#![feature(align_offset)]
|
||||
#![feature(reverse_bits)]
|
||||
#![feature(inner_deref)]
|
||||
|
@ -338,6 +338,228 @@ fn test_chunks_exact_mut_zip() {
|
||||
assert_eq!(v1, [13, 14, 19, 20, 4]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_count() {
|
||||
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||
let c = v.rchunks(3);
|
||||
assert_eq!(c.count(), 2);
|
||||
|
||||
let v2: &[i32] = &[0, 1, 2, 3, 4];
|
||||
let c2 = v2.rchunks(2);
|
||||
assert_eq!(c2.count(), 3);
|
||||
|
||||
let v3: &[i32] = &[];
|
||||
let c3 = v3.rchunks(2);
|
||||
assert_eq!(c3.count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_nth() {
|
||||
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||
let mut c = v.rchunks(2);
|
||||
assert_eq!(c.nth(1).unwrap(), &[2, 3]);
|
||||
assert_eq!(c.next().unwrap(), &[0, 1]);
|
||||
|
||||
let v2: &[i32] = &[0, 1, 2, 3, 4];
|
||||
let mut c2 = v2.rchunks(3);
|
||||
assert_eq!(c2.nth(1).unwrap(), &[0, 1]);
|
||||
assert_eq!(c2.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_last() {
|
||||
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||
let c = v.rchunks(2);
|
||||
assert_eq!(c.last().unwrap()[1], 1);
|
||||
|
||||
let v2: &[i32] = &[0, 1, 2, 3, 4];
|
||||
let c2 = v2.rchunks(2);
|
||||
assert_eq!(c2.last().unwrap()[0], 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_zip() {
|
||||
let v1: &[i32] = &[0, 1, 2, 3, 4];
|
||||
let v2: &[i32] = &[6, 7, 8, 9, 10];
|
||||
|
||||
let res = v1.rchunks(2)
|
||||
.zip(v2.rchunks(2))
|
||||
.map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(res, vec![26, 18, 6]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_mut_count() {
|
||||
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let c = v.rchunks_mut(3);
|
||||
assert_eq!(c.count(), 2);
|
||||
|
||||
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let c2 = v2.rchunks_mut(2);
|
||||
assert_eq!(c2.count(), 3);
|
||||
|
||||
let v3: &mut [i32] = &mut [];
|
||||
let c3 = v3.rchunks_mut(2);
|
||||
assert_eq!(c3.count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_mut_nth() {
|
||||
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let mut c = v.rchunks_mut(2);
|
||||
assert_eq!(c.nth(1).unwrap(), &[2, 3]);
|
||||
assert_eq!(c.next().unwrap(), &[0, 1]);
|
||||
|
||||
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let mut c2 = v2.rchunks_mut(3);
|
||||
assert_eq!(c2.nth(1).unwrap(), &[0, 1]);
|
||||
assert_eq!(c2.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_mut_last() {
|
||||
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let c = v.rchunks_mut(2);
|
||||
assert_eq!(c.last().unwrap(), &[0, 1]);
|
||||
|
||||
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let c2 = v2.rchunks_mut(2);
|
||||
assert_eq!(c2.last().unwrap(), &[0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_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.rchunks_mut(2).zip(v2.rchunks(2)) {
|
||||
let sum = b.iter().sum::<i32>();
|
||||
for v in a {
|
||||
*v += sum;
|
||||
}
|
||||
}
|
||||
assert_eq!(v1, [6, 16, 17, 22, 23]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_exact_count() {
|
||||
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||
let c = v.rchunks_exact(3);
|
||||
assert_eq!(c.count(), 2);
|
||||
|
||||
let v2: &[i32] = &[0, 1, 2, 3, 4];
|
||||
let c2 = v2.rchunks_exact(2);
|
||||
assert_eq!(c2.count(), 2);
|
||||
|
||||
let v3: &[i32] = &[];
|
||||
let c3 = v3.rchunks_exact(2);
|
||||
assert_eq!(c3.count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_exact_nth() {
|
||||
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||
let mut c = v.rchunks_exact(2);
|
||||
assert_eq!(c.nth(1).unwrap(), &[2, 3]);
|
||||
assert_eq!(c.next().unwrap(), &[0, 1]);
|
||||
|
||||
let v2: &[i32] = &[0, 1, 2, 3, 4, 5, 6];
|
||||
let mut c2 = v2.rchunks_exact(3);
|
||||
assert_eq!(c2.nth(1).unwrap(), &[1, 2, 3]);
|
||||
assert_eq!(c2.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_exact_last() {
|
||||
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||
let c = v.rchunks_exact(2);
|
||||
assert_eq!(c.last().unwrap(), &[0, 1]);
|
||||
|
||||
let v2: &[i32] = &[0, 1, 2, 3, 4];
|
||||
let c2 = v2.rchunks_exact(2);
|
||||
assert_eq!(c2.last().unwrap(), &[1, 2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_exact_remainder() {
|
||||
let v: &[i32] = &[0, 1, 2, 3, 4];
|
||||
let c = v.rchunks_exact(2);
|
||||
assert_eq!(c.remainder(), &[0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_exact_zip() {
|
||||
let v1: &[i32] = &[0, 1, 2, 3, 4];
|
||||
let v2: &[i32] = &[6, 7, 8, 9, 10];
|
||||
|
||||
let res = v1.rchunks_exact(2)
|
||||
.zip(v2.rchunks_exact(2))
|
||||
.map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(res, vec![26, 18]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_exact_mut_count() {
|
||||
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let c = v.rchunks_exact_mut(3);
|
||||
assert_eq!(c.count(), 2);
|
||||
|
||||
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let c2 = v2.rchunks_exact_mut(2);
|
||||
assert_eq!(c2.count(), 2);
|
||||
|
||||
let v3: &mut [i32] = &mut [];
|
||||
let c3 = v3.rchunks_exact_mut(2);
|
||||
assert_eq!(c3.count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_exact_mut_nth() {
|
||||
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let mut c = v.rchunks_exact_mut(2);
|
||||
assert_eq!(c.nth(1).unwrap(), &[2, 3]);
|
||||
assert_eq!(c.next().unwrap(), &[0, 1]);
|
||||
|
||||
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4, 5, 6];
|
||||
let mut c2 = v2.rchunks_exact_mut(3);
|
||||
assert_eq!(c2.nth(1).unwrap(), &[1, 2, 3]);
|
||||
assert_eq!(c2.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_exact_mut_last() {
|
||||
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
|
||||
let c = v.rchunks_exact_mut(2);
|
||||
assert_eq!(c.last().unwrap(), &[0, 1]);
|
||||
|
||||
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let c2 = v2.rchunks_exact_mut(2);
|
||||
assert_eq!(c2.last().unwrap(), &[1, 2]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_exact_mut_remainder() {
|
||||
let v: &mut [i32] = &mut [0, 1, 2, 3, 4];
|
||||
let c = v.rchunks_exact_mut(2);
|
||||
assert_eq!(c.into_remainder(), &[0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_exact_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.rchunks_exact_mut(2).zip(v2.rchunks_exact(2)) {
|
||||
let sum = b.iter().sum::<i32>();
|
||||
for v in a {
|
||||
*v += sum;
|
||||
}
|
||||
}
|
||||
assert_eq!(v1, [0, 16, 17, 22, 23]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_windows_count() {
|
||||
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||
|
Loading…
x
Reference in New Issue
Block a user