Skip to content

Commit

Permalink
Rollup merge of rust-lang#117678 - niklasf:stabilize-slice_group_by, …
Browse files Browse the repository at this point in the history
…r=dtolnay

Stabilize `slice_group_by`

Renamed "group by" to "chunk by" a per rust-lang#80552.

Newly stable items:

* `core::slice::ChunkBy`
* `core::slice::ChunkByMut`
* `[T]::chunk`
* `[T]::chunk_by`

Closes rust-lang#80552.
  • Loading branch information
matthiaskrgr committed Jan 26, 2024
2 parents 9450e2f + c3a8237 commit 7749e49
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 71 deletions.
1 change: 0 additions & 1 deletion library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@
#![feature(set_ptr_value)]
#![feature(sized_type_properties)]
#![feature(slice_from_ptr_range)]
#![feature(slice_group_by)]
#![feature(slice_ptr_get)]
#![feature(slice_ptr_len)]
#![feature(slice_range)]
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ pub use core::slice::{from_mut, from_ref};
pub use core::slice::{from_mut_ptr_range, from_ptr_range};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
pub use core::slice::{ChunkBy, ChunkByMut};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::slice::{Chunks, Windows};
#[stable(feature = "chunks_exact", since = "1.31.0")]
pub use core::slice::{ChunksExact, ChunksExactMut};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::slice::{ChunksMut, Split, SplitMut};
#[unstable(feature = "slice_group_by", issue = "80552")]
pub use core::slice::{GroupBy, GroupByMut};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::slice::{Iter, IterMut};
#[stable(feature = "rchunks", since = "1.31.0")]
Expand Down
1 change: 0 additions & 1 deletion library/alloc/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#![feature(iter_advance_by)]
#![feature(iter_next_chunk)]
#![feature(round_char_boundary)]
#![feature(slice_group_by)]
#![feature(slice_partition_dedup)]
#![feature(string_remove_matches)]
#![feature(const_btree_len)]
Expand Down
16 changes: 8 additions & 8 deletions library/alloc/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1614,26 +1614,26 @@ fn subslice_patterns() {
}

