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