Skip to content

Add ExactChunks::remainder and ExactChunks::into_remainder #51339

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 40 additions & 8 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,8 @@ impl<T> [T] {
/// 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.
/// elements will be omitted and can be retrieved from the `remainder`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and the same for exact_chunks_mut can't be linked to the documentation of the function. It would have to be ../std/slice/etc for the direct documentation here and ../../std/slice/etc for the "copied" documentation in e.g. Vec (for its AsRef<_> impl)

Just omitting the link for now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#32130 Is the relevant issue for this AFAIU

/// 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
Expand Down Expand Up @@ -758,14 +759,15 @@ impl<T> [T] {
assert!(chunk_size != 0);
let rem = self.len() % chunk_size;
let len = self.len() - rem;
ExactChunks { v: &self[..len], chunk_size: chunk_size}
let (fst, snd) = self.split_at(len);
ExactChunks { v: fst, rem: snd, chunk_size: 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.
///
/// 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
Expand Down Expand Up @@ -799,7 +801,8 @@ impl<T> [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}
let (fst, snd) = self.split_at_mut(len);
ExactChunksMut { v: fst, rem: snd, chunk_size: chunk_size}
}

/// Divides one slice into two at an index.
Expand Down Expand Up @@ -3654,25 +3657,39 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
/// time).
///
/// When the slice len is not evenly divided by the chunk size, the last
/// up to `chunk_size-1` elements will be omitted.
/// 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 [`exact_chunks`] method on [slices].
///
/// [`exact_chunks`]: ../../std/primitive.slice.html#method.exact_chunks
/// [`remainder`]: ../../std/slice/struct.ExactChunks.html#method.remainder
/// [slices]: ../../std/primitive.slice.html
#[derive(Debug)]
#[unstable(feature = "exact_chunks", issue = "47115")]
pub struct ExactChunks<'a, T:'a> {
v: &'a [T],
rem: &'a [T],
chunk_size: usize
}

#[unstable(feature = "exact_chunks", issue = "47115")]
impl<'a, T> ExactChunks<'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 = "exact_chunks", issue = "47115")]
impl<'a, T> Clone for ExactChunks<'a, T> {
fn clone(&self) -> ExactChunks<'a, T> {
ExactChunks {
v: self.v,
rem: self.rem,
chunk_size: self.chunk_size,
}
}
Expand Down Expand Up @@ -3760,20 +3777,35 @@ unsafe impl<'a, T> TrustedRandomAccess for ExactChunks<'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 up to `chunk_size-1` elements will be omitted.
/// 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 but can be retrieved from the
/// [`into_remainder`] function from the iterator.
///
/// This struct is created by the [`exact_chunks_mut`] method on [slices].
///
/// [`exact_chunks_mut`]: ../../std/primitive.slice.html#method.exact_chunks_mut
/// [`into_remainder`]: ../../std/slice/struct.ExactChunksMut.html#method.into_remainder
/// [slices]: ../../std/primitive.slice.html
#[derive(Debug)]
#[unstable(feature = "exact_chunks", issue = "47115")]
pub struct ExactChunksMut<'a, T:'a> {
v: &'a mut [T],
rem: &'a mut [T],
chunk_size: usize
}

#[unstable(feature = "exact_chunks", issue = "47115")]
impl<'a, T> ExactChunksMut<'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 = "exact_chunks", issue = "47115")]
impl<'a, T> Iterator for ExactChunksMut<'a, T> {
type Item = &'a mut [T];
Expand Down
14 changes: 14 additions & 0 deletions src/libcore/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,13 @@ fn test_exact_chunks_last() {
assert_eq!(c2.last().unwrap(), &[2, 3]);
}

#[test]
fn test_exact_chunks_remainder() {
let v: &[i32] = &[0, 1, 2, 3, 4];
let c = v.exact_chunks(2);
assert_eq!(c.remainder(), &[4]);
}

#[test]
fn test_exact_chunks_zip() {
let v1: &[i32] = &[0, 1, 2, 3, 4];
Expand Down Expand Up @@ -310,6 +317,13 @@ fn test_exact_chunks_mut_last() {
assert_eq!(c2.last().unwrap(), &[2, 3]);
}

#[test]
fn test_exact_chunks_mut_remainder() {
let v: &mut [i32] = &mut [0, 1, 2, 3, 4];
let c = v.exact_chunks_mut(2);
assert_eq!(c.into_remainder(), &[4]);
}

#[test]
fn test_exact_chunks_mut_zip() {
let v1: &mut [i32] = &mut [0, 1, 2, 3, 4];
Expand Down