diff options
| author | Sebastian Dröge <sebastian@centricular.com> | 2018-01-02 02:13:20 +0200 |
|---|---|---|
| committer | Sebastian Dröge <sebastian@centricular.com> | 2018-01-13 12:18:46 +0200 |
| commit | 51d546f4aa8a94b81d2a580518d95d1ab12a3655 (patch) | |
| tree | c490689fc10b38b4abf7e4494ea72d876c138ef9 /src/liballoc | |
| parent | 2e33c89ff1518359c4bd5fbed1571ea00cb3b146 (diff) | |
| download | rust-51d546f4aa8a94b81d2a580518d95d1ab12a3655.tar.gz rust-51d546f4aa8a94b81d2a580518d95d1ab12a3655.zip | |
Add slice::ExactChunks and ::ExactChunksMut iterators
These guarantee that always the requested slice size will be returned and any leftoever elements at the end will be ignored. It allows llvm to get rid of bounds checks in the code using the iterator. This is inspired by the same iterators provided by ndarray. See https://github.com/rust-lang/rust/issues/47115
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/lib.rs | 1 | ||||
| -rw-r--r-- | src/liballoc/slice.rs | 56 |
2 files changed, 57 insertions, 0 deletions
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 3cc3ea46796..d8ce28695ab 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -124,6 +124,7 @@ #![feature(unsize)] #![feature(allocator_internals)] #![feature(on_unimplemented)] +#![feature(exact_chunks)] #![cfg_attr(not(test), feature(fused, fn_traits, placement_new_protocol, swap_with_slice, i128))] #![cfg_attr(test, feature(test, box_heap))] diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index fa73197885b..bae36673637 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -123,6 +123,8 @@ pub use core::slice::{from_raw_parts, from_raw_parts_mut}; 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 @@ -631,6 +633,31 @@ impl<T> [T] { 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. + /// + /// # Panics + /// + /// Panics if `chunk_size` is 0. + /// + /// # Examples + /// + /// ``` + /// let slice = ['l', 'o', 'r', 'e', 'm']; + /// let mut iter = slice.chunks(2); + /// assert_eq!(iter.next().unwrap(), &['l', 'o']); + /// assert_eq!(iter.next().unwrap(), &['r', 'e']); + /// assert_eq!(iter.next().unwrap(), &['m']); + /// 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 @@ -660,6 +687,35 @@ impl<T> [T] { 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. + /// + /// # Panics + /// + /// Panics if `chunk_size` is 0. + /// + /// # Examples + /// + /// ``` + /// 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, 3]); + /// ``` + #[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 |
