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