Skip to content

Commit 57850e5

Browse files
committed
Auto merge of #47445 - kennytm:rollup, r=kennytm
Rollup of 10 pull requests - Successful merges: #47120, #47126, #47277, #47330, #47368, #47372, #47414, #47417, #47432, #47443 - Failed merges: #47334
2 parents 8ff449d + fa008c0 commit 57850e5

30 files changed

+660
-212
lines changed

src/liballoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@
124124
#![feature(unsize)]
125125
#![feature(allocator_internals)]
126126
#![feature(on_unimplemented)]
127+
#![feature(exact_chunks)]
127128

128129
#![cfg_attr(not(test), feature(fused, fn_traits, placement_new_protocol, swap_with_slice, i128))]
129130
#![cfg_attr(test, feature(test, box_heap))]

src/liballoc/slice.rs

+74
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ pub use core::slice::{from_raw_parts, from_raw_parts_mut};
123123
pub use core::slice::{from_ref, from_ref_mut};
124124
#[unstable(feature = "slice_get_slice", issue = "35729")]
125125
pub use core::slice::SliceIndex;
126+
#[unstable(feature = "exact_chunks", issue = "47115")]
127+
pub use core::slice::{ExactChunks, ExactChunksMut};
126128

127129
////////////////////////////////////////////////////////////////////////////////
128130
// Basic slice extension methods
@@ -611,6 +613,9 @@ impl<T> [T] {
611613
/// not divide the length of the slice, then the last chunk will
612614
/// not have length `chunk_size`.
613615
///
616+
/// See [`exact_chunks`] for a variant of this iterator that returns chunks
617+
/// of always exactly `chunk_size` elements.
618+
///
614619
/// # Panics
615620
///
616621
/// Panics if `chunk_size` is 0.
@@ -631,11 +636,44 @@ impl<T> [T] {
631636
core_slice::SliceExt::chunks(self, chunk_size)
632637
}
633638

639+
/// Returns an iterator over `chunk_size` elements of the slice at a
640+
/// time. The chunks are slices and do not overlap. If `chunk_size` does
641+
/// not divide the length of the slice, then the last up to `chunk_size-1`
642+
/// elements will be omitted.
643+
///
644+
/// Due to each chunk having exactly `chunk_size` elements, the compiler
645+
/// can often optimize the resulting code better than in the case of
646+
/// [`chunks`].
647+
///
648+
/// # Panics
649+
///
650+
/// Panics if `chunk_size` is 0.
651+
///
652+
/// # Examples
653+
///
654+
/// ```
655+
/// #![feature(exact_chunks)]
656+
///
657+
/// let slice = ['l', 'o', 'r', 'e', 'm'];
658+
/// let mut iter = slice.exact_chunks(2);
659+
/// assert_eq!(iter.next().unwrap(), &['l', 'o']);
660+
/// assert_eq!(iter.next().unwrap(), &['r', 'e']);
661+
/// assert!(iter.next().is_none());
662+
/// ```
663+
#[unstable(feature = "exact_chunks", issue = "47115")]
664+
#[inline]
665+
pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
666+
core_slice::SliceExt::exact_chunks(self, chunk_size)
667+
}
668+
634669
/// Returns an iterator over `chunk_size` elements of the slice at a time.
635670
/// The chunks are mutable slices, and do not overlap. If `chunk_size` does
636671
/// not divide the length of the slice, then the last chunk will not
637672
/// have length `chunk_size`.
638673
///
674+
/// See [`exact_chunks_mut`] for a variant of this iterator that returns chunks
675+
/// of always exactly `chunk_size` elements.
676+
///
639677
/// # Panics
640678
///
641679
/// Panics if `chunk_size` is 0.
@@ -660,6 +698,42 @@ impl<T> [T] {
660698
core_slice::SliceExt::chunks_mut(self, chunk_size)
661699
}
662700

701+
/// Returns an iterator over `chunk_size` elements of the slice at a time.
702+
/// The chunks are mutable slices, and do not overlap. If `chunk_size` does
703+
/// not divide the length of the slice, then the last up to `chunk_size-1`
704+
/// elements will be omitted.
705+
///
706+
///
707+
/// Due to each chunk having exactly `chunk_size` elements, the compiler
708+
/// can often optimize the resulting code better than in the case of
709+
/// [`chunks_mut`].
710+
///
711+
/// # Panics
712+
///
713+
/// Panics if `chunk_size` is 0.
714+
///
715+
/// # Examples
716+
///
717+
/// ```
718+
/// #![feature(exact_chunks)]
719+
///
720+
/// let v = &mut [0, 0, 0, 0, 0];
721+
/// let mut count = 1;
722+
///
723+
/// for chunk in v.exact_chunks_mut(2) {
724+
/// for elem in chunk.iter_mut() {
725+
/// *elem += count;
726+
/// }
727+
/// count += 1;
728+
/// }
729+
/// assert_eq!(v, &[1, 1, 2, 2, 0]);
730+
/// ```
731+
#[unstable(feature = "exact_chunks", issue = "47115")]
732+
#[inline]
733+
pub fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut<T> {
734+
core_slice::SliceExt::exact_chunks_mut(self, chunk_size)
735+
}
736+
663737
/// Divides one slice into two at an index.
664738
///
665739
/// The first will contain all indices from `[0, mid)` (excluding