#[test]
fn test_group_by() {
fn test_chunk_by() {
let slice = &[1, 1, 1, 3, 3, 2, 2, 2, 1, 0];

let mut iter = slice.group_by(|a, b| a == b);
let mut iter = slice.chunk_by(|a, b| a == b);
assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
assert_eq!(iter.next(), Some(&[3, 3][..]));
assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
assert_eq!(iter.next(), Some(&[1][..]));
assert_eq!(iter.next(), Some(&[0][..]));
assert_eq!(iter.next(), None);

let mut iter = slice.group_by(|a, b| a == b);
let mut iter = slice.chunk_by(|a, b| a == b);
assert_eq!(iter.next_back(), Some(&[0][..]));
assert_eq!(iter.next_back(), Some(&[1][..]));
assert_eq!(iter.next_back(), Some(&[2, 2, 2][..]));
assert_eq!(iter.next_back(), Some(&[3, 3][..]));
assert_eq!(iter.next_back(), Some(&[1, 1, 1][..]));
assert_eq!(iter.next_back(), None);

let mut iter = slice.group_by(|a, b| a == b);
let mut iter = slice.chunk_by(|a, b| a == b);
assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
assert_eq!(iter.next_back(), Some(&[0][..]));
assert_eq!(iter.next(), Some(&[3, 3][..]));
Expand All @@ -1643,26 +1643,26 @@ fn test_group_by() {
}

#[test]
fn test_group_by_mut() {
fn test_chunk_by_mut() {
let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2, 1, 0];

let mut iter = slice.group_by_mut(|a, b| a == b);
let mut iter = slice.chunk_by_mut(|a, b| a == b);
assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
assert_eq!(iter.next(), Some(&mut [3, 3][..]));
assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
assert_eq!(iter.next(), Some(&mut [1][..]));
assert_eq!(iter.next(), Some(&mut [0][..]));
assert_eq!(iter.next(), None);

let mut iter = slice.group_by_mut(|a, b| a == b);
let mut iter = slice.chunk_by_mut(|a, b| a == b);
assert_eq!(iter.next_back(), Some(&mut [0][..]));
assert_eq!(iter.next_back(), Some(&mut [1][..]));
assert_eq!(iter.next_back(), Some(&mut [2, 2, 2][..]));
assert_eq!(iter.next_back(), Some(&mut [3, 3][..]));
assert_eq!(iter.next_back(), Some(&mut [1, 1, 1][..]));
assert_eq!(iter.next_back(), None);

let mut iter = slice.group_by_mut(|a, b| a == b);
let mut iter = slice.chunk_by_mut(|a, b| a == b);
assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
assert_eq!(iter.next_back(), Some(&mut [0][..]));
assert_eq!(iter.next(), Some(&mut [3, 3][..]));
Expand Down
64 changes: 32 additions & 32 deletions library/core/src/slice/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3248,26 +3248,26 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for IterMut<'a, T> {

/// An iterator over slice in (non-overlapping) chunks separated by a predicate.
///
/// This struct is created by the [`group_by`] method on [slices].
/// This struct is created by the [`chunk_by`] method on [slices].
///
/// [`group_by`]: slice::group_by
/// [`chunk_by`]: slice::chunk_by
/// [slices]: slice
#[unstable(feature = "slice_group_by", issue = "80552")]
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct GroupBy<'a, T: 'a, P> {
pub struct ChunkBy<'a, T: 'a, P> {
slice: &'a [T],
predicate: P,
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> GroupBy<'a, T, P> {
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> ChunkBy<'a, T, P> {
pub(super) fn new(slice: &'a [T], predicate: P) -> Self {
GroupBy { slice, predicate }
ChunkBy { slice, predicate }
}
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> Iterator for GroupBy<'a, T, P>
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> Iterator for ChunkBy<'a, T, P>
where
P: FnMut(&T, &T) -> bool,
{
Expand Down Expand Up @@ -3300,8 +3300,8 @@ where
}
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> DoubleEndedIterator for GroupBy<'a, T, P>
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> DoubleEndedIterator for ChunkBy<'a, T, P>
where
P: FnMut(&T, &T) -> bool,
{
Expand All @@ -3322,39 +3322,39 @@ where
}
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> FusedIterator for GroupBy<'a, T, P> where P: FnMut(&T, &T) -> bool {}
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> FusedIterator for ChunkBy<'a, T, P> where P: FnMut(&T, &T) -> bool {}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for GroupBy<'a, T, P> {
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkBy<'a, T, P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("GroupBy").field("slice", &self.slice).finish()
f.debug_struct("ChunkBy").field("slice", &self.slice).finish()
}
}

/// An iterator over slice in (non-overlapping) mutable chunks separated
/// by a predicate.
///
/// This struct is created by the [`group_by_mut`] method on [slices].
/// This struct is created by the [`chunk_by_mut`] method on [slices].
///
/// [`group_by_mut`]: slice::group_by_mut
/// [`chunk_by_mut`]: slice::chunk_by_mut
/// [slices]: slice
#[unstable(feature = "slice_group_by", issue = "80552")]
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct GroupByMut<'a, T: 'a, P> {
pub struct ChunkByMut<'a, T: 'a, P> {
slice: &'a mut [T],
predicate: P,
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> GroupByMut<'a, T, P> {
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> ChunkByMut<'a, T, P> {
pub(super) fn new(slice: &'a mut [T], predicate: P) -> Self {
GroupByMut { slice, predicate }
ChunkByMut { slice, predicate }
}
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> Iterator for GroupByMut<'a, T, P>
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> Iterator for ChunkByMut<'a, T, P>
where
P: FnMut(&T, &T) -> bool,
{
Expand Down Expand Up @@ -3388,8 +3388,8 @@ where
}
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> DoubleEndedIterator for GroupByMut<'a, T, P>
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> DoubleEndedIterator for ChunkByMut<'a, T, P>
where
P: FnMut(&T, &T) -> bool,
{
Expand All @@ -3411,12 +3411,12 @@ where
}
}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a, P> FusedIterator for GroupByMut<'a, T, P> where P: FnMut(&T, &T) -> bool {}
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a, P> FusedIterator for ChunkByMut<'a, T, P> where P: FnMut(&T, &T) -> bool {}

#[unstable(feature = "slice_group_by", issue = "80552")]
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for GroupByMut<'a, T, P> {
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkByMut<'a, T, P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("GroupByMut").field("slice", &self.slice).finish()
f.debug_struct("ChunkByMut").field("slice", &self.slice).finish()
}
}
44 changes: 18 additions & 26 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ pub use iter::{ArrayChunks, ArrayChunksMut};
#[unstable(feature = "array_windows", issue = "75027")]
pub use iter::ArrayWindows;

#[unstable(feature = "slice_group_by", issue = "80552")]
pub use iter::{GroupBy, GroupByMut};
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
pub use iter::{ChunkBy, ChunkByMut};

#[stable(feature = "split_inclusive", since = "1.51.0")]
pub use iter::{SplitInclusive, SplitInclusiveMut};
Expand Down Expand Up @@ -1748,18 +1748,16 @@ impl<T> [T] {
/// Returns an iterator over the slice producing non-overlapping runs
/// of elements using the predicate to separate them.
///
/// The predicate is called on two elements following themselves,
/// it means the predicate is called on `slice[0]` and `slice[1]`
/// then on `slice[1]` and `slice[2]` and so on.
/// The predicate is called for every pair of consecutive elements,
/// meaning that it is called on `slice[0]` and `slice[1]`,
/// followed by `slice[1]` and `slice[2]`, and so on.
///
/// # Examples
///
/// ```
/// #![feature(slice_group_by)]
///
/// let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
///
/// let mut iter = slice.group_by(|a, b| a == b);
/// let mut iter = slice.chunk_by(|a, b| a == b);
///
/// assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
/// assert_eq!(iter.next(), Some(&[3, 3][..]));
Expand All @@ -1770,41 +1768,37 @@ impl<T> [T] {
/// This method can be used to extract the sorted subslices:
///
/// ```
/// #![feature(slice_group_by)]
///
/// let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
///
/// let mut iter = slice.group_by(|a, b| a <= b);
/// let mut iter = slice.chunk_by(|a, b| a <= b);
///
/// assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
/// assert_eq!(iter.next(), Some(&[2, 3][..]));
/// assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
/// assert_eq!(iter.next(), None);
/// ```
#[unstable(feature = "slice_group_by", issue = "80552")]
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub fn group_by<F>(&self, pred: F) -> GroupBy<'_, T, F>
pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
where
F: FnMut(&T, &T) -> bool,
{
GroupBy::new(self, pred)
ChunkBy::new(self, pred)
}

/// Returns an iterator over the slice producing non-overlapping mutable
/// runs of elements using the predicate to separate them.
///
/// The predicate is called on two elements following themselves,
/// it means the predicate is called on `slice[0]` and `slice[1]`
/// then on `slice[1]` and `slice[2]` and so on.
/// The predicate is called for every pair of consecutive elements,
/// meaning that it is called on `slice[0]` and `slice[1]`,
/// followed by `slice[1]` and `slice[2]`, and so on.
///
/// # Examples
///
/// ```
/// #![feature(slice_group_by)]
///
/// let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
///
/// let mut iter = slice.group_by_mut(|a, b| a == b);
/// let mut iter = slice.chunk_by_mut(|a, b| a == b);
///
/// assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
/// assert_eq!(iter.next(), Some(&mut [3, 3][..]));
Expand All @@ -1815,24 +1809,22 @@ impl<T> [T] {
/// This method can be used to extract the sorted subslices:
///
/// ```
/// #![feature(slice_group_by)]
///
/// let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
///
/// let mut iter = slice.group_by_mut(|a, b| a <= b);
/// let mut iter = slice.chunk_by_mut(|a, b| a <= b);
///
/// assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
/// assert_eq!(iter.next(), Some(&mut [2, 3][..]));
/// assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
/// assert_eq!(iter.next(), None);
/// ```
#[unstable(feature = "slice_group_by", issue = "80552")]
#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub fn group_by_mut<F>(&mut self, pred: F) -> GroupByMut<'_, T, F>
pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
where
F: FnMut(&T, &T) -> bool,
{
GroupByMut::new(self, pred)
ChunkByMut::new(self, pred)
}

/// Divides one slice into two at an index.
Expand Down
1 change: 0 additions & 1 deletion library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@
#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
#![cfg_attr(test, feature(cfg_match))]
#![feature(int_roundings)]
#![feature(slice_group_by)]
#![feature(split_array)]
#![feature(strict_provenance)]
#![feature(strict_provenance_atomic_ptr)]
Expand Down

0 comments on commit 7749e49

Please sign in to comment.