Skip to content

Commit 89c8d47

Browse files
committed
Add par_rchunks* for slices
1 parent 14dce4d commit 89c8d47

6 files changed

Lines changed: 540 additions & 0 deletions

File tree

src/slice/mod.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
mod chunks;
99
mod mergesort;
1010
mod quicksort;
11+
mod rchunks;
1112

1213
mod test;
1314

@@ -21,6 +22,7 @@ use std::cmp::Ordering;
2122
use std::fmt::{self, Debug};
2223

2324
pub use self::chunks::{Chunks, ChunksExact, ChunksExactMut, ChunksMut};
25+
pub use self::rchunks::{RChunks, RChunksExact, RChunksExactMut, RChunksMut};
2426

2527
/// Parallel extensions for slices.
2628
pub trait ParallelSlice<T: Sync> {
@@ -105,6 +107,44 @@ pub trait ParallelSlice<T: Sync> {
105107
assert!(chunk_size != 0, "chunk_size must not be zero");
106108
ChunksExact::new(chunk_size, self.as_parallel_slice())
107109
}
110+
111+
/// Returns a parallel iterator over at most `chunk_size` elements of `self` at a time,
112+
/// starting at the end. The chunks do not overlap.
113+
///
114+
/// If the number of elements in the iterator is not divisible by
115+
/// `chunk_size`, the last chunk may be shorter than `chunk_size`. All
116+
/// other chunks will have that exact length.
117+
///
118+
/// # Examples
119+
///
120+
/// ```
121+
/// use rayon::prelude::*;
122+
/// let chunks: Vec<_> = [1, 2, 3, 4, 5].par_rchunks(2).collect();
123+
/// assert_eq!(chunks, vec![&[4, 5][..], &[2, 3], &[1]]);
124+
/// ```
125+
fn par_rchunks(&self, chunk_size: usize) -> RChunks<'_, T> {
126+
assert!(chunk_size != 0, "chunk_size must not be zero");
127+
RChunks::new(chunk_size, self.as_parallel_slice())
128+
}
129+
130+
/// Returns a parallel iterator over `chunk_size` elements of `self` at a time,
131+
/// starting at the end. The chunks do not overlap.
132+
///
133+
/// If `chunk_size` does not divide the length of the slice, then the
134+
/// last up to `chunk_size-1` elements will be omitted and can be
135+
/// retrieved from the remainder function of the iterator.
136+
///
137+
/// # Examples
138+
///
139+
/// ```
140+
/// use rayon::prelude::*;
141+
/// let chunks: Vec<_> = [1, 2, 3, 4, 5].par_rchunks_exact(2).collect();
142+
/// assert_eq!(chunks, vec![&[4, 5][..], &[2, 3]]);
143+
/// ```
144+
fn par_rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> {
145+
assert!(chunk_size != 0, "chunk_size must not be zero");
146+
RChunksExact::new(chunk_size, self.as_parallel_slice())
147+
}
108148
}
109149

110150
impl<T: Sync> ParallelSlice<T> for [T] {
@@ -184,6 +224,48 @@ pub trait ParallelSliceMut<T: Send> {
184224
ChunksExactMut::new(chunk_size, self.as_parallel_slice_mut())
185225
}
186226

227+
/// Returns a parallel iterator over at most `chunk_size` elements of `self` at a time,
228+
/// starting at the end. The chunks are mutable and do not overlap.
229+
///
230+
/// If the number of elements in the iterator is not divisible by
231+
/// `chunk_size`, the last chunk may be shorter than `chunk_size`. All
232+
/// other chunks will have that exact length.
233+
///
234+
/// # Examples
235+
///
236+
/// ```
237+
/// use rayon::prelude::*;
238+
/// let mut array = [1, 2, 3, 4, 5];
239+
/// array.par_rchunks_mut(2)
240+
/// .for_each(|slice| slice.reverse());
241+
/// assert_eq!(array, [1, 3, 2, 5, 4]);
242+
/// ```
243+
fn par_rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> {
244+
assert!(chunk_size != 0, "chunk_size must not be zero");
245+
RChunksMut::new(chunk_size, self.as_parallel_slice_mut())
246+
}
247+
248+
/// Returns a parallel iterator over `chunk_size` elements of `self` at a time,
249+
/// starting at the end. The chunks are mutable and do not overlap.
250+
///
251+
/// If `chunk_size` does not divide the length of the slice, then the
252+
/// last up to `chunk_size-1` elements will be omitted and can be
253+
/// retrieved from the remainder function of the iterator.
254+
///
255+
/// # Examples
256+
///
257+
/// ```
258+
/// use rayon::prelude::*;
259+
/// let mut array = [1, 2, 3, 4, 5];
260+
/// array.par_rchunks_exact_mut(3)
261+
/// .for_each(|slice| slice.reverse());
262+
/// assert_eq!(array, [1, 2, 5, 4, 3]);
263+
/// ```
264+
fn par_rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> {
265+
assert!(chunk_size != 0, "chunk_size must not be zero");
266+
RChunksExactMut::new(chunk_size, self.as_parallel_slice_mut())
267+
}
268+
187269
/// Sorts the slice in parallel.
188270
///
189271
/// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.

0 commit comments

Comments
 (0)