src/liballoc/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#![feature(string_retain)]
3131
#![feature(unboxed_closures)]
3232
#![feature(unicode)]
33+
#![feature(exact_chunks)]
3334

3435
extern crate alloc_system;
3536
extern crate std_unicode;

src/liballoc/tests/slice.rs

+58-2
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,30 @@ fn test_chunksator_0() {
945945
let _it = v.chunks(0);
946946
}
947947

948+
#[test]
949+
fn test_exact_chunksator() {
950+
let v = &[1, 2, 3, 4, 5];
951+
952+
assert_eq!(v.exact_chunks(2).len(), 2);
953+
954+
let chunks: &[&[_]] = &[&[1, 2], &[3, 4]];
955+
assert_eq!(v.exact_chunks(2).collect::<Vec<_>>(), chunks);
956+
let chunks: &[&[_]] = &[&[1, 2, 3]];
957+
assert_eq!(v.exact_chunks(3).collect::<Vec<_>>(), chunks);
958+
let chunks: &[&[_]] = &[];
959+
assert_eq!(v.exact_chunks(6).collect::<Vec<_>>(), chunks);
960+
961+
let chunks: &[&[_]] = &[&[3, 4], &[1, 2]];
962+
assert_eq!(v.exact_chunks(2).rev().collect::<Vec<_>>(), chunks);
963+
}
964+
965+
#[test]
966+
#[should_panic]
967+
fn test_exact_chunksator_0() {
968+
let v = &[1, 2, 3, 4];
969+
let _it = v.exact_chunks(0);
970+
}
971+
948972
#[test]
949973
fn test_reverse_part() {
950974
let mut values = [1, 2, 3, 4, 5];
@@ -1159,7 +1183,7 @@ fn test_mut_chunks() {
11591183
}
11601184
}
11611185
let result = [0, 0, 0, 1, 1, 1, 2];
1162-
assert!(v == result);
1186+
assert_eq!(v, result);
11631187
}
11641188

11651189
#[test]
@@ -1171,7 +1195,7 @@ fn test_mut_chunks_rev() {
11711195
}
11721196
}
11731197
let result = [2, 2, 2, 1, 1, 1, 0];
1174-
assert!(v == result);
1198+
assert_eq!(v, result);
11751199
}
11761200

11771201
#[test]
@@ -1181,6 +1205,38 @@ fn test_mut_chunks_0() {
11811205
let _it = v.chunks_mut(0);
11821206
}
11831207

1208+
#[test]
1209+
fn test_mut_exact_chunks() {
1210+
let mut v = [0, 1, 2, 3, 4, 5, 6];
1211+
assert_eq!(v.exact_chunks_mut(2).len(), 3);
1212+
for (i, chunk) in v.exact_chunks_mut(3).enumerate() {
1213+
for x in chunk {
1214+
*x = i as u8;
1215+
}
1216+
}
1217+
let result = [0, 0, 0, 1, 1, 1, 6];
1218+
assert_eq!(v, result);
1219+
}
1220+
1221+
#[test]
1222+
fn test_mut_exact_chunks_rev() {
1223+
let mut v = [0, 1, 2, 3, 4, 5, 6];
1224+
for (i, chunk) in v.exact_chunks_mut(3).rev().enumerate() {
1225+
for x in chunk {
1226+
*x = i as u8;
1227+
}
1228+
}
1229+
let result = [1, 1, 1, 0, 0, 0, 6];
1230+
assert_eq!(v, result);
1231+
}
1232+
1233+
#[test]
1234+
#[should_panic]
1235+
fn test_mut_exact_chunks_0() {
1236+
let mut v = [1, 2, 3, 4];
1237+
let _it = v.exact_chunks_mut(0);
1238+
}
1239+
11841240
#[test]
11851241
fn test_mut_last() {
11861242
let mut x = [1, 2, 3, 4, 5];

0 commit comments

Comments
 (0)