1 //! Parallel iterator types for [slices][std::slice] 2 //! 3 //! You will rarely need to interact with this module directly unless you need 4 //! to name one of the iterator types. 5 //! 6 //! [std::slice]: https://doc.rust-lang.org/stable/std/slice/ 7 8 mod chunk_by; 9 mod chunks; 10 mod mergesort; 11 mod quicksort; 12 mod rchunks; 13 14 mod test; 15 16 use self::mergesort::par_mergesort; 17 use self::quicksort::par_quicksort; 18 use crate::iter::plumbing::*; 19 use crate::iter::*; 20 use crate::split_producer::*; 21 22 use std::cmp::Ordering; 23 use std::fmt::{self, Debug}; 24 use std::mem; 25 26 pub use self::chunk_by::{ChunkBy, ChunkByMut}; 27 pub use self::chunks::{Chunks, ChunksExact, ChunksExactMut, ChunksMut}; 28 pub use self::rchunks::{RChunks, RChunksExact, RChunksExactMut, RChunksMut}; 29 30 /// Parallel extensions for slices. 31 pub trait ParallelSlice<T: Sync> { 32 /// Returns a plain slice, which is used to implement the rest of the 33 /// parallel methods. as_parallel_slice(&self) -> &[T]34 fn as_parallel_slice(&self) -> &[T]; 35 36 /// Returns a parallel iterator over subslices separated by elements that 37 /// match the separator. 38 /// 39 /// # Examples 40 /// 41 /// ``` 42 /// use rayon::prelude::*; 43 /// let products: Vec<_> = [1, 2, 3, 0, 2, 4, 8, 0, 3, 6, 9] 44 /// .par_split(|i| *i == 0) 45 /// .map(|numbers| numbers.iter().product::<i32>()) 46 /// .collect(); 47 /// assert_eq!(products, [6, 64, 162]); 48 /// ``` par_split<P>(&self, separator: P) -> Split<'_, T, P> where P: Fn(&T) -> bool + Sync + Send,49 fn par_split<P>(&self, separator: P) -> Split<'_, T, P> 50 where 51 P: Fn(&T) -> bool + Sync + Send, 52 { 53 Split { 54 slice: self.as_parallel_slice(), 55 separator, 56 } 57 } 58 59 /// Returns a parallel iterator over subslices separated by elements that 60 /// match the separator, including the matched part as a terminator. 61 /// 62 /// # Examples 63 /// 64 /// ``` 65 /// use rayon::prelude::*; 66 /// let lengths: Vec<_> = [1, 2, 3, 0, 2, 4, 8, 0, 3, 6, 9] 67 /// .par_split_inclusive(|i| *i == 0) 68 /// .map(|numbers| numbers.len()) 69 /// .collect(); 70 /// assert_eq!(lengths, [4, 4, 3]); 71 /// ``` par_split_inclusive<P>(&self, separator: P) -> SplitInclusive<'_, T, P> where P: Fn(&T) -> bool + Sync + Send,72 fn par_split_inclusive<P>(&self, separator: P) -> SplitInclusive<'_, T, P> 73 where 74 P: Fn(&T) -> bool + Sync + Send, 75 { 76 SplitInclusive { 77 slice: self.as_parallel_slice(), 78 separator, 79 } 80 } 81 82 /// Returns a parallel iterator over all contiguous windows of length 83 /// `window_size`. The windows overlap. 84 /// 85 /// # Examples 86 /// 87 /// ``` 88 /// use rayon::prelude::*; 89 /// let windows: Vec<_> = [1, 2, 3].par_windows(2).collect(); 90 /// assert_eq!(vec![[1, 2], [2, 3]], windows); 91 /// ``` par_windows(&self, window_size: usize) -> Windows<'_, T>92 fn par_windows(&self, window_size: usize) -> Windows<'_, T> { 93 Windows { 94 window_size, 95 slice: self.as_parallel_slice(), 96 } 97 } 98 99 /// Returns a parallel iterator over at most `chunk_size` elements of 100 /// `self` at a time. The chunks do not overlap. 101 /// 102 /// If the number of elements in the iterator is not divisible by 103 /// `chunk_size`, the last chunk may be shorter than `chunk_size`. All 104 /// other chunks will have that exact length. 105 /// 106 /// # Examples 107 /// 108 /// ``` 109 /// use rayon::prelude::*; 110 /// let chunks: Vec<_> = [1, 2, 3, 4, 5].par_chunks(2).collect(); 111 /// assert_eq!(chunks, vec![&[1, 2][..], &[3, 4], &[5]]); 112 /// ``` 113 #[track_caller] par_chunks(&self, chunk_size: usize) -> Chunks<'_, T>114 fn par_chunks(&self, chunk_size: usize) -> Chunks<'_, T> { 115 assert!(chunk_size != 0, "chunk_size must not be zero"); 116 Chunks::new(chunk_size, self.as_parallel_slice()) 117 } 118 119 /// Returns a parallel iterator over `chunk_size` elements of 120 /// `self` at a time. The chunks do not overlap. 121 /// 122 /// If `chunk_size` does not divide the length of the slice, then the 123 /// last up to `chunk_size-1` elements will be omitted and can be 124 /// retrieved from the remainder function of the iterator. 125 /// 126 /// # Examples 127 /// 128 /// ``` 129 /// use rayon::prelude::*; 130 /// let chunks: Vec<_> = [1, 2, 3, 4, 5].par_chunks_exact(2).collect(); 131 /// assert_eq!(chunks, vec![&[1, 2][..], &[3, 4]]); 132 /// ``` 133 #[track_caller] par_chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>134 fn par_chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> { 135 assert!(chunk_size != 0, "chunk_size must not be zero"); 136 ChunksExact::new(chunk_size, self.as_parallel_slice()) 137 } 138 139 /// Returns a parallel iterator over at most `chunk_size` elements of `self` at a time, 140 /// starting at the end. The chunks do not overlap. 141 /// 142 /// If the number of elements in the iterator is not divisible by 143 /// `chunk_size`, the last chunk may be shorter than `chunk_size`. All 144 /// other chunks will have that exact length. 145 /// 146 /// # Examples 147 /// 148 /// ``` 149 /// use rayon::prelude::*; 150 /// let chunks: Vec<_> = [1, 2, 3, 4, 5].par_rchunks(2).collect(); 151 /// assert_eq!(chunks, vec![&[4, 5][..], &[2, 3], &[1]]); 152 /// ``` 153 #[track_caller] par_rchunks(&self, chunk_size: usize) -> RChunks<'_, T>154 fn par_rchunks(&self, chunk_size: usize) -> RChunks<'_, T> { 155 assert!(chunk_size != 0, "chunk_size must not be zero"); 156 RChunks::new(chunk_size, self.as_parallel_slice()) 157 } 158 159 /// Returns a parallel iterator over `chunk_size` elements of `self` at a time, 160 /// starting at the end. The chunks do not overlap. 161 /// 162 /// If `chunk_size` does not divide the length of the slice, then the 163 /// last up to `chunk_size-1` elements will be omitted and can be 164 /// retrieved from the remainder function of the iterator. 165 /// 166 /// # Examples 167 /// 168 /// ``` 169 /// use rayon::prelude::*; 170 /// let chunks: Vec<_> = [1, 2, 3, 4, 5].par_rchunks_exact(2).collect(); 171 /// assert_eq!(chunks, vec![&[4, 5][..], &[2, 3]]); 172 /// ``` 173 #[track_caller] par_rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>174 fn par_rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> { 175 assert!(chunk_size != 0, "chunk_size must not be zero"); 176 RChunksExact::new(chunk_size, self.as_parallel_slice()) 177 } 178 179 /// Returns a parallel iterator over the slice producing non-overlapping runs 180 /// of elements using the predicate to separate them. 181 /// 182 /// The predicate is called on two elements following themselves, 183 /// it means the predicate is called on `slice[0]` and `slice[1]` 184 /// then on `slice[1]` and `slice[2]` and so on. 185 /// 186 /// # Examples 187 /// 188 /// ``` 189 /// use rayon::prelude::*; 190 /// let chunks: Vec<_> = [1, 2, 2, 3, 3, 3].par_chunk_by(|&x, &y| x == y).collect(); 191 /// assert_eq!(chunks[0], &[1]); 192 /// assert_eq!(chunks[1], &[2, 2]); 193 /// assert_eq!(chunks[2], &[3, 3, 3]); 194 /// ``` par_chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F> where F: Fn(&T, &T) -> bool + Send + Sync,195 fn par_chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F> 196 where 197 F: Fn(&T, &T) -> bool + Send + Sync, 198 { 199 ChunkBy::new(self.as_parallel_slice(), pred) 200 } 201 } 202 203 impl<T: Sync> ParallelSlice<T> for [T] { 204 #[inline] as_parallel_slice(&self) -> &[T]205 fn as_parallel_slice(&self) -> &[T] { 206 self 207 } 208 } 209 210 /// Parallel extensions for mutable slices. 211 pub trait ParallelSliceMut<T: Send> { 212 /// Returns a plain mutable slice, which is used to implement the rest of 213 /// the parallel methods. as_parallel_slice_mut(&mut self) -> &mut [T]214 fn as_parallel_slice_mut(&mut self) -> &mut [T]; 215 216 /// Returns a parallel iterator over mutable subslices separated by 217 /// elements that match the separator. 218 /// 219 /// # Examples 220 /// 221 /// ``` 222 /// use rayon::prelude::*; 223 /// let mut array = [1, 2, 3, 0, 2, 4, 8, 0, 3, 6, 9]; 224 /// array.par_split_mut(|i| *i == 0) 225 /// .for_each(|slice| slice.reverse()); 226 /// assert_eq!(array, [3, 2, 1, 0, 8, 4, 2, 0, 9, 6, 3]); 227 /// ``` par_split_mut<P>(&mut self, separator: P) -> SplitMut<'_, T, P> where P: Fn(&T) -> bool + Sync + Send,228 fn par_split_mut<P>(&mut self, separator: P) -> SplitMut<'_, T, P> 229 where 230 P: Fn(&T) -> bool + Sync + Send, 231 { 232 SplitMut { 233 slice: self.as_parallel_slice_mut(), 234 separator, 235 } 236 } 237 238 /// Returns a parallel iterator over mutable subslices separated by elements 239 /// that match the separator, including the matched part as a terminator. 240 /// 241 /// # Examples 242 /// 243 /// ``` 244 /// use rayon::prelude::*; 245 /// let mut array = [1, 2, 3, 0, 2, 4, 8, 0, 3, 6, 9]; 246 /// array.par_split_inclusive_mut(|i| *i == 0) 247 /// .for_each(|slice| slice.reverse()); 248 /// assert_eq!(array, [0, 3, 2, 1, 0, 8, 4, 2, 9, 6, 3]); 249 /// ``` par_split_inclusive_mut<P>(&mut self, separator: P) -> SplitInclusiveMut<'_, T, P> where P: Fn(&T) -> bool + Sync + Send,250 fn par_split_inclusive_mut<P>(&mut self, separator: P) -> SplitInclusiveMut<'_, T, P> 251 where 252 P: Fn(&T) -> bool + Sync + Send, 253 { 254 SplitInclusiveMut { 255 slice: self.as_parallel_slice_mut(), 256 separator, 257 } 258 } 259 260 /// Returns a parallel iterator over at most `chunk_size` elements of 261 /// `self` at a time. The chunks are mutable and do not overlap. 262 /// 263 /// If the number of elements in the iterator is not divisible by 264 /// `chunk_size`, the last chunk may be shorter than `chunk_size`. All 265 /// other chunks will have that exact length. 266 /// 267 /// # Examples 268 /// 269 /// ``` 270 /// use rayon::prelude::*; 271 /// let mut array = [1, 2, 3, 4, 5]; 272 /// array.par_chunks_mut(2) 273 /// .for_each(|slice| slice.reverse()); 274 /// assert_eq!(array, [2, 1, 4, 3, 5]); 275 /// ``` 276 #[track_caller] par_chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>277 fn par_chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> { 278 assert!(chunk_size != 0, "chunk_size must not be zero"); 279 ChunksMut::new(chunk_size, self.as_parallel_slice_mut()) 280 } 281 282 /// Returns a parallel iterator over `chunk_size` elements of 283 /// `self` at a time. The chunks are mutable and do not overlap. 284 /// 285 /// If `chunk_size` does not divide the length of the slice, then the 286 /// last up to `chunk_size-1` elements will be omitted and can be 287 /// retrieved from the remainder function of the iterator. 288 /// 289 /// # Examples 290 /// 291 /// ``` 292 /// use rayon::prelude::*; 293 /// let mut array = [1, 2, 3, 4, 5]; 294 /// array.par_chunks_exact_mut(3) 295 /// .for_each(|slice| slice.reverse()); 296 /// assert_eq!(array, [3, 2, 1, 4, 5]); 297 /// ``` 298 #[track_caller] par_chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>299 fn par_chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> { 300 assert!(chunk_size != 0, "chunk_size must not be zero"); 301 ChunksExactMut::new(chunk_size, self.as_parallel_slice_mut()) 302 } 303 304 /// Returns a parallel iterator over at most `chunk_size` elements of `self` at a time, 305 /// starting at the end. The chunks are mutable and do not overlap. 306 /// 307 /// If the number of elements in the iterator is not divisible by 308 /// `chunk_size`, the last chunk may be shorter than `chunk_size`. All 309 /// other chunks will have that exact length. 310 /// 311 /// # Examples 312 /// 313 /// ``` 314 /// use rayon::prelude::*; 315 /// let mut array = [1, 2, 3, 4, 5]; 316 /// array.par_rchunks_mut(2) 317 /// .for_each(|slice| slice.reverse()); 318 /// assert_eq!(array, [1, 3, 2, 5, 4]); 319 /// ``` 320 #[track_caller] par_rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>321 fn par_rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> { 322 assert!(chunk_size != 0, "chunk_size must not be zero"); 323 RChunksMut::new(chunk_size, self.as_parallel_slice_mut()) 324 } 325 326 /// Returns a parallel iterator over `chunk_size` elements of `self` at a time, 327 /// starting at the end. The chunks are mutable and do not overlap. 328 /// 329 /// If `chunk_size` does not divide the length of the slice, then the 330 /// last up to `chunk_size-1` elements will be omitted and can be 331 /// retrieved from the remainder function of the iterator. 332 /// 333 /// # Examples 334 /// 335 /// ``` 336 /// use rayon::prelude::*; 337 /// let mut array = [1, 2, 3, 4, 5]; 338 /// array.par_rchunks_exact_mut(3) 339 /// .for_each(|slice| slice.reverse()); 340 /// assert_eq!(array, [1, 2, 5, 4, 3]); 341 /// ``` 342 #[track_caller] par_rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>343 fn par_rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> { 344 assert!(chunk_size != 0, "chunk_size must not be zero"); 345 RChunksExactMut::new(chunk_size, self.as_parallel_slice_mut()) 346 } 347 348 /// Sorts the slice in parallel. 349 /// 350 /// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*)) worst-case. 351 /// 352 /// When applicable, unstable sorting is preferred because it is generally faster than stable 353 /// sorting and it doesn't allocate auxiliary memory. 354 /// See [`par_sort_unstable`](#method.par_sort_unstable). 355 /// 356 /// # Current implementation 357 /// 358 /// The current algorithm is an adaptive merge sort inspired by 359 /// [timsort](https://en.wikipedia.org/wiki/Timsort). 360 /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of 361 /// two or more sorted sequences concatenated one after another. 362 /// 363 /// Also, it allocates temporary storage the same size as `self`, but for very short slices a 364 /// non-allocating insertion sort is used instead. 365 /// 366 /// In order to sort the slice in parallel, the slice is first divided into smaller chunks and 367 /// all chunks are sorted in parallel. Then, adjacent chunks that together form non-descending 368 /// or descending runs are concatenated. Finally, the remaining chunks are merged together using 369 /// parallel subdivision of chunks and parallel merge operation. 370 /// 371 /// # Examples 372 /// 373 /// ``` 374 /// use rayon::prelude::*; 375 /// 376 /// let mut v = [-5, 4, 1, -3, 2]; 377 /// 378 /// v.par_sort(); 379 /// assert_eq!(v, [-5, -3, 1, 2, 4]); 380 /// ``` par_sort(&mut self) where T: Ord,381 fn par_sort(&mut self) 382 where 383 T: Ord, 384 { 385 par_mergesort(self.as_parallel_slice_mut(), T::lt); 386 } 387 388 /// Sorts the slice in parallel with a comparator function. 389 /// 390 /// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*)) worst-case. 391 /// 392 /// The comparator function must define a total ordering for the elements in the slice. If 393 /// the ordering is not total, the order of the elements is unspecified. An order is a 394 /// total order if it is (for all `a`, `b` and `c`): 395 /// 396 /// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and 397 /// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`. 398 /// 399 /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use 400 /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`. 401 /// 402 /// ``` 403 /// use rayon::prelude::*; 404 /// 405 /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0]; 406 /// floats.par_sort_by(|a, b| a.partial_cmp(b).unwrap()); 407 /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]); 408 /// ``` 409 /// 410 /// When applicable, unstable sorting is preferred because it is generally faster than stable 411 /// sorting and it doesn't allocate auxiliary memory. 412 /// See [`par_sort_unstable_by`](#method.par_sort_unstable_by). 413 /// 414 /// # Current implementation 415 /// 416 /// The current algorithm is an adaptive merge sort inspired by 417 /// [timsort](https://en.wikipedia.org/wiki/Timsort). 418 /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of 419 /// two or more sorted sequences concatenated one after another. 420 /// 421 /// Also, it allocates temporary storage the same size as `self`, but for very short slices a 422 /// non-allocating insertion sort is used instead. 423 /// 424 /// In order to sort the slice in parallel, the slice is first divided into smaller chunks and 425 /// all chunks are sorted in parallel. Then, adjacent chunks that together form non-descending 426 /// or descending runs are concatenated. Finally, the remaining chunks are merged together using 427 /// parallel subdivision of chunks and parallel merge operation. 428 /// 429 /// # Examples 430 /// 431 /// ``` 432 /// use rayon::prelude::*; 433 /// 434 /// let mut v = [5, 4, 1, 3, 2]; 435 /// v.par_sort_by(|a, b| a.cmp(b)); 436 /// assert_eq!(v, [1, 2, 3, 4, 5]); 437 /// 438 /// // reverse sorting 439 /// v.par_sort_by(|a, b| b.cmp(a)); 440 /// assert_eq!(v, [5, 4, 3, 2, 1]); 441 /// ``` par_sort_by<F>(&mut self, compare: F) where F: Fn(&T, &T) -> Ordering + Sync,442 fn par_sort_by<F>(&mut self, compare: F) 443 where 444 F: Fn(&T, &T) -> Ordering + Sync, 445 { 446 par_mergesort(self.as_parallel_slice_mut(), |a, b| { 447 compare(a, b) == Ordering::Less 448 }); 449 } 450 451 /// Sorts the slice in parallel with a key extraction function. 452 /// 453 /// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* \* log(*n*)) 454 /// worst-case, where the key function is *O*(*m*). 455 /// 456 /// For expensive key functions (e.g. functions that are not simple property accesses or 457 /// basic operations), [`par_sort_by_cached_key`](#method.par_sort_by_cached_key) is likely to 458 /// be significantly faster, as it does not recompute element keys. 459 /// 460 /// When applicable, unstable sorting is preferred because it is generally faster than stable 461 /// sorting and it doesn't allocate auxiliary memory. 462 /// See [`par_sort_unstable_by_key`](#method.par_sort_unstable_by_key). 463 /// 464 /// # Current implementation 465 /// 466 /// The current algorithm is an adaptive merge sort inspired by 467 /// [timsort](https://en.wikipedia.org/wiki/Timsort). 468 /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of 469 /// two or more sorted sequences concatenated one after another. 470 /// 471 /// Also, it allocates temporary storage the same size as `self`, but for very short slices a 472 /// non-allocating insertion sort is used instead. 473 /// 474 /// In order to sort the slice in parallel, the slice is first divided into smaller chunks and 475 /// all chunks are sorted in parallel. Then, adjacent chunks that together form non-descending 476 /// or descending runs are concatenated. Finally, the remaining chunks are merged together using 477 /// parallel subdivision of chunks and parallel merge operation. 478 /// 479 /// # Examples 480 /// 481 /// ``` 482 /// use rayon::prelude::*; 483 /// 484 /// let mut v = [-5i32, 4, 1, -3, 2]; 485 /// 486 /// v.par_sort_by_key(|k| k.abs()); 487 /// assert_eq!(v, [1, 2, -3, 4, -5]); 488 /// ``` par_sort_by_key<K, F>(&mut self, f: F) where K: Ord, F: Fn(&T) -> K + Sync,489 fn par_sort_by_key<K, F>(&mut self, f: F) 490 where 491 K: Ord, 492 F: Fn(&T) -> K + Sync, 493 { 494 par_mergesort(self.as_parallel_slice_mut(), |a, b| f(a).lt(&f(b))); 495 } 496 497 /// Sorts the slice in parallel with a key extraction function. 498 /// 499 /// During sorting, the key function is called at most once per element, by using 500 /// temporary storage to remember the results of key evaluation. 501 /// The key function is called in parallel, so the order of calls is completely unspecified. 502 /// 503 /// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* + *n* \* log(*n*)) 504 /// worst-case, where the key function is *O*(*m*). 505 /// 506 /// For simple key functions (e.g., functions that are property accesses or 507 /// basic operations), [`par_sort_by_key`](#method.par_sort_by_key) is likely to be 508 /// faster. 509 /// 510 /// # Current implementation 511 /// 512 /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters, 513 /// which combines the fast average case of randomized quicksort with the fast worst case of 514 /// heapsort, while achieving linear time on slices with certain patterns. It uses some 515 /// randomization to avoid degenerate cases, but with a fixed seed to always provide 516 /// deterministic behavior. 517 /// 518 /// In the worst case, the algorithm allocates temporary storage in a `Vec<(K, usize)>` the 519 /// length of the slice. 520 /// 521 /// All quicksorts work in two stages: partitioning into two halves followed by recursive 522 /// calls. The partitioning phase is sequential, but the two recursive calls are performed in 523 /// parallel. Finally, after sorting the cached keys, the item positions are updated sequentially. 524 /// 525 /// [pdqsort]: https://github.com/orlp/pdqsort 526 /// 527 /// # Examples 528 /// 529 /// ``` 530 /// use rayon::prelude::*; 531 /// 532 /// let mut v = [-5i32, 4, 32, -3, 2]; 533 /// 534 /// v.par_sort_by_cached_key(|k| k.to_string()); 535 /// assert!(v == [-3, -5, 2, 32, 4]); 536 /// ``` par_sort_by_cached_key<K, F>(&mut self, f: F) where F: Fn(&T) -> K + Sync, K: Ord + Send,537 fn par_sort_by_cached_key<K, F>(&mut self, f: F) 538 where 539 F: Fn(&T) -> K + Sync, 540 K: Ord + Send, 541 { 542 let slice = self.as_parallel_slice_mut(); 543 let len = slice.len(); 544 if len < 2 { 545 return; 546 } 547 548 // Helper macro for indexing our vector by the smallest possible type, to reduce allocation. 549 macro_rules! sort_by_key { 550 ($t:ty) => {{ 551 let mut indices: Vec<_> = slice 552 .par_iter_mut() 553 .enumerate() 554 .map(|(i, x)| (f(&*x), i as $t)) 555 .collect(); 556 // The elements of `indices` are unique, as they are indexed, so any sort will be 557 // stable with respect to the original slice. We use `sort_unstable` here because 558 // it requires less memory allocation. 559 indices.par_sort_unstable(); 560 for i in 0..len { 561 let mut index = indices[i].1; 562 while (index as usize) < i { 563 index = indices[index as usize].1; 564 } 565 indices[i].1 = index; 566 slice.swap(i, index as usize); 567 } 568 }}; 569 } 570 571 let sz_u8 = mem::size_of::<(K, u8)>(); 572 let sz_u16 = mem::size_of::<(K, u16)>(); 573 let sz_u32 = mem::size_of::<(K, u32)>(); 574 let sz_usize = mem::size_of::<(K, usize)>(); 575 576 if sz_u8 < sz_u16 && len <= (std::u8::MAX as usize) { 577 return sort_by_key!(u8); 578 } 579 if sz_u16 < sz_u32 && len <= (std::u16::MAX as usize) { 580 return sort_by_key!(u16); 581 } 582 if sz_u32 < sz_usize && len <= (std::u32::MAX as usize) { 583 return sort_by_key!(u32); 584 } 585 sort_by_key!(usize) 586 } 587 588 /// Sorts the slice in parallel, but might not preserve the order of equal elements. 589 /// 590 /// This sort is unstable (i.e., may reorder equal elements), in-place 591 /// (i.e., does not allocate), and *O*(*n* \* log(*n*)) worst-case. 592 /// 593 /// # Current implementation 594 /// 595 /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters, 596 /// which combines the fast average case of randomized quicksort with the fast worst case of 597 /// heapsort, while achieving linear time on slices with certain patterns. It uses some 598 /// randomization to avoid degenerate cases, but with a fixed seed to always provide 599 /// deterministic behavior. 600 /// 601 /// It is typically faster than stable sorting, except in a few special cases, e.g., when the 602 /// slice consists of several concatenated sorted sequences. 603 /// 604 /// All quicksorts work in two stages: partitioning into two halves followed by recursive 605 /// calls. The partitioning phase is sequential, but the two recursive calls are performed in 606 /// parallel. 607 /// 608 /// [pdqsort]: https://github.com/orlp/pdqsort 609 /// 610 /// # Examples 611 /// 612 /// ``` 613 /// use rayon::prelude::*; 614 /// 615 /// let mut v = [-5, 4, 1, -3, 2]; 616 /// 617 /// v.par_sort_unstable(); 618 /// assert_eq!(v, [-5, -3, 1, 2, 4]); 619 /// ``` par_sort_unstable(&mut self) where T: Ord,620 fn par_sort_unstable(&mut self) 621 where 622 T: Ord, 623 { 624 par_quicksort(self.as_parallel_slice_mut(), T::lt); 625 } 626 627 /// Sorts the slice in parallel with a comparator function, but might not preserve the order of 628 /// equal elements. 629 /// 630 /// This sort is unstable (i.e., may reorder equal elements), in-place 631 /// (i.e., does not allocate), and *O*(*n* \* log(*n*)) worst-case. 632 /// 633 /// The comparator function must define a total ordering for the elements in the slice. If 634 /// the ordering is not total, the order of the elements is unspecified. An order is a 635 /// total order if it is (for all `a`, `b` and `c`): 636 /// 637 /// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and 638 /// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`. 639 /// 640 /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use 641 /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`. 642 /// 643 /// ``` 644 /// use rayon::prelude::*; 645 /// 646 /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0]; 647 /// floats.par_sort_unstable_by(|a, b| a.partial_cmp(b).unwrap()); 648 /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]); 649 /// ``` 650 /// 651 /// # Current implementation 652 /// 653 /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters, 654 /// which combines the fast average case of randomized quicksort with the fast worst case of 655 /// heapsort, while achieving linear time on slices with certain patterns. It uses some 656 /// randomization to avoid degenerate cases, but with a fixed seed to always provide 657 /// deterministic behavior. 658 /// 659 /// It is typically faster than stable sorting, except in a few special cases, e.g., when the 660 /// slice consists of several concatenated sorted sequences. 661 /// 662 /// All quicksorts work in two stages: partitioning into two halves followed by recursive 663 /// calls. The partitioning phase is sequential, but the two recursive calls are performed in 664 /// parallel. 665 /// 666 /// [pdqsort]: https://github.com/orlp/pdqsort 667 /// 668 /// # Examples 669 /// 670 /// ``` 671 /// use rayon::prelude::*; 672 /// 673 /// let mut v = [5, 4, 1, 3, 2]; 674 /// v.par_sort_unstable_by(|a, b| a.cmp(b)); 675 /// assert_eq!(v, [1, 2, 3, 4, 5]); 676 /// 677 /// // reverse sorting 678 /// v.par_sort_unstable_by(|a, b| b.cmp(a)); 679 /// assert_eq!(v, [5, 4, 3, 2, 1]); 680 /// ``` par_sort_unstable_by<F>(&mut self, compare: F) where F: Fn(&T, &T) -> Ordering + Sync,681 fn par_sort_unstable_by<F>(&mut self, compare: F) 682 where 683 F: Fn(&T, &T) -> Ordering + Sync, 684 { 685 par_quicksort(self.as_parallel_slice_mut(), |a, b| { 686 compare(a, b) == Ordering::Less 687 }); 688 } 689 690 /// Sorts the slice in parallel with a key extraction function, but might not preserve the order 691 /// of equal elements. 692 /// 693 /// This sort is unstable (i.e., may reorder equal elements), in-place 694 /// (i.e., does not allocate), and *O*(m \* *n* \* log(*n*)) worst-case, 695 /// where the key function is *O*(*m*). 696 /// 697 /// # Current implementation 698 /// 699 /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters, 700 /// which combines the fast average case of randomized quicksort with the fast worst case of 701 /// heapsort, while achieving linear time on slices with certain patterns. It uses some 702 /// randomization to avoid degenerate cases, but with a fixed seed to always provide 703 /// deterministic behavior. 704 /// 705 /// Due to its key calling strategy, `par_sort_unstable_by_key` is likely to be slower than 706 /// [`par_sort_by_cached_key`](#method.par_sort_by_cached_key) in cases where the key function 707 /// is expensive. 708 /// 709 /// All quicksorts work in two stages: partitioning into two halves followed by recursive 710 /// calls. The partitioning phase is sequential, but the two recursive calls are performed in 711 /// parallel. 712 /// 713 /// [pdqsort]: https://github.com/orlp/pdqsort 714 /// 715 /// # Examples 716 /// 717 /// ``` 718 /// use rayon::prelude::*; 719 /// 720 /// let mut v = [-5i32, 4, 1, -3, 2]; 721 /// 722 /// v.par_sort_unstable_by_key(|k| k.abs()); 723 /// assert_eq!(v, [1, 2, -3, 4, -5]); 724 /// ``` par_sort_unstable_by_key<K, F>(&mut self, f: F) where K: Ord, F: Fn(&T) -> K + Sync,725 fn par_sort_unstable_by_key<K, F>(&mut self, f: F) 726 where 727 K: Ord, 728 F: Fn(&T) -> K + Sync, 729 { 730 par_quicksort(self.as_parallel_slice_mut(), |a, b| f(a).lt(&f(b))); 731 } 732 733 /// Returns a parallel iterator over the slice producing non-overlapping mutable 734 /// runs of elements using the predicate to separate them. 735 /// 736 /// The predicate is called on two elements following themselves, 737 /// it means the predicate is called on `slice[0]` and `slice[1]` 738 /// then on `slice[1]` and `slice[2]` and so on. 739 /// 740 /// # Examples 741 /// 742 /// ``` 743 /// use rayon::prelude::*; 744 /// let mut xs = [1, 2, 2, 3, 3, 3]; 745 /// let chunks: Vec<_> = xs.par_chunk_by_mut(|&x, &y| x == y).collect(); 746 /// assert_eq!(chunks[0], &mut [1]); 747 /// assert_eq!(chunks[1], &mut [2, 2]); 748 /// assert_eq!(chunks[2], &mut [3, 3, 3]); 749 /// ``` par_chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F> where F: Fn(&T, &T) -> bool + Send + Sync,750 fn par_chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F> 751 where 752 F: Fn(&T, &T) -> bool + Send + Sync, 753 { 754 ChunkByMut::new(self.as_parallel_slice_mut(), pred) 755 } 756 } 757 758 impl<T: Send> ParallelSliceMut<T> for [T] { 759 #[inline] as_parallel_slice_mut(&mut self) -> &mut [T]760 fn as_parallel_slice_mut(&mut self) -> &mut [T] { 761 self 762 } 763 } 764 765 impl<'data, T: Sync + 'data> IntoParallelIterator for &'data [T] { 766 type Item = &'data T; 767 type Iter = Iter<'data, T>; 768 into_par_iter(self) -> Self::Iter769 fn into_par_iter(self) -> Self::Iter { 770 Iter { slice: self } 771 } 772 } 773 774 impl<'data, T: Send + 'data> IntoParallelIterator for &'data mut [T] { 775 type Item = &'data mut T; 776 type Iter = IterMut<'data, T>; 777 into_par_iter(self) -> Self::Iter778 fn into_par_iter(self) -> Self::Iter { 779 IterMut { slice: self } 780 } 781 } 782 783 /// Parallel iterator over immutable items in a slice 784 #[derive(Debug)] 785 pub struct Iter<'data, T: Sync> { 786 slice: &'data [T], 787 } 788 789 impl<'data, T: Sync> Clone for Iter<'data, T> { clone(&self) -> Self790 fn clone(&self) -> Self { 791 Iter { ..*self } 792 } 793 } 794 795 impl<'data, T: Sync + 'data> ParallelIterator for Iter<'data, T> { 796 type Item = &'data T; 797 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,798 fn drive_unindexed<C>(self, consumer: C) -> C::Result 799 where 800 C: UnindexedConsumer<Self::Item>, 801 { 802 bridge(self, consumer) 803 } 804 opt_len(&self) -> Option<usize>805 fn opt_len(&self) -> Option<usize> { 806 Some(self.len()) 807 } 808 } 809 810 impl<'data, T: Sync + 'data> IndexedParallelIterator for Iter<'data, T> { drive<C>(self, consumer: C) -> C::Result where C: Consumer<Self::Item>,811 fn drive<C>(self, consumer: C) -> C::Result 812 where 813 C: Consumer<Self::Item>, 814 { 815 bridge(self, consumer) 816 } 817 len(&self) -> usize818 fn len(&self) -> usize { 819 self.slice.len() 820 } 821 with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,822 fn with_producer<CB>(self, callback: CB) -> CB::Output 823 where 824 CB: ProducerCallback<Self::Item>, 825 { 826 callback.callback(IterProducer { slice: self.slice }) 827 } 828 } 829 830 struct IterProducer<'data, T: Sync> { 831 slice: &'data [T], 832 } 833 834 impl<'data, T: 'data + Sync> Producer for IterProducer<'data, T> { 835 type Item = &'data T; 836 type IntoIter = ::std::slice::Iter<'data, T>; 837 into_iter(self) -> Self::IntoIter838 fn into_iter(self) -> Self::IntoIter { 839 self.slice.iter() 840 } 841 split_at(self, index: usize) -> (Self, Self)842 fn split_at(self, index: usize) -> (Self, Self) { 843 let (left, right) = self.slice.split_at(index); 844 (IterProducer { slice: left }, IterProducer { slice: right }) 845 } 846 } 847 848 /// Parallel iterator over immutable overlapping windows of a slice 849 #[derive(Debug)] 850 pub struct Windows<'data, T: Sync> { 851 window_size: usize, 852 slice: &'data [T], 853 } 854 855 impl<'data, T: Sync> Clone for Windows<'data, T> { clone(&self) -> Self856 fn clone(&self) -> Self { 857 Windows { ..*self } 858 } 859 } 860 861 impl<'data, T: Sync + 'data> ParallelIterator for Windows<'data, T> { 862 type Item = &'data [T]; 863 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,864 fn drive_unindexed<C>(self, consumer: C) -> C::Result 865 where 866 C: UnindexedConsumer<Self::Item>, 867 { 868 bridge(self, consumer) 869 } 870 opt_len(&self) -> Option<usize>871 fn opt_len(&self) -> Option<usize> { 872 Some(self.len()) 873 } 874 } 875 876 impl<'data, T: Sync + 'data> IndexedParallelIterator for Windows<'data, T> { drive<C>(self, consumer: C) -> C::Result where C: Consumer<Self::Item>,877 fn drive<C>(self, consumer: C) -> C::Result 878 where 879 C: Consumer<Self::Item>, 880 { 881 bridge(self, consumer) 882 } 883 len(&self) -> usize884 fn len(&self) -> usize { 885 assert!(self.window_size >= 1); 886 self.slice.len().saturating_sub(self.window_size - 1) 887 } 888 with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,889 fn with_producer<CB>(self, callback: CB) -> CB::Output 890 where 891 CB: ProducerCallback<Self::Item>, 892 { 893 callback.callback(WindowsProducer { 894 window_size: self.window_size, 895 slice: self.slice, 896 }) 897 } 898 } 899 900 struct WindowsProducer<'data, T: Sync> { 901 window_size: usize, 902 slice: &'data [T], 903 } 904 905 impl<'data, T: 'data + Sync> Producer for WindowsProducer<'data, T> { 906 type Item = &'data [T]; 907 type IntoIter = ::std::slice::Windows<'data, T>; 908 into_iter(self) -> Self::IntoIter909 fn into_iter(self) -> Self::IntoIter { 910 self.slice.windows(self.window_size) 911 } 912 split_at(self, index: usize) -> (Self, Self)913 fn split_at(self, index: usize) -> (Self, Self) { 914 let left_index = Ord::min(self.slice.len(), index + (self.window_size - 1)); 915 let left = &self.slice[..left_index]; 916 let right = &self.slice[index..]; 917 ( 918 WindowsProducer { 919 window_size: self.window_size, 920 slice: left, 921 }, 922 WindowsProducer { 923 window_size: self.window_size, 924 slice: right, 925 }, 926 ) 927 } 928 } 929 930 /// Parallel iterator over mutable items in a slice 931 #[derive(Debug)] 932 pub struct IterMut<'data, T: Send> { 933 slice: &'data mut [T], 934 } 935 936 impl<'data, T: Send + 'data> ParallelIterator for IterMut<'data, T> { 937 type Item = &'data mut T; 938 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,939 fn drive_unindexed<C>(self, consumer: C) -> C::Result 940 where 941 C: UnindexedConsumer<Self::Item>, 942 { 943 bridge(self, consumer) 944 } 945 opt_len(&self) -> Option<usize>946 fn opt_len(&self) -> Option<usize> { 947 Some(self.len()) 948 } 949 } 950 951 impl<'data, T: Send + 'data> IndexedParallelIterator for IterMut<'data, T> { drive<C>(self, consumer: C) -> C::Result where C: Consumer<Self::Item>,952 fn drive<C>(self, consumer: C) -> C::Result 953 where 954 C: Consumer<Self::Item>, 955 { 956 bridge(self, consumer) 957 } 958 len(&self) -> usize959 fn len(&self) -> usize { 960 self.slice.len() 961 } 962 with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,963 fn with_producer<CB>(self, callback: CB) -> CB::Output 964 where 965 CB: ProducerCallback<Self::Item>, 966 { 967 callback.callback(IterMutProducer { slice: self.slice }) 968 } 969 } 970 971 struct IterMutProducer<'data, T: Send> { 972 slice: &'data mut [T], 973 } 974 975 impl<'data, T: 'data + Send> Producer for IterMutProducer<'data, T> { 976 type Item = &'data mut T; 977 type IntoIter = ::std::slice::IterMut<'data, T>; 978 into_iter(self) -> Self::IntoIter979 fn into_iter(self) -> Self::IntoIter { 980 self.slice.iter_mut() 981 } 982 split_at(self, index: usize) -> (Self, Self)983 fn split_at(self, index: usize) -> (Self, Self) { 984 let (left, right) = self.slice.split_at_mut(index); 985 ( 986 IterMutProducer { slice: left }, 987 IterMutProducer { slice: right }, 988 ) 989 } 990 } 991 992 /// Parallel iterator over slices separated by a predicate 993 pub struct Split<'data, T, P> { 994 slice: &'data [T], 995 separator: P, 996 } 997 998 impl<'data, T, P: Clone> Clone for Split<'data, T, P> { clone(&self) -> Self999 fn clone(&self) -> Self { 1000 Split { 1001 separator: self.separator.clone(), 1002 ..*self 1003 } 1004 } 1005 } 1006 1007 impl<'data, T: Debug, P> Debug for Split<'data, T, P> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1008 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1009 f.debug_struct("Split").field("slice", &self.slice).finish() 1010 } 1011 } 1012 1013 impl<'data, T, P> ParallelIterator for Split<'data, T, P> 1014 where 1015 P: Fn(&T) -> bool + Sync + Send, 1016 T: Sync, 1017 { 1018 type Item = &'data [T]; 1019 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,1020 fn drive_unindexed<C>(self, consumer: C) -> C::Result 1021 where 1022 C: UnindexedConsumer<Self::Item>, 1023 { 1024 let producer = SplitProducer::new(self.slice, &self.separator); 1025 bridge_unindexed(producer, consumer) 1026 } 1027 } 1028 1029 /// Parallel iterator over slices separated by a predicate, 1030 /// including the matched part as a terminator. 1031 pub struct SplitInclusive<'data, T, P> { 1032 slice: &'data [T], 1033 separator: P, 1034 } 1035 1036 impl<'data, T, P: Clone> Clone for SplitInclusive<'data, T, P> { clone(&self) -> Self1037 fn clone(&self) -> Self { 1038 SplitInclusive { 1039 separator: self.separator.clone(), 1040 ..*self 1041 } 1042 } 1043 } 1044 1045 impl<'data, T: Debug, P> Debug for SplitInclusive<'data, T, P> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1046 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1047 f.debug_struct("SplitInclusive") 1048 .field("slice", &self.slice) 1049 .finish() 1050 } 1051 } 1052 1053 impl<'data, T, P> ParallelIterator for SplitInclusive<'data, T, P> 1054 where 1055 P: Fn(&T) -> bool + Sync + Send, 1056 T: Sync, 1057 { 1058 type Item = &'data [T]; 1059 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,1060 fn drive_unindexed<C>(self, consumer: C) -> C::Result 1061 where 1062 C: UnindexedConsumer<Self::Item>, 1063 { 1064 let producer = SplitInclusiveProducer::new_incl(self.slice, &self.separator); 1065 bridge_unindexed(producer, consumer) 1066 } 1067 } 1068 1069 /// Implement support for `SplitProducer`. 1070 impl<'data, T, P> Fissile<P> for &'data [T] 1071 where 1072 P: Fn(&T) -> bool, 1073 { length(&self) -> usize1074 fn length(&self) -> usize { 1075 self.len() 1076 } 1077 midpoint(&self, end: usize) -> usize1078 fn midpoint(&self, end: usize) -> usize { 1079 end / 2 1080 } 1081 find(&self, separator: &P, start: usize, end: usize) -> Option<usize>1082 fn find(&self, separator: &P, start: usize, end: usize) -> Option<usize> { 1083 self[start..end].iter().position(separator) 1084 } 1085 rfind(&self, separator: &P, end: usize) -> Option<usize>1086 fn rfind(&self, separator: &P, end: usize) -> Option<usize> { 1087 self[..end].iter().rposition(separator) 1088 } 1089 split_once<const INCL: bool>(self, index: usize) -> (Self, Self)1090 fn split_once<const INCL: bool>(self, index: usize) -> (Self, Self) { 1091 if INCL { 1092 // include the separator in the left side 1093 self.split_at(index + 1) 1094 } else { 1095 let (left, right) = self.split_at(index); 1096 (left, &right[1..]) // skip the separator 1097 } 1098 } 1099 fold_splits<F, const INCL: bool>(self, separator: &P, folder: F, skip_last: bool) -> F where F: Folder<Self>, Self: Send,1100 fn fold_splits<F, const INCL: bool>(self, separator: &P, folder: F, skip_last: bool) -> F 1101 where 1102 F: Folder<Self>, 1103 Self: Send, 1104 { 1105 if INCL { 1106 debug_assert!(!skip_last); 1107 folder.consume_iter(self.split_inclusive(separator)) 1108 } else { 1109 let mut split = self.split(separator); 1110 if skip_last { 1111 split.next_back(); 1112 } 1113 folder.consume_iter(split) 1114 } 1115 } 1116 } 1117 1118 /// Parallel iterator over mutable slices separated by a predicate 1119 pub struct SplitMut<'data, T, P> { 1120 slice: &'data mut [T], 1121 separator: P, 1122 } 1123 1124 impl<'data, T: Debug, P> Debug for SplitMut<'data, T, P> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1126 f.debug_struct("SplitMut") 1127 .field("slice", &self.slice) 1128 .finish() 1129 } 1130 } 1131 1132 impl<'data, T, P> ParallelIterator for SplitMut<'data, T, P> 1133 where 1134 P: Fn(&T) -> bool + Sync + Send, 1135 T: Send, 1136 { 1137 type Item = &'data mut [T]; 1138 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,1139 fn drive_unindexed<C>(self, consumer: C) -> C::Result 1140 where 1141 C: UnindexedConsumer<Self::Item>, 1142 { 1143 let producer = SplitProducer::new(self.slice, &self.separator); 1144 bridge_unindexed(producer, consumer) 1145 } 1146 } 1147 1148 /// Parallel iterator over mutable slices separated by a predicate, 1149 /// including the matched part as a terminator. 1150 pub struct SplitInclusiveMut<'data, T, P> { 1151 slice: &'data mut [T], 1152 separator: P, 1153 } 1154 1155 impl<'data, T: Debug, P> Debug for SplitInclusiveMut<'data, T, P> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1157 f.debug_struct("SplitInclusiveMut") 1158 .field("slice", &self.slice) 1159 .finish() 1160 } 1161 } 1162 1163 impl<'data, T, P> ParallelIterator for SplitInclusiveMut<'data, T, P> 1164 where 1165 P: Fn(&T) -> bool + Sync + Send, 1166 T: Send, 1167 { 1168 type Item = &'data mut [T]; 1169 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,1170 fn drive_unindexed<C>(self, consumer: C) -> C::Result 1171 where 1172 C: UnindexedConsumer<Self::Item>, 1173 { 1174 let producer = SplitInclusiveProducer::new_incl(self.slice, &self.separator); 1175 bridge_unindexed(producer, consumer) 1176 } 1177 } 1178 1179 /// Implement support for `SplitProducer`. 1180 impl<'data, T, P> Fissile<P> for &'data mut [T] 1181 where 1182 P: Fn(&T) -> bool, 1183 { length(&self) -> usize1184 fn length(&self) -> usize { 1185 self.len() 1186 } 1187 midpoint(&self, end: usize) -> usize1188 fn midpoint(&self, end: usize) -> usize { 1189 end / 2 1190 } 1191 find(&self, separator: &P, start: usize, end: usize) -> Option<usize>1192 fn find(&self, separator: &P, start: usize, end: usize) -> Option<usize> { 1193 self[start..end].iter().position(separator) 1194 } 1195 rfind(&self, separator: &P, end: usize) -> Option<usize>1196 fn rfind(&self, separator: &P, end: usize) -> Option<usize> { 1197 self[..end].iter().rposition(separator) 1198 } 1199 split_once<const INCL: bool>(self, index: usize) -> (Self, Self)1200 fn split_once<const INCL: bool>(self, index: usize) -> (Self, Self) { 1201 if INCL { 1202 // include the separator in the left side 1203 self.split_at_mut(index + 1) 1204 } else { 1205 let (left, right) = self.split_at_mut(index); 1206 (left, &mut right[1..]) // skip the separator 1207 } 1208 } 1209 fold_splits<F, const INCL: bool>(self, separator: &P, folder: F, skip_last: bool) -> F where F: Folder<Self>, Self: Send,1210 fn fold_splits<F, const INCL: bool>(self, separator: &P, folder: F, skip_last: bool) -> F 1211 where 1212 F: Folder<Self>, 1213 Self: Send, 1214 { 1215 if INCL { 1216 debug_assert!(!skip_last); 1217 folder.consume_iter(self.split_inclusive_mut(separator)) 1218 } else { 1219 let mut split = self.split_mut(separator); 1220 if skip_last { 1221 split.next_back(); 1222 } 1223 folder.consume_iter(split) 1224 } 1225 } 1226 } 1227