core/slice/mod.rs
1//! Slice management and manipulation.
2//!
3//! For more details see [`std::slice`].
4//!
5//! [`std::slice`]: ../../std/slice/index.html
6
7#![stable(feature = "rust1", since = "1.0.0")]
8
9#[cfg(not(feature = "ferrocene_subset"))]
10use crate::clone::TrivialClone;
11use crate::cmp::Ordering::{self, Equal, Greater, Less};
12use crate::intrinsics::{exact_div, unchecked_sub};
13use crate::marker::Destruct;
14#[cfg(not(feature = "ferrocene_subset"))]
15use crate::mem::{self, MaybeUninit, SizedTypeProperties};
16use crate::num::NonZero;
17#[cfg(not(feature = "ferrocene_subset"))]
18use crate::ops::{OneSidedRange, OneSidedRangeBound, Range, RangeBounds, RangeInclusive};
19use crate::panic::const_panic;
20#[cfg(not(feature = "ferrocene_subset"))]
21use crate::simd::{self, Simd};
22use crate::ub_checks::assert_unsafe_precondition;
23#[cfg(not(feature = "ferrocene_subset"))]
24use crate::{fmt, hint, ptr, range, slice};
25
26// Ferrocene addition: imports for certified subset
27#[cfg(feature = "ferrocene_subset")]
28#[rustfmt::skip]
29use crate::{hint, mem::SizedTypeProperties, ptr};
30
31#[unstable(
32 feature = "slice_internals",
33 issue = "none",
34 reason = "exposed from core to be reused in std; use the memchr crate"
35)]
36#[doc(hidden)]
37/// Pure Rust memchr implementation, taken from rust-memchr
38pub mod memchr;
39
40#[unstable(
41 feature = "slice_internals",
42 issue = "none",
43 reason = "exposed from core to be reused in std;"
44)]
45#[doc(hidden)]
46#[cfg(not(feature = "ferrocene_subset"))]
47pub mod sort;
48
49mod ascii;
50mod cmp;
51pub(crate) mod index;
52mod iter;
53mod raw;
54mod rotate;
55mod specialize;
56
57/// Ferrocene addition: Hidden module to test crate-internal functionality
58#[doc(hidden)]
59#[unstable(feature = "ferrocene_test", issue = "none")]
60#[cfg(not(feature = "ferrocene_subset"))]
61pub mod ferrocene_test;
62
63#[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
64#[cfg(not(feature = "ferrocene_subset"))]
65pub use ascii::EscapeAscii;
66#[unstable(feature = "str_internals", issue = "none")]
67#[doc(hidden)]
68pub use ascii::is_ascii_simple;
69#[stable(feature = "slice_get_slice", since = "1.28.0")]
70pub use index::SliceIndex;
71#[unstable(feature = "slice_range", issue = "76393")]
72#[cfg(not(feature = "ferrocene_subset"))]
73pub use index::{range, try_range};
74#[cfg(not(feature = "ferrocene_subset"))]
75#[stable(feature = "array_windows", since = "1.94.0")]
76pub use iter::ArrayWindows;
77#[stable(feature = "slice_group_by", since = "1.77.0")]
78#[cfg(not(feature = "ferrocene_subset"))]
79pub use iter::{ChunkBy, ChunkByMut};
80#[stable(feature = "rust1", since = "1.0.0")]
81#[cfg(not(feature = "ferrocene_subset"))]
82pub use iter::{Chunks, ChunksMut, Windows};
83#[stable(feature = "chunks_exact", since = "1.31.0")]
84pub use iter::{ChunksExact, ChunksExactMut};
85#[stable(feature = "rust1", since = "1.0.0")]
86pub use iter::{Iter, IterMut};
87#[stable(feature = "rchunks", since = "1.31.0")]
88#[cfg(not(feature = "ferrocene_subset"))]
89pub use iter::{RChunks, RChunksExact, RChunksExactMut, RChunksMut};
90#[stable(feature = "slice_rsplit", since = "1.27.0")]
91#[cfg(not(feature = "ferrocene_subset"))]
92pub use iter::{RSplit, RSplitMut};
93#[stable(feature = "rust1", since = "1.0.0")]
94#[cfg(not(feature = "ferrocene_subset"))]
95pub use iter::{RSplitN, RSplitNMut, Split, SplitMut, SplitN, SplitNMut};
96#[stable(feature = "split_inclusive", since = "1.51.0")]
97#[cfg(not(feature = "ferrocene_subset"))]
98pub use iter::{SplitInclusive, SplitInclusiveMut};
99#[stable(feature = "from_ref", since = "1.28.0")]
100pub use raw::{from_mut, from_ref};
101#[unstable(feature = "slice_from_ptr_range", issue = "89792")]
102#[cfg(not(feature = "ferrocene_subset"))]
103pub use raw::{from_mut_ptr_range, from_ptr_range};
104#[stable(feature = "rust1", since = "1.0.0")]
105pub use raw::{from_raw_parts, from_raw_parts_mut};
106
107// Ferrocene addition: imports for certified subset
108#[stable(feature = "rust1", since = "1.0.0")]
109#[cfg(feature = "ferrocene_subset")]
110#[rustfmt::skip]
111pub use iter::{Chunks, ChunksMut, Windows};
112
113/// Calculates the direction and split point of a one-sided range.
114///
115/// This is a helper function for `split_off` and `split_off_mut` that returns
116/// the direction of the split (front or back) as well as the index at
117/// which to split. Returns `None` if the split index would overflow.
118#[inline]
119#[cfg(not(feature = "ferrocene_subset"))]
120fn split_point_of(range: impl OneSidedRange<usize>) -> Option<(Direction, usize)> {
121 use OneSidedRangeBound::{End, EndInclusive, StartInclusive};
122
123 Some(match range.bound() {
124 (StartInclusive, i) => (Direction::Back, i),
125 (End, i) => (Direction::Front, i),
126 (EndInclusive, i) => (Direction::Front, i.checked_add(1)?),
127 })
128}
129
130#[cfg(not(feature = "ferrocene_subset"))]
131enum Direction {
132 Front,
133 Back,
134}
135
136impl<T> [T] {
137 /// Returns the number of elements in the slice.
138 ///
139 /// # Examples
140 ///
141 /// ```
142 /// let a = [1, 2, 3];
143 /// assert_eq!(a.len(), 3);
144 /// ```
145 #[lang = "slice_len_fn"]
146 #[stable(feature = "rust1", since = "1.0.0")]
147 #[rustc_const_stable(feature = "const_slice_len", since = "1.39.0")]
148 #[rustc_no_implicit_autorefs]
149 #[inline]
150 #[must_use]
151 #[ferrocene::annotation(
152 "this function is guaranteed to be constant-evaluated as the size of arrays is always available at compilation"
153 )]
154 pub const fn len(&self) -> usize {
155 ptr::metadata(self)
156 }
157
158 /// Returns `true` if the slice has a length of 0.
159 ///
160 /// # Examples
161 ///
162 /// ```
163 /// let a = [1, 2, 3];
164 /// assert!(!a.is_empty());
165 ///
166 /// let b: &[i32] = &[];
167 /// assert!(b.is_empty());
168 /// ```
169 #[stable(feature = "rust1", since = "1.0.0")]
170 #[rustc_const_stable(feature = "const_slice_is_empty", since = "1.39.0")]
171 #[rustc_no_implicit_autorefs]
172 #[inline]
173 #[must_use]
174 pub const fn is_empty(&self) -> bool {
175 self.len() == 0
176 }
177
178 /// Returns the first element of the slice, or `None` if it is empty.
179 ///
180 /// # Examples
181 ///
182 /// ```
183 /// let v = [10, 40, 30];
184 /// assert_eq!(Some(&10), v.first());
185 ///
186 /// let w: &[i32] = &[];
187 /// assert_eq!(None, w.first());
188 /// ```
189 #[stable(feature = "rust1", since = "1.0.0")]
190 #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")]
191 #[inline]
192 #[must_use]
193 pub const fn first(&self) -> Option<&T> {
194 if let [first, ..] = self { Some(first) } else { None }
195 }
196
197 /// Returns a mutable reference to the first element of the slice, or `None` if it is empty.
198 ///
199 /// # Examples
200 ///
201 /// ```
202 /// let x = &mut [0, 1, 2];
203 ///
204 /// if let Some(first) = x.first_mut() {
205 /// *first = 5;
206 /// }
207 /// assert_eq!(x, &[5, 1, 2]);
208 ///
209 /// let y: &mut [i32] = &mut [];
210 /// assert_eq!(None, y.first_mut());
211 /// ```
212 #[stable(feature = "rust1", since = "1.0.0")]
213 #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")]
214 #[inline]
215 #[must_use]
216 pub const fn first_mut(&mut self) -> Option<&mut T> {
217 if let [first, ..] = self { Some(first) } else { None }
218 }
219
220 /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
221 ///
222 /// # Examples
223 ///
224 /// ```
225 /// let x = &[0, 1, 2];
226 ///
227 /// if let Some((first, elements)) = x.split_first() {
228 /// assert_eq!(first, &0);
229 /// assert_eq!(elements, &[1, 2]);
230 /// }
231 /// ```
232 #[stable(feature = "slice_splits", since = "1.5.0")]
233 #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")]
234 #[inline]
235 #[must_use]
236 pub const fn split_first(&self) -> Option<(&T, &[T])> {
237 if let [first, tail @ ..] = self { Some((first, tail)) } else { None }
238 }
239
240 /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
241 ///
242 /// # Examples
243 ///
244 /// ```
245 /// let x = &mut [0, 1, 2];
246 ///
247 /// if let Some((first, elements)) = x.split_first_mut() {
248 /// *first = 3;
249 /// elements[0] = 4;
250 /// elements[1] = 5;
251 /// }
252 /// assert_eq!(x, &[3, 4, 5]);
253 /// ```
254 #[stable(feature = "slice_splits", since = "1.5.0")]
255 #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")]
256 #[inline]
257 #[must_use]
258 pub const fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
259 if let [first, tail @ ..] = self { Some((first, tail)) } else { None }
260 }
261
262 /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
263 ///
264 /// # Examples
265 ///
266 /// ```
267 /// let x = &[0, 1, 2];
268 ///
269 /// if let Some((last, elements)) = x.split_last() {
270 /// assert_eq!(last, &2);
271 /// assert_eq!(elements, &[0, 1]);
272 /// }
273 /// ```
274 #[stable(feature = "slice_splits", since = "1.5.0")]
275 #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")]
276 #[inline]
277 #[must_use]
278 pub const fn split_last(&self) -> Option<(&T, &[T])> {
279 if let [init @ .., last] = self { Some((last, init)) } else { None }
280 }
281
282 /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
283 ///
284 /// # Examples
285 ///
286 /// ```
287 /// let x = &mut [0, 1, 2];
288 ///
289 /// if let Some((last, elements)) = x.split_last_mut() {
290 /// *last = 3;
291 /// elements[0] = 4;
292 /// elements[1] = 5;
293 /// }
294 /// assert_eq!(x, &[4, 5, 3]);
295 /// ```
296 #[stable(feature = "slice_splits", since = "1.5.0")]
297 #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")]
298 #[inline]
299 #[must_use]
300 pub const fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
301 if let [init @ .., last] = self { Some((last, init)) } else { None }
302 }
303
304 /// Returns the last element of the slice, or `None` if it is empty.
305 ///
306 /// # Examples
307 ///
308 /// ```
309 /// let v = [10, 40, 30];
310 /// assert_eq!(Some(&30), v.last());
311 ///
312 /// let w: &[i32] = &[];
313 /// assert_eq!(None, w.last());
314 /// ```
315 #[stable(feature = "rust1", since = "1.0.0")]
316 #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")]
317 #[inline]
318 #[must_use]
319 pub const fn last(&self) -> Option<&T> {
320 if let [.., last] = self { Some(last) } else { None }
321 }
322
323 /// Returns a mutable reference to the last item in the slice, or `None` if it is empty.
324 ///
325 /// # Examples
326 ///
327 /// ```
328 /// let x = &mut [0, 1, 2];
329 ///
330 /// if let Some(last) = x.last_mut() {
331 /// *last = 10;
332 /// }
333 /// assert_eq!(x, &[0, 1, 10]);
334 ///
335 /// let y: &mut [i32] = &mut [];
336 /// assert_eq!(None, y.last_mut());
337 /// ```
338 #[stable(feature = "rust1", since = "1.0.0")]
339 #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")]
340 #[inline]
341 #[must_use]
342 pub const fn last_mut(&mut self) -> Option<&mut T> {
343 if let [.., last] = self { Some(last) } else { None }
344 }
345
346 /// Returns an array reference to the first `N` items in the slice.
347 ///
348 /// If the slice is not at least `N` in length, this will return `None`.
349 ///
350 /// # Examples
351 ///
352 /// ```
353 /// let u = [10, 40, 30];
354 /// assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
355 ///
356 /// let v: &[i32] = &[10];
357 /// assert_eq!(None, v.first_chunk::<2>());
358 ///
359 /// let w: &[i32] = &[];
360 /// assert_eq!(Some(&[]), w.first_chunk::<0>());
361 /// ```
362 #[inline]
363 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
364 #[rustc_const_stable(feature = "slice_first_last_chunk", since = "1.77.0")]
365 pub const fn first_chunk<const N: usize>(&self) -> Option<&[T; N]> {
366 if self.len() < N {
367 None
368 } else {
369 // SAFETY: We explicitly check for the correct number of elements,
370 // and do not let the reference outlive the slice.
371 Some(unsafe { &*(self.as_ptr().cast_array()) })
372 }
373 }
374
375 /// Returns a mutable array reference to the first `N` items in the slice.
376 ///
377 /// If the slice is not at least `N` in length, this will return `None`.
378 ///
379 /// # Examples
380 ///
381 /// ```
382 /// let x = &mut [0, 1, 2];
383 ///
384 /// if let Some(first) = x.first_chunk_mut::<2>() {
385 /// first[0] = 5;
386 /// first[1] = 4;
387 /// }
388 /// assert_eq!(x, &[5, 4, 2]);
389 ///
390 /// assert_eq!(None, x.first_chunk_mut::<4>());
391 /// ```
392 #[inline]
393 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
394 #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")]
395 pub const fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]> {
396 if self.len() < N {
397 None
398 } else {
399 // SAFETY: We explicitly check for the correct number of elements,
400 // do not let the reference outlive the slice,
401 // and require exclusive access to the entire slice to mutate the chunk.
402 Some(unsafe { &mut *(self.as_mut_ptr().cast_array()) })
403 }
404 }
405
406 /// Returns an array reference to the first `N` items in the slice and the remaining slice.
407 ///
408 /// If the slice is not at least `N` in length, this will return `None`.
409 ///
410 /// # Examples
411 ///
412 /// ```
413 /// let x = &[0, 1, 2];
414 ///
415 /// if let Some((first, elements)) = x.split_first_chunk::<2>() {
416 /// assert_eq!(first, &[0, 1]);
417 /// assert_eq!(elements, &[2]);
418 /// }
419 ///
420 /// assert_eq!(None, x.split_first_chunk::<4>());
421 /// ```
422 #[inline]
423 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
424 #[rustc_const_stable(feature = "slice_first_last_chunk", since = "1.77.0")]
425 #[cfg(not(feature = "ferrocene_subset"))]
426 pub const fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])> {
427 let Some((first, tail)) = self.split_at_checked(N) else { return None };
428
429 // SAFETY: We explicitly check for the correct number of elements,
430 // and do not let the references outlive the slice.
431 Some((unsafe { &*(first.as_ptr().cast_array()) }, tail))
432 }
433
434 /// Returns a mutable array reference to the first `N` items in the slice and the remaining
435 /// slice.
436 ///
437 /// If the slice is not at least `N` in length, this will return `None`.
438 ///
439 /// # Examples
440 ///
441 /// ```
442 /// let x = &mut [0, 1, 2];
443 ///
444 /// if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
445 /// first[0] = 3;
446 /// first[1] = 4;
447 /// elements[0] = 5;
448 /// }
449 /// assert_eq!(x, &[3, 4, 5]);
450 ///
451 /// assert_eq!(None, x.split_first_chunk_mut::<4>());
452 /// ```
453 #[inline]
454 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
455 #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")]
456 #[cfg(not(feature = "ferrocene_subset"))]
457 pub const fn split_first_chunk_mut<const N: usize>(
458 &mut self,
459 ) -> Option<(&mut [T; N], &mut [T])> {
460 let Some((first, tail)) = self.split_at_mut_checked(N) else { return None };
461
462 // SAFETY: We explicitly check for the correct number of elements,
463 // do not let the reference outlive the slice,
464 // and enforce exclusive mutability of the chunk by the split.
465 Some((unsafe { &mut *(first.as_mut_ptr().cast_array()) }, tail))
466 }
467
468 /// Returns an array reference to the last `N` items in the slice and the remaining slice.
469 ///
470 /// If the slice is not at least `N` in length, this will return `None`.
471 ///
472 /// # Examples
473 ///
474 /// ```
475 /// let x = &[0, 1, 2];
476 ///
477 /// if let Some((elements, last)) = x.split_last_chunk::<2>() {
478 /// assert_eq!(elements, &[0]);
479 /// assert_eq!(last, &[1, 2]);
480 /// }
481 ///
482 /// assert_eq!(None, x.split_last_chunk::<4>());
483 /// ```
484 #[inline]
485 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
486 #[rustc_const_stable(feature = "slice_first_last_chunk", since = "1.77.0")]
487 #[cfg(not(feature = "ferrocene_subset"))]
488 pub const fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])> {
489 let Some(index) = self.len().checked_sub(N) else { return None };
490 let (init, last) = self.split_at(index);
491
492 // SAFETY: We explicitly check for the correct number of elements,
493 // and do not let the references outlive the slice.
494 Some((init, unsafe { &*(last.as_ptr().cast_array()) }))
495 }
496
497 /// Returns a mutable array reference to the last `N` items in the slice and the remaining
498 /// slice.
499 ///
500 /// If the slice is not at least `N` in length, this will return `None`.
501 ///
502 /// # Examples
503 ///
504 /// ```
505 /// let x = &mut [0, 1, 2];
506 ///
507 /// if let Some((elements, last)) = x.split_last_chunk_mut::<2>() {
508 /// last[0] = 3;
509 /// last[1] = 4;
510 /// elements[0] = 5;
511 /// }
512 /// assert_eq!(x, &[5, 3, 4]);
513 ///
514 /// assert_eq!(None, x.split_last_chunk_mut::<4>());
515 /// ```
516 #[inline]
517 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
518 #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")]
519 #[cfg(not(feature = "ferrocene_subset"))]
520 pub const fn split_last_chunk_mut<const N: usize>(
521 &mut self,
522 ) -> Option<(&mut [T], &mut [T; N])> {
523 let Some(index) = self.len().checked_sub(N) else { return None };
524 let (init, last) = self.split_at_mut(index);
525
526 // SAFETY: We explicitly check for the correct number of elements,
527 // do not let the reference outlive the slice,
528 // and enforce exclusive mutability of the chunk by the split.
529 Some((init, unsafe { &mut *(last.as_mut_ptr().cast_array()) }))
530 }
531
532 /// Returns an array reference to the last `N` items in the slice.
533 ///
534 /// If the slice is not at least `N` in length, this will return `None`.
535 ///
536 /// # Examples
537 ///
538 /// ```
539 /// let u = [10, 40, 30];
540 /// assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
541 ///
542 /// let v: &[i32] = &[10];
543 /// assert_eq!(None, v.last_chunk::<2>());
544 ///
545 /// let w: &[i32] = &[];
546 /// assert_eq!(Some(&[]), w.last_chunk::<0>());
547 /// ```
548 #[inline]
549 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
550 #[rustc_const_stable(feature = "const_slice_last_chunk", since = "1.80.0")]
551 #[cfg(not(feature = "ferrocene_subset"))]
552 pub const fn last_chunk<const N: usize>(&self) -> Option<&[T; N]> {
553 // FIXME(const-hack): Without const traits, we need this instead of `get`.
554 let Some(index) = self.len().checked_sub(N) else { return None };
555 let (_, last) = self.split_at(index);
556
557 // SAFETY: We explicitly check for the correct number of elements,
558 // and do not let the references outlive the slice.
559 Some(unsafe { &*(last.as_ptr().cast_array()) })
560 }
561
562 /// Returns a mutable array reference to the last `N` items in the slice.
563 ///
564 /// If the slice is not at least `N` in length, this will return `None`.
565 ///
566 /// # Examples
567 ///
568 /// ```
569 /// let x = &mut [0, 1, 2];
570 ///
571 /// if let Some(last) = x.last_chunk_mut::<2>() {
572 /// last[0] = 10;
573 /// last[1] = 20;
574 /// }
575 /// assert_eq!(x, &[0, 10, 20]);
576 ///
577 /// assert_eq!(None, x.last_chunk_mut::<4>());
578 /// ```
579 #[inline]
580 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
581 #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")]
582 #[cfg(not(feature = "ferrocene_subset"))]
583 pub const fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]> {
584 // FIXME(const-hack): Without const traits, we need this instead of `get`.
585 let Some(index) = self.len().checked_sub(N) else { return None };
586 let (_, last) = self.split_at_mut(index);
587
588 // SAFETY: We explicitly check for the correct number of elements,
589 // do not let the reference outlive the slice,
590 // and require exclusive access to the entire slice to mutate the chunk.
591 Some(unsafe { &mut *(last.as_mut_ptr().cast_array()) })
592 }
593
594 /// Returns a reference to an element or subslice depending on the type of
595 /// index.
596 ///
597 /// - If given a position, returns a reference to the element at that
598 /// position or `None` if out of bounds.
599 /// - If given a range, returns the subslice corresponding to that range,
600 /// or `None` if out of bounds.
601 ///
602 /// # Examples
603 ///
604 /// ```
605 /// let v = [10, 40, 30];
606 /// assert_eq!(Some(&40), v.get(1));
607 /// assert_eq!(Some(&[10, 40][..]), v.get(0..2));
608 /// assert_eq!(None, v.get(3));
609 /// assert_eq!(None, v.get(0..4));
610 /// ```
611 #[stable(feature = "rust1", since = "1.0.0")]
612 #[rustc_no_implicit_autorefs]
613 #[inline]
614 #[must_use]
615 #[rustc_const_unstable(feature = "const_index", issue = "143775")]
616 pub const fn get<I>(&self, index: I) -> Option<&I::Output>
617 where
618 I: [const] SliceIndex<Self>,
619 {
620 index.get(self)
621 }
622
623 /// Returns a mutable reference to an element or subslice depending on the
624 /// type of index (see [`get`]) or `None` if the index is out of bounds.
625 ///
626 /// [`get`]: slice::get
627 ///
628 /// # Examples
629 ///
630 /// ```
631 /// let x = &mut [0, 1, 2];
632 ///
633 /// if let Some(elem) = x.get_mut(1) {
634 /// *elem = 42;
635 /// }
636 /// assert_eq!(x, &[0, 42, 2]);
637 /// ```
638 #[stable(feature = "rust1", since = "1.0.0")]
639 #[rustc_no_implicit_autorefs]
640 #[inline]
641 #[must_use]
642 #[rustc_const_unstable(feature = "const_index", issue = "143775")]
643 pub const fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
644 where
645 I: [const] SliceIndex<Self>,
646 {
647 index.get_mut(self)
648 }
649
650 /// Returns a reference to an element or subslice, without doing bounds
651 /// checking.
652 ///
653 /// For a safe alternative see [`get`].
654 ///
655 /// # Safety
656 ///
657 /// Calling this method with an out-of-bounds index is *[undefined behavior]*
658 /// even if the resulting reference is not used.
659 ///
660 /// You can think of this like `.get(index).unwrap_unchecked()`. It's UB
661 /// to call `.get_unchecked(len)`, even if you immediately convert to a
662 /// pointer. And it's UB to call `.get_unchecked(..len + 1)`,
663 /// `.get_unchecked(..=len)`, or similar.
664 ///
665 /// [`get`]: slice::get
666 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
667 ///
668 /// # Examples
669 ///
670 /// ```
671 /// let x = &[1, 2, 4];
672 ///
673 /// unsafe {
674 /// assert_eq!(x.get_unchecked(1), &2);
675 /// }
676 /// ```
677 #[stable(feature = "rust1", since = "1.0.0")]
678 #[rustc_no_implicit_autorefs]
679 #[inline]
680 #[must_use]
681 #[track_caller]
682 #[rustc_const_unstable(feature = "const_index", issue = "143775")]
683 pub const unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
684 where
685 I: [const] SliceIndex<Self>,
686 {
687 // SAFETY: the caller must uphold most of the safety requirements for `get_unchecked`;
688 // the slice is dereferenceable because `self` is a safe reference.
689 // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
690 unsafe { &*index.get_unchecked(self) }
691 }
692
693 /// Returns a mutable reference to an element or subslice, without doing
694 /// bounds checking.
695 ///
696 /// For a safe alternative see [`get_mut`].
697 ///
698 /// # Safety
699 ///
700 /// Calling this method with an out-of-bounds index is *[undefined behavior]*
701 /// even if the resulting reference is not used.
702 ///
703 /// You can think of this like `.get_mut(index).unwrap_unchecked()`. It's
704 /// UB to call `.get_unchecked_mut(len)`, even if you immediately convert
705 /// to a pointer. And it's UB to call `.get_unchecked_mut(..len + 1)`,
706 /// `.get_unchecked_mut(..=len)`, or similar.
707 ///
708 /// [`get_mut`]: slice::get_mut
709 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
710 ///
711 /// # Examples
712 ///
713 /// ```
714 /// let x = &mut [1, 2, 4];
715 ///
716 /// unsafe {
717 /// let elem = x.get_unchecked_mut(1);
718 /// *elem = 13;
719 /// }
720 /// assert_eq!(x, &[1, 13, 4]);
721 /// ```
722 #[stable(feature = "rust1", since = "1.0.0")]
723 #[rustc_no_implicit_autorefs]
724 #[inline]
725 #[must_use]
726 #[track_caller]
727 #[rustc_const_unstable(feature = "const_index", issue = "143775")]
728 pub const unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
729 where
730 I: [const] SliceIndex<Self>,
731 {
732 // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`;
733 // the slice is dereferenceable because `self` is a safe reference.
734 // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
735 unsafe { &mut *index.get_unchecked_mut(self) }
736 }
737
738 /// Returns a raw pointer to the slice's buffer.
739 ///
740 /// The caller must ensure that the slice outlives the pointer this
741 /// function returns, or else it will end up dangling.
742 ///
743 /// The caller must also ensure that the memory the pointer (non-transitively) points to
744 /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
745 /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
746 ///
747 /// Modifying the container referenced by this slice may cause its buffer
748 /// to be reallocated, which would also make any pointers to it invalid.
749 ///
750 /// # Examples
751 ///
752 /// ```
753 /// let x = &[1, 2, 4];
754 /// let x_ptr = x.as_ptr();
755 ///
756 /// unsafe {
757 /// for i in 0..x.len() {
758 /// assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
759 /// }
760 /// }
761 /// ```
762 ///
763 /// [`as_mut_ptr`]: slice::as_mut_ptr
764 #[stable(feature = "rust1", since = "1.0.0")]
765 #[rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0")]
766 #[rustc_never_returns_null_ptr]
767 #[rustc_as_ptr]
768 #[inline(always)]
769 #[must_use]
770 pub const fn as_ptr(&self) -> *const T {
771 self as *const [T] as *const T
772 }
773
774 /// Returns an unsafe mutable pointer to the slice's buffer.
775 ///
776 /// The caller must ensure that the slice outlives the pointer this
777 /// function returns, or else it will end up dangling.
778 ///
779 /// Modifying the container referenced by this slice may cause its buffer
780 /// to be reallocated, which would also make any pointers to it invalid.
781 ///
782 /// # Examples
783 ///
784 /// ```
785 /// let x = &mut [1, 2, 4];
786 /// let x_ptr = x.as_mut_ptr();
787 ///
788 /// unsafe {
789 /// for i in 0..x.len() {
790 /// *x_ptr.add(i) += 2;
791 /// }
792 /// }
793 /// assert_eq!(x, &[3, 4, 6]);
794 /// ```
795 #[stable(feature = "rust1", since = "1.0.0")]
796 #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
797 #[rustc_never_returns_null_ptr]
798 #[rustc_as_ptr]
799 #[inline(always)]
800 #[must_use]
801 pub const fn as_mut_ptr(&mut self) -> *mut T {
802 self as *mut [T] as *mut T
803 }
804
805 /// Returns the two raw pointers spanning the slice.
806 ///
807 /// The returned range is half-open, which means that the end pointer
808 /// points *one past* the last element of the slice. This way, an empty
809 /// slice is represented by two equal pointers, and the difference between
810 /// the two pointers represents the size of the slice.
811 ///
812 /// See [`as_ptr`] for warnings on using these pointers. The end pointer
813 /// requires extra caution, as it does not point to a valid element in the
814 /// slice.
815 ///
816 /// This function is useful for interacting with foreign interfaces which
817 /// use two pointers to refer to a range of elements in memory, as is
818 /// common in C++.
819 ///
820 /// It can also be useful to check if a pointer to an element refers to an
821 /// element of this slice:
822 ///
823 /// ```
824 /// let a = [1, 2, 3];
825 /// let x = &a[1] as *const _;
826 /// let y = &5 as *const _;
827 ///
828 /// assert!(a.as_ptr_range().contains(&x));
829 /// assert!(!a.as_ptr_range().contains(&y));
830 /// ```
831 ///
832 /// [`as_ptr`]: slice::as_ptr
833 #[stable(feature = "slice_ptr_range", since = "1.48.0")]
834 #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
835 #[inline]
836 #[must_use]
837 #[cfg(not(feature = "ferrocene_subset"))]
838 pub const fn as_ptr_range(&self) -> Range<*const T> {
839 let start = self.as_ptr();
840 // SAFETY: The `add` here is safe, because:
841 //
842 // - Both pointers are part of the same object, as pointing directly
843 // past the object also counts.
844 //
845 // - The size of the slice is never larger than `isize::MAX` bytes, as
846 // noted here:
847 // - https://github.com/rust-lang/unsafe-code-guidelines/issues/102#issuecomment-473340447
848 // - https://doc.rust-lang.org/reference/behavior-considered-undefined.html
849 // - https://doc.rust-lang.org/core/slice/fn.from_raw_parts.html#safety
850 // (This doesn't seem normative yet, but the very same assumption is
851 // made in many places, including the Index implementation of slices.)
852 //
853 // - There is no wrapping around involved, as slices do not wrap past
854 // the end of the address space.
855 //
856 // See the documentation of [`pointer::add`].
857 let end = unsafe { start.add(self.len()) };
858 start..end
859 }
860
861 /// Returns the two unsafe mutable pointers spanning the slice.
862 ///
863 /// The returned range is half-open, which means that the end pointer
864 /// points *one past* the last element of the slice. This way, an empty
865 /// slice is represented by two equal pointers, and the difference between
866 /// the two pointers represents the size of the slice.
867 ///
868 /// See [`as_mut_ptr`] for warnings on using these pointers. The end
869 /// pointer requires extra caution, as it does not point to a valid element
870 /// in the slice.
871 ///
872 /// This function is useful for interacting with foreign interfaces which
873 /// use two pointers to refer to a range of elements in memory, as is
874 /// common in C++.
875 ///
876 /// [`as_mut_ptr`]: slice::as_mut_ptr
877 #[stable(feature = "slice_ptr_range", since = "1.48.0")]
878 #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
879 #[inline]
880 #[must_use]
881 #[cfg(not(feature = "ferrocene_subset"))]
882 pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> {
883 let start = self.as_mut_ptr();
884 // SAFETY: See as_ptr_range() above for why `add` here is safe.
885 let end = unsafe { start.add(self.len()) };
886 start..end
887 }
888
889 /// Gets a reference to the underlying array.
890 ///
891 /// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
892 #[stable(feature = "core_slice_as_array", since = "1.93.0")]
893 #[rustc_const_stable(feature = "core_slice_as_array", since = "1.93.0")]
894 #[inline]
895 #[must_use]
896 pub const fn as_array<const N: usize>(&self) -> Option<&[T; N]> {
897 if self.len() == N {
898 let ptr = self.as_ptr().cast_array();
899
900 // SAFETY: The underlying array of a slice can be reinterpreted as an actual array `[T; N]` if `N` is not greater than the slice's length.
901 let me = unsafe { &*ptr };
902 Some(me)
903 } else {
904 None
905 }
906 }
907
908 /// Gets a mutable reference to the slice's underlying array.
909 ///
910 /// If `N` is not exactly equal to the length of `self`, then this method returns `None`.
911 #[stable(feature = "core_slice_as_array", since = "1.93.0")]
912 #[rustc_const_stable(feature = "core_slice_as_array", since = "1.93.0")]
913 #[inline]
914 #[must_use]
915 pub const fn as_mut_array<const N: usize>(&mut self) -> Option<&mut [T; N]> {
916 if self.len() == N {
917 let ptr = self.as_mut_ptr().cast_array();
918
919 // SAFETY: The underlying array of a slice can be reinterpreted as an actual array `[T; N]` if `N` is not greater than the slice's length.
920 let me = unsafe { &mut *ptr };
921 Some(me)
922 } else {
923 None
924 }
925 }
926
927 /// Swaps two elements in the slice.
928 ///
929 /// If `a` equals to `b`, it's guaranteed that elements won't change value.
930 ///
931 /// # Arguments
932 ///
933 /// * a - The index of the first element
934 /// * b - The index of the second element
935 ///
936 /// # Panics
937 ///
938 /// Panics if `a` or `b` are out of bounds.
939 ///
940 /// # Examples
941 ///
942 /// ```
943 /// let mut v = ["a", "b", "c", "d", "e"];
944 /// v.swap(2, 4);
945 /// assert!(v == ["a", "b", "e", "d", "c"]);
946 /// ```
947 #[stable(feature = "rust1", since = "1.0.0")]
948 #[rustc_const_stable(feature = "const_swap", since = "1.85.0")]
949 #[inline]
950 #[track_caller]
951 pub const fn swap(&mut self, a: usize, b: usize) {
952 // FIXME: use swap_unchecked here (https://github.com/rust-lang/rust/pull/88540#issuecomment-944344343)
953 // Can't take two mutable loans from one vector, so instead use raw pointers.
954 let pa = &raw mut self[a];
955 let pb = &raw mut self[b];
956 // SAFETY: `pa` and `pb` have been created from safe mutable references and refer
957 // to elements in the slice and therefore are guaranteed to be valid and aligned.
958 // Note that accessing the elements behind `a` and `b` is checked and will
959 // panic when out of bounds.
960 unsafe {
961 ptr::swap(pa, pb);
962 }
963 }
964
965 /// Swaps two elements in the slice, without doing bounds checking.
966 ///
967 /// For a safe alternative see [`swap`].
968 ///
969 /// # Arguments
970 ///
971 /// * a - The index of the first element
972 /// * b - The index of the second element
973 ///
974 /// # Safety
975 ///
976 /// Calling this method with an out-of-bounds index is *[undefined behavior]*.
977 /// The caller has to ensure that `a < self.len()` and `b < self.len()`.
978 ///
979 /// # Examples
980 ///
981 /// ```
982 /// #![feature(slice_swap_unchecked)]
983 ///
984 /// let mut v = ["a", "b", "c", "d"];
985 /// // SAFETY: we know that 1 and 3 are both indices of the slice
986 /// unsafe { v.swap_unchecked(1, 3) };
987 /// assert!(v == ["a", "d", "c", "b"]);
988 /// ```
989 ///
990 /// [`swap`]: slice::swap
991 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
992 #[unstable(feature = "slice_swap_unchecked", issue = "88539")]
993 #[track_caller]
994 #[cfg(not(feature = "ferrocene_subset"))]
995 pub const unsafe fn swap_unchecked(&mut self, a: usize, b: usize) {
996 assert_unsafe_precondition!(
997 check_library_ub,
998 "slice::swap_unchecked requires that the indices are within the slice",
999 (
1000 len: usize = self.len(),
1001 a: usize = a,
1002 b: usize = b,
1003 ) => a < len && b < len,
1004 );
1005
1006 let ptr = self.as_mut_ptr();
1007 // SAFETY: caller has to guarantee that `a < self.len()` and `b < self.len()`
1008 unsafe {
1009 ptr::swap(ptr.add(a), ptr.add(b));
1010 }
1011 }
1012
1013 /// Reverses the order of elements in the slice, in place.
1014 ///
1015 /// # Examples
1016 ///
1017 /// ```
1018 /// let mut v = [1, 2, 3];
1019 /// v.reverse();
1020 /// assert!(v == [3, 2, 1]);
1021 /// ```
1022 #[stable(feature = "rust1", since = "1.0.0")]
1023 #[rustc_const_stable(feature = "const_slice_reverse", since = "1.90.0")]
1024 #[inline]
1025 #[cfg(not(feature = "ferrocene_subset"))]
1026 pub const fn reverse(&mut self) {
1027 let half_len = self.len() / 2;
1028 let Range { start, end } = self.as_mut_ptr_range();
1029
1030 // These slices will skip the middle item for an odd length,
1031 // since that one doesn't need to move.
1032 let (front_half, back_half) =
1033 // SAFETY: Both are subparts of the original slice, so the memory
1034 // range is valid, and they don't overlap because they're each only
1035 // half (or less) of the original slice.
1036 unsafe {
1037 (
1038 slice::from_raw_parts_mut(start, half_len),
1039 slice::from_raw_parts_mut(end.sub(half_len), half_len),
1040 )
1041 };
1042
1043 // Introducing a function boundary here means that the two halves
1044 // get `noalias` markers, allowing better optimization as LLVM
1045 // knows that they're disjoint, unlike in the original slice.
1046 revswap(front_half, back_half, half_len);
1047
1048 #[inline]
1049 const fn revswap<T>(a: &mut [T], b: &mut [T], n: usize) {
1050 debug_assert!(a.len() == n);
1051 debug_assert!(b.len() == n);
1052
1053 // Because this function is first compiled in isolation,
1054 // this check tells LLVM that the indexing below is
1055 // in-bounds. Then after inlining -- once the actual
1056 // lengths of the slices are known -- it's removed.
1057 // FIXME(const_trait_impl) replace with let (a, b) = (&mut a[..n], &mut b[..n]);
1058 let (a, _) = a.split_at_mut(n);
1059 let (b, _) = b.split_at_mut(n);
1060
1061 let mut i = 0;
1062 while i < n {
1063 mem::swap(&mut a[i], &mut b[n - 1 - i]);
1064 i += 1;
1065 }
1066 }
1067 }
1068
1069 /// Returns an iterator over the slice.
1070 ///
1071 /// The iterator yields all items from start to end.
1072 ///
1073 /// # Examples
1074 ///
1075 /// ```
1076 /// let x = &[1, 2, 4];
1077 /// let mut iterator = x.iter();
1078 ///
1079 /// assert_eq!(iterator.next(), Some(&1));
1080 /// assert_eq!(iterator.next(), Some(&2));
1081 /// assert_eq!(iterator.next(), Some(&4));
1082 /// assert_eq!(iterator.next(), None);
1083 /// ```
1084 #[stable(feature = "rust1", since = "1.0.0")]
1085 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1086 #[inline]
1087 #[rustc_diagnostic_item = "slice_iter"]
1088 pub const fn iter(&self) -> Iter<'_, T> {
1089 Iter::new(self)
1090 }
1091
1092 /// Returns an iterator that allows modifying each value.
1093 ///
1094 /// The iterator yields all items from start to end.
1095 ///
1096 /// # Examples
1097 ///
1098 /// ```
1099 /// let x = &mut [1, 2, 4];
1100 /// for elem in x.iter_mut() {
1101 /// *elem += 2;
1102 /// }
1103 /// assert_eq!(x, &[3, 4, 6]);
1104 /// ```
1105 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1106 #[stable(feature = "rust1", since = "1.0.0")]
1107 #[inline]
1108 pub const fn iter_mut(&mut self) -> IterMut<'_, T> {
1109 IterMut::new(self)
1110 }
1111
1112 /// Returns an iterator over all contiguous windows of length
1113 /// `size`. The windows overlap. If the slice is shorter than
1114 /// `size`, the iterator returns no values.
1115 ///
1116 /// # Panics
1117 ///
1118 /// Panics if `size` is zero.
1119 ///
1120 /// # Examples
1121 ///
1122 /// ```
1123 /// let slice = ['l', 'o', 'r', 'e', 'm'];
1124 /// let mut iter = slice.windows(3);
1125 /// assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
1126 /// assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
1127 /// assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
1128 /// assert!(iter.next().is_none());
1129 /// ```
1130 ///
1131 /// If the slice is shorter than `size`:
1132 ///
1133 /// ```
1134 /// let slice = ['f', 'o', 'o'];
1135 /// let mut iter = slice.windows(4);
1136 /// assert!(iter.next().is_none());
1137 /// ```
1138 ///
1139 /// Because the [Iterator] trait cannot represent the required lifetimes,
1140 /// there is no `windows_mut` analog to `windows`;
1141 /// `[0,1,2].windows_mut(2).collect()` would violate [the rules of references]
1142 /// (though a [LendingIterator] analog is possible). You can sometimes use
1143 /// [`Cell::as_slice_of_cells`](crate::cell::Cell::as_slice_of_cells) in
1144 /// conjunction with `windows` instead:
1145 ///
1146 /// [the rules of references]: https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#the-rules-of-references
1147 /// [LendingIterator]: https://blog.rust-lang.org/2022/10/28/gats-stabilization.html
1148 /// ```
1149 /// use std::cell::Cell;
1150 ///
1151 /// let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
1152 /// let slice = &mut array[..];
1153 /// let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
1154 /// for w in slice_of_cells.windows(3) {
1155 /// Cell::swap(&w[0], &w[2]);
1156 /// }
1157 /// assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
1158 /// ```
1159 #[stable(feature = "rust1", since = "1.0.0")]
1160 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1161 #[inline]
1162 #[track_caller]
1163 pub const fn windows(&self, size: usize) -> Windows<'_, T> {
1164 let size = NonZero::new(size).expect("window size must be non-zero");
1165 Windows::new(self, size)
1166 }
1167
1168 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
1169 /// beginning of the slice.
1170 ///
1171 /// The chunks are slices and do not overlap. If `chunk_size` does not divide the length of the
1172 /// slice, then the last chunk will not have length `chunk_size`.
1173 ///
1174 /// See [`chunks_exact`] for a variant of this iterator that returns chunks of always exactly
1175 /// `chunk_size` elements, and [`rchunks`] for the same iterator but starting at the end of the
1176 /// slice.
1177 ///
1178 /// If your `chunk_size` is a constant, consider using [`as_chunks`] instead, which will
1179 /// give references to arrays of exactly that length, rather than slices.
1180 ///
1181 /// # Panics
1182 ///
1183 /// Panics if `chunk_size` is zero.
1184 ///
1185 /// # Examples
1186 ///
1187 /// ```
1188 /// let slice = ['l', 'o', 'r', 'e', 'm'];
1189 /// let mut iter = slice.chunks(2);
1190 /// assert_eq!(iter.next().unwrap(), &['l', 'o']);
1191 /// assert_eq!(iter.next().unwrap(), &['r', 'e']);
1192 /// assert_eq!(iter.next().unwrap(), &['m']);
1193 /// assert!(iter.next().is_none());
1194 /// ```
1195 ///
1196 /// [`chunks_exact`]: slice::chunks_exact
1197 /// [`rchunks`]: slice::rchunks
1198 /// [`as_chunks`]: slice::as_chunks
1199 #[stable(feature = "rust1", since = "1.0.0")]
1200 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1201 #[inline]
1202 #[track_caller]
1203 pub const fn chunks(&self, chunk_size: usize) -> Chunks<'_, T> {
1204 assert!(chunk_size != 0, "chunk size must be non-zero");
1205 Chunks::new(self, chunk_size)
1206 }
1207
1208 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
1209 /// beginning of the slice.
1210 ///
1211 /// The chunks are mutable slices, and do not overlap. If `chunk_size` does not divide the
1212 /// length of the slice, then the last chunk will not have length `chunk_size`.
1213 ///
1214 /// See [`chunks_exact_mut`] for a variant of this iterator that returns chunks of always
1215 /// exactly `chunk_size` elements, and [`rchunks_mut`] for the same iterator but starting at
1216 /// the end of the slice.
1217 ///
1218 /// If your `chunk_size` is a constant, consider using [`as_chunks_mut`] instead, which will
1219 /// give references to arrays of exactly that length, rather than slices.
1220 ///
1221 /// # Panics
1222 ///
1223 /// Panics if `chunk_size` is zero.
1224 ///
1225 /// # Examples
1226 ///
1227 /// ```
1228 /// let v = &mut [0, 0, 0, 0, 0];
1229 /// let mut count = 1;
1230 ///
1231 /// for chunk in v.chunks_mut(2) {
1232 /// for elem in chunk.iter_mut() {
1233 /// *elem += count;
1234 /// }
1235 /// count += 1;
1236 /// }
1237 /// assert_eq!(v, &[1, 1, 2, 2, 3]);
1238 /// ```
1239 ///
1240 /// [`chunks_exact_mut`]: slice::chunks_exact_mut
1241 /// [`rchunks_mut`]: slice::rchunks_mut
1242 /// [`as_chunks_mut`]: slice::as_chunks_mut
1243 #[stable(feature = "rust1", since = "1.0.0")]
1244 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1245 #[inline]
1246 #[track_caller]
1247 pub const fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> {
1248 assert!(chunk_size != 0, "chunk size must be non-zero");
1249 ChunksMut::new(self, chunk_size)
1250 }
1251
1252 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
1253 /// beginning of the slice.
1254 ///
1255 /// The chunks are slices and do not overlap. If `chunk_size` does not divide the length of the
1256 /// slice, then the last up to `chunk_size-1` elements will be omitted and can be retrieved
1257 /// from the `remainder` function of the iterator.
1258 ///
1259 /// Due to each chunk having exactly `chunk_size` elements, the compiler can often optimize the
1260 /// resulting code better than in the case of [`chunks`].
1261 ///
1262 /// See [`chunks`] for a variant of this iterator that also returns the remainder as a smaller
1263 /// chunk, and [`rchunks_exact`] for the same iterator but starting at the end of the slice.
1264 ///
1265 /// If your `chunk_size` is a constant, consider using [`as_chunks`] instead, which will
1266 /// give references to arrays of exactly that length, rather than slices.
1267 ///
1268 /// # Panics
1269 ///
1270 /// Panics if `chunk_size` is zero.
1271 ///
1272 /// # Examples
1273 ///
1274 /// ```
1275 /// let slice = ['l', 'o', 'r', 'e', 'm'];
1276 /// let mut iter = slice.chunks_exact(2);
1277 /// assert_eq!(iter.next().unwrap(), &['l', 'o']);
1278 /// assert_eq!(iter.next().unwrap(), &['r', 'e']);
1279 /// assert!(iter.next().is_none());
1280 /// assert_eq!(iter.remainder(), &['m']);
1281 /// ```
1282 ///
1283 /// [`chunks`]: slice::chunks
1284 /// [`rchunks_exact`]: slice::rchunks_exact
1285 /// [`as_chunks`]: slice::as_chunks
1286 #[stable(feature = "chunks_exact", since = "1.31.0")]
1287 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1288 #[inline]
1289 #[track_caller]
1290 pub const fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
1291 assert!(chunk_size != 0, "chunk size must be non-zero");
1292 ChunksExact::new(self, chunk_size)
1293 }
1294
1295 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
1296 /// beginning of the slice.
1297 ///
1298 /// The chunks are mutable slices, and do not overlap. If `chunk_size` does not divide the
1299 /// length of the slice, then the last up to `chunk_size-1` elements will be omitted and can be
1300 /// retrieved from the `into_remainder` function of the iterator.
1301 ///
1302 /// Due to each chunk having exactly `chunk_size` elements, the compiler can often optimize the
1303 /// resulting code better than in the case of [`chunks_mut`].
1304 ///
1305 /// See [`chunks_mut`] for a variant of this iterator that also returns the remainder as a
1306 /// smaller chunk, and [`rchunks_exact_mut`] for the same iterator but starting at the end of
1307 /// the slice.
1308 ///
1309 /// If your `chunk_size` is a constant, consider using [`as_chunks_mut`] instead, which will
1310 /// give references to arrays of exactly that length, rather than slices.
1311 ///
1312 /// # Panics
1313 ///
1314 /// Panics if `chunk_size` is zero.
1315 ///
1316 /// # Examples
1317 ///
1318 /// ```
1319 /// let v = &mut [0, 0, 0, 0, 0];
1320 /// let mut count = 1;
1321 ///
1322 /// for chunk in v.chunks_exact_mut(2) {
1323 /// for elem in chunk.iter_mut() {
1324 /// *elem += count;
1325 /// }
1326 /// count += 1;
1327 /// }
1328 /// assert_eq!(v, &[1, 1, 2, 2, 0]);
1329 /// ```
1330 ///
1331 /// [`chunks_mut`]: slice::chunks_mut
1332 /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut
1333 /// [`as_chunks_mut`]: slice::as_chunks_mut
1334 #[stable(feature = "chunks_exact", since = "1.31.0")]
1335 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1336 #[inline]
1337 #[track_caller]
1338 pub const fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
1339 assert!(chunk_size != 0, "chunk size must be non-zero");
1340 ChunksExactMut::new(self, chunk_size)
1341 }
1342
1343 /// Splits the slice into a slice of `N`-element arrays,
1344 /// assuming that there's no remainder.
1345 ///
1346 /// This is the inverse operation to [`as_flattened`].
1347 ///
1348 /// [`as_flattened`]: slice::as_flattened
1349 ///
1350 /// As this is `unsafe`, consider whether you could use [`as_chunks`] or
1351 /// [`as_rchunks`] instead, perhaps via something like
1352 /// `if let (chunks, []) = slice.as_chunks()` or
1353 /// `let (chunks, []) = slice.as_chunks() else { unreachable!() };`.
1354 ///
1355 /// [`as_chunks`]: slice::as_chunks
1356 /// [`as_rchunks`]: slice::as_rchunks
1357 ///
1358 /// # Safety
1359 ///
1360 /// This may only be called when
1361 /// - The slice splits exactly into `N`-element chunks (aka `self.len() % N == 0`).
1362 /// - `N != 0`.
1363 ///
1364 /// # Examples
1365 ///
1366 /// ```
1367 /// let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
1368 /// let chunks: &[[char; 1]] =
1369 /// // SAFETY: 1-element chunks never have remainder
1370 /// unsafe { slice.as_chunks_unchecked() };
1371 /// assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
1372 /// let chunks: &[[char; 3]] =
1373 /// // SAFETY: The slice length (6) is a multiple of 3
1374 /// unsafe { slice.as_chunks_unchecked() };
1375 /// assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
1376 ///
1377 /// // These would be unsound:
1378 /// // let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
1379 /// // let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
1380 /// ```
1381 #[stable(feature = "slice_as_chunks", since = "1.88.0")]
1382 #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")]
1383 #[inline]
1384 #[must_use]
1385 #[track_caller]
1386 pub const unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]] {
1387 assert_unsafe_precondition!(
1388 check_language_ub,
1389 "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks",
1390 (n: usize = N, len: usize = self.len()) => n != 0 && len.is_multiple_of(n),
1391 );
1392 // SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
1393 let new_len = unsafe { exact_div(self.len(), N) };
1394 // SAFETY: We cast a slice of `new_len * N` elements into
1395 // a slice of `new_len` many `N` elements chunks.
1396 unsafe { from_raw_parts(self.as_ptr().cast(), new_len) }
1397 }
1398
1399 /// Splits the slice into a slice of `N`-element arrays,
1400 /// starting at the beginning of the slice,
1401 /// and a remainder slice with length strictly less than `N`.
1402 ///
1403 /// The remainder is meaningful in the division sense. Given
1404 /// `let (chunks, remainder) = slice.as_chunks()`, then:
1405 /// - `chunks.len()` equals `slice.len() / N`,
1406 /// - `remainder.len()` equals `slice.len() % N`, and
1407 /// - `slice.len()` equals `chunks.len() * N + remainder.len()`.
1408 ///
1409 /// You can flatten the chunks back into a slice-of-`T` with [`as_flattened`].
1410 ///
1411 /// [`as_flattened`]: slice::as_flattened
1412 ///
1413 /// # Panics
1414 ///
1415 /// Panics if `N` is zero.
1416 ///
1417 /// Note that this check is against a const generic parameter, not a runtime
1418 /// value, and thus a particular monomorphization will either always panic
1419 /// or it will never panic.
1420 ///
1421 /// # Examples
1422 ///
1423 /// ```
1424 /// let slice = ['l', 'o', 'r', 'e', 'm'];
1425 /// let (chunks, remainder) = slice.as_chunks();
1426 /// assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
1427 /// assert_eq!(remainder, &['m']);
1428 /// ```
1429 ///
1430 /// If you expect the slice to be an exact multiple, you can combine
1431 /// `let`-`else` with an empty slice pattern:
1432 /// ```
1433 /// let slice = ['R', 'u', 's', 't'];
1434 /// let (chunks, []) = slice.as_chunks::<2>() else {
1435 /// panic!("slice didn't have even length")
1436 /// };
1437 /// assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
1438 /// ```
1439 #[stable(feature = "slice_as_chunks", since = "1.88.0")]
1440 #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")]
1441 #[inline]
1442 #[track_caller]
1443 #[must_use]
1444 pub const fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T]) {
1445 assert!(N != 0, "chunk size must be non-zero");
1446 let len_rounded_down = self.len() / N * N;
1447 // SAFETY: The rounded-down value is always the same or smaller than the
1448 // original length, and thus must be in-bounds of the slice.
1449 let (multiple_of_n, remainder) = unsafe { self.split_at_unchecked(len_rounded_down) };
1450 // SAFETY: We already panicked for zero, and ensured by construction
1451 // that the length of the subslice is a multiple of N.
1452 let array_slice = unsafe { multiple_of_n.as_chunks_unchecked() };
1453 (array_slice, remainder)
1454 }
1455
1456 /// Splits the slice into a slice of `N`-element arrays,
1457 /// starting at the end of the slice,
1458 /// and a remainder slice with length strictly less than `N`.
1459 ///
1460 /// The remainder is meaningful in the division sense. Given
1461 /// `let (remainder, chunks) = slice.as_rchunks()`, then:
1462 /// - `remainder.len()` equals `slice.len() % N`,
1463 /// - `chunks.len()` equals `slice.len() / N`, and
1464 /// - `slice.len()` equals `chunks.len() * N + remainder.len()`.
1465 ///
1466 /// You can flatten the chunks back into a slice-of-`T` with [`as_flattened`].
1467 ///
1468 /// [`as_flattened`]: slice::as_flattened
1469 ///
1470 /// # Panics
1471 ///
1472 /// Panics if `N` is zero.
1473 ///
1474 /// Note that this check is against a const generic parameter, not a runtime
1475 /// value, and thus a particular monomorphization will either always panic
1476 /// or it will never panic.
1477 ///
1478 /// # Examples
1479 ///
1480 /// ```
1481 /// let slice = ['l', 'o', 'r', 'e', 'm'];
1482 /// let (remainder, chunks) = slice.as_rchunks();
1483 /// assert_eq!(remainder, &['l']);
1484 /// assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
1485 /// ```
1486 #[stable(feature = "slice_as_chunks", since = "1.88.0")]
1487 #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")]
1488 #[inline]
1489 #[track_caller]
1490 #[must_use]
1491 #[cfg(not(feature = "ferrocene_subset"))]
1492 pub const fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]]) {
1493 assert!(N != 0, "chunk size must be non-zero");
1494 let len = self.len() / N;
1495 let (remainder, multiple_of_n) = self.split_at(self.len() - len * N);
1496 // SAFETY: We already panicked for zero, and ensured by construction
1497 // that the length of the subslice is a multiple of N.
1498 let array_slice = unsafe { multiple_of_n.as_chunks_unchecked() };
1499 (remainder, array_slice)
1500 }
1501
1502 /// Splits the slice into a slice of `N`-element arrays,
1503 /// assuming that there's no remainder.
1504 ///
1505 /// This is the inverse operation to [`as_flattened_mut`].
1506 ///
1507 /// [`as_flattened_mut`]: slice::as_flattened_mut
1508 ///
1509 /// As this is `unsafe`, consider whether you could use [`as_chunks_mut`] or
1510 /// [`as_rchunks_mut`] instead, perhaps via something like
1511 /// `if let (chunks, []) = slice.as_chunks_mut()` or
1512 /// `let (chunks, []) = slice.as_chunks_mut() else { unreachable!() };`.
1513 ///
1514 /// [`as_chunks_mut`]: slice::as_chunks_mut
1515 /// [`as_rchunks_mut`]: slice::as_rchunks_mut
1516 ///
1517 /// # Safety
1518 ///
1519 /// This may only be called when
1520 /// - The slice splits exactly into `N`-element chunks (aka `self.len() % N == 0`).
1521 /// - `N != 0`.
1522 ///
1523 /// # Examples
1524 ///
1525 /// ```
1526 /// let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
1527 /// let chunks: &mut [[char; 1]] =
1528 /// // SAFETY: 1-element chunks never have remainder
1529 /// unsafe { slice.as_chunks_unchecked_mut() };
1530 /// chunks[0] = ['L'];
1531 /// assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
1532 /// let chunks: &mut [[char; 3]] =
1533 /// // SAFETY: The slice length (6) is a multiple of 3
1534 /// unsafe { slice.as_chunks_unchecked_mut() };
1535 /// chunks[1] = ['a', 'x', '?'];
1536 /// assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
1537 ///
1538 /// // These would be unsound:
1539 /// // let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
1540 /// // let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
1541 /// ```
1542 #[stable(feature = "slice_as_chunks", since = "1.88.0")]
1543 #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")]
1544 #[inline]
1545 #[must_use]
1546 #[track_caller]
1547 #[cfg(not(feature = "ferrocene_subset"))]
1548 pub const unsafe fn as_chunks_unchecked_mut<const N: usize>(&mut self) -> &mut [[T; N]] {
1549 assert_unsafe_precondition!(
1550 check_language_ub,
1551 "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks",
1552 (n: usize = N, len: usize = self.len()) => n != 0 && len.is_multiple_of(n)
1553 );
1554 // SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
1555 let new_len = unsafe { exact_div(self.len(), N) };
1556 // SAFETY: We cast a slice of `new_len * N` elements into
1557 // a slice of `new_len` many `N` elements chunks.
1558 unsafe { from_raw_parts_mut(self.as_mut_ptr().cast(), new_len) }
1559 }
1560
1561 /// Splits the slice into a slice of `N`-element arrays,
1562 /// starting at the beginning of the slice,
1563 /// and a remainder slice with length strictly less than `N`.
1564 ///
1565 /// The remainder is meaningful in the division sense. Given
1566 /// `let (chunks, remainder) = slice.as_chunks_mut()`, then:
1567 /// - `chunks.len()` equals `slice.len() / N`,
1568 /// - `remainder.len()` equals `slice.len() % N`, and
1569 /// - `slice.len()` equals `chunks.len() * N + remainder.len()`.
1570 ///
1571 /// You can flatten the chunks back into a slice-of-`T` with [`as_flattened_mut`].
1572 ///
1573 /// [`as_flattened_mut`]: slice::as_flattened_mut
1574 ///
1575 /// # Panics
1576 ///
1577 /// Panics if `N` is zero.
1578 ///
1579 /// Note that this check is against a const generic parameter, not a runtime
1580 /// value, and thus a particular monomorphization will either always panic
1581 /// or it will never panic.
1582 ///
1583 /// # Examples
1584 ///
1585 /// ```
1586 /// let v = &mut [0, 0, 0, 0, 0];
1587 /// let mut count = 1;
1588 ///
1589 /// let (chunks, remainder) = v.as_chunks_mut();
1590 /// remainder[0] = 9;
1591 /// for chunk in chunks {
1592 /// *chunk = [count; 2];
1593 /// count += 1;
1594 /// }
1595 /// assert_eq!(v, &[1, 1, 2, 2, 9]);
1596 /// ```
1597 #[stable(feature = "slice_as_chunks", since = "1.88.0")]
1598 #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")]
1599 #[inline]
1600 #[track_caller]
1601 #[must_use]
1602 #[cfg(not(feature = "ferrocene_subset"))]
1603 pub const fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T]) {
1604 assert!(N != 0, "chunk size must be non-zero");
1605 let len_rounded_down = self.len() / N * N;
1606 // SAFETY: The rounded-down value is always the same or smaller than the
1607 // original length, and thus must be in-bounds of the slice.
1608 let (multiple_of_n, remainder) = unsafe { self.split_at_mut_unchecked(len_rounded_down) };
1609 // SAFETY: We already panicked for zero, and ensured by construction
1610 // that the length of the subslice is a multiple of N.
1611 let array_slice = unsafe { multiple_of_n.as_chunks_unchecked_mut() };
1612 (array_slice, remainder)
1613 }
1614
1615 /// Splits the slice into a slice of `N`-element arrays,
1616 /// starting at the end of the slice,
1617 /// and a remainder slice with length strictly less than `N`.
1618 ///
1619 /// The remainder is meaningful in the division sense. Given
1620 /// `let (remainder, chunks) = slice.as_rchunks_mut()`, then:
1621 /// - `remainder.len()` equals `slice.len() % N`,
1622 /// - `chunks.len()` equals `slice.len() / N`, and
1623 /// - `slice.len()` equals `chunks.len() * N + remainder.len()`.
1624 ///
1625 /// You can flatten the chunks back into a slice-of-`T` with [`as_flattened_mut`].
1626 ///
1627 /// [`as_flattened_mut`]: slice::as_flattened_mut
1628 ///
1629 /// # Panics
1630 ///
1631 /// Panics if `N` is zero.
1632 ///
1633 /// Note that this check is against a const generic parameter, not a runtime
1634 /// value, and thus a particular monomorphization will either always panic
1635 /// or it will never panic.
1636 ///
1637 /// # Examples
1638 ///
1639 /// ```
1640 /// let v = &mut [0, 0, 0, 0, 0];
1641 /// let mut count = 1;
1642 ///
1643 /// let (remainder, chunks) = v.as_rchunks_mut();
1644 /// remainder[0] = 9;
1645 /// for chunk in chunks {
1646 /// *chunk = [count; 2];
1647 /// count += 1;
1648 /// }
1649 /// assert_eq!(v, &[9, 1, 1, 2, 2]);
1650 /// ```
1651 #[stable(feature = "slice_as_chunks", since = "1.88.0")]
1652 #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")]
1653 #[inline]
1654 #[track_caller]
1655 #[must_use]
1656 #[cfg(not(feature = "ferrocene_subset"))]
1657 pub const fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]]) {
1658 assert!(N != 0, "chunk size must be non-zero");
1659 let len = self.len() / N;
1660 let (remainder, multiple_of_n) = self.split_at_mut(self.len() - len * N);
1661 // SAFETY: We already panicked for zero, and ensured by construction
1662 // that the length of the subslice is a multiple of N.
1663 let array_slice = unsafe { multiple_of_n.as_chunks_unchecked_mut() };
1664 (remainder, array_slice)
1665 }
1666
1667 /// Returns an iterator over overlapping windows of `N` elements of a slice,
1668 /// starting at the beginning of the slice.
1669 ///
1670 /// This is the const generic equivalent of [`windows`].
1671 ///
1672 /// If `N` is greater than the size of the slice, it will return no windows.
1673 ///
1674 /// # Panics
1675 ///
1676 /// Panics if `N` is zero.
1677 ///
1678 /// Note that this check is against a const generic parameter, not a runtime
1679 /// value, and thus a particular monomorphization will either always panic
1680 /// or it will never panic.
1681 ///
1682 /// # Examples
1683 ///
1684 /// ```
1685 /// let slice = [0, 1, 2, 3];
1686 /// let mut iter = slice.array_windows();
1687 /// assert_eq!(iter.next().unwrap(), &[0, 1]);
1688 /// assert_eq!(iter.next().unwrap(), &[1, 2]);
1689 /// assert_eq!(iter.next().unwrap(), &[2, 3]);
1690 /// assert!(iter.next().is_none());
1691 /// ```
1692 ///
1693 /// [`windows`]: slice::windows
1694 #[stable(feature = "array_windows", since = "1.94.0")]
1695 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1696 #[inline]
1697 #[track_caller]
1698 #[cfg(not(feature = "ferrocene_subset"))]
1699 pub const fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
1700 assert!(N != 0, "window size must be non-zero");
1701 ArrayWindows::new(self)
1702 }
1703
1704 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
1705 /// of the slice.
1706 ///
1707 /// The chunks are slices and do not overlap. If `chunk_size` does not divide the length of the
1708 /// slice, then the last chunk will not have length `chunk_size`.
1709 ///
1710 /// See [`rchunks_exact`] for a variant of this iterator that returns chunks of always exactly
1711 /// `chunk_size` elements, and [`chunks`] for the same iterator but starting at the beginning
1712 /// of the slice.
1713 ///
1714 /// If your `chunk_size` is a constant, consider using [`as_rchunks`] instead, which will
1715 /// give references to arrays of exactly that length, rather than slices.
1716 ///
1717 /// # Panics
1718 ///
1719 /// Panics if `chunk_size` is zero.
1720 ///
1721 /// # Examples
1722 ///
1723 /// ```
1724 /// let slice = ['l', 'o', 'r', 'e', 'm'];
1725 /// let mut iter = slice.rchunks(2);
1726 /// assert_eq!(iter.next().unwrap(), &['e', 'm']);
1727 /// assert_eq!(iter.next().unwrap(), &['o', 'r']);
1728 /// assert_eq!(iter.next().unwrap(), &['l']);
1729 /// assert!(iter.next().is_none());
1730 /// ```
1731 ///
1732 /// [`rchunks_exact`]: slice::rchunks_exact
1733 /// [`chunks`]: slice::chunks
1734 /// [`as_rchunks`]: slice::as_rchunks
1735 #[stable(feature = "rchunks", since = "1.31.0")]
1736 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1737 #[inline]
1738 #[track_caller]
1739 #[cfg(not(feature = "ferrocene_subset"))]
1740 pub const fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T> {
1741 assert!(chunk_size != 0, "chunk size must be non-zero");
1742 RChunks::new(self, chunk_size)
1743 }
1744
1745 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
1746 /// of the slice.
1747 ///
1748 /// The chunks are mutable slices, and do not overlap. If `chunk_size` does not divide the
1749 /// length of the slice, then the last chunk will not have length `chunk_size`.
1750 ///
1751 /// See [`rchunks_exact_mut`] for a variant of this iterator that returns chunks of always
1752 /// exactly `chunk_size` elements, and [`chunks_mut`] for the same iterator but starting at the
1753 /// beginning of the slice.
1754 ///
1755 /// If your `chunk_size` is a constant, consider using [`as_rchunks_mut`] instead, which will
1756 /// give references to arrays of exactly that length, rather than slices.
1757 ///
1758 /// # Panics
1759 ///
1760 /// Panics if `chunk_size` is zero.
1761 ///
1762 /// # Examples
1763 ///
1764 /// ```
1765 /// let v = &mut [0, 0, 0, 0, 0];
1766 /// let mut count = 1;
1767 ///
1768 /// for chunk in v.rchunks_mut(2) {
1769 /// for elem in chunk.iter_mut() {
1770 /// *elem += count;
1771 /// }
1772 /// count += 1;
1773 /// }
1774 /// assert_eq!(v, &[3, 2, 2, 1, 1]);
1775 /// ```
1776 ///
1777 /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut
1778 /// [`chunks_mut`]: slice::chunks_mut
1779 /// [`as_rchunks_mut`]: slice::as_rchunks_mut
1780 #[stable(feature = "rchunks", since = "1.31.0")]
1781 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1782 #[inline]
1783 #[track_caller]
1784 #[cfg(not(feature = "ferrocene_subset"))]
1785 pub const fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> {
1786 assert!(chunk_size != 0, "chunk size must be non-zero");
1787 RChunksMut::new(self, chunk_size)
1788 }
1789
1790 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
1791 /// end of the slice.
1792 ///
1793 /// The chunks are slices and do not overlap. If `chunk_size` does not divide the length of the
1794 /// slice, then the last up to `chunk_size-1` elements will be omitted and can be retrieved
1795 /// from the `remainder` function of the iterator.
1796 ///
1797 /// Due to each chunk having exactly `chunk_size` elements, the compiler can often optimize the
1798 /// resulting code better than in the case of [`rchunks`].
1799 ///
1800 /// See [`rchunks`] for a variant of this iterator that also returns the remainder as a smaller
1801 /// chunk, and [`chunks_exact`] for the same iterator but starting at the beginning of the
1802 /// slice.
1803 ///
1804 /// If your `chunk_size` is a constant, consider using [`as_rchunks`] instead, which will
1805 /// give references to arrays of exactly that length, rather than slices.
1806 ///
1807 /// # Panics
1808 ///
1809 /// Panics if `chunk_size` is zero.
1810 ///
1811 /// # Examples
1812 ///
1813 /// ```
1814 /// let slice = ['l', 'o', 'r', 'e', 'm'];
1815 /// let mut iter = slice.rchunks_exact(2);
1816 /// assert_eq!(iter.next().unwrap(), &['e', 'm']);
1817 /// assert_eq!(iter.next().unwrap(), &['o', 'r']);
1818 /// assert!(iter.next().is_none());
1819 /// assert_eq!(iter.remainder(), &['l']);
1820 /// ```
1821 ///
1822 /// [`chunks`]: slice::chunks
1823 /// [`rchunks`]: slice::rchunks
1824 /// [`chunks_exact`]: slice::chunks_exact
1825 /// [`as_rchunks`]: slice::as_rchunks
1826 #[stable(feature = "rchunks", since = "1.31.0")]
1827 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1828 #[inline]
1829 #[track_caller]
1830 #[cfg(not(feature = "ferrocene_subset"))]
1831 pub const fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> {
1832 assert!(chunk_size != 0, "chunk size must be non-zero");
1833 RChunksExact::new(self, chunk_size)
1834 }
1835
1836 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
1837 /// of the slice.
1838 ///
1839 /// The chunks are mutable slices, and do not overlap. If `chunk_size` does not divide the
1840 /// length of the slice, then the last up to `chunk_size-1` elements will be omitted and can be
1841 /// retrieved from the `into_remainder` function of the iterator.
1842 ///
1843 /// Due to each chunk having exactly `chunk_size` elements, the compiler can often optimize the
1844 /// resulting code better than in the case of [`chunks_mut`].
1845 ///
1846 /// See [`rchunks_mut`] for a variant of this iterator that also returns the remainder as a
1847 /// smaller chunk, and [`chunks_exact_mut`] for the same iterator but starting at the beginning
1848 /// of the slice.
1849 ///
1850 /// If your `chunk_size` is a constant, consider using [`as_rchunks_mut`] instead, which will
1851 /// give references to arrays of exactly that length, rather than slices.
1852 ///
1853 /// # Panics
1854 ///
1855 /// Panics if `chunk_size` is zero.
1856 ///
1857 /// # Examples
1858 ///
1859 /// ```
1860 /// let v = &mut [0, 0, 0, 0, 0];
1861 /// let mut count = 1;
1862 ///
1863 /// for chunk in v.rchunks_exact_mut(2) {
1864 /// for elem in chunk.iter_mut() {
1865 /// *elem += count;
1866 /// }
1867 /// count += 1;
1868 /// }
1869 /// assert_eq!(v, &[0, 2, 2, 1, 1]);
1870 /// ```
1871 ///
1872 /// [`chunks_mut`]: slice::chunks_mut
1873 /// [`rchunks_mut`]: slice::rchunks_mut
1874 /// [`chunks_exact_mut`]: slice::chunks_exact_mut
1875 /// [`as_rchunks_mut`]: slice::as_rchunks_mut
1876 #[stable(feature = "rchunks", since = "1.31.0")]
1877 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1878 #[inline]
1879 #[track_caller]
1880 #[cfg(not(feature = "ferrocene_subset"))]
1881 pub const fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> {
1882 assert!(chunk_size != 0, "chunk size must be non-zero");
1883 RChunksExactMut::new(self, chunk_size)
1884 }
1885
1886 /// Returns an iterator over the slice producing non-overlapping runs
1887 /// of elements using the predicate to separate them.
1888 ///
1889 /// The predicate is called for every pair of consecutive elements,
1890 /// meaning that it is called on `slice[0]` and `slice[1]`,
1891 /// followed by `slice[1]` and `slice[2]`, and so on.
1892 ///
1893 /// # Examples
1894 ///
1895 /// ```
1896 /// let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
1897 ///
1898 /// let mut iter = slice.chunk_by(|a, b| a == b);
1899 ///
1900 /// assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
1901 /// assert_eq!(iter.next(), Some(&[3, 3][..]));
1902 /// assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
1903 /// assert_eq!(iter.next(), None);
1904 /// ```
1905 ///
1906 /// This method can be used to extract the sorted subslices:
1907 ///
1908 /// ```
1909 /// let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
1910 ///
1911 /// let mut iter = slice.chunk_by(|a, b| a <= b);
1912 ///
1913 /// assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
1914 /// assert_eq!(iter.next(), Some(&[2, 3][..]));
1915 /// assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
1916 /// assert_eq!(iter.next(), None);
1917 /// ```
1918 #[stable(feature = "slice_group_by", since = "1.77.0")]
1919 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1920 #[inline]
1921 #[cfg(not(feature = "ferrocene_subset"))]
1922 pub const fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
1923 where
1924 F: FnMut(&T, &T) -> bool,
1925 {
1926 ChunkBy::new(self, pred)
1927 }
1928
1929 /// Returns an iterator over the slice producing non-overlapping mutable
1930 /// runs of elements using the predicate to separate them.
1931 ///
1932 /// The predicate is called for every pair of consecutive elements,
1933 /// meaning that it is called on `slice[0]` and `slice[1]`,
1934 /// followed by `slice[1]` and `slice[2]`, and so on.
1935 ///
1936 /// # Examples
1937 ///
1938 /// ```
1939 /// let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
1940 ///
1941 /// let mut iter = slice.chunk_by_mut(|a, b| a == b);
1942 ///
1943 /// assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
1944 /// assert_eq!(iter.next(), Some(&mut [3, 3][..]));
1945 /// assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
1946 /// assert_eq!(iter.next(), None);
1947 /// ```
1948 ///
1949 /// This method can be used to extract the sorted subslices:
1950 ///
1951 /// ```
1952 /// let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
1953 ///
1954 /// let mut iter = slice.chunk_by_mut(|a, b| a <= b);
1955 ///
1956 /// assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
1957 /// assert_eq!(iter.next(), Some(&mut [2, 3][..]));
1958 /// assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
1959 /// assert_eq!(iter.next(), None);
1960 /// ```
1961 #[stable(feature = "slice_group_by", since = "1.77.0")]
1962 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
1963 #[inline]
1964 #[cfg(not(feature = "ferrocene_subset"))]
1965 pub const fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
1966 where
1967 F: FnMut(&T, &T) -> bool,
1968 {
1969 ChunkByMut::new(self, pred)
1970 }
1971
1972 /// Divides one slice into two at an index.
1973 ///
1974 /// The first will contain all indices from `[0, mid)` (excluding
1975 /// the index `mid` itself) and the second will contain all
1976 /// indices from `[mid, len)` (excluding the index `len` itself).
1977 ///
1978 /// # Panics
1979 ///
1980 /// Panics if `mid > len`. For a non-panicking alternative see
1981 /// [`split_at_checked`](slice::split_at_checked).
1982 ///
1983 /// # Examples
1984 ///
1985 /// ```
1986 /// let v = ['a', 'b', 'c'];
1987 ///
1988 /// {
1989 /// let (left, right) = v.split_at(0);
1990 /// assert_eq!(left, []);
1991 /// assert_eq!(right, ['a', 'b', 'c']);
1992 /// }
1993 ///
1994 /// {
1995 /// let (left, right) = v.split_at(2);
1996 /// assert_eq!(left, ['a', 'b']);
1997 /// assert_eq!(right, ['c']);
1998 /// }
1999 ///
2000 /// {
2001 /// let (left, right) = v.split_at(3);
2002 /// assert_eq!(left, ['a', 'b', 'c']);
2003 /// assert_eq!(right, []);
2004 /// }
2005 /// ```
2006 #[stable(feature = "rust1", since = "1.0.0")]
2007 #[rustc_const_stable(feature = "const_slice_split_at_not_mut", since = "1.71.0")]
2008 #[inline]
2009 #[track_caller]
2010 #[must_use]
2011 pub const fn split_at(&self, mid: usize) -> (&[T], &[T]) {
2012 match self.split_at_checked(mid) {
2013 Some(pair) => pair,
2014 None => panic!("mid > len"),
2015 }
2016 }
2017
2018 /// Divides one mutable slice into two at an index.
2019 ///
2020 /// The first will contain all indices from `[0, mid)` (excluding
2021 /// the index `mid` itself) and the second will contain all
2022 /// indices from `[mid, len)` (excluding the index `len` itself).
2023 ///
2024 /// # Panics
2025 ///
2026 /// Panics if `mid > len`. For a non-panicking alternative see
2027 /// [`split_at_mut_checked`](slice::split_at_mut_checked).
2028 ///
2029 /// # Examples
2030 ///
2031 /// ```
2032 /// let mut v = [1, 0, 3, 0, 5, 6];
2033 /// let (left, right) = v.split_at_mut(2);
2034 /// assert_eq!(left, [1, 0]);
2035 /// assert_eq!(right, [3, 0, 5, 6]);
2036 /// left[1] = 2;
2037 /// right[1] = 4;
2038 /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
2039 /// ```
2040 #[stable(feature = "rust1", since = "1.0.0")]
2041 #[inline]
2042 #[track_caller]
2043 #[must_use]
2044 #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")]
2045 pub const fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
2046 match self.split_at_mut_checked(mid) {
2047 Some(pair) => pair,
2048 None => panic!("mid > len"),
2049 }
2050 }
2051
2052 /// Divides one slice into two at an index, without doing bounds checking.
2053 ///
2054 /// The first will contain all indices from `[0, mid)` (excluding
2055 /// the index `mid` itself) and the second will contain all
2056 /// indices from `[mid, len)` (excluding the index `len` itself).
2057 ///
2058 /// For a safe alternative see [`split_at`].
2059 ///
2060 /// # Safety
2061 ///
2062 /// Calling this method with an out-of-bounds index is *[undefined behavior]*
2063 /// even if the resulting reference is not used. The caller has to ensure that
2064 /// `0 <= mid <= self.len()`.
2065 ///
2066 /// [`split_at`]: slice::split_at
2067 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2068 ///
2069 /// # Examples
2070 ///
2071 /// ```
2072 /// let v = ['a', 'b', 'c'];
2073 ///
2074 /// unsafe {
2075 /// let (left, right) = v.split_at_unchecked(0);
2076 /// assert_eq!(left, []);
2077 /// assert_eq!(right, ['a', 'b', 'c']);
2078 /// }
2079 ///
2080 /// unsafe {
2081 /// let (left, right) = v.split_at_unchecked(2);
2082 /// assert_eq!(left, ['a', 'b']);
2083 /// assert_eq!(right, ['c']);
2084 /// }
2085 ///
2086 /// unsafe {
2087 /// let (left, right) = v.split_at_unchecked(3);
2088 /// assert_eq!(left, ['a', 'b', 'c']);
2089 /// assert_eq!(right, []);
2090 /// }
2091 /// ```
2092 #[stable(feature = "slice_split_at_unchecked", since = "1.79.0")]
2093 #[rustc_const_stable(feature = "const_slice_split_at_unchecked", since = "1.77.0")]
2094 #[inline]
2095 #[must_use]
2096 #[track_caller]
2097 pub const unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) {
2098 // FIXME(const-hack): the const function `from_raw_parts` is used to make this
2099 // function const; previously the implementation used
2100 // `(self.get_unchecked(..mid), self.get_unchecked(mid..))`
2101
2102 let len = self.len();
2103 let ptr = self.as_ptr();
2104
2105 assert_unsafe_precondition!(
2106 check_library_ub,
2107 "slice::split_at_unchecked requires the index to be within the slice",
2108 (mid: usize = mid, len: usize = len) => mid <= len,
2109 );
2110
2111 // SAFETY: Caller has to check that `0 <= mid <= self.len()`
2112 unsafe { (from_raw_parts(ptr, mid), from_raw_parts(ptr.add(mid), unchecked_sub(len, mid))) }
2113 }
2114
2115 /// Divides one mutable slice into two at an index, without doing bounds checking.
2116 ///
2117 /// The first will contain all indices from `[0, mid)` (excluding
2118 /// the index `mid` itself) and the second will contain all
2119 /// indices from `[mid, len)` (excluding the index `len` itself).
2120 ///
2121 /// For a safe alternative see [`split_at_mut`].
2122 ///
2123 /// # Safety
2124 ///
2125 /// Calling this method with an out-of-bounds index is *[undefined behavior]*
2126 /// even if the resulting reference is not used. The caller has to ensure that
2127 /// `0 <= mid <= self.len()`.
2128 ///
2129 /// [`split_at_mut`]: slice::split_at_mut
2130 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2131 ///
2132 /// # Examples
2133 ///
2134 /// ```
2135 /// let mut v = [1, 0, 3, 0, 5, 6];
2136 /// // scoped to restrict the lifetime of the borrows
2137 /// unsafe {
2138 /// let (left, right) = v.split_at_mut_unchecked(2);
2139 /// assert_eq!(left, [1, 0]);
2140 /// assert_eq!(right, [3, 0, 5, 6]);
2141 /// left[1] = 2;
2142 /// right[1] = 4;
2143 /// }
2144 /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
2145 /// ```
2146 #[stable(feature = "slice_split_at_unchecked", since = "1.79.0")]
2147 #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")]
2148 #[inline]
2149 #[must_use]
2150 #[track_caller]
2151 pub const unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
2152 let len = self.len();
2153 let ptr = self.as_mut_ptr();
2154
2155 assert_unsafe_precondition!(
2156 check_library_ub,
2157 "slice::split_at_mut_unchecked requires the index to be within the slice",
2158 (mid: usize = mid, len: usize = len) => mid <= len,
2159 );
2160
2161 // SAFETY: Caller has to check that `0 <= mid <= self.len()`.
2162 //
2163 // `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference
2164 // is fine.
2165 unsafe {
2166 (
2167 from_raw_parts_mut(ptr, mid),
2168 from_raw_parts_mut(ptr.add(mid), unchecked_sub(len, mid)),
2169 )
2170 }
2171 }
2172
2173 /// Divides one slice into two at an index, returning `None` if the slice is
2174 /// too short.
2175 ///
2176 /// If `mid ≤ len` returns a pair of slices where the first will contain all
2177 /// indices from `[0, mid)` (excluding the index `mid` itself) and the
2178 /// second will contain all indices from `[mid, len)` (excluding the index
2179 /// `len` itself).
2180 ///
2181 /// Otherwise, if `mid > len`, returns `None`.
2182 ///
2183 /// # Examples
2184 ///
2185 /// ```
2186 /// let v = [1, -2, 3, -4, 5, -6];
2187 ///
2188 /// {
2189 /// let (left, right) = v.split_at_checked(0).unwrap();
2190 /// assert_eq!(left, []);
2191 /// assert_eq!(right, [1, -2, 3, -4, 5, -6]);
2192 /// }
2193 ///
2194 /// {
2195 /// let (left, right) = v.split_at_checked(2).unwrap();
2196 /// assert_eq!(left, [1, -2]);
2197 /// assert_eq!(right, [3, -4, 5, -6]);
2198 /// }
2199 ///
2200 /// {
2201 /// let (left, right) = v.split_at_checked(6).unwrap();
2202 /// assert_eq!(left, [1, -2, 3, -4, 5, -6]);
2203 /// assert_eq!(right, []);
2204 /// }
2205 ///
2206 /// assert_eq!(None, v.split_at_checked(7));
2207 /// ```
2208 #[stable(feature = "split_at_checked", since = "1.80.0")]
2209 #[rustc_const_stable(feature = "split_at_checked", since = "1.80.0")]
2210 #[inline]
2211 #[must_use]
2212 pub const fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])> {
2213 if mid <= self.len() {
2214 // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
2215 // fulfills the requirements of `split_at_unchecked`.
2216 Some(unsafe { self.split_at_unchecked(mid) })
2217 } else {
2218 None
2219 }
2220 }
2221
2222 /// Divides one mutable slice into two at an index, returning `None` if the
2223 /// slice is too short.
2224 ///
2225 /// If `mid ≤ len` returns a pair of slices where the first will contain all
2226 /// indices from `[0, mid)` (excluding the index `mid` itself) and the
2227 /// second will contain all indices from `[mid, len)` (excluding the index
2228 /// `len` itself).
2229 ///
2230 /// Otherwise, if `mid > len`, returns `None`.
2231 ///
2232 /// # Examples
2233 ///
2234 /// ```
2235 /// let mut v = [1, 0, 3, 0, 5, 6];
2236 ///
2237 /// if let Some((left, right)) = v.split_at_mut_checked(2) {
2238 /// assert_eq!(left, [1, 0]);
2239 /// assert_eq!(right, [3, 0, 5, 6]);
2240 /// left[1] = 2;
2241 /// right[1] = 4;
2242 /// }
2243 /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
2244 ///
2245 /// assert_eq!(None, v.split_at_mut_checked(7));
2246 /// ```
2247 #[stable(feature = "split_at_checked", since = "1.80.0")]
2248 #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")]
2249 #[inline]
2250 #[must_use]
2251 pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut [T], &mut [T])> {
2252 if mid <= self.len() {
2253 // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
2254 // fulfills the requirements of `split_at_unchecked`.
2255 Some(unsafe { self.split_at_mut_unchecked(mid) })
2256 } else {
2257 None
2258 }
2259 }
2260
2261 /// Returns an iterator over subslices separated by elements that match
2262 /// `pred`. The matched element is not contained in the subslices.
2263 ///
2264 /// # Examples
2265 ///
2266 /// ```
2267 /// let slice = [10, 40, 33, 20];
2268 /// let mut iter = slice.split(|num| num % 3 == 0);
2269 ///
2270 /// assert_eq!(iter.next().unwrap(), &[10, 40]);
2271 /// assert_eq!(iter.next().unwrap(), &[20]);
2272 /// assert!(iter.next().is_none());
2273 /// ```
2274 ///
2275 /// If the first element is matched, an empty slice will be the first item
2276 /// returned by the iterator. Similarly, if the last element in the slice
2277 /// is matched, an empty slice will be the last item returned by the
2278 /// iterator:
2279 ///
2280 /// ```
2281 /// let slice = [10, 40, 33];
2282 /// let mut iter = slice.split(|num| num % 3 == 0);
2283 ///
2284 /// assert_eq!(iter.next().unwrap(), &[10, 40]);
2285 /// assert_eq!(iter.next().unwrap(), &[]);
2286 /// assert!(iter.next().is_none());
2287 /// ```
2288 ///
2289 /// If two matched elements are directly adjacent, an empty slice will be
2290 /// present between them:
2291 ///
2292 /// ```
2293 /// let slice = [10, 6, 33, 20];
2294 /// let mut iter = slice.split(|num| num % 3 == 0);
2295 ///
2296 /// assert_eq!(iter.next().unwrap(), &[10]);
2297 /// assert_eq!(iter.next().unwrap(), &[]);
2298 /// assert_eq!(iter.next().unwrap(), &[20]);
2299 /// assert!(iter.next().is_none());
2300 /// ```
2301 #[stable(feature = "rust1", since = "1.0.0")]
2302 #[inline]
2303 #[cfg(not(feature = "ferrocene_subset"))]
2304 pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
2305 where
2306 F: FnMut(&T) -> bool,
2307 {
2308 Split::new(self, pred)
2309 }
2310
2311 /// Returns an iterator over mutable subslices separated by elements that
2312 /// match `pred`. The matched element is not contained in the subslices.
2313 ///
2314 /// # Examples
2315 ///
2316 /// ```
2317 /// let mut v = [10, 40, 30, 20, 60, 50];
2318 ///
2319 /// for group in v.split_mut(|num| *num % 3 == 0) {
2320 /// group[0] = 1;
2321 /// }
2322 /// assert_eq!(v, [1, 40, 30, 1, 60, 1]);
2323 /// ```
2324 #[stable(feature = "rust1", since = "1.0.0")]
2325 #[inline]
2326 #[cfg(not(feature = "ferrocene_subset"))]
2327 pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>
2328 where
2329 F: FnMut(&T) -> bool,
2330 {
2331 SplitMut::new(self, pred)
2332 }
2333
2334 /// Returns an iterator over subslices separated by elements that match
2335 /// `pred`. The matched element is contained in the end of the previous
2336 /// subslice as a terminator.
2337 ///
2338 /// # Examples
2339 ///
2340 /// ```
2341 /// let slice = [10, 40, 33, 20];
2342 /// let mut iter = slice.split_inclusive(|num| num % 3 == 0);
2343 ///
2344 /// assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
2345 /// assert_eq!(iter.next().unwrap(), &[20]);
2346 /// assert!(iter.next().is_none());
2347 /// ```
2348 ///
2349 /// If the last element of the slice is matched,
2350 /// that element will be considered the terminator of the preceding slice.
2351 /// That slice will be the last item returned by the iterator.
2352 ///
2353 /// ```
2354 /// let slice = [3, 10, 40, 33];
2355 /// let mut iter = slice.split_inclusive(|num| num % 3 == 0);
2356 ///
2357 /// assert_eq!(iter.next().unwrap(), &[3]);
2358 /// assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
2359 /// assert!(iter.next().is_none());
2360 /// ```
2361 #[stable(feature = "split_inclusive", since = "1.51.0")]
2362 #[inline]
2363 #[cfg(not(feature = "ferrocene_subset"))]
2364 pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
2365 where
2366 F: FnMut(&T) -> bool,
2367 {
2368 SplitInclusive::new(self, pred)
2369 }
2370
2371 /// Returns an iterator over mutable subslices separated by elements that
2372 /// match `pred`. The matched element is contained in the previous
2373 /// subslice as a terminator.
2374 ///
2375 /// # Examples
2376 ///
2377 /// ```
2378 /// let mut v = [10, 40, 30, 20, 60, 50];
2379 ///
2380 /// for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
2381 /// let terminator_idx = group.len()-1;
2382 /// group[terminator_idx] = 1;
2383 /// }
2384 /// assert_eq!(v, [10, 40, 1, 20, 1, 1]);
2385 /// ```
2386 #[stable(feature = "split_inclusive", since = "1.51.0")]
2387 #[inline]
2388 #[cfg(not(feature = "ferrocene_subset"))]
2389 pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>
2390 where
2391 F: FnMut(&T) -> bool,
2392 {
2393 SplitInclusiveMut::new(self, pred)
2394 }
2395
2396 /// Returns an iterator over subslices separated by elements that match
2397 /// `pred`, starting at the end of the slice and working backwards.
2398 /// The matched element is not contained in the subslices.
2399 ///
2400 /// # Examples
2401 ///
2402 /// ```
2403 /// let slice = [11, 22, 33, 0, 44, 55];
2404 /// let mut iter = slice.rsplit(|num| *num == 0);
2405 ///
2406 /// assert_eq!(iter.next().unwrap(), &[44, 55]);
2407 /// assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
2408 /// assert_eq!(iter.next(), None);
2409 /// ```
2410 ///
2411 /// As with `split()`, if the first or last element is matched, an empty
2412 /// slice will be the first (or last) item returned by the iterator.
2413 ///
2414 /// ```
2415 /// let v = &[0, 1, 1, 2, 3, 5, 8];
2416 /// let mut it = v.rsplit(|n| *n % 2 == 0);
2417 /// assert_eq!(it.next().unwrap(), &[]);
2418 /// assert_eq!(it.next().unwrap(), &[3, 5]);
2419 /// assert_eq!(it.next().unwrap(), &[1, 1]);
2420 /// assert_eq!(it.next().unwrap(), &[]);
2421 /// assert_eq!(it.next(), None);
2422 /// ```
2423 #[stable(feature = "slice_rsplit", since = "1.27.0")]
2424 #[inline]
2425 #[cfg(not(feature = "ferrocene_subset"))]
2426 pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
2427 where
2428 F: FnMut(&T) -> bool,
2429 {
2430 RSplit::new(self, pred)
2431 }
2432
2433 /// Returns an iterator over mutable subslices separated by elements that
2434 /// match `pred`, starting at the end of the slice and working
2435 /// backwards. The matched element is not contained in the subslices.
2436 ///
2437 /// # Examples
2438 ///
2439 /// ```
2440 /// let mut v = [100, 400, 300, 200, 600, 500];
2441 ///
2442 /// let mut count = 0;
2443 /// for group in v.rsplit_mut(|num| *num % 3 == 0) {
2444 /// count += 1;
2445 /// group[0] = count;
2446 /// }
2447 /// assert_eq!(v, [3, 400, 300, 2, 600, 1]);
2448 /// ```
2449 ///
2450 #[stable(feature = "slice_rsplit", since = "1.27.0")]
2451 #[inline]
2452 #[cfg(not(feature = "ferrocene_subset"))]
2453 pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>
2454 where
2455 F: FnMut(&T) -> bool,
2456 {
2457 RSplitMut::new(self, pred)
2458 }
2459
2460 /// Returns an iterator over subslices separated by elements that match
2461 /// `pred`, limited to returning at most `n` items. The matched element is
2462 /// not contained in the subslices.
2463 ///
2464 /// The last element returned, if any, will contain the remainder of the
2465 /// slice.
2466 ///
2467 /// # Examples
2468 ///
2469 /// Print the slice split once by numbers divisible by 3 (i.e., `[10, 40]`,
2470 /// `[20, 60, 50]`):
2471 ///
2472 /// ```
2473 /// let v = [10, 40, 30, 20, 60, 50];
2474 ///
2475 /// for group in v.splitn(2, |num| *num % 3 == 0) {
2476 /// println!("{group:?}");
2477 /// }
2478 /// ```
2479 #[stable(feature = "rust1", since = "1.0.0")]
2480 #[inline]
2481 #[cfg(not(feature = "ferrocene_subset"))]
2482 pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
2483 where
2484 F: FnMut(&T) -> bool,
2485 {
2486 SplitN::new(self.split(pred), n)
2487 }
2488
2489 /// Returns an iterator over mutable subslices separated by elements that match
2490 /// `pred`, limited to returning at most `n` items. The matched element is
2491 /// not contained in the subslices.
2492 ///
2493 /// The last element returned, if any, will contain the remainder of the
2494 /// slice.
2495 ///
2496 /// # Examples
2497 ///
2498 /// ```
2499 /// let mut v = [10, 40, 30, 20, 60, 50];
2500 ///
2501 /// for group in v.splitn_mut(2, |num| *num % 3 == 0) {
2502 /// group[0] = 1;
2503 /// }
2504 /// assert_eq!(v, [1, 40, 30, 1, 60, 50]);
2505 /// ```
2506 #[stable(feature = "rust1", since = "1.0.0")]
2507 #[inline]
2508 #[cfg(not(feature = "ferrocene_subset"))]
2509 pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>
2510 where
2511 F: FnMut(&T) -> bool,
2512 {
2513 SplitNMut::new(self.split_mut(pred), n)
2514 }
2515
2516 /// Returns an iterator over subslices separated by elements that match
2517 /// `pred` limited to returning at most `n` items. This starts at the end of
2518 /// the slice and works backwards. The matched element is not contained in
2519 /// the subslices.
2520 ///
2521 /// The last element returned, if any, will contain the remainder of the
2522 /// slice.
2523 ///
2524 /// # Examples
2525 ///
2526 /// Print the slice split once, starting from the end, by numbers divisible
2527 /// by 3 (i.e., `[50]`, `[10, 40, 30, 20]`):
2528 ///
2529 /// ```
2530 /// let v = [10, 40, 30, 20, 60, 50];
2531 ///
2532 /// for group in v.rsplitn(2, |num| *num % 3 == 0) {
2533 /// println!("{group:?}");
2534 /// }
2535 /// ```
2536 #[stable(feature = "rust1", since = "1.0.0")]
2537 #[inline]
2538 #[cfg(not(feature = "ferrocene_subset"))]
2539 pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
2540 where
2541 F: FnMut(&T) -> bool,
2542 {
2543 RSplitN::new(self.rsplit(pred), n)
2544 }
2545
2546 /// Returns an iterator over subslices separated by elements that match
2547 /// `pred` limited to returning at most `n` items. This starts at the end of
2548 /// the slice and works backwards. The matched element is not contained in
2549 /// the subslices.
2550 ///
2551 /// The last element returned, if any, will contain the remainder of the
2552 /// slice.
2553 ///
2554 /// # Examples
2555 ///
2556 /// ```
2557 /// let mut s = [10, 40, 30, 20, 60, 50];
2558 ///
2559 /// for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
2560 /// group[0] = 1;
2561 /// }
2562 /// assert_eq!(s, [1, 40, 30, 20, 60, 1]);
2563 /// ```
2564 #[stable(feature = "rust1", since = "1.0.0")]
2565 #[inline]
2566 #[cfg(not(feature = "ferrocene_subset"))]
2567 pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>
2568 where
2569 F: FnMut(&T) -> bool,
2570 {
2571 RSplitNMut::new(self.rsplit_mut(pred), n)
2572 }
2573
2574 /// Splits the slice on the first element that matches the specified
2575 /// predicate.
2576 ///
2577 /// If any matching elements are present in the slice, returns the prefix
2578 /// before the match and suffix after. The matching element itself is not
2579 /// included. If no elements match, returns `None`.
2580 ///
2581 /// # Examples
2582 ///
2583 /// ```
2584 /// #![feature(slice_split_once)]
2585 /// let s = [1, 2, 3, 2, 4];
2586 /// assert_eq!(s.split_once(|&x| x == 2), Some((
2587 /// &[1][..],
2588 /// &[3, 2, 4][..]
2589 /// )));
2590 /// assert_eq!(s.split_once(|&x| x == 0), None);
2591 /// ```
2592 #[unstable(feature = "slice_split_once", issue = "112811")]
2593 #[inline]
2594 #[cfg(not(feature = "ferrocene_subset"))]
2595 pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
2596 where
2597 F: FnMut(&T) -> bool,
2598 {
2599 let index = self.iter().position(pred)?;
2600 Some((&self[..index], &self[index + 1..]))
2601 }
2602
2603 /// Splits the slice on the last element that matches the specified
2604 /// predicate.
2605 ///
2606 /// If any matching elements are present in the slice, returns the prefix
2607 /// before the match and suffix after. The matching element itself is not
2608 /// included. If no elements match, returns `None`.
2609 ///
2610 /// # Examples
2611 ///
2612 /// ```
2613 /// #![feature(slice_split_once)]
2614 /// let s = [1, 2, 3, 2, 4];
2615 /// assert_eq!(s.rsplit_once(|&x| x == 2), Some((
2616 /// &[1, 2, 3][..],
2617 /// &[4][..]
2618 /// )));
2619 /// assert_eq!(s.rsplit_once(|&x| x == 0), None);
2620 /// ```
2621 #[unstable(feature = "slice_split_once", issue = "112811")]
2622 #[inline]
2623 #[cfg(not(feature = "ferrocene_subset"))]
2624 pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
2625 where
2626 F: FnMut(&T) -> bool,
2627 {
2628 let index = self.iter().rposition(pred)?;
2629 Some((&self[..index], &self[index + 1..]))
2630 }
2631
2632 /// Returns `true` if the slice contains an element with the given value.
2633 ///
2634 /// This operation is *O*(*n*).
2635 ///
2636 /// Note that if you have a sorted slice, [`binary_search`] may be faster.
2637 ///
2638 /// [`binary_search`]: slice::binary_search
2639 ///
2640 /// # Examples
2641 ///
2642 /// ```
2643 /// let v = [10, 40, 30];
2644 /// assert!(v.contains(&30));
2645 /// assert!(!v.contains(&50));
2646 /// ```
2647 ///
2648 /// If you do not have a `&T`, but some other value that you can compare
2649 /// with one (for example, `String` implements `PartialEq<str>`), you can
2650 /// use `iter().any`:
2651 ///
2652 /// ```
2653 /// let v = [String::from("hello"), String::from("world")]; // slice of `String`
2654 /// assert!(v.iter().any(|e| e == "hello")); // search with `&str`
2655 /// assert!(!v.iter().any(|e| e == "hi"));
2656 /// ```
2657 #[stable(feature = "rust1", since = "1.0.0")]
2658 #[inline]
2659 #[must_use]
2660 #[cfg(not(feature = "ferrocene_subset"))]
2661 pub fn contains(&self, x: &T) -> bool
2662 where
2663 T: PartialEq,
2664 {
2665 cmp::SliceContains::slice_contains(x, self)
2666 }
2667
2668 /// Returns `true` if `needle` is a prefix of the slice or equal to the slice.
2669 ///
2670 /// # Examples
2671 ///
2672 /// ```
2673 /// let v = [10, 40, 30];
2674 /// assert!(v.starts_with(&[10]));
2675 /// assert!(v.starts_with(&[10, 40]));
2676 /// assert!(v.starts_with(&v));
2677 /// assert!(!v.starts_with(&[50]));
2678 /// assert!(!v.starts_with(&[10, 50]));
2679 /// ```
2680 ///
2681 /// Always returns `true` if `needle` is an empty slice:
2682 ///
2683 /// ```
2684 /// let v = &[10, 40, 30];
2685 /// assert!(v.starts_with(&[]));
2686 /// let v: &[u8] = &[];
2687 /// assert!(v.starts_with(&[]));
2688 /// ```
2689 #[stable(feature = "rust1", since = "1.0.0")]
2690 #[must_use]
2691 pub fn starts_with(&self, needle: &[T]) -> bool
2692 where
2693 T: PartialEq,
2694 {
2695 let n = needle.len();
2696 self.len() >= n && needle == &self[..n]
2697 }
2698
2699 /// Returns `true` if `needle` is a suffix of the slice or equal to the slice.
2700 ///
2701 /// # Examples
2702 ///
2703 /// ```
2704 /// let v = [10, 40, 30];
2705 /// assert!(v.ends_with(&[30]));
2706 /// assert!(v.ends_with(&[40, 30]));
2707 /// assert!(v.ends_with(&v));
2708 /// assert!(!v.ends_with(&[50]));
2709 /// assert!(!v.ends_with(&[50, 30]));
2710 /// ```
2711 ///
2712 /// Always returns `true` if `needle` is an empty slice:
2713 ///
2714 /// ```
2715 /// let v = &[10, 40, 30];
2716 /// assert!(v.ends_with(&[]));
2717 /// let v: &[u8] = &[];
2718 /// assert!(v.ends_with(&[]));
2719 /// ```
2720 #[stable(feature = "rust1", since = "1.0.0")]
2721 #[must_use]
2722 pub fn ends_with(&self, needle: &[T]) -> bool
2723 where
2724 T: PartialEq,
2725 {
2726 let (m, n) = (self.len(), needle.len());
2727 m >= n && needle == &self[m - n..]
2728 }
2729
2730 /// Returns a subslice with the prefix removed.
2731 ///
2732 /// If the slice starts with `prefix`, returns the subslice after the prefix, wrapped in `Some`.
2733 /// If `prefix` is empty, simply returns the original slice. If `prefix` is equal to the
2734 /// original slice, returns an empty slice.
2735 ///
2736 /// If the slice does not start with `prefix`, returns `None`.
2737 ///
2738 /// # Examples
2739 ///
2740 /// ```
2741 /// let v = &[10, 40, 30];
2742 /// assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
2743 /// assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
2744 /// assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
2745 /// assert_eq!(v.strip_prefix(&[50]), None);
2746 /// assert_eq!(v.strip_prefix(&[10, 50]), None);
2747 ///
2748 /// let prefix : &str = "he";
2749 /// assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
2750 /// Some(b"llo".as_ref()));
2751 /// ```
2752 #[must_use = "returns the subslice without modifying the original"]
2753 #[stable(feature = "slice_strip", since = "1.51.0")]
2754 #[cfg(not(feature = "ferrocene_subset"))]
2755 pub fn strip_prefix<P: SlicePattern<Item = T> + ?Sized>(&self, prefix: &P) -> Option<&[T]>
2756 where
2757 T: PartialEq,
2758 {
2759 // This function will need rewriting if and when SlicePattern becomes more sophisticated.
2760 let prefix = prefix.as_slice();
2761 let n = prefix.len();
2762 if n <= self.len() {
2763 let (head, tail) = self.split_at(n);
2764 if head == prefix {
2765 return Some(tail);
2766 }
2767 }
2768 None
2769 }
2770
2771 /// Returns a subslice with the suffix removed.
2772 ///
2773 /// If the slice ends with `suffix`, returns the subslice before the suffix, wrapped in `Some`.
2774 /// If `suffix` is empty, simply returns the original slice. If `suffix` is equal to the
2775 /// original slice, returns an empty slice.
2776 ///
2777 /// If the slice does not end with `suffix`, returns `None`.
2778 ///
2779 /// # Examples
2780 ///
2781 /// ```
2782 /// let v = &[10, 40, 30];
2783 /// assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
2784 /// assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
2785 /// assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
2786 /// assert_eq!(v.strip_suffix(&[50]), None);
2787 /// assert_eq!(v.strip_suffix(&[50, 30]), None);
2788 /// ```
2789 #[must_use = "returns the subslice without modifying the original"]
2790 #[stable(feature = "slice_strip", since = "1.51.0")]
2791 #[cfg(not(feature = "ferrocene_subset"))]
2792 pub fn strip_suffix<P: SlicePattern<Item = T> + ?Sized>(&self, suffix: &P) -> Option<&[T]>
2793 where
2794 T: PartialEq,
2795 {
2796 // This function will need rewriting if and when SlicePattern becomes more sophisticated.
2797 let suffix = suffix.as_slice();
2798 let (len, n) = (self.len(), suffix.len());
2799 if n <= len {
2800 let (head, tail) = self.split_at(len - n);
2801 if tail == suffix {
2802 return Some(head);
2803 }
2804 }
2805 None
2806 }
2807
2808 /// Returns a subslice with the prefix and suffix removed.
2809 ///
2810 /// If the slice starts with `prefix` and ends with `suffix`, returns the subslice after the
2811 /// prefix and before the suffix, wrapped in `Some`.
2812 ///
2813 /// If the slice does not start with `prefix` or does not end with `suffix`, returns `None`.
2814 ///
2815 /// # Examples
2816 ///
2817 /// ```
2818 /// #![feature(strip_circumfix)]
2819 ///
2820 /// let v = &[10, 50, 40, 30];
2821 /// assert_eq!(v.strip_circumfix(&[10], &[30]), Some(&[50, 40][..]));
2822 /// assert_eq!(v.strip_circumfix(&[10], &[40, 30]), Some(&[50][..]));
2823 /// assert_eq!(v.strip_circumfix(&[10, 50], &[40, 30]), Some(&[][..]));
2824 /// assert_eq!(v.strip_circumfix(&[50], &[30]), None);
2825 /// assert_eq!(v.strip_circumfix(&[10], &[40]), None);
2826 /// assert_eq!(v.strip_circumfix(&[], &[40, 30]), Some(&[10, 50][..]));
2827 /// assert_eq!(v.strip_circumfix(&[10, 50], &[]), Some(&[40, 30][..]));
2828 /// ```
2829 #[must_use = "returns the subslice without modifying the original"]
2830 #[unstable(feature = "strip_circumfix", issue = "147946")]
2831 #[cfg(not(feature = "ferrocene_subset"))]
2832 pub fn strip_circumfix<S, P>(&self, prefix: &P, suffix: &S) -> Option<&[T]>
2833 where
2834 T: PartialEq,
2835 S: SlicePattern<Item = T> + ?Sized,
2836 P: SlicePattern<Item = T> + ?Sized,
2837 {
2838 self.strip_prefix(prefix)?.strip_suffix(suffix)
2839 }
2840
2841 /// Returns a subslice with the optional prefix removed.
2842 ///
2843 /// If the slice starts with `prefix`, returns the subslice after the prefix. If `prefix`
2844 /// is empty or the slice does not start with `prefix`, simply returns the original slice.
2845 /// If `prefix` is equal to the original slice, returns an empty slice.
2846 ///
2847 /// # Examples
2848 ///
2849 /// ```
2850 /// #![feature(trim_prefix_suffix)]
2851 ///
2852 /// let v = &[10, 40, 30];
2853 ///
2854 /// // Prefix present - removes it
2855 /// assert_eq!(v.trim_prefix(&[10]), &[40, 30][..]);
2856 /// assert_eq!(v.trim_prefix(&[10, 40]), &[30][..]);
2857 /// assert_eq!(v.trim_prefix(&[10, 40, 30]), &[][..]);
2858 ///
2859 /// // Prefix absent - returns original slice
2860 /// assert_eq!(v.trim_prefix(&[50]), &[10, 40, 30][..]);
2861 /// assert_eq!(v.trim_prefix(&[10, 50]), &[10, 40, 30][..]);
2862 ///
2863 /// let prefix : &str = "he";
2864 /// assert_eq!(b"hello".trim_prefix(prefix.as_bytes()), b"llo".as_ref());
2865 /// ```
2866 #[must_use = "returns the subslice without modifying the original"]
2867 #[unstable(feature = "trim_prefix_suffix", issue = "142312")]
2868 #[cfg(not(feature = "ferrocene_subset"))]
2869 pub fn trim_prefix<P: SlicePattern<Item = T> + ?Sized>(&self, prefix: &P) -> &[T]
2870 where
2871 T: PartialEq,
2872 {
2873 // This function will need rewriting if and when SlicePattern becomes more sophisticated.
2874 let prefix = prefix.as_slice();
2875 let n = prefix.len();
2876 if n <= self.len() {
2877 let (head, tail) = self.split_at(n);
2878 if head == prefix {
2879 return tail;
2880 }
2881 }
2882 self
2883 }
2884
2885 /// Returns a subslice with the optional suffix removed.
2886 ///
2887 /// If the slice ends with `suffix`, returns the subslice before the suffix. If `suffix`
2888 /// is empty or the slice does not end with `suffix`, simply returns the original slice.
2889 /// If `suffix` is equal to the original slice, returns an empty slice.
2890 ///
2891 /// # Examples
2892 ///
2893 /// ```
2894 /// #![feature(trim_prefix_suffix)]
2895 ///
2896 /// let v = &[10, 40, 30];
2897 ///
2898 /// // Suffix present - removes it
2899 /// assert_eq!(v.trim_suffix(&[30]), &[10, 40][..]);
2900 /// assert_eq!(v.trim_suffix(&[40, 30]), &[10][..]);
2901 /// assert_eq!(v.trim_suffix(&[10, 40, 30]), &[][..]);
2902 ///
2903 /// // Suffix absent - returns original slice
2904 /// assert_eq!(v.trim_suffix(&[50]), &[10, 40, 30][..]);
2905 /// assert_eq!(v.trim_suffix(&[50, 30]), &[10, 40, 30][..]);
2906 /// ```
2907 #[must_use = "returns the subslice without modifying the original"]
2908 #[unstable(feature = "trim_prefix_suffix", issue = "142312")]
2909 #[cfg(not(feature = "ferrocene_subset"))]
2910 pub fn trim_suffix<P: SlicePattern<Item = T> + ?Sized>(&self, suffix: &P) -> &[T]
2911 where
2912 T: PartialEq,
2913 {
2914 // This function will need rewriting if and when SlicePattern becomes more sophisticated.
2915 let suffix = suffix.as_slice();
2916 let (len, n) = (self.len(), suffix.len());
2917 if n <= len {
2918 let (head, tail) = self.split_at(len - n);
2919 if tail == suffix {
2920 return head;
2921 }
2922 }
2923 self
2924 }
2925
2926 /// Binary searches this slice for a given element.
2927 /// If the slice is not sorted, the returned result is unspecified and
2928 /// meaningless.
2929 ///
2930 /// If the value is found then [`Result::Ok`] is returned, containing the
2931 /// index of the matching element. If there are multiple matches, then any
2932 /// one of the matches could be returned. The index is chosen
2933 /// deterministically, but is subject to change in future versions of Rust.
2934 /// If the value is not found then [`Result::Err`] is returned, containing
2935 /// the index where a matching element could be inserted while maintaining
2936 /// sorted order.
2937 ///
2938 /// See also [`binary_search_by`], [`binary_search_by_key`], and [`partition_point`].
2939 ///
2940 /// [`binary_search_by`]: slice::binary_search_by
2941 /// [`binary_search_by_key`]: slice::binary_search_by_key
2942 /// [`partition_point`]: slice::partition_point
2943 ///
2944 /// # Examples
2945 ///
2946 /// Looks up a series of four elements. The first is found, with a
2947 /// uniquely determined position; the second and third are not
2948 /// found; the fourth could match any position in `[1, 4]`.
2949 ///
2950 /// ```
2951 /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
2952 ///
2953 /// assert_eq!(s.binary_search(&13), Ok(9));
2954 /// assert_eq!(s.binary_search(&4), Err(7));
2955 /// assert_eq!(s.binary_search(&100), Err(13));
2956 /// let r = s.binary_search(&1);
2957 /// assert!(match r { Ok(1..=4) => true, _ => false, });
2958 /// ```
2959 ///
2960 /// If you want to find that whole *range* of matching items, rather than
2961 /// an arbitrary matching one, that can be done using [`partition_point`]:
2962 /// ```
2963 /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
2964 ///
2965 /// let low = s.partition_point(|x| x < &1);
2966 /// assert_eq!(low, 1);
2967 /// let high = s.partition_point(|x| x <= &1);
2968 /// assert_eq!(high, 5);
2969 /// let r = s.binary_search(&1);
2970 /// assert!((low..high).contains(&r.unwrap()));
2971 ///
2972 /// assert!(s[..low].iter().all(|&x| x < 1));
2973 /// assert!(s[low..high].iter().all(|&x| x == 1));
2974 /// assert!(s[high..].iter().all(|&x| x > 1));
2975 ///
2976 /// // For something not found, the "range" of equal items is empty
2977 /// assert_eq!(s.partition_point(|x| x < &11), 9);
2978 /// assert_eq!(s.partition_point(|x| x <= &11), 9);
2979 /// assert_eq!(s.binary_search(&11), Err(9));
2980 /// ```
2981 ///
2982 /// If you want to insert an item to a sorted vector, while maintaining
2983 /// sort order, consider using [`partition_point`]:
2984 ///
2985 /// ```
2986 /// let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
2987 /// let num = 42;
2988 /// let idx = s.partition_point(|&x| x <= num);
2989 /// // If `num` is unique, `s.partition_point(|&x| x < num)` (with `<`) is equivalent to
2990 /// // `s.binary_search(&num).unwrap_or_else(|x| x)`, but using `<=` will allow `insert`
2991 /// // to shift less elements.
2992 /// s.insert(idx, num);
2993 /// assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
2994 /// ```
2995 #[stable(feature = "rust1", since = "1.0.0")]
2996 #[cfg(not(feature = "ferrocene_subset"))]
2997 pub fn binary_search(&self, x: &T) -> Result<usize, usize>
2998 where
2999 T: Ord,
3000 {
3001 self.binary_search_by(|p| p.cmp(x))
3002 }
3003
3004 /// Binary searches this slice with a comparator function.
3005 ///
3006 /// The comparator function should return an order code that indicates
3007 /// whether its argument is `Less`, `Equal` or `Greater` the desired
3008 /// target.
3009 /// If the slice is not sorted or if the comparator function does not
3010 /// implement an order consistent with the sort order of the underlying
3011 /// slice, the returned result is unspecified and meaningless.
3012 ///
3013 /// If the value is found then [`Result::Ok`] is returned, containing the
3014 /// index of the matching element. If there are multiple matches, then any
3015 /// one of the matches could be returned. The index is chosen
3016 /// deterministically, but is subject to change in future versions of Rust.
3017 /// If the value is not found then [`Result::Err`] is returned, containing
3018 /// the index where a matching element could be inserted while maintaining
3019 /// sorted order.
3020 ///
3021 /// See also [`binary_search`], [`binary_search_by_key`], and [`partition_point`].
3022 ///
3023 /// [`binary_search`]: slice::binary_search
3024 /// [`binary_search_by_key`]: slice::binary_search_by_key
3025 /// [`partition_point`]: slice::partition_point
3026 ///
3027 /// # Examples
3028 ///
3029 /// Looks up a series of four elements. The first is found, with a
3030 /// uniquely determined position; the second and third are not
3031 /// found; the fourth could match any position in `[1, 4]`.
3032 ///
3033 /// ```
3034 /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
3035 ///
3036 /// let seek = 13;
3037 /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
3038 /// let seek = 4;
3039 /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
3040 /// let seek = 100;
3041 /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
3042 /// let seek = 1;
3043 /// let r = s.binary_search_by(|probe| probe.cmp(&seek));
3044 /// assert!(match r { Ok(1..=4) => true, _ => false, });
3045 /// ```
3046 #[stable(feature = "rust1", since = "1.0.0")]
3047 #[inline]
3048 pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
3049 where
3050 F: FnMut(&'a T) -> Ordering,
3051 {
3052 let mut size = self.len();
3053 if size == 0 {
3054 return Err(0);
3055 }
3056 let mut base = 0usize;
3057
3058 // This loop intentionally doesn't have an early exit if the comparison
3059 // returns Equal. We want the number of loop iterations to depend *only*
3060 // on the size of the input slice so that the CPU can reliably predict
3061 // the loop count.
3062 while size > 1 {
3063 let half = size / 2;
3064 let mid = base + half;
3065
3066 // SAFETY: the call is made safe by the following invariants:
3067 // - `mid >= 0`: by definition
3068 // - `mid < size`: `mid = size / 2 + size / 4 + size / 8 ...`
3069 let cmp = f(unsafe { self.get_unchecked(mid) });
3070
3071 // Binary search interacts poorly with branch prediction, so force
3072 // the compiler to use conditional moves if supported by the target
3073 // architecture.
3074 base = hint::select_unpredictable(cmp == Greater, base, mid);
3075
3076 // This is imprecise in the case where `size` is odd and the
3077 // comparison returns Greater: the mid element still gets included
3078 // by `size` even though it's known to be larger than the element
3079 // being searched for.
3080 //
3081 // This is fine though: we gain more performance by keeping the
3082 // loop iteration count invariant (and thus predictable) than we
3083 // lose from considering one additional element.
3084 size -= half;
3085 }
3086
3087 // SAFETY: base is always in [0, size) because base <= mid.
3088 let cmp = f(unsafe { self.get_unchecked(base) });
3089 if cmp == Equal {
3090 // SAFETY: same as the `get_unchecked` above.
3091 unsafe { hint::assert_unchecked(base < self.len()) };
3092 Ok(base)
3093 } else {
3094 let result = base + (cmp == Less) as usize;
3095 // SAFETY: same as the `get_unchecked` above.
3096 // Note that this is `<=`, unlike the assume in the `Ok` path.
3097 unsafe { hint::assert_unchecked(result <= self.len()) };
3098 Err(result)
3099 }
3100 }
3101
3102 /// Binary searches this slice with a key extraction function.
3103 ///
3104 /// Assumes that the slice is sorted by the key, for instance with
3105 /// [`sort_by_key`] using the same key extraction function.
3106 /// If the slice is not sorted by the key, the returned result is
3107 /// unspecified and meaningless.
3108 ///
3109 /// If the value is found then [`Result::Ok`] is returned, containing the
3110 /// index of the matching element. If there are multiple matches, then any
3111 /// one of the matches could be returned. The index is chosen
3112 /// deterministically, but is subject to change in future versions of Rust.
3113 /// If the value is not found then [`Result::Err`] is returned, containing
3114 /// the index where a matching element could be inserted while maintaining
3115 /// sorted order.
3116 ///
3117 /// See also [`binary_search`], [`binary_search_by`], and [`partition_point`].
3118 ///
3119 /// [`sort_by_key`]: slice::sort_by_key
3120 /// [`binary_search`]: slice::binary_search
3121 /// [`binary_search_by`]: slice::binary_search_by
3122 /// [`partition_point`]: slice::partition_point
3123 ///
3124 /// # Examples
3125 ///
3126 /// Looks up a series of four elements in a slice of pairs sorted by
3127 /// their second elements. The first is found, with a uniquely
3128 /// determined position; the second and third are not found; the
3129 /// fourth could match any position in `[1, 4]`.
3130 ///
3131 /// ```
3132 /// let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
3133 /// (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
3134 /// (1, 21), (2, 34), (4, 55)];
3135 ///
3136 /// assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b), Ok(9));
3137 /// assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b), Err(7));
3138 /// assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
3139 /// let r = s.binary_search_by_key(&1, |&(a, b)| b);
3140 /// assert!(match r { Ok(1..=4) => true, _ => false, });
3141 /// ```
3142 // Lint rustdoc::broken_intra_doc_links is allowed as `slice::sort_by_key` is
3143 // in crate `alloc`, and as such doesn't exists yet when building `core`: #74481.
3144 // This breaks links when slice is displayed in core, but changing it to use relative links
3145 // would break when the item is re-exported. So allow the core links to be broken for now.
3146 #[allow(rustdoc::broken_intra_doc_links)]
3147 #[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
3148 #[inline]
3149 pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
3150 where
3151 F: FnMut(&'a T) -> B,
3152 B: Ord,
3153 {
3154 self.binary_search_by(|k| f(k).cmp(b))
3155 }
3156
3157 /// Sorts the slice in ascending order **without** preserving the initial order of equal elements.
3158 ///
3159 /// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
3160 /// allocate), and *O*(*n* \* log(*n*)) worst-case.
3161 ///
3162 /// If the implementation of [`Ord`] for `T` does not implement a [total order], the function
3163 /// may panic; even if the function exits normally, the resulting order of elements in the slice
3164 /// is unspecified. See also the note on panicking below.
3165 ///
3166 /// For example `|a, b| (a - b).cmp(a)` is a comparison function that is neither transitive nor
3167 /// reflexive nor total, `a < b < c < a` with `a = 1, b = 2, c = 3`. For more information and
3168 /// examples see the [`Ord`] documentation.
3169 ///
3170 ///
3171 /// All original elements will remain in the slice and any possible modifications via interior
3172 /// mutability are observed in the input. Same is true if the implementation of [`Ord`] for `T` panics.
3173 ///
3174 /// Sorting types that only implement [`PartialOrd`] such as [`f32`] and [`f64`] require
3175 /// additional precautions. For example, `f32::NAN != f32::NAN`, which doesn't fulfill the
3176 /// reflexivity requirement of [`Ord`]. By using an alternative comparison function with
3177 /// `slice::sort_unstable_by` such as [`f32::total_cmp`] or [`f64::total_cmp`] that defines a
3178 /// [total order] users can sort slices containing floating-point values. Alternatively, if all
3179 /// values in the slice are guaranteed to be in a subset for which [`PartialOrd::partial_cmp`]
3180 /// forms a [total order], it's possible to sort the slice with `sort_unstable_by(|a, b|
3181 /// a.partial_cmp(b).unwrap())`.
3182 ///
3183 /// # Current implementation
3184 ///
3185 /// The current implementation is based on [ipnsort] by Lukas Bergdoll and Orson Peters, which
3186 /// combines the fast average case of quicksort with the fast worst case of heapsort, achieving
3187 /// linear time on fully sorted and reversed inputs. On inputs with k distinct elements, the
3188 /// expected time to sort the data is *O*(*n* \* log(*k*)).
3189 ///
3190 /// It is typically faster than stable sorting, except in a few special cases, e.g., when the
3191 /// slice is partially sorted.
3192 ///
3193 /// # Panics
3194 ///
3195 /// May panic if the implementation of [`Ord`] for `T` does not implement a [total order], or if
3196 /// the [`Ord`] implementation panics.
3197 ///
3198 /// # Examples
3199 ///
3200 /// ```
3201 /// let mut v = [4, -5, 1, -3, 2];
3202 ///
3203 /// v.sort_unstable();
3204 /// assert_eq!(v, [-5, -3, 1, 2, 4]);
3205 /// ```
3206 ///
3207 /// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
3208 /// [total order]: https://en.wikipedia.org/wiki/Total_order
3209 #[stable(feature = "sort_unstable", since = "1.20.0")]
3210 #[inline]
3211 #[cfg(not(feature = "ferrocene_subset"))]
3212 pub fn sort_unstable(&mut self)
3213 where
3214 T: Ord,
3215 {
3216 sort::unstable::sort(self, &mut T::lt);
3217 }
3218
3219 /// Sorts the slice in ascending order with a comparison function, **without** preserving the
3220 /// initial order of equal elements.
3221 ///
3222 /// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
3223 /// allocate), and *O*(*n* \* log(*n*)) worst-case.
3224 ///
3225 /// If the comparison function `compare` does not implement a [total order], the function
3226 /// may panic; even if the function exits normally, the resulting order of elements in the slice
3227 /// is unspecified. See also the note on panicking below.
3228 ///
3229 /// For example `|a, b| (a - b).cmp(a)` is a comparison function that is neither transitive nor
3230 /// reflexive nor total, `a < b < c < a` with `a = 1, b = 2, c = 3`. For more information and
3231 /// examples see the [`Ord`] documentation.
3232 ///
3233 /// All original elements will remain in the slice and any possible modifications via interior
3234 /// mutability are observed in the input. Same is true if `compare` panics.
3235 ///
3236 /// # Current implementation
3237 ///
3238 /// The current implementation is based on [ipnsort] by Lukas Bergdoll and Orson Peters, which
3239 /// combines the fast average case of quicksort with the fast worst case of heapsort, achieving
3240 /// linear time on fully sorted and reversed inputs. On inputs with k distinct elements, the
3241 /// expected time to sort the data is *O*(*n* \* log(*k*)).
3242 ///
3243 /// It is typically faster than stable sorting, except in a few special cases, e.g., when the
3244 /// slice is partially sorted.
3245 ///
3246 /// # Panics
3247 ///
3248 /// May panic if the `compare` does not implement a [total order], or if
3249 /// the `compare` itself panics.
3250 ///
3251 /// # Examples
3252 ///
3253 /// ```
3254 /// let mut v = [4, -5, 1, -3, 2];
3255 /// v.sort_unstable_by(|a, b| a.cmp(b));
3256 /// assert_eq!(v, [-5, -3, 1, 2, 4]);
3257 ///
3258 /// // reverse sorting
3259 /// v.sort_unstable_by(|a, b| b.cmp(a));
3260 /// assert_eq!(v, [4, 2, 1, -3, -5]);
3261 /// ```
3262 ///
3263 /// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
3264 /// [total order]: https://en.wikipedia.org/wiki/Total_order
3265 #[stable(feature = "sort_unstable", since = "1.20.0")]
3266 #[inline]
3267 #[cfg(not(feature = "ferrocene_subset"))]
3268 pub fn sort_unstable_by<F>(&mut self, mut compare: F)
3269 where
3270 F: FnMut(&T, &T) -> Ordering,
3271 {
3272 sort::unstable::sort(self, &mut |a, b| compare(a, b) == Ordering::Less);
3273 }
3274
3275 /// Sorts the slice in ascending order with a key extraction function, **without** preserving
3276 /// the initial order of equal elements.
3277 ///
3278 /// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
3279 /// allocate), and *O*(*n* \* log(*n*)) worst-case.
3280 ///
3281 /// If the implementation of [`Ord`] for `K` does not implement a [total order], the function
3282 /// may panic; even if the function exits normally, the resulting order of elements in the slice
3283 /// is unspecified. See also the note on panicking below.
3284 ///
3285 /// For example `|a, b| (a - b).cmp(a)` is a comparison function that is neither transitive nor
3286 /// reflexive nor total, `a < b < c < a` with `a = 1, b = 2, c = 3`. For more information and
3287 /// examples see the [`Ord`] documentation.
3288 ///
3289 /// All original elements will remain in the slice and any possible modifications via interior
3290 /// mutability are observed in the input. Same is true if the implementation of [`Ord`] for `K` panics.
3291 ///
3292 /// # Current implementation
3293 ///
3294 /// The current implementation is based on [ipnsort] by Lukas Bergdoll and Orson Peters, which
3295 /// combines the fast average case of quicksort with the fast worst case of heapsort, achieving
3296 /// linear time on fully sorted and reversed inputs. On inputs with k distinct elements, the
3297 /// expected time to sort the data is *O*(*n* \* log(*k*)).
3298 ///
3299 /// It is typically faster than stable sorting, except in a few special cases, e.g., when the
3300 /// slice is partially sorted.
3301 ///
3302 /// # Panics
3303 ///
3304 /// May panic if the implementation of [`Ord`] for `K` does not implement a [total order], or if
3305 /// the [`Ord`] implementation panics.
3306 ///
3307 /// # Examples
3308 ///
3309 /// ```
3310 /// let mut v = [4i32, -5, 1, -3, 2];
3311 ///
3312 /// v.sort_unstable_by_key(|k| k.abs());
3313 /// assert_eq!(v, [1, 2, -3, 4, -5]);
3314 /// ```
3315 ///
3316 /// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
3317 /// [total order]: https://en.wikipedia.org/wiki/Total_order
3318 #[stable(feature = "sort_unstable", since = "1.20.0")]
3319 #[inline]
3320 #[cfg(not(feature = "ferrocene_subset"))]
3321 pub fn sort_unstable_by_key<K, F>(&mut self, mut f: F)
3322 where
3323 F: FnMut(&T) -> K,
3324 K: Ord,
3325 {
3326 sort::unstable::sort(self, &mut |a, b| f(a).lt(&f(b)));
3327 }
3328
3329 /// Partially sorts the slice in ascending order **without** preserving the initial order of equal elements.
3330 ///
3331 /// Upon completion, for the specified range `start..end`, it's guaranteed that:
3332 ///
3333 /// 1. Every element in `self[..start]` is smaller than or equal to
3334 /// 2. Every element in `self[start..end]`, which is sorted, and smaller than or equal to
3335 /// 3. Every element in `self[end..]`.
3336 ///
3337 /// This partial sort is unstable, meaning it may reorder equal elements in the specified range.
3338 /// It may reorder elements outside the specified range as well, but the guarantees above still hold.
3339 ///
3340 /// This partial sort is in-place (i.e., does not allocate), and *O*(*n* + *k* \* log(*k*)) worst-case,
3341 /// where *n* is the length of the slice and *k* is the length of the specified range.
3342 ///
3343 /// See the documentation of [`sort_unstable`] for implementation notes.
3344 ///
3345 /// # Panics
3346 ///
3347 /// May panic if the implementation of [`Ord`] for `T` does not implement a total order, or if
3348 /// the [`Ord`] implementation panics, or if the specified range is out of bounds.
3349 ///
3350 /// # Examples
3351 ///
3352 /// ```
3353 /// #![feature(slice_partial_sort_unstable)]
3354 ///
3355 /// let mut v = [4, -5, 1, -3, 2];
3356 ///
3357 /// // empty range at the beginning, nothing changed
3358 /// v.partial_sort_unstable(0..0);
3359 /// assert_eq!(v, [4, -5, 1, -3, 2]);
3360 ///
3361 /// // empty range in the middle, partitioning the slice
3362 /// v.partial_sort_unstable(2..2);
3363 /// for i in 0..2 {
3364 /// assert!(v[i] <= v[2]);
3365 /// }
3366 /// for i in 3..v.len() {
3367 /// assert!(v[2] <= v[i]);
3368 /// }
3369 ///
3370 /// // single element range, same as select_nth_unstable
3371 /// v.partial_sort_unstable(2..3);
3372 /// for i in 0..2 {
3373 /// assert!(v[i] <= v[2]);
3374 /// }
3375 /// for i in 3..v.len() {
3376 /// assert!(v[2] <= v[i]);
3377 /// }
3378 ///
3379 /// // partial sort a subrange
3380 /// v.partial_sort_unstable(1..4);
3381 /// assert_eq!(&v[1..4], [-3, 1, 2]);
3382 ///
3383 /// // partial sort the whole range, same as sort_unstable
3384 /// v.partial_sort_unstable(..);
3385 /// assert_eq!(v, [-5, -3, 1, 2, 4]);
3386 /// ```
3387 ///
3388 /// [`sort_unstable`]: slice::sort_unstable
3389 #[unstable(feature = "slice_partial_sort_unstable", issue = "149046")]
3390 #[inline]
3391 #[cfg(not(feature = "ferrocene_subset"))]
3392 pub fn partial_sort_unstable<R>(&mut self, range: R)
3393 where
3394 T: Ord,
3395 R: RangeBounds<usize>,
3396 {
3397 sort::unstable::partial_sort(self, range, T::lt);
3398 }
3399
3400 /// Partially sorts the slice in ascending order with a comparison function, **without**
3401 /// preserving the initial order of equal elements.
3402 ///
3403 /// Upon completion, for the specified range `start..end`, it's guaranteed that:
3404 ///
3405 /// 1. Every element in `self[..start]` is smaller than or equal to
3406 /// 2. Every element in `self[start..end]`, which is sorted, and smaller than or equal to
3407 /// 3. Every element in `self[end..]`.
3408 ///
3409 /// This partial sort is unstable, meaning it may reorder equal elements in the specified range.
3410 /// It may reorder elements outside the specified range as well, but the guarantees above still hold.
3411 ///
3412 /// This partial sort is in-place (i.e., does not allocate), and *O*(*n* + *k* \* log(*k*)) worst-case,
3413 /// where *n* is the length of the slice and *k* is the length of the specified range.
3414 ///
3415 /// See the documentation of [`sort_unstable_by`] for implementation notes.
3416 ///
3417 /// # Panics
3418 ///
3419 /// May panic if the `compare` does not implement a total order, or if
3420 /// the `compare` itself panics, or if the specified range is out of bounds.
3421 ///
3422 /// # Examples
3423 ///
3424 /// ```
3425 /// #![feature(slice_partial_sort_unstable)]
3426 ///
3427 /// let mut v = [4, -5, 1, -3, 2];
3428 ///
3429 /// // empty range at the beginning, nothing changed
3430 /// v.partial_sort_unstable_by(0..0, |a, b| b.cmp(a));
3431 /// assert_eq!(v, [4, -5, 1, -3, 2]);
3432 ///
3433 /// // empty range in the middle, partitioning the slice
3434 /// v.partial_sort_unstable_by(2..2, |a, b| b.cmp(a));
3435 /// for i in 0..2 {
3436 /// assert!(v[i] >= v[2]);
3437 /// }
3438 /// for i in 3..v.len() {
3439 /// assert!(v[2] >= v[i]);
3440 /// }
3441 ///
3442 /// // single element range, same as select_nth_unstable
3443 /// v.partial_sort_unstable_by(2..3, |a, b| b.cmp(a));
3444 /// for i in 0..2 {
3445 /// assert!(v[i] >= v[2]);
3446 /// }
3447 /// for i in 3..v.len() {
3448 /// assert!(v[2] >= v[i]);
3449 /// }
3450 ///
3451 /// // partial sort a subrange
3452 /// v.partial_sort_unstable_by(1..4, |a, b| b.cmp(a));
3453 /// assert_eq!(&v[1..4], [2, 1, -3]);
3454 ///
3455 /// // partial sort the whole range, same as sort_unstable
3456 /// v.partial_sort_unstable_by(.., |a, b| b.cmp(a));
3457 /// assert_eq!(v, [4, 2, 1, -3, -5]);
3458 /// ```
3459 ///
3460 /// [`sort_unstable_by`]: slice::sort_unstable_by
3461 #[unstable(feature = "slice_partial_sort_unstable", issue = "149046")]
3462 #[inline]
3463 #[cfg(not(feature = "ferrocene_subset"))]
3464 pub fn partial_sort_unstable_by<F, R>(&mut self, range: R, mut compare: F)
3465 where
3466 F: FnMut(&T, &T) -> Ordering,
3467 R: RangeBounds<usize>,
3468 {
3469 sort::unstable::partial_sort(self, range, |a, b| compare(a, b) == Less);
3470 }
3471
3472 /// Partially sorts the slice in ascending order with a key extraction function, **without**
3473 /// preserving the initial order of equal elements.
3474 ///
3475 /// Upon completion, for the specified range `start..end`, it's guaranteed that:
3476 ///
3477 /// 1. Every element in `self[..start]` is smaller than or equal to
3478 /// 2. Every element in `self[start..end]`, which is sorted, and smaller than or equal to
3479 /// 3. Every element in `self[end..]`.
3480 ///
3481 /// This partial sort is unstable, meaning it may reorder equal elements in the specified range.
3482 /// It may reorder elements outside the specified range as well, but the guarantees above still hold.
3483 ///
3484 /// This partial sort is in-place (i.e., does not allocate), and *O*(*n* + *k* \* log(*k*)) worst-case,
3485 /// where *n* is the length of the slice and *k* is the length of the specified range.
3486 ///
3487 /// See the documentation of [`sort_unstable_by_key`] for implementation notes.
3488 ///
3489 /// # Panics
3490 ///
3491 /// May panic if the implementation of [`Ord`] for `K` does not implement a total order, or if
3492 /// the [`Ord`] implementation panics, or if the specified range is out of bounds.
3493 ///
3494 /// # Examples
3495 ///
3496 /// ```
3497 /// #![feature(slice_partial_sort_unstable)]
3498 ///
3499 /// let mut v = [4i32, -5, 1, -3, 2];
3500 ///
3501 /// // empty range at the beginning, nothing changed
3502 /// v.partial_sort_unstable_by_key(0..0, |k| k.abs());
3503 /// assert_eq!(v, [4, -5, 1, -3, 2]);
3504 ///
3505 /// // empty range in the middle, partitioning the slice
3506 /// v.partial_sort_unstable_by_key(2..2, |k| k.abs());
3507 /// for i in 0..2 {
3508 /// assert!(v[i].abs() <= v[2].abs());
3509 /// }
3510 /// for i in 3..v.len() {
3511 /// assert!(v[2].abs() <= v[i].abs());
3512 /// }
3513 ///
3514 /// // single element range, same as select_nth_unstable
3515 /// v.partial_sort_unstable_by_key(2..3, |k| k.abs());
3516 /// for i in 0..2 {
3517 /// assert!(v[i].abs() <= v[2].abs());
3518 /// }
3519 /// for i in 3..v.len() {
3520 /// assert!(v[2].abs() <= v[i].abs());
3521 /// }
3522 ///
3523 /// // partial sort a subrange
3524 /// v.partial_sort_unstable_by_key(1..4, |k| k.abs());
3525 /// assert_eq!(&v[1..4], [2, -3, 4]);
3526 ///
3527 /// // partial sort the whole range, same as sort_unstable
3528 /// v.partial_sort_unstable_by_key(.., |k| k.abs());
3529 /// assert_eq!(v, [1, 2, -3, 4, -5]);
3530 /// ```
3531 ///
3532 /// [`sort_unstable_by_key`]: slice::sort_unstable_by_key
3533 #[unstable(feature = "slice_partial_sort_unstable", issue = "149046")]
3534 #[inline]
3535 #[cfg(not(feature = "ferrocene_subset"))]
3536 pub fn partial_sort_unstable_by_key<K, F, R>(&mut self, range: R, mut f: F)
3537 where
3538 F: FnMut(&T) -> K,
3539 K: Ord,
3540 R: RangeBounds<usize>,
3541 {
3542 sort::unstable::partial_sort(self, range, |a, b| f(a).lt(&f(b)));
3543 }
3544
3545 /// Reorders the slice such that the element at `index` is at a sort-order position. All
3546 /// elements before `index` will be `<=` to this value, and all elements after will be `>=` to
3547 /// it.
3548 ///
3549 /// This reordering is unstable (i.e. any element that compares equal to the nth element may end
3550 /// up at that position), in-place (i.e. does not allocate), and runs in *O*(*n*) time. This
3551 /// function is also known as "kth element" in other libraries.
3552 ///
3553 /// Returns a triple that partitions the reordered slice:
3554 ///
3555 /// * The unsorted subslice before `index`, whose elements all satisfy `x <= self[index]`.
3556 ///
3557 /// * The element at `index`.
3558 ///
3559 /// * The unsorted subslice after `index`, whose elements all satisfy `x >= self[index]`.
3560 ///
3561 /// # Current implementation
3562 ///
3563 /// The current algorithm is an introselect implementation based on [ipnsort] by Lukas Bergdoll
3564 /// and Orson Peters, which is also the basis for [`sort_unstable`]. The fallback algorithm is
3565 /// Median of Medians using Tukey's Ninther for pivot selection, which guarantees linear runtime
3566 /// for all inputs.
3567 ///
3568 /// [`sort_unstable`]: slice::sort_unstable
3569 ///
3570 /// # Panics
3571 ///
3572 /// Panics when `index >= len()`, and so always panics on empty slices.
3573 ///
3574 /// May panic if the implementation of [`Ord`] for `T` does not implement a [total order].
3575 ///
3576 /// # Examples
3577 ///
3578 /// ```
3579 /// let mut v = [-5i32, 4, 2, -3, 1];
3580 ///
3581 /// // Find the items `<=` to the median, the median itself, and the items `>=` to it.
3582 /// let (lesser, median, greater) = v.select_nth_unstable(2);
3583 ///
3584 /// assert!(lesser == [-3, -5] || lesser == [-5, -3]);
3585 /// assert_eq!(median, &mut 1);
3586 /// assert!(greater == [4, 2] || greater == [2, 4]);
3587 ///
3588 /// // We are only guaranteed the slice will be one of the following, based on the way we sort
3589 /// // about the specified index.
3590 /// assert!(v == [-3, -5, 1, 2, 4] ||
3591 /// v == [-5, -3, 1, 2, 4] ||
3592 /// v == [-3, -5, 1, 4, 2] ||
3593 /// v == [-5, -3, 1, 4, 2]);
3594 /// ```
3595 ///
3596 /// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
3597 /// [total order]: https://en.wikipedia.org/wiki/Total_order
3598 #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")]
3599 #[inline]
3600 #[cfg(not(feature = "ferrocene_subset"))]
3601 pub fn select_nth_unstable(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T])
3602 where
3603 T: Ord,
3604 {
3605 sort::select::partition_at_index(self, index, T::lt)
3606 }
3607
3608 /// Reorders the slice with a comparator function such that the element at `index` is at a
3609 /// sort-order position. All elements before `index` will be `<=` to this value, and all
3610 /// elements after will be `>=` to it, according to the comparator function.
3611 ///
3612 /// This reordering is unstable (i.e. any element that compares equal to the nth element may end
3613 /// up at that position), in-place (i.e. does not allocate), and runs in *O*(*n*) time. This
3614 /// function is also known as "kth element" in other libraries.
3615 ///
3616 /// Returns a triple partitioning the reordered slice:
3617 ///
3618 /// * The unsorted subslice before `index`, whose elements all satisfy
3619 /// `compare(x, self[index]).is_le()`.
3620 ///
3621 /// * The element at `index`.
3622 ///
3623 /// * The unsorted subslice after `index`, whose elements all satisfy
3624 /// `compare(x, self[index]).is_ge()`.
3625 ///
3626 /// # Current implementation
3627 ///
3628 /// The current algorithm is an introselect implementation based on [ipnsort] by Lukas Bergdoll
3629 /// and Orson Peters, which is also the basis for [`sort_unstable`]. The fallback algorithm is
3630 /// Median of Medians using Tukey's Ninther for pivot selection, which guarantees linear runtime
3631 /// for all inputs.
3632 ///
3633 /// [`sort_unstable`]: slice::sort_unstable
3634 ///
3635 /// # Panics
3636 ///
3637 /// Panics when `index >= len()`, and so always panics on empty slices.
3638 ///
3639 /// May panic if `compare` does not implement a [total order].
3640 ///
3641 /// # Examples
3642 ///
3643 /// ```
3644 /// let mut v = [-5i32, 4, 2, -3, 1];
3645 ///
3646 /// // Find the items `>=` to the median, the median itself, and the items `<=` to it, by using
3647 /// // a reversed comparator.
3648 /// let (before, median, after) = v.select_nth_unstable_by(2, |a, b| b.cmp(a));
3649 ///
3650 /// assert!(before == [4, 2] || before == [2, 4]);
3651 /// assert_eq!(median, &mut 1);
3652 /// assert!(after == [-3, -5] || after == [-5, -3]);
3653 ///
3654 /// // We are only guaranteed the slice will be one of the following, based on the way we sort
3655 /// // about the specified index.
3656 /// assert!(v == [2, 4, 1, -5, -3] ||
3657 /// v == [2, 4, 1, -3, -5] ||
3658 /// v == [4, 2, 1, -5, -3] ||
3659 /// v == [4, 2, 1, -3, -5]);
3660 /// ```
3661 ///
3662 /// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
3663 /// [total order]: https://en.wikipedia.org/wiki/Total_order
3664 #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")]
3665 #[inline]
3666 #[cfg(not(feature = "ferrocene_subset"))]
3667 pub fn select_nth_unstable_by<F>(
3668 &mut self,
3669 index: usize,
3670 mut compare: F,
3671 ) -> (&mut [T], &mut T, &mut [T])
3672 where
3673 F: FnMut(&T, &T) -> Ordering,
3674 {
3675 sort::select::partition_at_index(self, index, |a: &T, b: &T| compare(a, b) == Less)
3676 }
3677
3678 /// Reorders the slice with a key extraction function such that the element at `index` is at a
3679 /// sort-order position. All elements before `index` will have keys `<=` to the key at `index`,
3680 /// and all elements after will have keys `>=` to it.
3681 ///
3682 /// This reordering is unstable (i.e. any element that compares equal to the nth element may end
3683 /// up at that position), in-place (i.e. does not allocate), and runs in *O*(*n*) time. This
3684 /// function is also known as "kth element" in other libraries.
3685 ///
3686 /// Returns a triple partitioning the reordered slice:
3687 ///
3688 /// * The unsorted subslice before `index`, whose elements all satisfy `f(x) <= f(self[index])`.
3689 ///
3690 /// * The element at `index`.
3691 ///
3692 /// * The unsorted subslice after `index`, whose elements all satisfy `f(x) >= f(self[index])`.
3693 ///
3694 /// # Current implementation
3695 ///
3696 /// The current algorithm is an introselect implementation based on [ipnsort] by Lukas Bergdoll
3697 /// and Orson Peters, which is also the basis for [`sort_unstable`]. The fallback algorithm is
3698 /// Median of Medians using Tukey's Ninther for pivot selection, which guarantees linear runtime
3699 /// for all inputs.
3700 ///
3701 /// [`sort_unstable`]: slice::sort_unstable
3702 ///
3703 /// # Panics
3704 ///
3705 /// Panics when `index >= len()`, meaning it always panics on empty slices.
3706 ///
3707 /// May panic if `K: Ord` does not implement a total order.
3708 ///
3709 /// # Examples
3710 ///
3711 /// ```
3712 /// let mut v = [-5i32, 4, 1, -3, 2];
3713 ///
3714 /// // Find the items `<=` to the absolute median, the absolute median itself, and the items
3715 /// // `>=` to it.
3716 /// let (lesser, median, greater) = v.select_nth_unstable_by_key(2, |a| a.abs());
3717 ///
3718 /// assert!(lesser == [1, 2] || lesser == [2, 1]);
3719 /// assert_eq!(median, &mut -3);
3720 /// assert!(greater == [4, -5] || greater == [-5, 4]);
3721 ///
3722 /// // We are only guaranteed the slice will be one of the following, based on the way we sort
3723 /// // about the specified index.
3724 /// assert!(v == [1, 2, -3, 4, -5] ||
3725 /// v == [1, 2, -3, -5, 4] ||
3726 /// v == [2, 1, -3, 4, -5] ||
3727 /// v == [2, 1, -3, -5, 4]);
3728 /// ```
3729 ///
3730 /// [ipnsort]: https://github.com/Voultapher/sort-research-rs/tree/main/ipnsort
3731 /// [total order]: https://en.wikipedia.org/wiki/Total_order
3732 #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")]
3733 #[inline]
3734 #[cfg(not(feature = "ferrocene_subset"))]
3735 pub fn select_nth_unstable_by_key<K, F>(
3736 &mut self,
3737 index: usize,
3738 mut f: F,
3739 ) -> (&mut [T], &mut T, &mut [T])
3740 where
3741 F: FnMut(&T) -> K,
3742 K: Ord,
3743 {
3744 sort::select::partition_at_index(self, index, |a: &T, b: &T| f(a).lt(&f(b)))
3745 }
3746
3747 /// Moves all consecutive repeated elements to the end of the slice according to the
3748 /// [`PartialEq`] trait implementation.
3749 ///
3750 /// Returns two slices. The first contains no consecutive repeated elements.
3751 /// The second contains all the duplicates in no specified order.
3752 ///
3753 /// If the slice is sorted, the first returned slice contains no duplicates.
3754 ///
3755 /// # Examples
3756 ///
3757 /// ```
3758 /// #![feature(slice_partition_dedup)]
3759 ///
3760 /// let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
3761 ///
3762 /// let (dedup, duplicates) = slice.partition_dedup();
3763 ///
3764 /// assert_eq!(dedup, [1, 2, 3, 2, 1]);
3765 /// assert_eq!(duplicates, [2, 3, 1]);
3766 /// ```
3767 #[unstable(feature = "slice_partition_dedup", issue = "54279")]
3768 #[inline]
3769 #[cfg(not(feature = "ferrocene_subset"))]
3770 pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])
3771 where
3772 T: PartialEq,
3773 {
3774 self.partition_dedup_by(|a, b| a == b)
3775 }
3776
3777 /// Moves all but the first of consecutive elements to the end of the slice satisfying
3778 /// a given equality relation.
3779 ///
3780 /// Returns two slices. The first contains no consecutive repeated elements.
3781 /// The second contains all the duplicates in no specified order.
3782 ///
3783 /// The `same_bucket` function is passed references to two elements from the slice and
3784 /// must determine if the elements compare equal. The elements are passed in opposite order
3785 /// from their order in the slice, so if `same_bucket(a, b)` returns `true`, `a` is moved
3786 /// at the end of the slice.
3787 ///
3788 /// If the slice is sorted, the first returned slice contains no duplicates.
3789 ///
3790 /// # Examples
3791 ///
3792 /// ```
3793 /// #![feature(slice_partition_dedup)]
3794 ///
3795 /// let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
3796 ///
3797 /// let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
3798 ///
3799 /// assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
3800 /// assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
3801 /// ```
3802 #[unstable(feature = "slice_partition_dedup", issue = "54279")]
3803 #[inline]
3804 #[cfg(not(feature = "ferrocene_subset"))]
3805 pub fn partition_dedup_by<F>(&mut self, mut same_bucket: F) -> (&mut [T], &mut [T])
3806 where
3807 F: FnMut(&mut T, &mut T) -> bool,
3808 {
3809 // Although we have a mutable reference to `self`, we cannot make
3810 // *arbitrary* changes. The `same_bucket` calls could panic, so we
3811 // must ensure that the slice is in a valid state at all times.
3812 //
3813 // The way that we handle this is by using swaps; we iterate
3814 // over all the elements, swapping as we go so that at the end
3815 // the elements we wish to keep are in the front, and those we
3816 // wish to reject are at the back. We can then split the slice.
3817 // This operation is still `O(n)`.
3818 //
3819 // Example: We start in this state, where `r` represents "next
3820 // read" and `w` represents "next_write".
3821 //
3822 // r
3823 // +---+---+---+---+---+---+
3824 // | 0 | 1 | 1 | 2 | 3 | 3 |
3825 // +---+---+---+---+---+---+
3826 // w
3827 //
3828 // Comparing self[r] against self[w-1], this is not a duplicate, so
3829 // we swap self[r] and self[w] (no effect as r==w) and then increment both
3830 // r and w, leaving us with:
3831 //
3832 // r
3833 // +---+---+---+---+---+---+
3834 // | 0 | 1 | 1 | 2 | 3 | 3 |
3835 // +---+---+---+---+---+---+
3836 // w
3837 //
3838 // Comparing self[r] against self[w-1], this value is a duplicate,
3839 // so we increment `r` but leave everything else unchanged:
3840 //
3841 // r
3842 // +---+---+---+---+---+---+
3843 // | 0 | 1 | 1 | 2 | 3 | 3 |
3844 // +---+---+---+---+---+---+
3845 // w
3846 //
3847 // Comparing self[r] against self[w-1], this is not a duplicate,
3848 // so swap self[r] and self[w] and advance r and w:
3849 //
3850 // r
3851 // +---+---+---+---+---+---+
3852 // | 0 | 1 | 2 | 1 | 3 | 3 |
3853 // +---+---+---+---+---+---+
3854 // w
3855 //
3856 // Not a duplicate, repeat:
3857 //
3858 // r
3859 // +---+---+---+---+---+---+
3860 // | 0 | 1 | 2 | 3 | 1 | 3 |
3861 // +---+---+---+---+---+---+
3862 // w
3863 //
3864 // Duplicate, advance r. End of slice. Split at w.
3865
3866 let len = self.len();
3867 if len <= 1 {
3868 return (self, &mut []);
3869 }
3870
3871 let ptr = self.as_mut_ptr();
3872 let mut next_read: usize = 1;
3873 let mut next_write: usize = 1;
3874
3875 // SAFETY: the `while` condition guarantees `next_read` and `next_write`
3876 // are less than `len`, thus are inside `self`. `prev_ptr_write` points to
3877 // one element before `ptr_write`, but `next_write` starts at 1, so
3878 // `prev_ptr_write` is never less than 0 and is inside the slice.
3879 // This fulfils the requirements for dereferencing `ptr_read`, `prev_ptr_write`
3880 // and `ptr_write`, and for using `ptr.add(next_read)`, `ptr.add(next_write - 1)`
3881 // and `prev_ptr_write.offset(1)`.
3882 //
3883 // `next_write` is also incremented at most once per loop at most meaning
3884 // no element is skipped when it may need to be swapped.
3885 //
3886 // `ptr_read` and `prev_ptr_write` never point to the same element. This
3887 // is required for `&mut *ptr_read`, `&mut *prev_ptr_write` to be safe.
3888 // The explanation is simply that `next_read >= next_write` is always true,
3889 // thus `next_read > next_write - 1` is too.
3890 unsafe {
3891 // Avoid bounds checks by using raw pointers.
3892 while next_read < len {
3893 let ptr_read = ptr.add(next_read);
3894 let prev_ptr_write = ptr.add(next_write - 1);
3895 if !same_bucket(&mut *ptr_read, &mut *prev_ptr_write) {
3896 if next_read != next_write {
3897 let ptr_write = prev_ptr_write.add(1);
3898 mem::swap(&mut *ptr_read, &mut *ptr_write);
3899 }
3900 next_write += 1;
3901 }
3902 next_read += 1;
3903 }
3904 }
3905
3906 self.split_at_mut(next_write)
3907 }
3908
3909 /// Moves all but the first of consecutive elements to the end of the slice that resolve
3910 /// to the same key.
3911 ///
3912 /// Returns two slices. The first contains no consecutive repeated elements.
3913 /// The second contains all the duplicates in no specified order.
3914 ///
3915 /// If the slice is sorted, the first returned slice contains no duplicates.
3916 ///
3917 /// # Examples
3918 ///
3919 /// ```
3920 /// #![feature(slice_partition_dedup)]
3921 ///
3922 /// let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
3923 ///
3924 /// let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
3925 ///
3926 /// assert_eq!(dedup, [10, 20, 30, 20, 11]);
3927 /// assert_eq!(duplicates, [21, 30, 13]);
3928 /// ```
3929 #[unstable(feature = "slice_partition_dedup", issue = "54279")]
3930 #[inline]
3931 #[cfg(not(feature = "ferrocene_subset"))]
3932 pub fn partition_dedup_by_key<K, F>(&mut self, mut key: F) -> (&mut [T], &mut [T])
3933 where
3934 F: FnMut(&mut T) -> K,
3935 K: PartialEq,
3936 {
3937 self.partition_dedup_by(|a, b| key(a) == key(b))
3938 }
3939
3940 /// Rotates the slice in-place such that the first `mid` elements of the
3941 /// slice move to the end while the last `self.len() - mid` elements move to
3942 /// the front.
3943 ///
3944 /// After calling `rotate_left`, the element previously at index `mid` will
3945 /// become the first element in the slice.
3946 ///
3947 /// # Panics
3948 ///
3949 /// This function will panic if `mid` is greater than the length of the
3950 /// slice. Note that `mid == self.len()` does _not_ panic and is a no-op
3951 /// rotation.
3952 ///
3953 /// # Complexity
3954 ///
3955 /// Takes linear (in `self.len()`) time.
3956 ///
3957 /// # Examples
3958 ///
3959 /// ```
3960 /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
3961 /// a.rotate_left(2);
3962 /// assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
3963 /// ```
3964 ///
3965 /// Rotating a subslice:
3966 ///
3967 /// ```
3968 /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
3969 /// a[1..5].rotate_left(1);
3970 /// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
3971 /// ```
3972 #[stable(feature = "slice_rotate", since = "1.26.0")]
3973 #[rustc_const_stable(feature = "const_slice_rotate", since = "1.92.0")]
3974 pub const fn rotate_left(&mut self, mid: usize) {
3975 assert!(mid <= self.len());
3976 let k = self.len() - mid;
3977 let p = self.as_mut_ptr();
3978
3979 // SAFETY: The range `[p.add(mid) - mid, p.add(mid) + k)` is trivially
3980 // valid for reading and writing, as required by `ptr_rotate`.
3981 unsafe {
3982 rotate::ptr_rotate(mid, p.add(mid), k);
3983 }
3984 }
3985
3986 /// Rotates the slice in-place such that the first `self.len() - k`
3987 /// elements of the slice move to the end while the last `k` elements move
3988 /// to the front.
3989 ///
3990 /// After calling `rotate_right`, the element previously at index
3991 /// `self.len() - k` will become the first element in the slice.
3992 ///
3993 /// # Panics
3994 ///
3995 /// This function will panic if `k` is greater than the length of the
3996 /// slice. Note that `k == self.len()` does _not_ panic and is a no-op
3997 /// rotation.
3998 ///
3999 /// # Complexity
4000 ///
4001 /// Takes linear (in `self.len()`) time.
4002 ///
4003 /// # Examples
4004 ///
4005 /// ```
4006 /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
4007 /// a.rotate_right(2);
4008 /// assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
4009 /// ```
4010 ///
4011 /// Rotating a subslice:
4012 ///
4013 /// ```
4014 /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
4015 /// a[1..5].rotate_right(1);
4016 /// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
4017 /// ```
4018 #[stable(feature = "slice_rotate", since = "1.26.0")]
4019 #[rustc_const_stable(feature = "const_slice_rotate", since = "1.92.0")]
4020 pub const fn rotate_right(&mut self, k: usize) {
4021 assert!(k <= self.len());
4022 let mid = self.len() - k;
4023 let p = self.as_mut_ptr();
4024
4025 // SAFETY: The range `[p.add(mid) - mid, p.add(mid) + k)` is trivially
4026 // valid for reading and writing, as required by `ptr_rotate`.
4027 unsafe {
4028 rotate::ptr_rotate(mid, p.add(mid), k);
4029 }
4030 }
4031
4032 /// Moves the elements of this slice `N` places to the left, returning the ones
4033 /// that "fall off" the front, and putting `inserted` at the end.
4034 ///
4035 /// Equivalently, you can think of concatenating `self` and `inserted` into one
4036 /// long sequence, then returning the left-most `N` items and the rest into `self`:
4037 ///
4038 /// ```text
4039 /// self (before) inserted
4040 /// vvvvvvvvvvvvvvv vvv
4041 /// [1, 2, 3, 4, 5] [9]
4042 /// ↙ ↙ ↙ ↙ ↙ ↙
4043 /// [1] [2, 3, 4, 5, 9]
4044 /// ^^^ ^^^^^^^^^^^^^^^
4045 /// returned self (after)
4046 /// ```
4047 ///
4048 /// See also [`Self::shift_right`] and compare [`Self::rotate_left`].
4049 ///
4050 /// # Examples
4051 ///
4052 /// ```
4053 /// #![feature(slice_shift)]
4054 ///
4055 /// // Same as the diagram above
4056 /// let mut a = [1, 2, 3, 4, 5];
4057 /// let inserted = [9];
4058 /// let returned = a.shift_left(inserted);
4059 /// assert_eq!(returned, [1]);
4060 /// assert_eq!(a, [2, 3, 4, 5, 9]);
4061 ///
4062 /// // You can shift multiple items at a time
4063 /// let mut a = *b"Hello world";
4064 /// assert_eq!(a.shift_left(*b" peace"), *b"Hello ");
4065 /// assert_eq!(a, *b"world peace");
4066 ///
4067 /// // The name comes from this operation's similarity to bitshifts
4068 /// let mut a: u8 = 0b10010110;
4069 /// a <<= 3;
4070 /// assert_eq!(a, 0b10110000_u8);
4071 /// let mut a: [_; 8] = [1, 0, 0, 1, 0, 1, 1, 0];
4072 /// a.shift_left([0; 3]);
4073 /// assert_eq!(a, [1, 0, 1, 1, 0, 0, 0, 0]);
4074 ///
4075 /// // Remember you can sub-slice to affect less that the whole slice.
4076 /// // For example, this is similar to `.remove(1)` + `.insert(4, 'Z')`
4077 /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
4078 /// assert_eq!(a[1..=4].shift_left(['Z']), ['b']);
4079 /// assert_eq!(a, ['a', 'c', 'd', 'e', 'Z', 'f']);
4080 ///
4081 /// // If the size matches it's equivalent to `mem::replace`
4082 /// let mut a = [1, 2, 3];
4083 /// assert_eq!(a.shift_left([7, 8, 9]), [1, 2, 3]);
4084 /// assert_eq!(a, [7, 8, 9]);
4085 ///
4086 /// // Some of the "inserted" elements end up returned if the slice is too short
4087 /// let mut a = [];
4088 /// assert_eq!(a.shift_left([1, 2, 3]), [1, 2, 3]);
4089 /// let mut a = [9];
4090 /// assert_eq!(a.shift_left([1, 2, 3]), [9, 1, 2]);
4091 /// assert_eq!(a, [3]);
4092 /// ```
4093 #[cfg(not(feature = "ferrocene_subset"))]
4094 #[unstable(feature = "slice_shift", issue = "151772")]
4095 pub const fn shift_left<const N: usize>(&mut self, inserted: [T; N]) -> [T; N] {
4096 if let Some(shift) = self.len().checked_sub(N) {
4097 // SAFETY: Having just checked that the inserted/returned arrays are
4098 // shorter than (or the same length as) the slice:
4099 // 1. The read for the items to return is in-bounds
4100 // 2. We can `memmove` the slice over to cover the items we're returning
4101 // to ensure those aren't double-dropped
4102 // 3. Then we write (in-bounds for the same reason as the read) the
4103 // inserted items atop the items of the slice that we just duplicated
4104 //
4105 // And none of this can panic, so there's no risk of intermediate unwinds.
4106 unsafe {
4107 let ptr = self.as_mut_ptr();
4108 let returned = ptr.cast_array::<N>().read();
4109 ptr.copy_from(ptr.add(N), shift);
4110 ptr.add(shift).cast_array::<N>().write(inserted);
4111 returned
4112 }
4113 } else {
4114 // SAFETY: Having checked that the slice is strictly shorter than the
4115 // inserted/returned arrays, it means we'll be copying the whole slice
4116 // into the returned array, but that's not enough on its own. We also
4117 // need to copy some of the inserted array into the returned array,
4118 // with the rest going into the slice. Because `&mut` is exclusive
4119 // and we own both `inserted` and `returned`, they're all disjoint
4120 // allocations from each other as we can use `nonoverlapping` copies.
4121 //
4122 // We avoid double-frees by `ManuallyDrop`ing the inserted items,
4123 // since we always copy them to other locations that will drop them
4124 // instead. Plus nothing in here can panic -- it's just memcpy three
4125 // times -- so there's no intermediate unwinds to worry about.
4126 unsafe {
4127 let len = self.len();
4128 let slice = self.as_mut_ptr();
4129 let inserted = mem::ManuallyDrop::new(inserted);
4130 let inserted = (&raw const inserted).cast::<T>();
4131
4132 let mut returned = MaybeUninit::<[T; N]>::uninit();
4133 let ptr = returned.as_mut_ptr().cast::<T>();
4134 ptr.copy_from_nonoverlapping(slice, len);
4135 ptr.add(len).copy_from_nonoverlapping(inserted, N - len);
4136 slice.copy_from_nonoverlapping(inserted.add(N - len), len);
4137 returned.assume_init()
4138 }
4139 }
4140 }
4141
4142 /// Moves the elements of this slice `N` places to the right, returning the ones
4143 /// that "fall off" the back, and putting `inserted` at the beginning.
4144 ///
4145 /// Equivalently, you can think of concatenating `inserted` and `self` into one
4146 /// long sequence, then returning the right-most `N` items and the rest into `self`:
4147 ///
4148 /// ```text
4149 /// inserted self (before)
4150 /// vvv vvvvvvvvvvvvvvv
4151 /// [0] [5, 6, 7, 8, 9]
4152 /// ↘ ↘ ↘ ↘ ↘ ↘
4153 /// [0, 5, 6, 7, 8] [9]
4154 /// ^^^^^^^^^^^^^^^ ^^^
4155 /// self (after) returned
4156 /// ```
4157 ///
4158 /// See also [`Self::shift_left`] and compare [`Self::rotate_right`].
4159 ///
4160 /// # Examples
4161 ///
4162 /// ```
4163 /// #![feature(slice_shift)]
4164 ///
4165 /// // Same as the diagram above
4166 /// let mut a = [5, 6, 7, 8, 9];
4167 /// let inserted = [0];
4168 /// let returned = a.shift_right(inserted);
4169 /// assert_eq!(returned, [9]);
4170 /// assert_eq!(a, [0, 5, 6, 7, 8]);
4171 ///
4172 /// // The name comes from this operation's similarity to bitshifts
4173 /// let mut a: u8 = 0b10010110;
4174 /// a >>= 3;
4175 /// assert_eq!(a, 0b00010010_u8);
4176 /// let mut a: [_; 8] = [1, 0, 0, 1, 0, 1, 1, 0];
4177 /// a.shift_right([0; 3]);
4178 /// assert_eq!(a, [0, 0, 0, 1, 0, 0, 1, 0]);
4179 ///
4180 /// // Remember you can sub-slice to affect less that the whole slice.
4181 /// // For example, this is similar to `.remove(4)` + `.insert(1, 'Z')`
4182 /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
4183 /// assert_eq!(a[1..=4].shift_right(['Z']), ['e']);
4184 /// assert_eq!(a, ['a', 'Z', 'b', 'c', 'd', 'f']);
4185 ///
4186 /// // If the size matches it's equivalent to `mem::replace`
4187 /// let mut a = [1, 2, 3];
4188 /// assert_eq!(a.shift_right([7, 8, 9]), [1, 2, 3]);
4189 /// assert_eq!(a, [7, 8, 9]);
4190 ///
4191 /// // Some of the "inserted" elements end up returned if the slice is too short
4192 /// let mut a = [];
4193 /// assert_eq!(a.shift_right([1, 2, 3]), [1, 2, 3]);
4194 /// let mut a = [9];
4195 /// assert_eq!(a.shift_right([1, 2, 3]), [2, 3, 9]);
4196 /// assert_eq!(a, [1]);
4197 /// ```
4198 #[cfg(not(feature = "ferrocene_subset"))]
4199 #[unstable(feature = "slice_shift", issue = "151772")]
4200 pub const fn shift_right<const N: usize>(&mut self, inserted: [T; N]) -> [T; N] {
4201 if let Some(shift) = self.len().checked_sub(N) {
4202 // SAFETY: Having just checked that the inserted/returned arrays are
4203 // shorter than (or the same length as) the slice:
4204 // 1. The read for the items to return is in-bounds
4205 // 2. We can `memmove` the slice over to cover the items we're returning
4206 // to ensure those aren't double-dropped
4207 // 3. Then we write (in-bounds for the same reason as the read) the
4208 // inserted items atop the items of the slice that we just duplicated
4209 //
4210 // And none of this can panic, so there's no risk of intermediate unwinds.
4211 unsafe {
4212 let ptr = self.as_mut_ptr();
4213 let returned = ptr.add(shift).cast_array::<N>().read();
4214 ptr.add(N).copy_from(ptr, shift);
4215 ptr.cast_array::<N>().write(inserted);
4216 returned
4217 }
4218 } else {
4219 // SAFETY: Having checked that the slice is strictly shorter than the
4220 // inserted/returned arrays, it means we'll be copying the whole slice
4221 // into the returned array, but that's not enough on its own. We also
4222 // need to copy some of the inserted array into the returned array,
4223 // with the rest going into the slice. Because `&mut` is exclusive
4224 // and we own both `inserted` and `returned`, they're all disjoint
4225 // allocations from each other as we can use `nonoverlapping` copies.
4226 //
4227 // We avoid double-frees by `ManuallyDrop`ing the inserted items,
4228 // since we always copy them to other locations that will drop them
4229 // instead. Plus nothing in here can panic -- it's just memcpy three
4230 // times -- so there's no intermediate unwinds to worry about.
4231 unsafe {
4232 let len = self.len();
4233 let slice = self.as_mut_ptr();
4234 let inserted = mem::ManuallyDrop::new(inserted);
4235 let inserted = (&raw const inserted).cast::<T>();
4236
4237 let mut returned = MaybeUninit::<[T; N]>::uninit();
4238 let ptr = returned.as_mut_ptr().cast::<T>();
4239 ptr.add(N - len).copy_from_nonoverlapping(slice, len);
4240 ptr.copy_from_nonoverlapping(inserted.add(len), N - len);
4241 slice.copy_from_nonoverlapping(inserted, len);
4242 returned.assume_init()
4243 }
4244 }
4245 }
4246
4247 /// Fills `self` with elements by cloning `value`.
4248 ///
4249 /// # Examples
4250 ///
4251 /// ```
4252 /// let mut buf = vec![0; 10];
4253 /// buf.fill(1);
4254 /// assert_eq!(buf, vec![1; 10]);
4255 /// ```
4256 #[doc(alias = "memset")]
4257 #[stable(feature = "slice_fill", since = "1.50.0")]
4258 pub fn fill(&mut self, value: T)
4259 where
4260 T: Clone,
4261 {
4262 specialize::SpecFill::spec_fill(self, value);
4263 }
4264
4265 /// Fills `self` with elements returned by calling a closure repeatedly.
4266 ///
4267 /// This method uses a closure to create new values. If you'd rather
4268 /// [`Clone`] a given value, use [`fill`]. If you want to use the [`Default`]
4269 /// trait to generate values, you can pass [`Default::default`] as the
4270 /// argument.
4271 ///
4272 /// [`fill`]: slice::fill
4273 ///
4274 /// # Examples
4275 ///
4276 /// ```
4277 /// let mut buf = vec![1; 10];
4278 /// buf.fill_with(Default::default);
4279 /// assert_eq!(buf, vec![0; 10]);
4280 /// ```
4281 #[stable(feature = "slice_fill_with", since = "1.51.0")]
4282 #[cfg(not(feature = "ferrocene_subset"))]
4283 pub fn fill_with<F>(&mut self, mut f: F)
4284 where
4285 F: FnMut() -> T,
4286 {
4287 for el in self {
4288 *el = f();
4289 }
4290 }
4291
4292 /// Copies the elements from `src` into `self`.
4293 ///
4294 /// The length of `src` must be the same as `self`.
4295 ///
4296 /// # Panics
4297 ///
4298 /// This function will panic if the two slices have different lengths.
4299 ///
4300 /// # Examples
4301 ///
4302 /// Cloning two elements from a slice into another:
4303 ///
4304 /// ```
4305 /// let src = [1, 2, 3, 4];
4306 /// let mut dst = [0, 0];
4307 ///
4308 /// // Because the slices have to be the same length,
4309 /// // we slice the source slice from four elements
4310 /// // to two. It will panic if we don't do this.
4311 /// dst.clone_from_slice(&src[2..]);
4312 ///
4313 /// assert_eq!(src, [1, 2, 3, 4]);
4314 /// assert_eq!(dst, [3, 4]);
4315 /// ```
4316 ///
4317 /// Rust enforces that there can only be one mutable reference with no
4318 /// immutable references to a particular piece of data in a particular
4319 /// scope. Because of this, attempting to use `clone_from_slice` on a
4320 /// single slice will result in a compile failure:
4321 ///
4322 /// ```compile_fail
4323 /// let mut slice = [1, 2, 3, 4, 5];
4324 ///
4325 /// slice[..2].clone_from_slice(&slice[3..]); // compile fail!
4326 /// ```
4327 ///
4328 /// To work around this, we can use [`split_at_mut`] to create two distinct
4329 /// sub-slices from a slice:
4330 ///
4331 /// ```
4332 /// let mut slice = [1, 2, 3, 4, 5];
4333 ///
4334 /// {
4335 /// let (left, right) = slice.split_at_mut(2);
4336 /// left.clone_from_slice(&right[1..]);
4337 /// }
4338 ///
4339 /// assert_eq!(slice, [4, 5, 3, 4, 5]);
4340 /// ```
4341 ///
4342 /// [`copy_from_slice`]: slice::copy_from_slice
4343 /// [`split_at_mut`]: slice::split_at_mut
4344 #[stable(feature = "clone_from_slice", since = "1.7.0")]
4345 #[track_caller]
4346 #[rustc_const_unstable(feature = "const_clone", issue = "142757")]
4347 pub const fn clone_from_slice(&mut self, src: &[T])
4348 where
4349 T: [const] Clone + [const] Destruct,
4350 {
4351 self.spec_clone_from(src);
4352 }
4353
4354 /// Copies all elements from `src` into `self`, using a memcpy.
4355 ///
4356 /// The length of `src` must be the same as `self`.
4357 ///
4358 /// If `T` does not implement `Copy`, use [`clone_from_slice`].
4359 ///
4360 /// # Panics
4361 ///
4362 /// This function will panic if the two slices have different lengths.
4363 ///
4364 /// # Examples
4365 ///
4366 /// Copying two elements from a slice into another:
4367 ///
4368 /// ```
4369 /// let src = [1, 2, 3, 4];
4370 /// let mut dst = [0, 0];
4371 ///
4372 /// // Because the slices have to be the same length,
4373 /// // we slice the source slice from four elements
4374 /// // to two. It will panic if we don't do this.
4375 /// dst.copy_from_slice(&src[2..]);
4376 ///
4377 /// assert_eq!(src, [1, 2, 3, 4]);
4378 /// assert_eq!(dst, [3, 4]);
4379 /// ```
4380 ///
4381 /// Rust enforces that there can only be one mutable reference with no
4382 /// immutable references to a particular piece of data in a particular
4383 /// scope. Because of this, attempting to use `copy_from_slice` on a
4384 /// single slice will result in a compile failure:
4385 ///
4386 /// ```compile_fail
4387 /// let mut slice = [1, 2, 3, 4, 5];
4388 ///
4389 /// slice[..2].copy_from_slice(&slice[3..]); // compile fail!
4390 /// ```
4391 ///
4392 /// To work around this, we can use [`split_at_mut`] to create two distinct
4393 /// sub-slices from a slice:
4394 ///
4395 /// ```
4396 /// let mut slice = [1, 2, 3, 4, 5];
4397 ///
4398 /// {
4399 /// let (left, right) = slice.split_at_mut(2);
4400 /// left.copy_from_slice(&right[1..]);
4401 /// }
4402 ///
4403 /// assert_eq!(slice, [4, 5, 3, 4, 5]);
4404 /// ```
4405 ///
4406 /// [`clone_from_slice`]: slice::clone_from_slice
4407 /// [`split_at_mut`]: slice::split_at_mut
4408 #[doc(alias = "memcpy")]
4409 #[inline]
4410 #[stable(feature = "copy_from_slice", since = "1.9.0")]
4411 #[rustc_const_stable(feature = "const_copy_from_slice", since = "1.87.0")]
4412 #[track_caller]
4413 pub const fn copy_from_slice(&mut self, src: &[T])
4414 where
4415 T: Copy,
4416 {
4417 // SAFETY: `T` implements `Copy`.
4418 unsafe { copy_from_slice_impl(self, src) }
4419 }
4420
4421 /// Copies elements from one part of the slice to another part of itself,
4422 /// using a memmove.
4423 ///
4424 /// `src` is the range within `self` to copy from. `dest` is the starting
4425 /// index of the range within `self` to copy to, which will have the same
4426 /// length as `src`. The two ranges may overlap. The ends of the two ranges
4427 /// must be less than or equal to `self.len()`.
4428 ///
4429 /// # Panics
4430 ///
4431 /// This function will panic if either range exceeds the end of the slice,
4432 /// or if the end of `src` is before the start.
4433 ///
4434 /// # Examples
4435 ///
4436 /// Copying four bytes within a slice:
4437 ///
4438 /// ```
4439 /// let mut bytes = *b"Hello, World!";
4440 ///
4441 /// bytes.copy_within(1..5, 8);
4442 ///
4443 /// assert_eq!(&bytes, b"Hello, Wello!");
4444 /// ```
4445 #[stable(feature = "copy_within", since = "1.37.0")]
4446 #[track_caller]
4447 #[cfg(not(feature = "ferrocene_subset"))]
4448 pub fn copy_within<R: RangeBounds<usize>>(&mut self, src: R, dest: usize)
4449 where
4450 T: Copy,
4451 {
4452 let Range { start: src_start, end: src_end } = slice::range(src, ..self.len());
4453 let count = src_end - src_start;
4454 assert!(dest <= self.len() - count, "dest is out of bounds");
4455 // SAFETY: the conditions for `ptr::copy` have all been checked above,
4456 // as have those for `ptr::add`.
4457 unsafe {
4458 // Derive both `src_ptr` and `dest_ptr` from the same loan
4459 let ptr = self.as_mut_ptr();
4460 let src_ptr = ptr.add(src_start);
4461 let dest_ptr = ptr.add(dest);
4462 ptr::copy(src_ptr, dest_ptr, count);
4463 }
4464 }
4465
4466 /// Swaps all elements in `self` with those in `other`.
4467 ///
4468 /// The length of `other` must be the same as `self`.
4469 ///
4470 /// # Panics
4471 ///
4472 /// This function will panic if the two slices have different lengths.
4473 ///
4474 /// # Example
4475 ///
4476 /// Swapping two elements across slices:
4477 ///
4478 /// ```
4479 /// let mut slice1 = [0, 0];
4480 /// let mut slice2 = [1, 2, 3, 4];
4481 ///
4482 /// slice1.swap_with_slice(&mut slice2[2..]);
4483 ///
4484 /// assert_eq!(slice1, [3, 4]);
4485 /// assert_eq!(slice2, [1, 2, 0, 0]);
4486 /// ```
4487 ///
4488 /// Rust enforces that there can only be one mutable reference to a
4489 /// particular piece of data in a particular scope. Because of this,
4490 /// attempting to use `swap_with_slice` on a single slice will result in
4491 /// a compile failure:
4492 ///
4493 /// ```compile_fail
4494 /// let mut slice = [1, 2, 3, 4, 5];
4495 /// slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
4496 /// ```
4497 ///
4498 /// To work around this, we can use [`split_at_mut`] to create two distinct
4499 /// mutable sub-slices from a slice:
4500 ///
4501 /// ```
4502 /// let mut slice = [1, 2, 3, 4, 5];
4503 ///
4504 /// {
4505 /// let (left, right) = slice.split_at_mut(2);
4506 /// left.swap_with_slice(&mut right[1..]);
4507 /// }
4508 ///
4509 /// assert_eq!(slice, [4, 5, 3, 1, 2]);
4510 /// ```
4511 ///
4512 /// [`split_at_mut`]: slice::split_at_mut
4513 #[stable(feature = "swap_with_slice", since = "1.27.0")]
4514 #[rustc_const_unstable(feature = "const_swap_with_slice", issue = "142204")]
4515 #[track_caller]
4516 #[cfg(not(feature = "ferrocene_subset"))]
4517 pub const fn swap_with_slice(&mut self, other: &mut [T]) {
4518 assert!(self.len() == other.len(), "destination and source slices have different lengths");
4519 // SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was
4520 // checked to have the same length. The slices cannot overlap because
4521 // mutable references are exclusive.
4522 unsafe {
4523 ptr::swap_nonoverlapping(self.as_mut_ptr(), other.as_mut_ptr(), self.len());
4524 }
4525 }
4526
4527 /// Function to calculate lengths of the middle and trailing slice for `align_to{,_mut}`.
4528
4529 fn align_to_offsets<U>(&self) -> (usize, usize) {
4530 // What we gonna do about `rest` is figure out what multiple of `U`s we can put in a
4531 // lowest number of `T`s. And how many `T`s we need for each such "multiple".
4532 //
4533 // Consider for example T=u8 U=u16. Then we can put 1 U in 2 Ts. Simple. Now, consider
4534 // for example a case where size_of::<T> = 16, size_of::<U> = 24. We can put 2 Us in
4535 // place of every 3 Ts in the `rest` slice. A bit more complicated.
4536 //
4537 // Formula to calculate this is:
4538 //
4539 // Us = lcm(size_of::<T>, size_of::<U>) / size_of::<U>
4540 // Ts = lcm(size_of::<T>, size_of::<U>) / size_of::<T>
4541 //
4542 // Expanded and simplified:
4543 //
4544 // Us = size_of::<T> / gcd(size_of::<T>, size_of::<U>)
4545 // Ts = size_of::<U> / gcd(size_of::<T>, size_of::<U>)
4546 //
4547 // Luckily since all this is constant-evaluated... performance here matters not!
4548 #[ferrocene::annotation(
4549 "the only use of this function is in a const block, which means it cannot be reached during runtime"
4550 )]
4551 const fn gcd(a: usize, b: usize) -> usize {
4552 if b == 0 { a } else { gcd(b, a % b) }
4553 }
4554
4555 // Explicitly wrap the function call in a const block so it gets
4556 // constant-evaluated even in debug mode.
4557 let gcd: usize = const { gcd(size_of::<T>(), size_of::<U>()) };
4558 let ts: usize = size_of::<U>() / gcd;
4559 let us: usize = size_of::<T>() / gcd;
4560
4561 // Armed with this knowledge, we can find how many `U`s we can fit!
4562 let us_len = self.len() / ts * us;
4563 // And how many `T`s will be in the trailing slice!
4564 let ts_len = self.len() % ts;
4565 (us_len, ts_len)
4566 }
4567
4568 /// Transmutes the slice to a slice of another type, ensuring alignment of the types is
4569 /// maintained.
4570 ///
4571 /// This method splits the slice into three distinct slices: prefix, correctly aligned middle
4572 /// slice of a new type, and the suffix slice. The middle part will be as big as possible under
4573 /// the given alignment constraint and element size.
4574 ///
4575 /// This method has no purpose when either input element `T` or output element `U` are
4576 /// zero-sized and will return the original slice without splitting anything.
4577 ///
4578 /// # Safety
4579 ///
4580 /// This method is essentially a `transmute` with respect to the elements in the returned
4581 /// middle slice, so all the usual caveats pertaining to `transmute::<T, U>` also apply here.
4582 ///
4583 /// # Examples
4584 ///
4585 /// Basic usage:
4586 ///
4587 /// ```
4588 /// unsafe {
4589 /// let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
4590 /// let (prefix, shorts, suffix) = bytes.align_to::<u16>();
4591 /// // less_efficient_algorithm_for_bytes(prefix);
4592 /// // more_efficient_algorithm_for_aligned_shorts(shorts);
4593 /// // less_efficient_algorithm_for_bytes(suffix);
4594 /// }
4595 /// ```
4596 #[stable(feature = "slice_align_to", since = "1.30.0")]
4597 #[must_use]
4598 pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T]) {
4599 // Note that most of this function will be constant-evaluated,
4600 if U::IS_ZST || T::IS_ZST {
4601 // handle ZSTs specially, which is – don't handle them at all.
4602 return (self, &[], &[]);
4603 }
4604
4605 // First, find at what point do we split between the first and 2nd slice. Easy with
4606 // ptr.align_offset.
4607 let ptr = self.as_ptr();
4608 // SAFETY: See the `align_to_mut` method for the detailed safety comment.
4609 let offset = unsafe { crate::ptr::align_offset(ptr, align_of::<U>()) };
4610 if offset > self.len() {
4611 (self, &[], &[])
4612 } else {
4613 let (left, rest) = self.split_at(offset);
4614 let (us_len, ts_len) = rest.align_to_offsets::<U>();
4615 // Inform Miri that we want to consider the "middle" pointer to be suitably aligned.
4616 #[cfg(miri)]
4617 crate::intrinsics::miri_promise_symbolic_alignment(
4618 rest.as_ptr().cast(),
4619 align_of::<U>(),
4620 );
4621 // SAFETY: now `rest` is definitely aligned, so `from_raw_parts` below is okay,
4622 // since the caller guarantees that we can transmute `T` to `U` safely.
4623 unsafe {
4624 (
4625 left,
4626 from_raw_parts(rest.as_ptr() as *const U, us_len),
4627 from_raw_parts(rest.as_ptr().add(rest.len() - ts_len), ts_len),
4628 )
4629 }
4630 }
4631 }
4632
4633 /// Transmutes the mutable slice to a mutable slice of another type, ensuring alignment of the
4634 /// types is maintained.
4635 ///
4636 /// This method splits the slice into three distinct slices: prefix, correctly aligned middle
4637 /// slice of a new type, and the suffix slice. The middle part will be as big as possible under
4638 /// the given alignment constraint and element size.
4639 ///
4640 /// This method has no purpose when either input element `T` or output element `U` are
4641 /// zero-sized and will return the original slice without splitting anything.
4642 ///
4643 /// # Safety
4644 ///
4645 /// This method is essentially a `transmute` with respect to the elements in the returned
4646 /// middle slice, so all the usual caveats pertaining to `transmute::<T, U>` also apply here.
4647 ///
4648 /// # Examples
4649 ///
4650 /// Basic usage:
4651 ///
4652 /// ```
4653 /// unsafe {
4654 /// let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
4655 /// let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
4656 /// // less_efficient_algorithm_for_bytes(prefix);
4657 /// // more_efficient_algorithm_for_aligned_shorts(shorts);
4658 /// // less_efficient_algorithm_for_bytes(suffix);
4659 /// }
4660 /// ```
4661 #[stable(feature = "slice_align_to", since = "1.30.0")]
4662 #[must_use]
4663 pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T]) {
4664 // Note that most of this function will be constant-evaluated,
4665 if U::IS_ZST || T::IS_ZST {
4666 // handle ZSTs specially, which is – don't handle them at all.
4667 return (self, &mut [], &mut []);
4668 }
4669
4670 // First, find at what point do we split between the first and 2nd slice. Easy with
4671 // ptr.align_offset.
4672 let ptr = self.as_ptr();
4673 // SAFETY: Here we are ensuring we will use aligned pointers for U for the
4674 // rest of the method. This is done by passing a pointer to &[T] with an
4675 // alignment targeted for U.
4676 // `crate::ptr::align_offset` is called with a correctly aligned and
4677 // valid pointer `ptr` (it comes from a reference to `self`) and with
4678 // a size that is a power of two (since it comes from the alignment for U),
4679 // satisfying its safety constraints.
4680 let offset = unsafe { crate::ptr::align_offset(ptr, align_of::<U>()) };
4681 if offset > self.len() {
4682 (self, &mut [], &mut [])
4683 } else {
4684 let (left, rest) = self.split_at_mut(offset);
4685 let (us_len, ts_len) = rest.align_to_offsets::<U>();
4686 let rest_len = rest.len();
4687 let mut_ptr = rest.as_mut_ptr();
4688 // Inform Miri that we want to consider the "middle" pointer to be suitably aligned.
4689 #[cfg(miri)]
4690 crate::intrinsics::miri_promise_symbolic_alignment(
4691 mut_ptr.cast() as *const (),
4692 align_of::<U>(),
4693 );
4694 // We can't use `rest` again after this, that would invalidate its alias `mut_ptr`!
4695 // SAFETY: see comments for `align_to`.
4696 unsafe {
4697 (
4698 left,
4699 from_raw_parts_mut(mut_ptr as *mut U, us_len),
4700 from_raw_parts_mut(mut_ptr.add(rest_len - ts_len), ts_len),
4701 )
4702 }
4703 }
4704 }
4705
4706 /// Splits a slice into a prefix, a middle of aligned SIMD types, and a suffix.
4707 ///
4708 /// This is a safe wrapper around [`slice::align_to`], so inherits the same
4709 /// guarantees as that method.
4710 ///
4711 /// # Panics
4712 ///
4713 /// This will panic if the size of the SIMD type is different from
4714 /// `LANES` times that of the scalar.
4715 ///
4716 /// At the time of writing, the trait restrictions on `Simd<T, LANES>` keeps
4717 /// that from ever happening, as only power-of-two numbers of lanes are
4718 /// supported. It's possible that, in the future, those restrictions might
4719 /// be lifted in a way that would make it possible to see panics from this
4720 /// method for something like `LANES == 3`.
4721 ///
4722 /// # Examples
4723 ///
4724 /// ```
4725 /// #![feature(portable_simd)]
4726 /// use core::simd::prelude::*;
4727 ///
4728 /// let short = &[1, 2, 3];
4729 /// let (prefix, middle, suffix) = short.as_simd::<4>();
4730 /// assert_eq!(middle, []); // Not enough elements for anything in the middle
4731 ///
4732 /// // They might be split in any possible way between prefix and suffix
4733 /// let it = prefix.iter().chain(suffix).copied();
4734 /// assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
4735 ///
4736 /// fn basic_simd_sum(x: &[f32]) -> f32 {
4737 /// use std::ops::Add;
4738 /// let (prefix, middle, suffix) = x.as_simd();
4739 /// let sums = f32x4::from_array([
4740 /// prefix.iter().copied().sum(),
4741 /// 0.0,
4742 /// 0.0,
4743 /// suffix.iter().copied().sum(),
4744 /// ]);
4745 /// let sums = middle.iter().copied().fold(sums, f32x4::add);
4746 /// sums.reduce_sum()
4747 /// }
4748 ///
4749 /// let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
4750 /// assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
4751 /// ```
4752 #[unstable(feature = "portable_simd", issue = "86656")]
4753 #[must_use]
4754 #[cfg(not(feature = "ferrocene_subset"))]
4755 pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
4756 where
4757 Simd<T, LANES>: AsRef<[T; LANES]>,
4758 T: simd::SimdElement,
4759 {
4760 // These are expected to always match, as vector types are laid out like
4761 // arrays per <https://llvm.org/docs/LangRef.html#vector-type>, but we
4762 // might as well double-check since it'll optimize away anyhow.
4763 assert_eq!(size_of::<Simd<T, LANES>>(), size_of::<[T; LANES]>());
4764
4765 // SAFETY: The simd types have the same layout as arrays, just with
4766 // potentially-higher alignment, so the de-facto transmutes are sound.
4767 unsafe { self.align_to() }
4768 }
4769
4770 /// Splits a mutable slice into a mutable prefix, a middle of aligned SIMD types,
4771 /// and a mutable suffix.
4772 ///
4773 /// This is a safe wrapper around [`slice::align_to_mut`], so inherits the same
4774 /// guarantees as that method.
4775 ///
4776 /// This is the mutable version of [`slice::as_simd`]; see that for examples.
4777 ///
4778 /// # Panics
4779 ///
4780 /// This will panic if the size of the SIMD type is different from
4781 /// `LANES` times that of the scalar.
4782 ///
4783 /// At the time of writing, the trait restrictions on `Simd<T, LANES>` keeps
4784 /// that from ever happening, as only power-of-two numbers of lanes are
4785 /// supported. It's possible that, in the future, those restrictions might
4786 /// be lifted in a way that would make it possible to see panics from this
4787 /// method for something like `LANES == 3`.
4788 #[unstable(feature = "portable_simd", issue = "86656")]
4789 #[must_use]
4790 #[cfg(not(feature = "ferrocene_subset"))]
4791 pub fn as_simd_mut<const LANES: usize>(&mut self) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])
4792 where
4793 Simd<T, LANES>: AsMut<[T; LANES]>,
4794 T: simd::SimdElement,
4795 {
4796 // These are expected to always match, as vector types are laid out like
4797 // arrays per <https://llvm.org/docs/LangRef.html#vector-type>, but we
4798 // might as well double-check since it'll optimize away anyhow.
4799 assert_eq!(size_of::<Simd<T, LANES>>(), size_of::<[T; LANES]>());
4800
4801 // SAFETY: The simd types have the same layout as arrays, just with
4802 // potentially-higher alignment, so the de-facto transmutes are sound.
4803 unsafe { self.align_to_mut() }
4804 }
4805
4806 /// Checks if the elements of this slice are sorted.
4807 ///
4808 /// That is, for each element `a` and its following element `b`, `a <= b` must hold. If the
4809 /// slice yields exactly zero or one element, `true` is returned.
4810 ///
4811 /// Note that if `Self::Item` is only `PartialOrd`, but not `Ord`, the above definition
4812 /// implies that this function returns `false` if any two consecutive items are not
4813 /// comparable.
4814 ///
4815 /// # Examples
4816 ///
4817 /// ```
4818 /// let empty: [i32; 0] = [];
4819 ///
4820 /// assert!([1, 2, 2, 9].is_sorted());
4821 /// assert!(![1, 3, 2, 4].is_sorted());
4822 /// assert!([0].is_sorted());
4823 /// assert!(empty.is_sorted());
4824 /// assert!(![0.0, 1.0, f32::NAN].is_sorted());
4825 /// ```
4826 #[inline]
4827 #[stable(feature = "is_sorted", since = "1.82.0")]
4828 #[must_use]
4829 #[cfg(not(feature = "ferrocene_subset"))]
4830 pub fn is_sorted(&self) -> bool
4831 where
4832 T: PartialOrd,
4833 {
4834 // This odd number works the best. 32 + 1 extra due to overlapping chunk boundaries.
4835 const CHUNK_SIZE: usize = 33;
4836 if self.len() < CHUNK_SIZE {
4837 return self.windows(2).all(|w| w[0] <= w[1]);
4838 }
4839 let mut i = 0;
4840 // Check in chunks for autovectorization.
4841 while i < self.len() - CHUNK_SIZE {
4842 let chunk = &self[i..i + CHUNK_SIZE];
4843 if !chunk.windows(2).fold(true, |acc, w| acc & (w[0] <= w[1])) {
4844 return false;
4845 }
4846 // We need to ensure that chunk boundaries are also sorted.
4847 // Overlap the next chunk with the last element of our last chunk.
4848 i += CHUNK_SIZE - 1;
4849 }
4850 self[i..].windows(2).all(|w| w[0] <= w[1])
4851 }
4852
4853 /// Checks if the elements of this slice are sorted using the given comparator function.
4854 ///
4855 /// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare`
4856 /// function to determine whether two elements are to be considered in sorted order.
4857 ///
4858 /// # Examples
4859 ///
4860 /// ```
4861 /// assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
4862 /// assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
4863 ///
4864 /// assert!([0].is_sorted_by(|a, b| true));
4865 /// assert!([0].is_sorted_by(|a, b| false));
4866 ///
4867 /// let empty: [i32; 0] = [];
4868 /// assert!(empty.is_sorted_by(|a, b| false));
4869 /// assert!(empty.is_sorted_by(|a, b| true));
4870 /// ```
4871 #[stable(feature = "is_sorted", since = "1.82.0")]
4872 #[must_use]
4873 #[cfg(not(feature = "ferrocene_subset"))]
4874 pub fn is_sorted_by<'a, F>(&'a self, mut compare: F) -> bool
4875 where
4876 F: FnMut(&'a T, &'a T) -> bool,
4877 {
4878 self.array_windows().all(|[a, b]| compare(a, b))
4879 }
4880
4881 /// Checks if the elements of this slice are sorted using the given key extraction function.
4882 ///
4883 /// Instead of comparing the slice's elements directly, this function compares the keys of the
4884 /// elements, as determined by `f`. Apart from that, it's equivalent to [`is_sorted`]; see its
4885 /// documentation for more information.
4886 ///
4887 /// [`is_sorted`]: slice::is_sorted
4888 ///
4889 /// # Examples
4890 ///
4891 /// ```
4892 /// assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
4893 /// assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
4894 /// ```
4895 #[inline]
4896 #[stable(feature = "is_sorted", since = "1.82.0")]
4897 #[must_use]
4898 #[cfg(not(feature = "ferrocene_subset"))]
4899 pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
4900 where
4901 F: FnMut(&'a T) -> K,
4902 K: PartialOrd,
4903 {
4904 self.iter().is_sorted_by_key(f)
4905 }
4906
4907 /// Returns the index of the partition point according to the given predicate
4908 /// (the index of the first element of the second partition).
4909 ///
4910 /// The slice is assumed to be partitioned according to the given predicate.
4911 /// This means that all elements for which the predicate returns true are at the start of the slice
4912 /// and all elements for which the predicate returns false are at the end.
4913 /// For example, `[7, 15, 3, 5, 4, 12, 6]` is partitioned under the predicate `x % 2 != 0`
4914 /// (all odd numbers are at the start, all even at the end).
4915 ///
4916 /// If this slice is not partitioned, the returned result is unspecified and meaningless,
4917 /// as this method performs a kind of binary search.
4918 ///
4919 /// See also [`binary_search`], [`binary_search_by`], and [`binary_search_by_key`].
4920 ///
4921 /// [`binary_search`]: slice::binary_search
4922 /// [`binary_search_by`]: slice::binary_search_by
4923 /// [`binary_search_by_key`]: slice::binary_search_by_key
4924 ///
4925 /// # Examples
4926 ///
4927 /// ```
4928 /// let v = [1, 2, 3, 3, 5, 6, 7];
4929 /// let i = v.partition_point(|&x| x < 5);
4930 ///
4931 /// assert_eq!(i, 4);
4932 /// assert!(v[..i].iter().all(|&x| x < 5));
4933 /// assert!(v[i..].iter().all(|&x| !(x < 5)));
4934 /// ```
4935 ///
4936 /// If all elements of the slice match the predicate, including if the slice
4937 /// is empty, then the length of the slice will be returned:
4938 ///
4939 /// ```
4940 /// let a = [2, 4, 8];
4941 /// assert_eq!(a.partition_point(|x| x < &100), a.len());
4942 /// let a: [i32; 0] = [];
4943 /// assert_eq!(a.partition_point(|x| x < &100), 0);
4944 /// ```
4945 ///
4946 /// If you want to insert an item to a sorted vector, while maintaining
4947 /// sort order:
4948 ///
4949 /// ```
4950 /// let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
4951 /// let num = 42;
4952 /// let idx = s.partition_point(|&x| x <= num);
4953 /// s.insert(idx, num);
4954 /// assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
4955 /// ```
4956 #[stable(feature = "partition_point", since = "1.52.0")]
4957 #[must_use]
4958 #[cfg(not(feature = "ferrocene_subset"))]
4959 pub fn partition_point<P>(&self, mut pred: P) -> usize
4960 where
4961 P: FnMut(&T) -> bool,
4962 {
4963 self.binary_search_by(|x| if pred(x) { Less } else { Greater }).unwrap_or_else(|i| i)
4964 }
4965
4966 /// Removes the subslice corresponding to the given range
4967 /// and returns a reference to it.
4968 ///
4969 /// Returns `None` and does not modify the slice if the given
4970 /// range is out of bounds.
4971 ///
4972 /// Note that this method only accepts one-sided ranges such as
4973 /// `2..` or `..6`, but not `2..6`.
4974 ///
4975 /// # Examples
4976 ///
4977 /// Splitting off the first three elements of a slice:
4978 ///
4979 /// ```
4980 /// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
4981 /// let mut first_three = slice.split_off(..3).unwrap();
4982 ///
4983 /// assert_eq!(slice, &['d']);
4984 /// assert_eq!(first_three, &['a', 'b', 'c']);
4985 /// ```
4986 ///
4987 /// Splitting off a slice starting with the third element:
4988 ///
4989 /// ```
4990 /// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
4991 /// let mut tail = slice.split_off(2..).unwrap();
4992 ///
4993 /// assert_eq!(slice, &['a', 'b']);
4994 /// assert_eq!(tail, &['c', 'd']);
4995 /// ```
4996 ///
4997 /// Getting `None` when `range` is out of bounds:
4998 ///
4999 /// ```
5000 /// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
5001 ///
5002 /// assert_eq!(None, slice.split_off(5..));
5003 /// assert_eq!(None, slice.split_off(..5));
5004 /// assert_eq!(None, slice.split_off(..=4));
5005 /// let expected: &[char] = &['a', 'b', 'c', 'd'];
5006 /// assert_eq!(Some(expected), slice.split_off(..4));
5007 /// ```
5008 #[inline]
5009 #[must_use = "method does not modify the slice if the range is out of bounds"]
5010 #[stable(feature = "slice_take", since = "1.87.0")]
5011 #[cfg(not(feature = "ferrocene_subset"))]
5012 pub fn split_off<'a, R: OneSidedRange<usize>>(
5013 self: &mut &'a Self,
5014 range: R,
5015 ) -> Option<&'a Self> {
5016 let (direction, split_index) = split_point_of(range)?;
5017 if split_index > self.len() {
5018 return None;
5019 }
5020 let (front, back) = self.split_at(split_index);
5021 match direction {
5022 Direction::Front => {
5023 *self = back;
5024 Some(front)
5025 }
5026 Direction::Back => {
5027 *self = front;
5028 Some(back)
5029 }
5030 }
5031 }
5032
5033 /// Removes the subslice corresponding to the given range
5034 /// and returns a mutable reference to it.
5035 ///
5036 /// Returns `None` and does not modify the slice if the given
5037 /// range is out of bounds.
5038 ///
5039 /// Note that this method only accepts one-sided ranges such as
5040 /// `2..` or `..6`, but not `2..6`.
5041 ///
5042 /// # Examples
5043 ///
5044 /// Splitting off the first three elements of a slice:
5045 ///
5046 /// ```
5047 /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
5048 /// let mut first_three = slice.split_off_mut(..3).unwrap();
5049 ///
5050 /// assert_eq!(slice, &mut ['d']);
5051 /// assert_eq!(first_three, &mut ['a', 'b', 'c']);
5052 /// ```
5053 ///
5054 /// Splitting off a slice starting with the third element:
5055 ///
5056 /// ```
5057 /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
5058 /// let mut tail = slice.split_off_mut(2..).unwrap();
5059 ///
5060 /// assert_eq!(slice, &mut ['a', 'b']);
5061 /// assert_eq!(tail, &mut ['c', 'd']);
5062 /// ```
5063 ///
5064 /// Getting `None` when `range` is out of bounds:
5065 ///
5066 /// ```
5067 /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
5068 ///
5069 /// assert_eq!(None, slice.split_off_mut(5..));
5070 /// assert_eq!(None, slice.split_off_mut(..5));
5071 /// assert_eq!(None, slice.split_off_mut(..=4));
5072 /// let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
5073 /// assert_eq!(Some(expected), slice.split_off_mut(..4));
5074 /// ```
5075 #[inline]
5076 #[must_use = "method does not modify the slice if the range is out of bounds"]
5077 #[stable(feature = "slice_take", since = "1.87.0")]
5078 #[cfg(not(feature = "ferrocene_subset"))]
5079 pub fn split_off_mut<'a, R: OneSidedRange<usize>>(
5080 self: &mut &'a mut Self,
5081 range: R,
5082 ) -> Option<&'a mut Self> {
5083 let (direction, split_index) = split_point_of(range)?;
5084 if split_index > self.len() {
5085 return None;
5086 }
5087 let (front, back) = mem::take(self).split_at_mut(split_index);
5088 match direction {
5089 Direction::Front => {
5090 *self = back;
5091 Some(front)
5092 }
5093 Direction::Back => {
5094 *self = front;
5095 Some(back)
5096 }
5097 }
5098 }
5099
5100 /// Removes the first element of the slice and returns a reference
5101 /// to it.
5102 ///
5103 /// Returns `None` if the slice is empty.
5104 ///
5105 /// # Examples
5106 ///
5107 /// ```
5108 /// let mut slice: &[_] = &['a', 'b', 'c'];
5109 /// let first = slice.split_off_first().unwrap();
5110 ///
5111 /// assert_eq!(slice, &['b', 'c']);
5112 /// assert_eq!(first, &'a');
5113 /// ```
5114 #[inline]
5115 #[stable(feature = "slice_take", since = "1.87.0")]
5116 #[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")]
5117 #[cfg(not(feature = "ferrocene_subset"))]
5118 pub const fn split_off_first<'a>(self: &mut &'a Self) -> Option<&'a T> {
5119 // FIXME(const-hack): Use `?` when available in const instead of `let-else`.
5120 let Some((first, rem)) = self.split_first() else { return None };
5121 *self = rem;
5122 Some(first)
5123 }
5124
5125 /// Removes the first element of the slice and returns a mutable
5126 /// reference to it.
5127 ///
5128 /// Returns `None` if the slice is empty.
5129 ///
5130 /// # Examples
5131 ///
5132 /// ```
5133 /// let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
5134 /// let first = slice.split_off_first_mut().unwrap();
5135 /// *first = 'd';
5136 ///
5137 /// assert_eq!(slice, &['b', 'c']);
5138 /// assert_eq!(first, &'d');
5139 /// ```
5140 #[inline]
5141 #[stable(feature = "slice_take", since = "1.87.0")]
5142 #[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")]
5143 #[cfg(not(feature = "ferrocene_subset"))]
5144 pub const fn split_off_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
5145 // FIXME(const-hack): Use `mem::take` and `?` when available in const.
5146 // Original: `mem::take(self).split_first_mut()?`
5147 let Some((first, rem)) = mem::replace(self, &mut []).split_first_mut() else { return None };
5148 *self = rem;
5149 Some(first)
5150 }
5151
5152 /// Removes the last element of the slice and returns a reference
5153 /// to it.
5154 ///
5155 /// Returns `None` if the slice is empty.
5156 ///
5157 /// # Examples
5158 ///
5159 /// ```
5160 /// let mut slice: &[_] = &['a', 'b', 'c'];
5161 /// let last = slice.split_off_last().unwrap();
5162 ///
5163 /// assert_eq!(slice, &['a', 'b']);
5164 /// assert_eq!(last, &'c');
5165 /// ```
5166 #[inline]
5167 #[stable(feature = "slice_take", since = "1.87.0")]
5168 #[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")]
5169 #[cfg(not(feature = "ferrocene_subset"))]
5170 pub const fn split_off_last<'a>(self: &mut &'a Self) -> Option<&'a T> {
5171 // FIXME(const-hack): Use `?` when available in const instead of `let-else`.
5172 let Some((last, rem)) = self.split_last() else { return None };
5173 *self = rem;
5174 Some(last)
5175 }
5176
5177 /// Removes the last element of the slice and returns a mutable
5178 /// reference to it.
5179 ///
5180 /// Returns `None` if the slice is empty.
5181 ///
5182 /// # Examples
5183 ///
5184 /// ```
5185 /// let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
5186 /// let last = slice.split_off_last_mut().unwrap();
5187 /// *last = 'd';
5188 ///
5189 /// assert_eq!(slice, &['a', 'b']);
5190 /// assert_eq!(last, &'d');
5191 /// ```
5192 #[inline]
5193 #[stable(feature = "slice_take", since = "1.87.0")]
5194 #[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")]
5195 #[cfg(not(feature = "ferrocene_subset"))]
5196 pub const fn split_off_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
5197 // FIXME(const-hack): Use `mem::take` and `?` when available in const.
5198 // Original: `mem::take(self).split_last_mut()?`
5199 let Some((last, rem)) = mem::replace(self, &mut []).split_last_mut() else { return None };
5200 *self = rem;
5201 Some(last)
5202 }
5203
5204 /// Returns mutable references to many indices at once, without doing any checks.
5205 ///
5206 /// An index can be either a `usize`, a [`Range`] or a [`RangeInclusive`]. Note
5207 /// that this method takes an array, so all indices must be of the same type.
5208 /// If passed an array of `usize`s this method gives back an array of mutable references
5209 /// to single elements, while if passed an array of ranges it gives back an array of
5210 /// mutable references to slices.
5211 ///
5212 /// For a safe alternative see [`get_disjoint_mut`].
5213 ///
5214 /// # Safety
5215 ///
5216 /// Calling this method with overlapping or out-of-bounds indices is *[undefined behavior]*
5217 /// even if the resulting references are not used.
5218 ///
5219 /// # Examples
5220 ///
5221 /// ```
5222 /// let x = &mut [1, 2, 4];
5223 ///
5224 /// unsafe {
5225 /// let [a, b] = x.get_disjoint_unchecked_mut([0, 2]);
5226 /// *a *= 10;
5227 /// *b *= 100;
5228 /// }
5229 /// assert_eq!(x, &[10, 2, 400]);
5230 ///
5231 /// unsafe {
5232 /// let [a, b] = x.get_disjoint_unchecked_mut([0..1, 1..3]);
5233 /// a[0] = 8;
5234 /// b[0] = 88;
5235 /// b[1] = 888;
5236 /// }
5237 /// assert_eq!(x, &[8, 88, 888]);
5238 ///
5239 /// unsafe {
5240 /// let [a, b] = x.get_disjoint_unchecked_mut([1..=2, 0..=0]);
5241 /// a[0] = 11;
5242 /// a[1] = 111;
5243 /// b[0] = 1;
5244 /// }
5245 /// assert_eq!(x, &[1, 11, 111]);
5246 /// ```
5247 ///
5248 /// [`get_disjoint_mut`]: slice::get_disjoint_mut
5249 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
5250 #[stable(feature = "get_many_mut", since = "1.86.0")]
5251 #[inline]
5252 #[track_caller]
5253 #[cfg(not(feature = "ferrocene_subset"))]
5254 pub unsafe fn get_disjoint_unchecked_mut<I, const N: usize>(
5255 &mut self,
5256 indices: [I; N],
5257 ) -> [&mut I::Output; N]
5258 where
5259 I: GetDisjointMutIndex + SliceIndex<Self>,
5260 {
5261 // NB: This implementation is written as it is because any variation of
5262 // `indices.map(|i| self.get_unchecked_mut(i))` would make miri unhappy,
5263 // or generate worse code otherwise. This is also why we need to go
5264 // through a raw pointer here.
5265 let slice: *mut [T] = self;
5266 let mut arr: MaybeUninit<[&mut I::Output; N]> = MaybeUninit::uninit();
5267 let arr_ptr = arr.as_mut_ptr();
5268
5269 // SAFETY: We expect `indices` to contain disjunct values that are
5270 // in bounds of `self`.
5271 unsafe {
5272 for i in 0..N {
5273 let idx = indices.get_unchecked(i).clone();
5274 arr_ptr.cast::<&mut I::Output>().add(i).write(&mut *slice.get_unchecked_mut(idx));
5275 }
5276 arr.assume_init()
5277 }
5278 }
5279
5280 /// Returns mutable references to many indices at once.
5281 ///
5282 /// An index can be either a `usize`, a [`Range`] or a [`RangeInclusive`]. Note
5283 /// that this method takes an array, so all indices must be of the same type.
5284 /// If passed an array of `usize`s this method gives back an array of mutable references
5285 /// to single elements, while if passed an array of ranges it gives back an array of
5286 /// mutable references to slices.
5287 ///
5288 /// Returns an error if any index is out-of-bounds, or if there are overlapping indices.
5289 /// An empty range is not considered to overlap if it is located at the beginning or at
5290 /// the end of another range, but is considered to overlap if it is located in the middle.
5291 ///
5292 /// This method does a O(n^2) check to check that there are no overlapping indices, so be careful
5293 /// when passing many indices.
5294 ///
5295 /// # Examples
5296 ///
5297 /// ```
5298 /// let v = &mut [1, 2, 3];
5299 /// if let Ok([a, b]) = v.get_disjoint_mut([0, 2]) {
5300 /// *a = 413;
5301 /// *b = 612;
5302 /// }
5303 /// assert_eq!(v, &[413, 2, 612]);
5304 ///
5305 /// if let Ok([a, b]) = v.get_disjoint_mut([0..1, 1..3]) {
5306 /// a[0] = 8;
5307 /// b[0] = 88;
5308 /// b[1] = 888;
5309 /// }
5310 /// assert_eq!(v, &[8, 88, 888]);
5311 ///
5312 /// if let Ok([a, b]) = v.get_disjoint_mut([1..=2, 0..=0]) {
5313 /// a[0] = 11;
5314 /// a[1] = 111;
5315 /// b[0] = 1;
5316 /// }
5317 /// assert_eq!(v, &[1, 11, 111]);
5318 /// ```
5319 #[stable(feature = "get_many_mut", since = "1.86.0")]
5320 #[inline]
5321 #[cfg(not(feature = "ferrocene_subset"))]
5322 pub fn get_disjoint_mut<I, const N: usize>(
5323 &mut self,
5324 indices: [I; N],
5325 ) -> Result<[&mut I::Output; N], GetDisjointMutError>
5326 where
5327 I: GetDisjointMutIndex + SliceIndex<Self>,
5328 {
5329 get_disjoint_check_valid(&indices, self.len())?;
5330 // SAFETY: The `get_disjoint_check_valid()` call checked that all indices
5331 // are disjunct and in bounds.
5332 unsafe { Ok(self.get_disjoint_unchecked_mut(indices)) }
5333 }
5334
5335 /// Returns the index that an element reference points to.
5336 ///
5337 /// Returns `None` if `element` does not point to the start of an element within the slice.
5338 ///
5339 /// This method is useful for extending slice iterators like [`slice::split`].
5340 ///
5341 /// Note that this uses pointer arithmetic and **does not compare elements**.
5342 /// To find the index of an element via comparison, use
5343 /// [`.iter().position()`](crate::iter::Iterator::position) instead.
5344 ///
5345 /// # Panics
5346 /// Panics if `T` is zero-sized.
5347 ///
5348 /// # Examples
5349 /// Basic usage:
5350 /// ```
5351 /// let nums: &[u32] = &[1, 7, 1, 1];
5352 /// let num = &nums[2];
5353 ///
5354 /// assert_eq!(num, &1);
5355 /// assert_eq!(nums.element_offset(num), Some(2));
5356 /// ```
5357 /// Returning `None` with an unaligned element:
5358 /// ```
5359 /// let arr: &[[u32; 2]] = &[[0, 1], [2, 3]];
5360 /// let flat_arr: &[u32] = arr.as_flattened();
5361 ///
5362 /// let ok_elm: &[u32; 2] = flat_arr[0..2].try_into().unwrap();
5363 /// let weird_elm: &[u32; 2] = flat_arr[1..3].try_into().unwrap();
5364 ///
5365 /// assert_eq!(ok_elm, &[0, 1]);
5366 /// assert_eq!(weird_elm, &[1, 2]);
5367 ///
5368 /// assert_eq!(arr.element_offset(ok_elm), Some(0)); // Points to element 0
5369 /// assert_eq!(arr.element_offset(weird_elm), None); // Points between element 0 and 1
5370 /// ```
5371 #[must_use]
5372 #[cfg(not(feature = "ferrocene_subset"))]
5373 #[stable(feature = "element_offset", since = "1.94.0")]
5374 pub fn element_offset(&self, element: &T) -> Option<usize> {
5375 if T::IS_ZST {
5376 panic!("elements are zero-sized");
5377 }
5378
5379 let self_start = self.as_ptr().addr();
5380 let elem_start = ptr::from_ref(element).addr();
5381
5382 let byte_offset = elem_start.wrapping_sub(self_start);
5383
5384 if !byte_offset.is_multiple_of(size_of::<T>()) {
5385 return None;
5386 }
5387
5388 let offset = byte_offset / size_of::<T>();
5389
5390 if offset < self.len() { Some(offset) } else { None }
5391 }
5392
5393 /// Returns the range of indices that a subslice points to.
5394 ///
5395 /// Returns `None` if `subslice` does not point within the slice or if it is not aligned with the
5396 /// elements in the slice.
5397 ///
5398 /// This method **does not compare elements**. Instead, this method finds the location in the slice that
5399 /// `subslice` was obtained from. To find the index of a subslice via comparison, instead use
5400 /// [`.windows()`](slice::windows)[`.position()`](crate::iter::Iterator::position).
5401 ///
5402 /// This method is useful for extending slice iterators like [`slice::split`].
5403 ///
5404 /// Note that this may return a false positive (either `Some(0..0)` or `Some(self.len()..self.len())`)
5405 /// if `subslice` has a length of zero and points to the beginning or end of another, separate, slice.
5406 ///
5407 /// # Panics
5408 /// Panics if `T` is zero-sized.
5409 ///
5410 /// # Examples
5411 /// Basic usage:
5412 /// ```
5413 /// #![feature(substr_range)]
5414 ///
5415 /// let nums = &[0, 5, 10, 0, 0, 5];
5416 ///
5417 /// let mut iter = nums
5418 /// .split(|t| *t == 0)
5419 /// .map(|n| nums.subslice_range(n).unwrap());
5420 ///
5421 /// assert_eq!(iter.next(), Some(0..0));
5422 /// assert_eq!(iter.next(), Some(1..3));
5423 /// assert_eq!(iter.next(), Some(4..4));
5424 /// assert_eq!(iter.next(), Some(5..6));
5425 /// ```
5426 #[must_use]
5427 #[unstable(feature = "substr_range", issue = "126769")]
5428 #[cfg(not(feature = "ferrocene_subset"))]
5429 pub fn subslice_range(&self, subslice: &[T]) -> Option<Range<usize>> {
5430 if T::IS_ZST {
5431 panic!("elements are zero-sized");
5432 }
5433
5434 let self_start = self.as_ptr().addr();
5435 let subslice_start = subslice.as_ptr().addr();
5436
5437 let byte_start = subslice_start.wrapping_sub(self_start);
5438
5439 if !byte_start.is_multiple_of(size_of::<T>()) {
5440 return None;
5441 }
5442
5443 let start = byte_start / size_of::<T>();
5444 let end = start.wrapping_add(subslice.len());
5445
5446 if start <= self.len() && end <= self.len() { Some(start..end) } else { None }
5447 }
5448
5449 /// Returns the same slice `&[T]`.
5450 ///
5451 /// This method is redundant when used directly on `&[T]`, but
5452 /// it helps dereferencing other "container" types to slices,
5453 /// for example `Box<[T]>` or `Arc<[T]>`.
5454 #[cfg(not(feature = "ferrocene_subset"))]
5455 #[inline]
5456 #[unstable(feature = "str_as_str", issue = "130366")]
5457 pub const fn as_slice(&self) -> &[T] {
5458 self
5459 }
5460
5461 /// Returns the same slice `&mut [T]`.
5462 ///
5463 /// This method is redundant when used directly on `&mut [T]`, but
5464 /// it helps dereferencing other "container" types to slices,
5465 /// for example `Box<[T]>` or `MutexGuard<[T]>`.
5466 #[cfg(not(feature = "ferrocene_subset"))]
5467 #[inline]
5468 #[unstable(feature = "str_as_str", issue = "130366")]
5469 pub const fn as_mut_slice(&mut self) -> &mut [T] {
5470 self
5471 }
5472}
5473
5474#[cfg(not(feature = "ferrocene_subset"))]
5475impl<T> [MaybeUninit<T>] {
5476 /// Transmutes the mutable uninitialized slice to a mutable uninitialized slice of
5477 /// another type, ensuring alignment of the types is maintained.
5478 ///
5479 /// This is a safe wrapper around [`slice::align_to_mut`], so inherits the same
5480 /// guarantees as that method.
5481 ///
5482 /// # Examples
5483 ///
5484 /// ```
5485 /// #![feature(align_to_uninit_mut)]
5486 /// use std::mem::MaybeUninit;
5487 ///
5488 /// pub struct BumpAllocator<'scope> {
5489 /// memory: &'scope mut [MaybeUninit<u8>],
5490 /// }
5491 ///
5492 /// impl<'scope> BumpAllocator<'scope> {
5493 /// pub fn new(memory: &'scope mut [MaybeUninit<u8>]) -> Self {
5494 /// Self { memory }
5495 /// }
5496 /// pub fn try_alloc_uninit<T>(&mut self) -> Option<&'scope mut MaybeUninit<T>> {
5497 /// let first_end = self.memory.as_ptr().align_offset(align_of::<T>()) + size_of::<T>();
5498 /// let prefix = self.memory.split_off_mut(..first_end)?;
5499 /// Some(&mut prefix.align_to_uninit_mut::<T>().1[0])
5500 /// }
5501 /// pub fn try_alloc_u32(&mut self, value: u32) -> Option<&'scope mut u32> {
5502 /// let uninit = self.try_alloc_uninit()?;
5503 /// Some(uninit.write(value))
5504 /// }
5505 /// }
5506 ///
5507 /// let mut memory = [MaybeUninit::<u8>::uninit(); 10];
5508 /// let mut allocator = BumpAllocator::new(&mut memory);
5509 /// let v = allocator.try_alloc_u32(42);
5510 /// assert_eq!(v, Some(&mut 42));
5511 /// ```
5512 #[unstable(feature = "align_to_uninit_mut", issue = "139062")]
5513 #[inline]
5514 #[must_use]
5515 pub fn align_to_uninit_mut<U>(&mut self) -> (&mut Self, &mut [MaybeUninit<U>], &mut Self) {
5516 // SAFETY: `MaybeUninit` is transparent. Correct size and alignment are guaranteed by
5517 // `align_to_mut` itself. Therefore the only thing that we have to ensure for a safe
5518 // `transmute` is that the values are valid for the types involved. But for `MaybeUninit`
5519 // any values are valid, so this operation is safe.
5520 unsafe { self.align_to_mut() }
5521 }
5522}
5523
5524#[cfg(not(feature = "ferrocene_subset"))]
5525impl<T, const N: usize> [[T; N]] {
5526 /// Takes a `&[[T; N]]`, and flattens it to a `&[T]`.
5527 ///
5528 /// For the opposite operation, see [`as_chunks`] and [`as_rchunks`].
5529 ///
5530 /// [`as_chunks`]: slice::as_chunks
5531 /// [`as_rchunks`]: slice::as_rchunks
5532 ///
5533 /// # Panics
5534 ///
5535 /// This panics if the length of the resulting slice would overflow a `usize`.
5536 ///
5537 /// This is only possible when flattening a slice of arrays of zero-sized
5538 /// types, and thus tends to be irrelevant in practice. If
5539 /// `size_of::<T>() > 0`, this will never panic.
5540 ///
5541 /// # Examples
5542 ///
5543 /// ```
5544 /// assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]);
5545 ///
5546 /// assert_eq!(
5547 /// [[1, 2, 3], [4, 5, 6]].as_flattened(),
5548 /// [[1, 2], [3, 4], [5, 6]].as_flattened(),
5549 /// );
5550 ///
5551 /// let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
5552 /// assert!(slice_of_empty_arrays.as_flattened().is_empty());
5553 ///
5554 /// let empty_slice_of_arrays: &[[u32; 10]] = &[];
5555 /// assert!(empty_slice_of_arrays.as_flattened().is_empty());
5556 /// ```
5557 #[stable(feature = "slice_flatten", since = "1.80.0")]
5558 #[rustc_const_stable(feature = "const_slice_flatten", since = "1.87.0")]
5559 pub const fn as_flattened(&self) -> &[T] {
5560 let len = if T::IS_ZST {
5561 self.len().checked_mul(N).expect("slice len overflow")
5562 } else {
5563 // SAFETY: `self.len() * N` cannot overflow because `self` is
5564 // already in the address space.
5565 unsafe { self.len().unchecked_mul(N) }
5566 };
5567 // SAFETY: `[T]` is layout-identical to `[T; N]`
5568 unsafe { from_raw_parts(self.as_ptr().cast(), len) }
5569 }
5570
5571 /// Takes a `&mut [[T; N]]`, and flattens it to a `&mut [T]`.
5572 ///
5573 /// For the opposite operation, see [`as_chunks_mut`] and [`as_rchunks_mut`].
5574 ///
5575 /// [`as_chunks_mut`]: slice::as_chunks_mut
5576 /// [`as_rchunks_mut`]: slice::as_rchunks_mut
5577 ///
5578 /// # Panics
5579 ///
5580 /// This panics if the length of the resulting slice would overflow a `usize`.
5581 ///
5582 /// This is only possible when flattening a slice of arrays of zero-sized
5583 /// types, and thus tends to be irrelevant in practice. If
5584 /// `size_of::<T>() > 0`, this will never panic.
5585 ///
5586 /// # Examples
5587 ///
5588 /// ```
5589 /// fn add_5_to_all(slice: &mut [i32]) {
5590 /// for i in slice {
5591 /// *i += 5;
5592 /// }
5593 /// }
5594 ///
5595 /// let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
5596 /// add_5_to_all(array.as_flattened_mut());
5597 /// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
5598 /// ```
5599 #[stable(feature = "slice_flatten", since = "1.80.0")]
5600 #[rustc_const_stable(feature = "const_slice_flatten", since = "1.87.0")]
5601 pub const fn as_flattened_mut(&mut self) -> &mut [T] {
5602 let len = if T::IS_ZST {
5603 self.len().checked_mul(N).expect("slice len overflow")
5604 } else {
5605 // SAFETY: `self.len() * N` cannot overflow because `self` is
5606 // already in the address space.
5607 unsafe { self.len().unchecked_mul(N) }
5608 };
5609 // SAFETY: `[T]` is layout-identical to `[T; N]`
5610 unsafe { from_raw_parts_mut(self.as_mut_ptr().cast(), len) }
5611 }
5612}
5613
5614#[cfg(not(feature = "ferrocene_subset"))]
5615impl [f32] {
5616 /// Sorts the slice of floats.
5617 ///
5618 /// This sort is in-place (i.e. does not allocate), *O*(*n* \* log(*n*)) worst-case, and uses
5619 /// the ordering defined by [`f32::total_cmp`].
5620 ///
5621 /// # Current implementation
5622 ///
5623 /// This uses the same sorting algorithm as [`sort_unstable_by`](slice::sort_unstable_by).
5624 ///
5625 /// # Examples
5626 ///
5627 /// ```
5628 /// #![feature(sort_floats)]
5629 /// let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
5630 ///
5631 /// v.sort_floats();
5632 /// let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
5633 /// assert_eq!(&v[..8], &sorted[..8]);
5634 /// assert!(v[8].is_nan());
5635 /// ```
5636 #[unstable(feature = "sort_floats", issue = "93396")]
5637 #[inline]
5638 pub fn sort_floats(&mut self) {
5639 self.sort_unstable_by(f32::total_cmp);
5640 }
5641}
5642
5643#[cfg(not(feature = "ferrocene_subset"))]
5644impl [f64] {
5645 /// Sorts the slice of floats.
5646 ///
5647 /// This sort is in-place (i.e. does not allocate), *O*(*n* \* log(*n*)) worst-case, and uses
5648 /// the ordering defined by [`f64::total_cmp`].
5649 ///
5650 /// # Current implementation
5651 ///
5652 /// This uses the same sorting algorithm as [`sort_unstable_by`](slice::sort_unstable_by).
5653 ///
5654 /// # Examples
5655 ///
5656 /// ```
5657 /// #![feature(sort_floats)]
5658 /// let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
5659 ///
5660 /// v.sort_floats();
5661 /// let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
5662 /// assert_eq!(&v[..8], &sorted[..8]);
5663 /// assert!(v[8].is_nan());
5664 /// ```
5665 #[unstable(feature = "sort_floats", issue = "93396")]
5666 #[inline]
5667 pub fn sort_floats(&mut self) {
5668 self.sort_unstable_by(f64::total_cmp);
5669 }
5670}
5671
5672/// Copies `src` to `dest`.
5673///
5674/// # Safety
5675/// `T` must implement one of `Copy` or `TrivialClone`.
5676#[track_caller]
5677const unsafe fn copy_from_slice_impl<T: Clone>(dest: &mut [T], src: &[T]) {
5678 // The panic code path was put into a cold function to not bloat the
5679 // call site.
5680 #[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
5681 #[cfg_attr(panic = "immediate-abort", inline)]
5682 #[track_caller]
5683 const fn len_mismatch_fail(dst_len: usize, src_len: usize) -> ! {
5684 const_panic!(
5685 "copy_from_slice: source slice length does not match destination slice length",
5686 "copy_from_slice: source slice length ({src_len}) does not match destination slice length ({dst_len})",
5687 src_len: usize,
5688 dst_len: usize,
5689 )
5690 }
5691
5692 if dest.len() != src.len() {
5693 len_mismatch_fail(dest.len(), src.len());
5694 }
5695
5696 // SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was
5697 // checked to have the same length. The slices cannot overlap because
5698 // mutable references are exclusive.
5699 unsafe {
5700 ptr::copy_nonoverlapping(src.as_ptr(), dest.as_mut_ptr(), dest.len());
5701 }
5702}
5703
5704#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
5705const trait CloneFromSpec<T> {
5706 fn spec_clone_from(&mut self, src: &[T])
5707 where
5708 T: [const] Destruct;
5709}
5710
5711#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
5712impl<T> const CloneFromSpec<T> for [T]
5713where
5714 T: [const] Clone + [const] Destruct,
5715{
5716 #[track_caller]
5717 default fn spec_clone_from(&mut self, src: &[T]) {
5718 assert!(self.len() == src.len(), "destination and source slices have different lengths");
5719 // NOTE: We need to explicitly slice them to the same length
5720 // to make it easier for the optimizer to elide bounds checking.
5721 // But since it can't be relied on we also have an explicit specialization for T: Copy.
5722 let len = self.len();
5723 let src = &src[..len];
5724 // FIXME(const_hack): make this a `for idx in 0..self.len()` loop.
5725 let mut idx = 0;
5726 while idx < self.len() {
5727 self[idx].clone_from(&src[idx]);
5728 idx += 1;
5729 }
5730 }
5731}
5732
5733#[cfg(not(feature = "ferrocene_subset"))]
5734#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
5735impl<T> const CloneFromSpec<T> for [T]
5736where
5737 T: [const] TrivialClone + [const] Destruct,
5738{
5739 #[track_caller]
5740 fn spec_clone_from(&mut self, src: &[T]) {
5741 // SAFETY: `T` implements `TrivialClone`.
5742 unsafe {
5743 copy_from_slice_impl(self, src);
5744 }
5745 }
5746}
5747
5748#[stable(feature = "rust1", since = "1.0.0")]
5749#[rustc_const_unstable(feature = "const_default", issue = "143894")]
5750#[cfg(not(feature = "ferrocene_subset"))]
5751impl<T> const Default for &[T] {
5752 /// Creates an empty slice.
5753 fn default() -> Self {
5754 &[]
5755 }
5756}
5757
5758#[stable(feature = "mut_slice_default", since = "1.5.0")]
5759#[rustc_const_unstable(feature = "const_default", issue = "143894")]
5760#[cfg(not(feature = "ferrocene_subset"))]
5761impl<T> const Default for &mut [T] {
5762 /// Creates a mutable empty slice.
5763 fn default() -> Self {
5764 &mut []
5765 }
5766}
5767
5768#[unstable(feature = "slice_pattern", reason = "stopgap trait for slice patterns", issue = "56345")]
5769/// Patterns in slices - currently, only used by `strip_prefix` and `strip_suffix`. At a future
5770/// point, we hope to generalise `core::str::Pattern` (which at the time of writing is limited to
5771/// `str`) to slices, and then this trait will be replaced or abolished.
5772#[cfg(not(feature = "ferrocene_subset"))]
5773pub trait SlicePattern {
5774 /// The element type of the slice being matched on.
5775 type Item;
5776
5777 /// Currently, the consumers of `SlicePattern` need a slice.
5778 fn as_slice(&self) -> &[Self::Item];
5779}
5780
5781#[stable(feature = "slice_strip", since = "1.51.0")]
5782#[cfg(not(feature = "ferrocene_subset"))]
5783impl<T> SlicePattern for [T] {
5784 type Item = T;
5785
5786 #[inline]
5787 fn as_slice(&self) -> &[Self::Item] {
5788 self
5789 }
5790}
5791
5792#[stable(feature = "slice_strip", since = "1.51.0")]
5793#[cfg(not(feature = "ferrocene_subset"))]
5794impl<T, const N: usize> SlicePattern for [T; N] {
5795 type Item = T;
5796
5797 #[inline]
5798 fn as_slice(&self) -> &[Self::Item] {
5799 self
5800 }
5801}
5802
5803/// This checks every index against each other, and against `len`.
5804///
5805/// This will do `binomial(N + 1, 2) = N * (N + 1) / 2 = 0, 1, 3, 6, 10, ..`
5806/// comparison operations.
5807#[inline]
5808#[cfg(not(feature = "ferrocene_subset"))]
5809fn get_disjoint_check_valid<I: GetDisjointMutIndex, const N: usize>(
5810 indices: &[I; N],
5811 len: usize,
5812) -> Result<(), GetDisjointMutError> {
5813 // NB: The optimizer should inline the loops into a sequence
5814 // of instructions without additional branching.
5815 for (i, idx) in indices.iter().enumerate() {
5816 if !idx.is_in_bounds(len) {
5817 return Err(GetDisjointMutError::IndexOutOfBounds);
5818 }
5819 for idx2 in &indices[..i] {
5820 if idx.is_overlapping(idx2) {
5821 return Err(GetDisjointMutError::OverlappingIndices);
5822 }
5823 }
5824 }
5825 Ok(())
5826}
5827
5828/// The error type returned by [`get_disjoint_mut`][`slice::get_disjoint_mut`].
5829///
5830/// It indicates one of two possible errors:
5831/// - An index is out-of-bounds.
5832/// - The same index appeared multiple times in the array
5833/// (or different but overlapping indices when ranges are provided).
5834///
5835/// # Examples
5836///
5837/// ```
5838/// use std::slice::GetDisjointMutError;
5839///
5840/// let v = &mut [1, 2, 3];
5841/// assert_eq!(v.get_disjoint_mut([0, 999]), Err(GetDisjointMutError::IndexOutOfBounds));
5842/// assert_eq!(v.get_disjoint_mut([1, 1]), Err(GetDisjointMutError::OverlappingIndices));
5843/// ```
5844#[stable(feature = "get_many_mut", since = "1.86.0")]
5845#[derive(Debug, Clone, PartialEq, Eq)]
5846#[cfg(not(feature = "ferrocene_subset"))]
5847pub enum GetDisjointMutError {
5848 /// An index provided was out-of-bounds for the slice.
5849 IndexOutOfBounds,
5850 /// Two indices provided were overlapping.
5851 OverlappingIndices,
5852}
5853
5854#[stable(feature = "get_many_mut", since = "1.86.0")]
5855#[cfg(not(feature = "ferrocene_subset"))]
5856impl fmt::Display for GetDisjointMutError {
5857 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5858 let msg = match self {
5859 GetDisjointMutError::IndexOutOfBounds => "an index is out of bounds",
5860 GetDisjointMutError::OverlappingIndices => "there were overlapping indices",
5861 };
5862 fmt::Display::fmt(msg, f)
5863 }
5864}
5865
5866#[cfg(not(feature = "ferrocene_subset"))]
5867mod private_get_disjoint_mut_index {
5868 use super::{Range, RangeInclusive, range};
5869
5870 #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5871 pub trait Sealed {}
5872
5873 #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5874 impl Sealed for usize {}
5875 #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5876 impl Sealed for Range<usize> {}
5877 #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5878 impl Sealed for RangeInclusive<usize> {}
5879 #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5880 impl Sealed for range::Range<usize> {}
5881 #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5882 impl Sealed for range::RangeInclusive<usize> {}
5883}
5884
5885/// A helper trait for `<[T]>::get_disjoint_mut()`.
5886///
5887/// # Safety
5888///
5889/// If `is_in_bounds()` returns `true` and `is_overlapping()` returns `false`,
5890/// it must be safe to index the slice with the indices.
5891#[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5892#[cfg(not(feature = "ferrocene_subset"))]
5893pub unsafe trait GetDisjointMutIndex:
5894 Clone + private_get_disjoint_mut_index::Sealed
5895{
5896 /// Returns `true` if `self` is in bounds for `len` slice elements.
5897 #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5898 fn is_in_bounds(&self, len: usize) -> bool;
5899
5900 /// Returns `true` if `self` overlaps with `other`.
5901 ///
5902 /// Note that we don't consider zero-length ranges to overlap at the beginning or the end,
5903 /// but do consider them to overlap in the middle.
5904 #[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5905 fn is_overlapping(&self, other: &Self) -> bool;
5906}
5907
5908#[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5909// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly.
5910#[cfg(not(feature = "ferrocene_subset"))]
5911unsafe impl GetDisjointMutIndex for usize {
5912 #[inline]
5913 fn is_in_bounds(&self, len: usize) -> bool {
5914 *self < len
5915 }
5916
5917 #[inline]
5918 fn is_overlapping(&self, other: &Self) -> bool {
5919 *self == *other
5920 }
5921}
5922
5923#[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5924// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly.
5925#[cfg(not(feature = "ferrocene_subset"))]
5926unsafe impl GetDisjointMutIndex for Range<usize> {
5927 #[inline]
5928 fn is_in_bounds(&self, len: usize) -> bool {
5929 (self.start <= self.end) & (self.end <= len)
5930 }
5931
5932 #[inline]
5933 fn is_overlapping(&self, other: &Self) -> bool {
5934 (self.start < other.end) & (other.start < self.end)
5935 }
5936}
5937
5938#[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5939// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly.
5940#[cfg(not(feature = "ferrocene_subset"))]
5941unsafe impl GetDisjointMutIndex for RangeInclusive<usize> {
5942 #[inline]
5943 fn is_in_bounds(&self, len: usize) -> bool {
5944 (self.start <= self.end) & (self.end < len)
5945 }
5946
5947 #[inline]
5948 fn is_overlapping(&self, other: &Self) -> bool {
5949 (self.start <= other.end) & (other.start <= self.end)
5950 }
5951}
5952
5953#[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5954// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly.
5955#[cfg(not(feature = "ferrocene_subset"))]
5956unsafe impl GetDisjointMutIndex for range::Range<usize> {
5957 #[inline]
5958 fn is_in_bounds(&self, len: usize) -> bool {
5959 Range::from(*self).is_in_bounds(len)
5960 }
5961
5962 #[inline]
5963 fn is_overlapping(&self, other: &Self) -> bool {
5964 Range::from(*self).is_overlapping(&Range::from(*other))
5965 }
5966}
5967
5968#[unstable(feature = "get_disjoint_mut_helpers", issue = "none")]
5969// SAFETY: We implement `is_in_bounds()` and `is_overlapping()` correctly.
5970#[cfg(not(feature = "ferrocene_subset"))]
5971unsafe impl GetDisjointMutIndex for range::RangeInclusive<usize> {
5972 #[inline]
5973 fn is_in_bounds(&self, len: usize) -> bool {
5974 RangeInclusive::from(*self).is_in_bounds(len)
5975 }
5976
5977 #[inline]
5978 fn is_overlapping(&self, other: &Self) -> bool {
5979 RangeInclusive::from(*self).is_overlapping(&RangeInclusive::from(*other))
5980 }
5981}