1#[macro_use] mod macros;
5
6use super::{from_raw_parts, from_raw_parts_mut};
7use crate::hint::assert_unchecked;
8#[cfg(not(feature = "ferrocene_subset"))]
9use crate::iter::{
10 FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, UncheckedIterator,
11};
12use crate::marker::PhantomData;
13#[cfg(not(feature = "ferrocene_subset"))]
14use crate::mem::{self, SizedTypeProperties};
15use crate::num::NonZero;
16use crate::ptr::{NonNull, without_provenance, without_provenance_mut};
17#[cfg(not(feature = "ferrocene_subset"))]
18use crate::{cmp, fmt};
19
20#[cfg(feature = "ferrocene_subset")]
22#[rustfmt::skip]
23use crate::{
24 cmp,
25 iter::{TrustedLen, UncheckedIterator},
26 mem,
27 mem::SizedTypeProperties,
28};
29
30#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
31impl<T> !Iterator for [T] {}
32
33#[stable(feature = "rust1", since = "1.0.0")]
34impl<'a, T> IntoIterator for &'a [T] {
35 type Item = &'a T;
36 type IntoIter = Iter<'a, T>;
37
38 fn into_iter(self) -> Iter<'a, T> {
39 self.iter()
40 }
41}
42
43#[stable(feature = "rust1", since = "1.0.0")]
44impl<'a, T> IntoIterator for &'a mut [T] {
45 type Item = &'a mut T;
46 type IntoIter = IterMut<'a, T>;
47
48 fn into_iter(self) -> IterMut<'a, T> {
49 self.iter_mut()
50 }
51}
52
53#[stable(feature = "rust1", since = "1.0.0")]
80#[must_use = "iterators are lazy and do nothing unless consumed"]
81#[rustc_diagnostic_item = "SliceIter"]
82pub struct Iter<'a, T: 'a> {
83 ptr: NonNull<T>,
88 end_or_len: *const T,
92 _marker: PhantomData<&'a T>,
93}
94
95#[stable(feature = "core_impl_debug", since = "1.9.0")]
96#[cfg(not(feature = "ferrocene_subset"))]
97impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 f.debug_tuple("Iter").field(&self.as_slice()).finish()
100 }
101}
102
103#[stable(feature = "rust1", since = "1.0.0")]
104unsafe impl<T: Sync> Sync for Iter<'_, T> {}
105#[stable(feature = "rust1", since = "1.0.0")]
106unsafe impl<T: Sync> Send for Iter<'_, T> {}
107
108impl<'a, T> Iter<'a, T> {
109 #[inline]
110 pub(super) const fn new(slice: &'a [T]) -> Self {
111 let len = slice.len();
112 let ptr: NonNull<T> = NonNull::from_ref(slice).cast();
113 unsafe {
115 let end_or_len =
116 if T::IS_ZST { without_provenance(len) } else { ptr.as_ptr().add(len) };
117
118 Self { ptr, end_or_len, _marker: PhantomData }
119 }
120 }
121
122 #[must_use]
149 #[stable(feature = "iter_to_slice", since = "1.4.0")]
150 #[inline]
151 pub fn as_slice(&self) -> &'a [T] {
152 self.make_slice()
153 }
154}
155
156iterator! {struct Iter -> *const T, &'a T, const, {}, as_ref, each_ref, {
157 #[cfg(not(feature = "ferrocene_subset"))]
158 fn is_sorted_by<F>(self, mut compare: F) -> bool
159 where
160 Self: Sized,
161 F: FnMut(&Self::Item, &Self::Item) -> bool,
162 {
163 self.as_slice().is_sorted_by(|a, b| compare(&a, &b))
164 }
165}}
166
167#[stable(feature = "rust1", since = "1.0.0")]
168#[cfg(not(feature = "ferrocene_subset"))]
169impl<T> Clone for Iter<'_, T> {
170 #[inline]
171 fn clone(&self) -> Self {
172 Iter { ptr: self.ptr, end_or_len: self.end_or_len, _marker: self._marker }
173 }
174}
175
176#[stable(feature = "slice_iter_as_ref", since = "1.13.0")]
177#[cfg(not(feature = "ferrocene_subset"))]
178impl<T> AsRef<[T]> for Iter<'_, T> {
179 #[inline]
180 fn as_ref(&self) -> &[T] {
181 self.as_slice()
182 }
183}
184
185#[stable(feature = "rust1", since = "1.0.0")]
210#[must_use = "iterators are lazy and do nothing unless consumed"]
211pub struct IterMut<'a, T: 'a> {
212 ptr: NonNull<T>,
217 end_or_len: *mut T,
221 _marker: PhantomData<&'a mut T>,
222}
223
224#[stable(feature = "core_impl_debug", since = "1.9.0")]
225#[cfg(not(feature = "ferrocene_subset"))]
226impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
227 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
228 f.debug_tuple("IterMut").field(&self.make_slice()).finish()
229 }
230}
231
232#[stable(feature = "rust1", since = "1.0.0")]
233unsafe impl<T: Sync> Sync for IterMut<'_, T> {}
234#[stable(feature = "rust1", since = "1.0.0")]
235unsafe impl<T: Send> Send for IterMut<'_, T> {}
236
237impl<'a, T> IterMut<'a, T> {
238 #[inline]
239 pub(super) const fn new(slice: &'a mut [T]) -> Self {
240 let len = slice.len();
241 let ptr: NonNull<T> = NonNull::from_mut(slice).cast();
242 unsafe {
259 let end_or_len =
260 if T::IS_ZST { without_provenance_mut(len) } else { ptr.as_ptr().add(len) };
261
262 Self { ptr, end_or_len, _marker: PhantomData }
263 }
264 }
265
266 #[must_use = "`self` will be dropped if the result is not used"]
293 #[stable(feature = "iter_to_slice", since = "1.4.0")]
294 #[cfg(not(feature = "ferrocene_subset"))]
295 pub fn into_slice(self) -> &'a mut [T] {
296 unsafe { from_raw_parts_mut(self.ptr.as_ptr(), len!(self)) }
300 }
301
302 #[must_use]
330 #[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")]
331 #[inline]
332 #[cfg(not(feature = "ferrocene_subset"))]
333 pub fn as_slice(&self) -> &[T] {
334 self.make_slice()
335 }
336
337 #[must_use]
366 #[unstable(feature = "slice_iter_mut_as_mut_slice", issue = "93079")]
368 pub fn as_mut_slice(&mut self) -> &mut [T] {
369 unsafe { from_raw_parts_mut(self.ptr.as_ptr(), len!(self)) }
373 }
374}
375
376#[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")]
377#[cfg(not(feature = "ferrocene_subset"))]
378impl<T> AsRef<[T]> for IterMut<'_, T> {
379 #[inline]
380 fn as_ref(&self) -> &[T] {
381 self.as_slice()
382 }
383}
384
385iterator! {struct IterMut -> *mut T, &'a mut T, mut, {mut}, as_mut, each_mut, {}}
393
394#[doc(hidden)]
397#[cfg(not(feature = "ferrocene_subset"))]
398pub(super) trait SplitIter: DoubleEndedIterator {
399 fn finish(&mut self) -> Option<Self::Item>;
402}
403
404#[stable(feature = "rust1", since = "1.0.0")]
422#[must_use = "iterators are lazy and do nothing unless consumed"]
423#[cfg(not(feature = "ferrocene_subset"))]
424pub struct Split<'a, T: 'a, P>
425where
426 P: FnMut(&T) -> bool,
427{
428 pub(crate) v: &'a [T],
430 pred: P,
431 pub(crate) finished: bool,
433}
434
435#[cfg(not(feature = "ferrocene_subset"))]
436impl<'a, T: 'a, P: FnMut(&T) -> bool> Split<'a, T, P> {
437 #[inline]
438 pub(super) fn new(slice: &'a [T], pred: P) -> Self {
439 Self { v: slice, pred, finished: false }
440 }
441 #[unstable(feature = "split_as_slice", issue = "96137")]
452 pub fn as_slice(&self) -> &'a [T] {
453 if self.finished { &[] } else { &self.v }
454 }
455}
456
457#[stable(feature = "core_impl_debug", since = "1.9.0")]
458#[cfg(not(feature = "ferrocene_subset"))]
459impl<T: fmt::Debug, P> fmt::Debug for Split<'_, T, P>
460where
461 P: FnMut(&T) -> bool,
462{
463 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
464 f.debug_struct("Split").field("v", &self.v).field("finished", &self.finished).finish()
465 }
466}
467
468#[stable(feature = "rust1", since = "1.0.0")]
470#[cfg(not(feature = "ferrocene_subset"))]
471impl<T, P> Clone for Split<'_, T, P>
472where
473 P: Clone + FnMut(&T) -> bool,
474{
475 fn clone(&self) -> Self {
476 Split { v: self.v, pred: self.pred.clone(), finished: self.finished }
477 }
478}
479
480#[stable(feature = "rust1", since = "1.0.0")]
481#[cfg(not(feature = "ferrocene_subset"))]
482impl<'a, T, P> Iterator for Split<'a, T, P>
483where
484 P: FnMut(&T) -> bool,
485{
486 type Item = &'a [T];
487
488 #[inline]
489 fn next(&mut self) -> Option<&'a [T]> {
490 if self.finished {
491 return None;
492 }
493
494 match self.v.iter().position(|x| (self.pred)(x)) {
495 None => self.finish(),
496 Some(idx) => {
497 let (left, right) =
498 unsafe { (self.v.get_unchecked(..idx), self.v.get_unchecked(idx + 1..)) };
501 let ret = Some(left);
502 self.v = right;
503 ret
504 }
505 }
506 }
507
508 #[inline]
509 fn size_hint(&self) -> (usize, Option<usize>) {
510 if self.finished {
511 (0, Some(0))
512 } else {
513 (1, Some(self.v.len() + 1))
516 }
517 }
518}
519
520#[stable(feature = "rust1", since = "1.0.0")]
521#[cfg(not(feature = "ferrocene_subset"))]
522impl<'a, T, P> DoubleEndedIterator for Split<'a, T, P>
523where
524 P: FnMut(&T) -> bool,
525{
526 #[inline]
527 fn next_back(&mut self) -> Option<&'a [T]> {
528 if self.finished {
529 return None;
530 }
531
532 match self.v.iter().rposition(|x| (self.pred)(x)) {
533 None => self.finish(),
534 Some(idx) => {
535 let (left, right) =
536 unsafe { (self.v.get_unchecked(..idx), self.v.get_unchecked(idx + 1..)) };
539 let ret = Some(right);
540 self.v = left;
541 ret
542 }
543 }
544 }
545}
546
547#[cfg(not(feature = "ferrocene_subset"))]
548impl<'a, T, P> SplitIter for Split<'a, T, P>
549where
550 P: FnMut(&T) -> bool,
551{
552 #[inline]
553 fn finish(&mut self) -> Option<&'a [T]> {
554 if self.finished {
555 None
556 } else {
557 self.finished = true;
558 Some(self.v)
559 }
560 }
561}
562
563#[stable(feature = "fused", since = "1.26.0")]
564#[cfg(not(feature = "ferrocene_subset"))]
565impl<T, P> FusedIterator for Split<'_, T, P> where P: FnMut(&T) -> bool {}
566
567#[stable(feature = "split_inclusive", since = "1.51.0")]
586#[must_use = "iterators are lazy and do nothing unless consumed"]
587#[cfg(not(feature = "ferrocene_subset"))]
588pub struct SplitInclusive<'a, T: 'a, P>
589where
590 P: FnMut(&T) -> bool,
591{
592 v: &'a [T],
593 pred: P,
594 finished: bool,
595}
596
597#[cfg(not(feature = "ferrocene_subset"))]
598impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusive<'a, T, P> {
599 #[inline]
600 pub(super) fn new(slice: &'a [T], pred: P) -> Self {
601 let finished = slice.is_empty();
602 Self { v: slice, pred, finished }
603 }
604}
605
606#[stable(feature = "split_inclusive", since = "1.51.0")]
607#[cfg(not(feature = "ferrocene_subset"))]
608impl<T: fmt::Debug, P> fmt::Debug for SplitInclusive<'_, T, P>
609where
610 P: FnMut(&T) -> bool,
611{
612 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
613 f.debug_struct("SplitInclusive")
614 .field("v", &self.v)
615 .field("finished", &self.finished)
616 .finish()
617 }
618}
619
620#[stable(feature = "split_inclusive", since = "1.51.0")]
622#[cfg(not(feature = "ferrocene_subset"))]
623impl<T, P> Clone for SplitInclusive<'_, T, P>
624where
625 P: Clone + FnMut(&T) -> bool,
626{
627 fn clone(&self) -> Self {
628 SplitInclusive { v: self.v, pred: self.pred.clone(), finished: self.finished }
629 }
630}
631
632#[stable(feature = "split_inclusive", since = "1.51.0")]
633#[cfg(not(feature = "ferrocene_subset"))]
634impl<'a, T, P> Iterator for SplitInclusive<'a, T, P>
635where
636 P: FnMut(&T) -> bool,
637{
638 type Item = &'a [T];
639
640 #[inline]
641 fn next(&mut self) -> Option<&'a [T]> {
642 if self.finished {
643 return None;
644 }
645
646 let idx =
647 self.v.iter().position(|x| (self.pred)(x)).map(|idx| idx + 1).unwrap_or(self.v.len());
648 if idx == self.v.len() {
649 self.finished = true;
650 }
651 let ret = Some(&self.v[..idx]);
652 self.v = &self.v[idx..];
653 ret
654 }
655
656 #[inline]
657 fn size_hint(&self) -> (usize, Option<usize>) {
658 if self.finished {
659 (0, Some(0))
660 } else {
661 (1, Some(cmp::max(1, self.v.len())))
665 }
666 }
667}
668
669#[stable(feature = "split_inclusive", since = "1.51.0")]
670#[cfg(not(feature = "ferrocene_subset"))]
671impl<'a, T, P> DoubleEndedIterator for SplitInclusive<'a, T, P>
672where
673 P: FnMut(&T) -> bool,
674{
675 #[inline]
676 fn next_back(&mut self) -> Option<&'a [T]> {
677 if self.finished {
678 return None;
679 }
680
681 let remainder = if self.v.is_empty() { &[] } else { &self.v[..(self.v.len() - 1)] };
685 let idx = remainder.iter().rposition(|x| (self.pred)(x)).map(|idx| idx + 1).unwrap_or(0);
686 if idx == 0 {
687 self.finished = true;
688 }
689 let ret = Some(&self.v[idx..]);
690 self.v = &self.v[..idx];
691 ret
692 }
693}
694
695#[stable(feature = "split_inclusive", since = "1.51.0")]
696#[cfg(not(feature = "ferrocene_subset"))]
697impl<T, P> FusedIterator for SplitInclusive<'_, T, P> where P: FnMut(&T) -> bool {}
698
699#[stable(feature = "rust1", since = "1.0.0")]
714#[must_use = "iterators are lazy and do nothing unless consumed"]
715#[cfg(not(feature = "ferrocene_subset"))]
716pub struct SplitMut<'a, T: 'a, P>
717where
718 P: FnMut(&T) -> bool,
719{
720 v: &'a mut [T],
721 pred: P,
722 finished: bool,
723}
724
725#[cfg(not(feature = "ferrocene_subset"))]
726impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitMut<'a, T, P> {
727 #[inline]
728 pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
729 Self { v: slice, pred, finished: false }
730 }
731}
732
733#[stable(feature = "core_impl_debug", since = "1.9.0")]
734#[cfg(not(feature = "ferrocene_subset"))]
735impl<T: fmt::Debug, P> fmt::Debug for SplitMut<'_, T, P>
736where
737 P: FnMut(&T) -> bool,
738{
739 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
740 f.debug_struct("SplitMut").field("v", &self.v).field("finished", &self.finished).finish()
741 }
742}
743
744#[cfg(not(feature = "ferrocene_subset"))]
745impl<'a, T, P> SplitIter for SplitMut<'a, T, P>
746where
747 P: FnMut(&T) -> bool,
748{
749 #[inline]
750 fn finish(&mut self) -> Option<&'a mut [T]> {
751 if self.finished {
752 None
753 } else {
754 self.finished = true;
755 Some(mem::take(&mut self.v))
756 }
757 }
758}
759
760#[stable(feature = "rust1", since = "1.0.0")]
761#[cfg(not(feature = "ferrocene_subset"))]
762impl<'a, T, P> Iterator for SplitMut<'a, T, P>
763where
764 P: FnMut(&T) -> bool,
765{
766 type Item = &'a mut [T];
767
768 #[inline]
769 fn next(&mut self) -> Option<&'a mut [T]> {
770 if self.finished {
771 return None;
772 }
773
774 match self.v.iter().position(|x| (self.pred)(x)) {
775 None => self.finish(),
776 Some(idx) => {
777 let tmp = mem::take(&mut self.v);
778 let (head, tail) = tmp.split_at_mut(idx + 1);
782 self.v = tail;
783 Some(&mut head[..idx])
785 }
786 }
787 }
788
789 #[inline]
790 fn size_hint(&self) -> (usize, Option<usize>) {
791 if self.finished {
792 (0, Some(0))
793 } else {
794 (1, Some(self.v.len() + 1))
797 }
798 }
799}
800
801#[stable(feature = "rust1", since = "1.0.0")]
802#[cfg(not(feature = "ferrocene_subset"))]
803impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P>
804where
805 P: FnMut(&T) -> bool,
806{
807 #[inline]
808 fn next_back(&mut self) -> Option<&'a mut [T]> {
809 if self.finished {
810 return None;
811 }
812
813 let idx_opt = {
814 let pred = &mut self.pred;
816 self.v.iter().rposition(|x| (*pred)(x))
817 };
818 match idx_opt {
819 None => self.finish(),
820 Some(idx) => {
821 let tmp = mem::take(&mut self.v);
822 let (head, tail) = tmp.split_at_mut(idx);
823 self.v = head;
824 Some(&mut tail[1..])
825 }
826 }
827 }
828}
829
830#[stable(feature = "fused", since = "1.26.0")]
831#[cfg(not(feature = "ferrocene_subset"))]
832impl<T, P> FusedIterator for SplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
833
834#[stable(feature = "split_inclusive", since = "1.51.0")]
850#[must_use = "iterators are lazy and do nothing unless consumed"]
851#[cfg(not(feature = "ferrocene_subset"))]
852pub struct SplitInclusiveMut<'a, T: 'a, P>
853where
854 P: FnMut(&T) -> bool,
855{
856 v: &'a mut [T],
857 pred: P,
858 finished: bool,
859}
860
861#[cfg(not(feature = "ferrocene_subset"))]
862impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusiveMut<'a, T, P> {
863 #[inline]
864 pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
865 let finished = slice.is_empty();
866 Self { v: slice, pred, finished }
867 }
868}
869
870#[stable(feature = "split_inclusive", since = "1.51.0")]
871#[cfg(not(feature = "ferrocene_subset"))]
872impl<T: fmt::Debug, P> fmt::Debug for SplitInclusiveMut<'_, T, P>
873where
874 P: FnMut(&T) -> bool,
875{
876 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
877 f.debug_struct("SplitInclusiveMut")
878 .field("v", &self.v)
879 .field("finished", &self.finished)
880 .finish()
881 }
882}
883
884#[stable(feature = "split_inclusive", since = "1.51.0")]
885#[cfg(not(feature = "ferrocene_subset"))]
886impl<'a, T, P> Iterator for SplitInclusiveMut<'a, T, P>
887where
888 P: FnMut(&T) -> bool,
889{
890 type Item = &'a mut [T];
891
892 #[inline]
893 fn next(&mut self) -> Option<&'a mut [T]> {
894 if self.finished {
895 return None;
896 }
897
898 let idx_opt = {
899 let pred = &mut self.pred;
901 self.v.iter().position(|x| (*pred)(x))
902 };
903 let idx = idx_opt.map(|idx| idx + 1).unwrap_or(self.v.len());
904 if idx == self.v.len() {
905 self.finished = true;
906 }
907 let tmp = mem::take(&mut self.v);
908 let (head, tail) = tmp.split_at_mut(idx);
909 self.v = tail;
910 Some(head)
911 }
912
913 #[inline]
914 fn size_hint(&self) -> (usize, Option<usize>) {
915 if self.finished {
916 (0, Some(0))
917 } else {
918 (1, Some(cmp::max(1, self.v.len())))
922 }
923 }
924}
925
926#[stable(feature = "split_inclusive", since = "1.51.0")]
927#[cfg(not(feature = "ferrocene_subset"))]
928impl<'a, T, P> DoubleEndedIterator for SplitInclusiveMut<'a, T, P>
929where
930 P: FnMut(&T) -> bool,
931{
932 #[inline]
933 fn next_back(&mut self) -> Option<&'a mut [T]> {
934 if self.finished {
935 return None;
936 }
937
938 let idx_opt = if self.v.is_empty() {
939 None
940 } else {
941 let pred = &mut self.pred;
943
944 let remainder = &self.v[..(self.v.len() - 1)];
948 remainder.iter().rposition(|x| (*pred)(x))
949 };
950 let idx = idx_opt.map(|idx| idx + 1).unwrap_or(0);
951 if idx == 0 {
952 self.finished = true;
953 }
954 let tmp = mem::take(&mut self.v);
955 let (head, tail) = tmp.split_at_mut(idx);
956 self.v = head;
957 Some(tail)
958 }
959}
960
961#[stable(feature = "split_inclusive", since = "1.51.0")]
962#[cfg(not(feature = "ferrocene_subset"))]
963impl<T, P> FusedIterator for SplitInclusiveMut<'_, T, P> where P: FnMut(&T) -> bool {}
964
965#[stable(feature = "slice_rsplit", since = "1.27.0")]
983#[must_use = "iterators are lazy and do nothing unless consumed"]
984#[cfg(not(feature = "ferrocene_subset"))]
985pub struct RSplit<'a, T: 'a, P>
986where
987 P: FnMut(&T) -> bool,
988{
989 inner: Split<'a, T, P>,
990}
991
992#[cfg(not(feature = "ferrocene_subset"))]
993impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplit<'a, T, P> {
994 #[inline]
995 pub(super) fn new(slice: &'a [T], pred: P) -> Self {
996 Self { inner: Split::new(slice, pred) }
997 }
998}
999
1000#[stable(feature = "slice_rsplit", since = "1.27.0")]
1001#[cfg(not(feature = "ferrocene_subset"))]
1002impl<T: fmt::Debug, P> fmt::Debug for RSplit<'_, T, P>
1003where
1004 P: FnMut(&T) -> bool,
1005{
1006 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1007 f.debug_struct("RSplit")
1008 .field("v", &self.inner.v)
1009 .field("finished", &self.inner.finished)
1010 .finish()
1011 }
1012}
1013
1014#[stable(feature = "slice_rsplit", since = "1.27.0")]
1016#[cfg(not(feature = "ferrocene_subset"))]
1017impl<T, P> Clone for RSplit<'_, T, P>
1018where
1019 P: Clone + FnMut(&T) -> bool,
1020{
1021 fn clone(&self) -> Self {
1022 RSplit { inner: self.inner.clone() }
1023 }
1024}
1025
1026#[stable(feature = "slice_rsplit", since = "1.27.0")]
1027#[cfg(not(feature = "ferrocene_subset"))]
1028impl<'a, T, P> Iterator for RSplit<'a, T, P>
1029where
1030 P: FnMut(&T) -> bool,
1031{
1032 type Item = &'a [T];
1033
1034 #[inline]
1035 fn next(&mut self) -> Option<&'a [T]> {
1036 self.inner.next_back()
1037 }
1038
1039 #[inline]
1040 fn size_hint(&self) -> (usize, Option<usize>) {
1041 self.inner.size_hint()
1042 }
1043}
1044
1045#[stable(feature = "slice_rsplit", since = "1.27.0")]
1046#[cfg(not(feature = "ferrocene_subset"))]
1047impl<'a, T, P> DoubleEndedIterator for RSplit<'a, T, P>
1048where
1049 P: FnMut(&T) -> bool,
1050{
1051 #[inline]
1052 fn next_back(&mut self) -> Option<&'a [T]> {
1053 self.inner.next()
1054 }
1055}
1056
1057#[stable(feature = "slice_rsplit", since = "1.27.0")]
1058#[cfg(not(feature = "ferrocene_subset"))]
1059impl<'a, T, P> SplitIter for RSplit<'a, T, P>
1060where
1061 P: FnMut(&T) -> bool,
1062{
1063 #[inline]
1064 fn finish(&mut self) -> Option<&'a [T]> {
1065 self.inner.finish()
1066 }
1067}
1068
1069#[stable(feature = "slice_rsplit", since = "1.27.0")]
1070#[cfg(not(feature = "ferrocene_subset"))]
1071impl<T, P> FusedIterator for RSplit<'_, T, P> where P: FnMut(&T) -> bool {}
1072
1073#[stable(feature = "slice_rsplit", since = "1.27.0")]
1088#[must_use = "iterators are lazy and do nothing unless consumed"]
1089#[cfg(not(feature = "ferrocene_subset"))]
1090pub struct RSplitMut<'a, T: 'a, P>
1091where
1092 P: FnMut(&T) -> bool,
1093{
1094 inner: SplitMut<'a, T, P>,
1095}
1096
1097#[cfg(not(feature = "ferrocene_subset"))]
1098impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitMut<'a, T, P> {
1099 #[inline]
1100 pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
1101 Self { inner: SplitMut::new(slice, pred) }
1102 }
1103}
1104
1105#[stable(feature = "slice_rsplit", since = "1.27.0")]
1106#[cfg(not(feature = "ferrocene_subset"))]
1107impl<T: fmt::Debug, P> fmt::Debug for RSplitMut<'_, T, P>
1108where
1109 P: FnMut(&T) -> bool,
1110{
1111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1112 f.debug_struct("RSplitMut")
1113 .field("v", &self.inner.v)
1114 .field("finished", &self.inner.finished)
1115 .finish()
1116 }
1117}
1118
1119#[stable(feature = "slice_rsplit", since = "1.27.0")]
1120#[cfg(not(feature = "ferrocene_subset"))]
1121impl<'a, T, P> SplitIter for RSplitMut<'a, T, P>
1122where
1123 P: FnMut(&T) -> bool,
1124{
1125 #[inline]
1126 fn finish(&mut self) -> Option<&'a mut [T]> {
1127 self.inner.finish()
1128 }
1129}
1130
1131#[stable(feature = "slice_rsplit", since = "1.27.0")]
1132#[cfg(not(feature = "ferrocene_subset"))]
1133impl<'a, T, P> Iterator for RSplitMut<'a, T, P>
1134where
1135 P: FnMut(&T) -> bool,
1136{
1137 type Item = &'a mut [T];
1138
1139 #[inline]
1140 fn next(&mut self) -> Option<&'a mut [T]> {
1141 self.inner.next_back()
1142 }
1143
1144 #[inline]
1145 fn size_hint(&self) -> (usize, Option<usize>) {
1146 self.inner.size_hint()
1147 }
1148}
1149
1150#[stable(feature = "slice_rsplit", since = "1.27.0")]
1151#[cfg(not(feature = "ferrocene_subset"))]
1152impl<'a, T, P> DoubleEndedIterator for RSplitMut<'a, T, P>
1153where
1154 P: FnMut(&T) -> bool,
1155{
1156 #[inline]
1157 fn next_back(&mut self) -> Option<&'a mut [T]> {
1158 self.inner.next()
1159 }
1160}
1161
1162#[stable(feature = "slice_rsplit", since = "1.27.0")]
1163#[cfg(not(feature = "ferrocene_subset"))]
1164impl<T, P> FusedIterator for RSplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
1165
1166#[derive(Debug)]
1170#[cfg(not(feature = "ferrocene_subset"))]
1171struct GenericSplitN<I> {
1172 iter: I,
1173 count: usize,
1174}
1175
1176#[cfg(not(feature = "ferrocene_subset"))]
1177impl<T, I: SplitIter<Item = T>> Iterator for GenericSplitN<I> {
1178 type Item = T;
1179
1180 #[inline]
1181 fn next(&mut self) -> Option<T> {
1182 match self.count {
1183 0 => None,
1184 1 => {
1185 self.count -= 1;
1186 self.iter.finish()
1187 }
1188 _ => {
1189 self.count -= 1;
1190 self.iter.next()
1191 }
1192 }
1193 }
1194
1195 #[inline]
1196 fn size_hint(&self) -> (usize, Option<usize>) {
1197 let (lower, upper_opt) = self.iter.size_hint();
1198 (
1199 cmp::min(self.count, lower),
1200 Some(upper_opt.map_or(self.count, |upper| cmp::min(self.count, upper))),
1201 )
1202 }
1203}
1204
1205#[stable(feature = "rust1", since = "1.0.0")]
1223#[must_use = "iterators are lazy and do nothing unless consumed"]
1224#[cfg(not(feature = "ferrocene_subset"))]
1225pub struct SplitN<'a, T: 'a, P>
1226where
1227 P: FnMut(&T) -> bool,
1228{
1229 inner: GenericSplitN<Split<'a, T, P>>,
1230}
1231
1232#[cfg(not(feature = "ferrocene_subset"))]
1233impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitN<'a, T, P> {
1234 #[inline]
1235 pub(super) fn new(s: Split<'a, T, P>, n: usize) -> Self {
1236 Self { inner: GenericSplitN { iter: s, count: n } }
1237 }
1238}
1239
1240#[stable(feature = "core_impl_debug", since = "1.9.0")]
1241#[cfg(not(feature = "ferrocene_subset"))]
1242impl<T: fmt::Debug, P> fmt::Debug for SplitN<'_, T, P>
1243where
1244 P: FnMut(&T) -> bool,
1245{
1246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1247 f.debug_struct("SplitN").field("inner", &self.inner).finish()
1248 }
1249}
1250
1251#[stable(feature = "rust1", since = "1.0.0")]
1270#[must_use = "iterators are lazy and do nothing unless consumed"]
1271#[cfg(not(feature = "ferrocene_subset"))]
1272pub struct RSplitN<'a, T: 'a, P>
1273where
1274 P: FnMut(&T) -> bool,
1275{
1276 inner: GenericSplitN<RSplit<'a, T, P>>,
1277}
1278
1279#[cfg(not(feature = "ferrocene_subset"))]
1280impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitN<'a, T, P> {
1281 #[inline]
1282 pub(super) fn new(s: RSplit<'a, T, P>, n: usize) -> Self {
1283 Self { inner: GenericSplitN { iter: s, count: n } }
1284 }
1285}
1286
1287#[stable(feature = "core_impl_debug", since = "1.9.0")]
1288#[cfg(not(feature = "ferrocene_subset"))]
1289impl<T: fmt::Debug, P> fmt::Debug for RSplitN<'_, T, P>
1290where
1291 P: FnMut(&T) -> bool,
1292{
1293 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1294 f.debug_struct("RSplitN").field("inner", &self.inner).finish()
1295 }
1296}
1297
1298#[stable(feature = "rust1", since = "1.0.0")]
1313#[must_use = "iterators are lazy and do nothing unless consumed"]
1314#[cfg(not(feature = "ferrocene_subset"))]
1315pub struct SplitNMut<'a, T: 'a, P>
1316where
1317 P: FnMut(&T) -> bool,
1318{
1319 inner: GenericSplitN<SplitMut<'a, T, P>>,
1320}
1321
1322#[cfg(not(feature = "ferrocene_subset"))]
1323impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitNMut<'a, T, P> {
1324 #[inline]
1325 pub(super) fn new(s: SplitMut<'a, T, P>, n: usize) -> Self {
1326 Self { inner: GenericSplitN { iter: s, count: n } }
1327 }
1328}
1329
1330#[stable(feature = "core_impl_debug", since = "1.9.0")]
1331#[cfg(not(feature = "ferrocene_subset"))]
1332impl<T: fmt::Debug, P> fmt::Debug for SplitNMut<'_, T, P>
1333where
1334 P: FnMut(&T) -> bool,
1335{
1336 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1337 f.debug_struct("SplitNMut").field("inner", &self.inner).finish()
1338 }
1339}
1340
1341#[stable(feature = "rust1", since = "1.0.0")]
1357#[must_use = "iterators are lazy and do nothing unless consumed"]
1358#[cfg(not(feature = "ferrocene_subset"))]
1359pub struct RSplitNMut<'a, T: 'a, P>
1360where
1361 P: FnMut(&T) -> bool,
1362{
1363 inner: GenericSplitN<RSplitMut<'a, T, P>>,
1364}
1365
1366#[cfg(not(feature = "ferrocene_subset"))]
1367impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitNMut<'a, T, P> {
1368 #[inline]
1369 pub(super) fn new(s: RSplitMut<'a, T, P>, n: usize) -> Self {
1370 Self { inner: GenericSplitN { iter: s, count: n } }
1371 }
1372}
1373
1374#[stable(feature = "core_impl_debug", since = "1.9.0")]
1375#[cfg(not(feature = "ferrocene_subset"))]
1376impl<T: fmt::Debug, P> fmt::Debug for RSplitNMut<'_, T, P>
1377where
1378 P: FnMut(&T) -> bool,
1379{
1380 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1381 f.debug_struct("RSplitNMut").field("inner", &self.inner).finish()
1382 }
1383}
1384
1385#[cfg(not(feature = "ferrocene_subset"))]
1386forward_iterator! { SplitN: T, &'a [T] }
1387#[cfg(not(feature = "ferrocene_subset"))]
1388forward_iterator! { RSplitN: T, &'a [T] }
1389#[cfg(not(feature = "ferrocene_subset"))]
1390forward_iterator! { SplitNMut: T, &'a mut [T] }
1391#[cfg(not(feature = "ferrocene_subset"))]
1392forward_iterator! { RSplitNMut: T, &'a mut [T] }
1393
1394#[cfg_attr(not(feature = "ferrocene_subset"), derive(Debug))]
1412#[stable(feature = "rust1", since = "1.0.0")]
1413#[must_use = "iterators are lazy and do nothing unless consumed"]
1414pub struct Windows<'a, T: 'a> {
1415 v: &'a [T],
1416 size: NonZero<usize>,
1417}
1418
1419impl<'a, T: 'a> Windows<'a, T> {
1420 #[inline]
1421 pub(super) const fn new(slice: &'a [T], size: NonZero<usize>) -> Self {
1422 Self { v: slice, size }
1423 }
1424}
1425
1426#[stable(feature = "rust1", since = "1.0.0")]
1428#[cfg(not(feature = "ferrocene_subset"))]
1429impl<T> Clone for Windows<'_, T> {
1430 fn clone(&self) -> Self {
1431 Windows { v: self.v, size: self.size }
1432 }
1433}
1434
1435#[stable(feature = "rust1", since = "1.0.0")]
1436impl<'a, T> Iterator for Windows<'a, T> {
1437 type Item = &'a [T];
1438
1439 #[inline]
1440 fn next(&mut self) -> Option<&'a [T]> {
1441 if self.size.get() > self.v.len() {
1442 None
1443 } else {
1444 let ret = Some(&self.v[..self.size.get()]);
1445 self.v = &self.v[1..];
1446 ret
1447 }
1448 }
1449
1450 #[inline]
1451 fn size_hint(&self) -> (usize, Option<usize>) {
1452 if self.size.get() > self.v.len() {
1453 (0, Some(0))
1454 } else {
1455 let size = self.v.len() - self.size.get() + 1;
1456 (size, Some(size))
1457 }
1458 }
1459
1460 #[inline]
1461 fn count(self) -> usize {
1462 self.len()
1463 }
1464
1465 #[inline]
1466 fn nth(&mut self, n: usize) -> Option<Self::Item> {
1467 let size = self.size.get();
1468 if let Some(rest) = self.v.get(n..)
1469 && let Some(nth) = rest.get(..size)
1470 {
1471 self.v = &rest[1..];
1472 Some(nth)
1473 } else {
1474 self.v = &self.v[..0]; None
1477 }
1478 }
1479
1480 #[inline]
1481 fn last(self) -> Option<Self::Item> {
1482 if self.size.get() > self.v.len() {
1483 None
1484 } else {
1485 let start = self.v.len() - self.size.get();
1486 Some(&self.v[start..])
1487 }
1488 }
1489
1490 #[cfg(not(feature = "ferrocene_subset"))]
1491 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
1492 unsafe { from_raw_parts(self.v.as_ptr().add(idx), self.size.get()) }
1497 }
1498}
1499
1500#[stable(feature = "rust1", since = "1.0.0")]
1501#[cfg(not(feature = "ferrocene_subset"))]
1502impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
1503 #[inline]
1504 fn next_back(&mut self) -> Option<Self::Item> {
1505 self.nth_back(0)
1506 }
1507
1508 #[inline]
1509 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1510 if let Some(end) = self.v.len().checked_sub(n)
1511 && let Some(start) = end.checked_sub(self.size.get())
1512 {
1513 let res = &self.v[start..end];
1514 self.v = &self.v[..end - 1];
1515 Some(res)
1516 } else {
1517 self.v = &self.v[..0]; None
1519 }
1520 }
1521}
1522
1523#[stable(feature = "rust1", since = "1.0.0")]
1524impl<T> ExactSizeIterator for Windows<'_, T> {}
1525
1526#[unstable(feature = "trusted_len", issue = "37572")]
1527#[cfg(not(feature = "ferrocene_subset"))]
1528unsafe impl<T> TrustedLen for Windows<'_, T> {}
1529
1530#[stable(feature = "fused", since = "1.26.0")]
1531#[cfg(not(feature = "ferrocene_subset"))]
1532impl<T> FusedIterator for Windows<'_, T> {}
1533
1534#[doc(hidden)]
1535#[unstable(feature = "trusted_random_access", issue = "none")]
1536#[cfg(not(feature = "ferrocene_subset"))]
1537unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {}
1538
1539#[doc(hidden)]
1540#[unstable(feature = "trusted_random_access", issue = "none")]
1541#[cfg(not(feature = "ferrocene_subset"))]
1542unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Windows<'a, T> {
1543 const MAY_HAVE_SIDE_EFFECT: bool = false;
1544}
1545
1546#[cfg_attr(not(feature = "ferrocene_subset"), derive(Debug))]
1568#[stable(feature = "rust1", since = "1.0.0")]
1569#[must_use = "iterators are lazy and do nothing unless consumed"]
1570pub struct Chunks<'a, T: 'a> {
1571 v: &'a [T],
1572 chunk_size: usize,
1573}
1574
1575impl<'a, T: 'a> Chunks<'a, T> {
1576 #[inline]
1577 pub(super) const fn new(slice: &'a [T], size: usize) -> Self {
1578 Self { v: slice, chunk_size: size }
1579 }
1580}
1581
1582#[stable(feature = "rust1", since = "1.0.0")]
1584#[cfg(not(feature = "ferrocene_subset"))]
1585impl<T> Clone for Chunks<'_, T> {
1586 fn clone(&self) -> Self {
1587 Chunks { v: self.v, chunk_size: self.chunk_size }
1588 }
1589}
1590
1591#[stable(feature = "rust1", since = "1.0.0")]
1592impl<'a, T> Iterator for Chunks<'a, T> {
1593 type Item = &'a [T];
1594
1595 #[inline]
1596 fn next(&mut self) -> Option<&'a [T]> {
1597 if self.v.is_empty() {
1598 None
1599 } else {
1600 let chunksz = cmp::min(self.v.len(), self.chunk_size);
1601 let (fst, snd) = self.v.split_at(chunksz);
1602 self.v = snd;
1603 Some(fst)
1604 }
1605 }
1606
1607 #[inline]
1608 fn size_hint(&self) -> (usize, Option<usize>) {
1609 if self.v.is_empty() {
1610 (0, Some(0))
1611 } else {
1612 let n = self.v.len().div_ceil(self.chunk_size);
1613 (n, Some(n))
1614 }
1615 }
1616
1617 #[inline]
1618 fn count(self) -> usize {
1619 self.len()
1620 }
1621
1622 #[inline]
1623 fn nth(&mut self, n: usize) -> Option<Self::Item> {
1624 if let Some(start) = n.checked_mul(self.chunk_size)
1625 && start < self.v.len()
1626 {
1627 let rest = &self.v[start..];
1628 let (chunk, rest) = rest.split_at(self.chunk_size.min(rest.len()));
1629 self.v = rest;
1630 Some(chunk)
1631 } else {
1632 self.v = &self.v[..0]; None
1634 }
1635 }
1636
1637 #[inline]
1638 fn last(self) -> Option<Self::Item> {
1639 if self.v.is_empty() {
1640 None
1641 } else {
1642 let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
1643 Some(&self.v[start..])
1644 }
1645 }
1646
1647 #[cfg(not(feature = "ferrocene_subset"))]
1648 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
1649 let start = idx * self.chunk_size;
1650 unsafe {
1658 let len = cmp::min(self.v.len().unchecked_sub(start), self.chunk_size);
1659 from_raw_parts(self.v.as_ptr().add(start), len)
1660 }
1661 }
1662}
1663
1664#[stable(feature = "rust1", since = "1.0.0")]
1665#[cfg(not(feature = "ferrocene_subset"))]
1666impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
1667 #[inline]
1668 fn next_back(&mut self) -> Option<&'a [T]> {
1669 if self.v.is_empty() {
1670 None
1671 } else {
1672 let remainder = self.v.len() % self.chunk_size;
1673 let chunksz = if remainder != 0 { remainder } else { self.chunk_size };
1674 let (fst, snd) = unsafe { self.v.split_at_unchecked(self.v.len() - chunksz) };
1689 self.v = fst;
1690 Some(snd)
1691 }
1692 }
1693
1694 #[inline]
1695 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1696 let len = self.len();
1697 if n < len {
1698 let start = (len - 1 - n) * self.chunk_size;
1699 let end = start + (self.v.len() - start).min(self.chunk_size);
1700 let nth_back = &self.v[start..end];
1701 self.v = &self.v[..start];
1702 Some(nth_back)
1703 } else {
1704 self.v = &self.v[..0]; None
1706 }
1707 }
1708}
1709
1710#[stable(feature = "rust1", since = "1.0.0")]
1711impl<T> ExactSizeIterator for Chunks<'_, T> {}
1712
1713#[unstable(feature = "trusted_len", issue = "37572")]
1714#[cfg(not(feature = "ferrocene_subset"))]
1715unsafe impl<T> TrustedLen for Chunks<'_, T> {}
1716
1717#[stable(feature = "fused", since = "1.26.0")]
1718#[cfg(not(feature = "ferrocene_subset"))]
1719impl<T> FusedIterator for Chunks<'_, T> {}
1720
1721#[doc(hidden)]
1722#[unstable(feature = "trusted_random_access", issue = "none")]
1723#[cfg(not(feature = "ferrocene_subset"))]
1724unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {}
1725
1726#[doc(hidden)]
1727#[unstable(feature = "trusted_random_access", issue = "none")]
1728#[cfg(not(feature = "ferrocene_subset"))]
1729unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Chunks<'a, T> {
1730 const MAY_HAVE_SIDE_EFFECT: bool = false;
1731}
1732
1733#[cfg_attr(not(feature = "ferrocene_subset"), derive(Debug))]
1751#[stable(feature = "rust1", since = "1.0.0")]
1752#[must_use = "iterators are lazy and do nothing unless consumed"]
1753pub struct ChunksMut<'a, T: 'a> {
1754 v: *mut [T],
1761 chunk_size: usize,
1762 _marker: PhantomData<&'a mut T>,
1763}
1764
1765impl<'a, T: 'a> ChunksMut<'a, T> {
1766 #[inline]
1767 pub(super) const fn new(slice: &'a mut [T], size: usize) -> Self {
1768 Self { v: slice, chunk_size: size, _marker: PhantomData }
1769 }
1770}
1771
1772#[stable(feature = "rust1", since = "1.0.0")]
1773impl<'a, T> Iterator for ChunksMut<'a, T> {
1774 type Item = &'a mut [T];
1775
1776 #[inline]
1777 fn next(&mut self) -> Option<&'a mut [T]> {
1778 if self.v.is_empty() {
1779 None
1780 } else {
1781 let sz = cmp::min(self.v.len(), self.chunk_size);
1782 let (head, tail) = unsafe { self.v.split_at_mut(sz) };
1784 self.v = tail;
1785 Some(unsafe { &mut *head })
1787 }
1788 }
1789
1790 #[inline]
1791 fn size_hint(&self) -> (usize, Option<usize>) {
1792 if self.v.is_empty() {
1793 (0, Some(0))
1794 } else {
1795 let n = self.v.len().div_ceil(self.chunk_size);
1796 (n, Some(n))
1797 }
1798 }
1799
1800 #[inline]
1801 fn count(self) -> usize {
1802 self.len()
1803 }
1804
1805 #[inline]
1806 fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
1807 if let Some(start) = n.checked_mul(self.chunk_size)
1808 && start < self.v.len()
1809 {
1810 let (_, rest) = unsafe { self.v.split_at_mut(start) };
1812 let (chunk, rest) = unsafe { rest.split_at_mut(self.chunk_size.min(rest.len())) };
1814 self.v = rest;
1815 Some(unsafe { &mut *chunk })
1817 } else {
1818 self.v = &mut [];
1819 None
1820 }
1821 }
1822
1823 #[inline]
1824 fn last(self) -> Option<Self::Item> {
1825 if self.v.is_empty() {
1826 None
1827 } else {
1828 let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
1829 Some(unsafe { &mut *self.v.get_unchecked_mut(start..) })
1831 }
1832 }
1833
1834 #[cfg(not(feature = "ferrocene_subset"))]
1835 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
1836 let start = idx * self.chunk_size;
1837 unsafe {
1844 let len = cmp::min(self.v.len().unchecked_sub(start), self.chunk_size);
1845 from_raw_parts_mut(self.v.as_mut_ptr().add(start), len)
1846 }
1847 }
1848}
1849
1850#[stable(feature = "rust1", since = "1.0.0")]
1851#[cfg(not(feature = "ferrocene_subset"))]
1852impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
1853 #[inline]
1854 fn next_back(&mut self) -> Option<&'a mut [T]> {
1855 if self.v.is_empty() {
1856 None
1857 } else {
1858 let remainder = self.v.len() % self.chunk_size;
1859 let sz = if remainder != 0 { remainder } else { self.chunk_size };
1860 let len = self.v.len();
1861 let (head, tail) = unsafe { self.v.split_at_mut_unchecked(len - sz) };
1863 self.v = head;
1864 Some(unsafe { &mut *tail })
1866 }
1867 }
1868
1869 #[inline]
1870 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1871 let len = self.len();
1872 if n < len {
1873 let start = (len - 1 - n) * self.chunk_size;
1874 let end = match start.checked_add(self.chunk_size) {
1875 Some(res) => cmp::min(self.v.len(), res),
1876 None => self.v.len(),
1877 };
1878 let (temp, _tail) = unsafe { self.v.split_at_mut(end) };
1880 let (head, nth_back) = unsafe { temp.split_at_mut(start) };
1882 self.v = head;
1883 Some(unsafe { &mut *nth_back })
1885 } else {
1886 self.v = &mut [];
1887 None
1888 }
1889 }
1890}
1891
1892#[stable(feature = "rust1", since = "1.0.0")]
1893impl<T> ExactSizeIterator for ChunksMut<'_, T> {}
1894
1895#[unstable(feature = "trusted_len", issue = "37572")]
1896#[cfg(not(feature = "ferrocene_subset"))]
1897unsafe impl<T> TrustedLen for ChunksMut<'_, T> {}
1898
1899#[stable(feature = "fused", since = "1.26.0")]
1900#[cfg(not(feature = "ferrocene_subset"))]
1901impl<T> FusedIterator for ChunksMut<'_, T> {}
1902
1903#[doc(hidden)]
1904#[unstable(feature = "trusted_random_access", issue = "none")]
1905#[cfg(not(feature = "ferrocene_subset"))]
1906unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {}
1907
1908#[doc(hidden)]
1909#[unstable(feature = "trusted_random_access", issue = "none")]
1910#[cfg(not(feature = "ferrocene_subset"))]
1911unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksMut<'a, T> {
1912 const MAY_HAVE_SIDE_EFFECT: bool = false;
1913}
1914
1915#[stable(feature = "rust1", since = "1.0.0")]
1916#[cfg(not(feature = "ferrocene_subset"))]
1917unsafe impl<T> Send for ChunksMut<'_, T> where T: Send {}
1918
1919#[stable(feature = "rust1", since = "1.0.0")]
1920#[cfg(not(feature = "ferrocene_subset"))]
1921unsafe impl<T> Sync for ChunksMut<'_, T> where T: Sync {}
1922
1923#[cfg_attr(not(feature = "ferrocene_subset"), derive(Debug))]
1946#[stable(feature = "chunks_exact", since = "1.31.0")]
1947#[must_use = "iterators are lazy and do nothing unless consumed"]
1948pub struct ChunksExact<'a, T: 'a> {
1949 v: &'a [T],
1950 rem: &'a [T],
1951 chunk_size: usize,
1952}
1953
1954impl<'a, T> ChunksExact<'a, T> {
1955 #[inline]
1956 pub(super) const fn new(slice: &'a [T], chunk_size: usize) -> Self {
1957 let rem = slice.len() % chunk_size;
1958 let fst_len = slice.len() - rem;
1959 let (fst, snd) = unsafe { slice.split_at_unchecked(fst_len) };
1961 Self { v: fst, rem: snd, chunk_size }
1962 }
1963
1964 #[must_use]
1982 #[stable(feature = "chunks_exact", since = "1.31.0")]
1983 pub fn remainder(&self) -> &'a [T] {
1984 self.rem
1985 }
1986}
1987
1988#[stable(feature = "chunks_exact", since = "1.31.0")]
1990#[cfg(not(feature = "ferrocene_subset"))]
1991impl<T> Clone for ChunksExact<'_, T> {
1992 fn clone(&self) -> Self {
1993 ChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size }
1994 }
1995}
1996
1997#[stable(feature = "chunks_exact", since = "1.31.0")]
1998impl<'a, T> Iterator for ChunksExact<'a, T> {
1999 type Item = &'a [T];
2000
2001 #[inline]
2002 fn next(&mut self) -> Option<&'a [T]> {
2003 self.v.split_at_checked(self.chunk_size).and_then(|(chunk, rest)| {
2004 self.v = rest;
2005 Some(chunk)
2006 })
2007 }
2008
2009 #[inline]
2010 fn size_hint(&self) -> (usize, Option<usize>) {
2011 let n = self.v.len() / self.chunk_size;
2012 (n, Some(n))
2013 }
2014
2015 #[inline]
2016 fn count(self) -> usize {
2017 self.len()
2018 }
2019
2020 #[inline]
2021 fn nth(&mut self, n: usize) -> Option<Self::Item> {
2022 if let Some(start) = n.checked_mul(self.chunk_size)
2023 && start < self.v.len()
2024 {
2025 self.v = &self.v[start..];
2026 self.next()
2027 } else {
2028 self.v = &self.v[..0]; None
2030 }
2031 }
2032
2033 #[inline]
2034 fn last(mut self) -> Option<Self::Item> {
2035 self.next_back()
2036 }
2037
2038 #[cfg(not(feature = "ferrocene_subset"))]
2039 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2040 let start = idx * self.chunk_size;
2041 unsafe { from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) }
2043 }
2044}
2045
2046#[stable(feature = "chunks_exact", since = "1.31.0")]
2047impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
2048 #[inline]
2049 fn next_back(&mut self) -> Option<&'a [T]> {
2050 if self.v.len() < self.chunk_size {
2051 None
2052 } else {
2053 let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
2054 self.v = fst;
2055 Some(snd)
2056 }
2057 }
2058
2059 #[inline]
2060 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2061 let len = self.len();
2062 if n < len {
2063 let start = (len - 1 - n) * self.chunk_size;
2064 let end = start + self.chunk_size;
2065 let nth_back = &self.v[start..end];
2066 self.v = &self.v[..start];
2067 Some(nth_back)
2068 } else {
2069 self.v = &self.v[..0]; None
2071 }
2072 }
2073}
2074
2075#[stable(feature = "chunks_exact", since = "1.31.0")]
2076impl<T> ExactSizeIterator for ChunksExact<'_, T> {
2077 fn is_empty(&self) -> bool {
2078 self.v.is_empty()
2079 }
2080}
2081
2082#[unstable(feature = "trusted_len", issue = "37572")]
2083#[cfg(not(feature = "ferrocene_subset"))]
2084unsafe impl<T> TrustedLen for ChunksExact<'_, T> {}
2085
2086#[stable(feature = "chunks_exact", since = "1.31.0")]
2087#[cfg(not(feature = "ferrocene_subset"))]
2088impl<T> FusedIterator for ChunksExact<'_, T> {}
2089
2090#[doc(hidden)]
2091#[unstable(feature = "trusted_random_access", issue = "none")]
2092#[cfg(not(feature = "ferrocene_subset"))]
2093unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {}
2094
2095#[doc(hidden)]
2096#[unstable(feature = "trusted_random_access", issue = "none")]
2097#[cfg(not(feature = "ferrocene_subset"))]
2098unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExact<'a, T> {
2099 const MAY_HAVE_SIDE_EFFECT: bool = false;
2100}
2101
2102#[cfg_attr(not(feature = "ferrocene_subset"), derive(Debug))]
2122#[stable(feature = "chunks_exact", since = "1.31.0")]
2123#[must_use = "iterators are lazy and do nothing unless consumed"]
2124pub struct ChunksExactMut<'a, T: 'a> {
2125 v: *mut [T],
2132 rem: &'a mut [T], chunk_size: usize,
2134 _marker: PhantomData<&'a mut T>,
2135}
2136
2137impl<'a, T> ChunksExactMut<'a, T> {
2138 #[inline]
2139 pub(super) const fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
2140 let rem = slice.len() % chunk_size;
2141 let fst_len = slice.len() - rem;
2142 let (fst, snd) = unsafe { slice.split_at_mut_unchecked(fst_len) };
2144 Self { v: fst, rem: snd, chunk_size, _marker: PhantomData }
2145 }
2146
2147 #[must_use = "`self` will be dropped if the result is not used"]
2151 #[stable(feature = "chunks_exact", since = "1.31.0")]
2152 pub fn into_remainder(self) -> &'a mut [T] {
2153 self.rem
2154 }
2155}
2156
2157#[stable(feature = "chunks_exact", since = "1.31.0")]
2158impl<'a, T> Iterator for ChunksExactMut<'a, T> {
2159 type Item = &'a mut [T];
2160
2161 #[inline]
2162 fn next(&mut self) -> Option<&'a mut [T]> {
2163 unsafe { &mut *self.v }.split_at_mut_checked(self.chunk_size).and_then(|(chunk, rest)| {
2165 self.v = rest;
2166 Some(chunk)
2167 })
2168 }
2169
2170 #[inline]
2171 fn size_hint(&self) -> (usize, Option<usize>) {
2172 let n = self.v.len() / self.chunk_size;
2173 (n, Some(n))
2174 }
2175
2176 #[inline]
2177 fn count(self) -> usize {
2178 self.len()
2179 }
2180
2181 #[inline]
2182 fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
2183 if let Some(start) = n.checked_mul(self.chunk_size)
2184 && start < self.v.len()
2185 {
2186 self.v = unsafe { self.v.split_at_mut(start).1 };
2188 self.next()
2189 } else {
2190 self.v = &mut [];
2191 None
2192 }
2193 }
2194
2195 #[inline]
2196 fn last(mut self) -> Option<Self::Item> {
2197 self.next_back()
2198 }
2199
2200 #[cfg(not(feature = "ferrocene_subset"))]
2201 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2202 let start = idx * self.chunk_size;
2203 unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
2205 }
2206}
2207
2208#[stable(feature = "chunks_exact", since = "1.31.0")]
2209impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
2210 #[inline]
2211 fn next_back(&mut self) -> Option<&'a mut [T]> {
2212 if self.v.len() < self.chunk_size {
2213 None
2214 } else {
2215 let (head, tail) = unsafe { self.v.split_at_mut(self.v.len() - self.chunk_size) };
2217 self.v = head;
2218 Some(unsafe { &mut *tail })
2220 }
2221 }
2222
2223 #[inline]
2224 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2225 let len = self.len();
2226 if n < len {
2227 let start = (len - 1 - n) * self.chunk_size;
2228 let end = start + self.chunk_size;
2229 let (temp, _tail) = unsafe { mem::replace(&mut self.v, &mut []).split_at_mut(end) };
2231 let (head, nth_back) = unsafe { temp.split_at_mut(start) };
2233 self.v = head;
2234 Some(unsafe { &mut *nth_back })
2236 } else {
2237 self.v = &mut [];
2238 None
2239 }
2240 }
2241}
2242
2243#[stable(feature = "chunks_exact", since = "1.31.0")]
2244impl<T> ExactSizeIterator for ChunksExactMut<'_, T> {
2245 fn is_empty(&self) -> bool {
2246 self.v.is_empty()
2247 }
2248}
2249
2250#[unstable(feature = "trusted_len", issue = "37572")]
2251#[cfg(not(feature = "ferrocene_subset"))]
2252unsafe impl<T> TrustedLen for ChunksExactMut<'_, T> {}
2253
2254#[stable(feature = "chunks_exact", since = "1.31.0")]
2255#[cfg(not(feature = "ferrocene_subset"))]
2256impl<T> FusedIterator for ChunksExactMut<'_, T> {}
2257
2258#[doc(hidden)]
2259#[unstable(feature = "trusted_random_access", issue = "none")]
2260#[cfg(not(feature = "ferrocene_subset"))]
2261unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {}
2262
2263#[doc(hidden)]
2264#[unstable(feature = "trusted_random_access", issue = "none")]
2265#[cfg(not(feature = "ferrocene_subset"))]
2266unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExactMut<'a, T> {
2267 const MAY_HAVE_SIDE_EFFECT: bool = false;
2268}
2269
2270#[stable(feature = "chunks_exact", since = "1.31.0")]
2271#[cfg(not(feature = "ferrocene_subset"))]
2272unsafe impl<T> Send for ChunksExactMut<'_, T> where T: Send {}
2273
2274#[stable(feature = "chunks_exact", since = "1.31.0")]
2275#[cfg(not(feature = "ferrocene_subset"))]
2276unsafe impl<T> Sync for ChunksExactMut<'_, T> where T: Sync {}
2277
2278#[derive(Debug, Clone, Copy)]
2297#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")]
2298#[must_use = "iterators are lazy and do nothing unless consumed"]
2299#[cfg(not(feature = "ferrocene_subset"))]
2300pub struct ArrayWindows<'a, T: 'a, const N: usize> {
2301 v: &'a [T],
2302}
2303
2304#[cfg(not(feature = "ferrocene_subset"))]
2305impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> {
2306 #[inline]
2307 pub(super) const fn new(slice: &'a [T]) -> Self {
2308 Self { v: slice }
2309 }
2310}
2311
2312#[cfg(not(feature = "ferrocene_subset"))]
2313#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")]
2314impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
2315 type Item = &'a [T; N];
2316
2317 #[inline]
2318 fn next(&mut self) -> Option<Self::Item> {
2319 let ret = self.v.first_chunk();
2320 if ret.is_some() {
2321 self.v = &self.v[1..];
2322 }
2323 ret
2324 }
2325
2326 #[inline]
2327 fn size_hint(&self) -> (usize, Option<usize>) {
2328 let size = self.v.len().saturating_sub(N - 1);
2329 (size, Some(size))
2330 }
2331
2332 #[inline]
2333 fn count(self) -> usize {
2334 self.len()
2335 }
2336
2337 #[inline]
2338 fn nth(&mut self, n: usize) -> Option<Self::Item> {
2339 let idx = n.min(self.v.len());
2340 self.v = &self.v[idx..];
2341 self.next()
2342 }
2343
2344 #[inline]
2345 fn last(self) -> Option<Self::Item> {
2346 self.v.last_chunk()
2347 }
2348}
2349
2350#[cfg(not(feature = "ferrocene_subset"))]
2351#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")]
2352impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> {
2353 #[inline]
2354 fn next_back(&mut self) -> Option<&'a [T; N]> {
2355 let ret = self.v.last_chunk();
2356 if ret.is_some() {
2357 self.v = &self.v[..self.v.len() - 1];
2358 }
2359 ret
2360 }
2361
2362 #[inline]
2363 fn nth_back(&mut self, n: usize) -> Option<&'a [T; N]> {
2364 let idx = self.v.len().saturating_sub(n);
2365 self.v = &self.v[..idx];
2366 self.next_back()
2367 }
2368}
2369
2370#[cfg(not(feature = "ferrocene_subset"))]
2371#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")]
2372impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
2373 fn is_empty(&self) -> bool {
2374 self.v.len() < N
2375 }
2376}
2377
2378#[derive(Debug)]
2400#[stable(feature = "rchunks", since = "1.31.0")]
2401#[must_use = "iterators are lazy and do nothing unless consumed"]
2402#[cfg(not(feature = "ferrocene_subset"))]
2403pub struct RChunks<'a, T: 'a> {
2404 v: &'a [T],
2405 chunk_size: usize,
2406}
2407
2408#[cfg(not(feature = "ferrocene_subset"))]
2409impl<'a, T: 'a> RChunks<'a, T> {
2410 #[inline]
2411 pub(super) const fn new(slice: &'a [T], size: usize) -> Self {
2412 Self { v: slice, chunk_size: size }
2413 }
2414}
2415
2416#[stable(feature = "rchunks", since = "1.31.0")]
2418#[cfg(not(feature = "ferrocene_subset"))]
2419impl<T> Clone for RChunks<'_, T> {
2420 fn clone(&self) -> Self {
2421 RChunks { v: self.v, chunk_size: self.chunk_size }
2422 }
2423}
2424
2425#[stable(feature = "rchunks", since = "1.31.0")]
2426#[cfg(not(feature = "ferrocene_subset"))]
2427impl<'a, T> Iterator for RChunks<'a, T> {
2428 type Item = &'a [T];
2429
2430 #[inline]
2431 fn next(&mut self) -> Option<&'a [T]> {
2432 if self.v.is_empty() {
2433 None
2434 } else {
2435 let idx = self.v.len().saturating_sub(self.chunk_size);
2436 let (rest, chunk) = unsafe { self.v.split_at_unchecked(idx) };
2439 self.v = rest;
2440 Some(chunk)
2441 }
2442 }
2443
2444 #[inline]
2445 fn size_hint(&self) -> (usize, Option<usize>) {
2446 if self.v.is_empty() {
2447 (0, Some(0))
2448 } else {
2449 let n = self.v.len().div_ceil(self.chunk_size);
2450 (n, Some(n))
2451 }
2452 }
2453
2454 #[inline]
2455 fn count(self) -> usize {
2456 self.len()
2457 }
2458
2459 #[inline]
2460 fn nth(&mut self, n: usize) -> Option<Self::Item> {
2461 if let Some(end) = n.checked_mul(self.chunk_size)
2462 && end < self.v.len()
2463 {
2464 let end = self.v.len() - end;
2465 let rest = &self.v[..end];
2466 let (rest, chunk) = rest.split_at(end.saturating_sub(self.chunk_size));
2467 self.v = rest;
2468 Some(chunk)
2469 } else {
2470 self.v = &self.v[..0]; None
2472 }
2473 }
2474
2475 #[inline]
2476 fn last(self) -> Option<Self::Item> {
2477 if self.v.is_empty() {
2478 None
2479 } else {
2480 let rem = self.v.len() % self.chunk_size;
2481 let end = if rem == 0 { self.chunk_size } else { rem };
2482 Some(&self.v[0..end])
2483 }
2484 }
2485
2486 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2487 let end = self.v.len() - idx * self.chunk_size;
2488 let start = end.saturating_sub(self.chunk_size);
2489 unsafe { from_raw_parts(self.v.as_ptr().add(start), end - start) }
2491 }
2492}
2493
2494#[stable(feature = "rchunks", since = "1.31.0")]
2495#[cfg(not(feature = "ferrocene_subset"))]
2496impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
2497 #[inline]
2498 fn next_back(&mut self) -> Option<&'a [T]> {
2499 if self.v.is_empty() {
2500 None
2501 } else {
2502 let remainder = self.v.len() % self.chunk_size;
2503 let chunksz = if remainder != 0 { remainder } else { self.chunk_size };
2504 let (fst, snd) = unsafe { self.v.split_at_unchecked(chunksz) };
2506 self.v = snd;
2507 Some(fst)
2508 }
2509 }
2510
2511 #[inline]
2512 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2513 let len = self.len();
2514 if n < len {
2515 let offset_from_end = (len - 1 - n) * self.chunk_size;
2516 let end = self.v.len() - offset_from_end;
2517 let start = end.saturating_sub(self.chunk_size);
2518 let nth_back = &self.v[start..end];
2519 self.v = &self.v[end..];
2520 Some(nth_back)
2521 } else {
2522 self.v = &self.v[..0]; None
2524 }
2525 }
2526}
2527
2528#[stable(feature = "rchunks", since = "1.31.0")]
2529#[cfg(not(feature = "ferrocene_subset"))]
2530impl<T> ExactSizeIterator for RChunks<'_, T> {}
2531
2532#[unstable(feature = "trusted_len", issue = "37572")]
2533#[cfg(not(feature = "ferrocene_subset"))]
2534unsafe impl<T> TrustedLen for RChunks<'_, T> {}
2535
2536#[stable(feature = "rchunks", since = "1.31.0")]
2537#[cfg(not(feature = "ferrocene_subset"))]
2538impl<T> FusedIterator for RChunks<'_, T> {}
2539
2540#[doc(hidden)]
2541#[unstable(feature = "trusted_random_access", issue = "none")]
2542#[cfg(not(feature = "ferrocene_subset"))]
2543unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {}
2544
2545#[doc(hidden)]
2546#[unstable(feature = "trusted_random_access", issue = "none")]
2547#[cfg(not(feature = "ferrocene_subset"))]
2548unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunks<'a, T> {
2549 const MAY_HAVE_SIDE_EFFECT: bool = false;
2550}
2551
2552#[derive(Debug)]
2570#[stable(feature = "rchunks", since = "1.31.0")]
2571#[must_use = "iterators are lazy and do nothing unless consumed"]
2572#[cfg(not(feature = "ferrocene_subset"))]
2573pub struct RChunksMut<'a, T: 'a> {
2574 v: *mut [T],
2581 chunk_size: usize,
2582 _marker: PhantomData<&'a mut T>,
2583}
2584
2585#[cfg(not(feature = "ferrocene_subset"))]
2586impl<'a, T: 'a> RChunksMut<'a, T> {
2587 #[inline]
2588 pub(super) const fn new(slice: &'a mut [T], size: usize) -> Self {
2589 Self { v: slice, chunk_size: size, _marker: PhantomData }
2590 }
2591}
2592
2593#[stable(feature = "rchunks", since = "1.31.0")]
2594#[cfg(not(feature = "ferrocene_subset"))]
2595impl<'a, T> Iterator for RChunksMut<'a, T> {
2596 type Item = &'a mut [T];
2597
2598 #[inline]
2599 fn next(&mut self) -> Option<&'a mut [T]> {
2600 if self.v.is_empty() {
2601 None
2602 } else {
2603 let idx = self.v.len().saturating_sub(self.chunk_size);
2604 let (rest, chunk) = unsafe { self.v.split_at_mut_unchecked(idx) };
2607 self.v = rest;
2608 Some(unsafe { &mut *chunk })
2610 }
2611 }
2612
2613 #[inline]
2614 fn size_hint(&self) -> (usize, Option<usize>) {
2615 if self.v.is_empty() {
2616 (0, Some(0))
2617 } else {
2618 let n = self.v.len().div_ceil(self.chunk_size);
2619 (n, Some(n))
2620 }
2621 }
2622
2623 #[inline]
2624 fn count(self) -> usize {
2625 self.len()
2626 }
2627
2628 #[inline]
2629 fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
2630 if let Some(end) = n.checked_mul(self.chunk_size)
2631 && end < self.v.len()
2632 {
2633 let end = self.v.len() - end;
2634 let (rest, _) = unsafe { self.v.split_at_mut(end) };
2636 let (rest, chunk) = unsafe { rest.split_at_mut(end.saturating_sub(self.chunk_size)) };
2638 self.v = rest;
2639 Some(unsafe { &mut *chunk })
2641 } else {
2642 self.v = &mut [];
2643 None
2644 }
2645 }
2646
2647 #[inline]
2648 fn last(self) -> Option<Self::Item> {
2649 if self.v.is_empty() {
2650 None
2651 } else {
2652 let rem = self.v.len() % self.chunk_size;
2653 let end = if rem == 0 { self.chunk_size } else { rem };
2654 Some(unsafe { &mut *self.v.get_unchecked_mut(0..end) })
2656 }
2657 }
2658
2659 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2660 let end = self.v.len() - idx * self.chunk_size;
2661 let start = end.saturating_sub(self.chunk_size);
2662 unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start) }
2665 }
2666}
2667
2668#[stable(feature = "rchunks", since = "1.31.0")]
2669#[cfg(not(feature = "ferrocene_subset"))]
2670impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
2671 #[inline]
2672 fn next_back(&mut self) -> Option<&'a mut [T]> {
2673 if self.v.is_empty() {
2674 None
2675 } else {
2676 let remainder = self.v.len() % self.chunk_size;
2677 let sz = if remainder != 0 { remainder } else { self.chunk_size };
2678 let (head, tail) = unsafe { self.v.split_at_mut_unchecked(sz) };
2680 self.v = tail;
2681 Some(unsafe { &mut *head })
2683 }
2684 }
2685
2686 #[inline]
2687 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2688 let len = self.len();
2689 if n < len {
2690 let offset_from_end = (len - 1 - n) * self.chunk_size;
2692 let end = self.v.len() - offset_from_end;
2693 let start = end.saturating_sub(self.chunk_size);
2694 let (tmp, tail) = unsafe { self.v.split_at_mut(end) };
2696 let (_, nth_back) = unsafe { tmp.split_at_mut(start) };
2698 self.v = tail;
2699 Some(unsafe { &mut *nth_back })
2701 } else {
2702 self.v = &mut [];
2703 None
2704 }
2705 }
2706}
2707
2708#[stable(feature = "rchunks", since = "1.31.0")]
2709#[cfg(not(feature = "ferrocene_subset"))]
2710impl<T> ExactSizeIterator for RChunksMut<'_, T> {}
2711
2712#[unstable(feature = "trusted_len", issue = "37572")]
2713#[cfg(not(feature = "ferrocene_subset"))]
2714unsafe impl<T> TrustedLen for RChunksMut<'_, T> {}
2715
2716#[stable(feature = "rchunks", since = "1.31.0")]
2717#[cfg(not(feature = "ferrocene_subset"))]
2718impl<T> FusedIterator for RChunksMut<'_, T> {}
2719
2720#[doc(hidden)]
2721#[unstable(feature = "trusted_random_access", issue = "none")]
2722#[cfg(not(feature = "ferrocene_subset"))]
2723unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {}
2724
2725#[doc(hidden)]
2726#[unstable(feature = "trusted_random_access", issue = "none")]
2727#[cfg(not(feature = "ferrocene_subset"))]
2728unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksMut<'a, T> {
2729 const MAY_HAVE_SIDE_EFFECT: bool = false;
2730}
2731
2732#[stable(feature = "rchunks", since = "1.31.0")]
2733#[cfg(not(feature = "ferrocene_subset"))]
2734unsafe impl<T> Send for RChunksMut<'_, T> where T: Send {}
2735
2736#[stable(feature = "rchunks", since = "1.31.0")]
2737#[cfg(not(feature = "ferrocene_subset"))]
2738unsafe impl<T> Sync for RChunksMut<'_, T> where T: Sync {}
2739
2740#[derive(Debug)]
2763#[stable(feature = "rchunks", since = "1.31.0")]
2764#[must_use = "iterators are lazy and do nothing unless consumed"]
2765#[cfg(not(feature = "ferrocene_subset"))]
2766pub struct RChunksExact<'a, T: 'a> {
2767 v: &'a [T],
2768 rem: &'a [T],
2769 chunk_size: usize,
2770}
2771
2772#[cfg(not(feature = "ferrocene_subset"))]
2773impl<'a, T> RChunksExact<'a, T> {
2774 #[inline]
2775 pub(super) const fn new(slice: &'a [T], chunk_size: usize) -> Self {
2776 let rem = slice.len() % chunk_size;
2777 let (fst, snd) = unsafe { slice.split_at_unchecked(rem) };
2779 Self { v: snd, rem: fst, chunk_size }
2780 }
2781
2782 #[must_use]
2800 #[stable(feature = "rchunks", since = "1.31.0")]
2801 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
2802 pub const fn remainder(&self) -> &'a [T] {
2803 self.rem
2804 }
2805}
2806
2807#[stable(feature = "rchunks", since = "1.31.0")]
2809#[cfg(not(feature = "ferrocene_subset"))]
2810impl<'a, T> Clone for RChunksExact<'a, T> {
2811 fn clone(&self) -> RChunksExact<'a, T> {
2812 RChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size }
2813 }
2814}
2815
2816#[stable(feature = "rchunks", since = "1.31.0")]
2817#[cfg(not(feature = "ferrocene_subset"))]
2818impl<'a, T> Iterator for RChunksExact<'a, T> {
2819 type Item = &'a [T];
2820
2821 #[inline]
2822 fn next(&mut self) -> Option<&'a [T]> {
2823 if self.v.len() < self.chunk_size {
2824 None
2825 } else {
2826 let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
2827 self.v = fst;
2828 Some(snd)
2829 }
2830 }
2831
2832 #[inline]
2833 fn size_hint(&self) -> (usize, Option<usize>) {
2834 let n = self.v.len() / self.chunk_size;
2835 (n, Some(n))
2836 }
2837
2838 #[inline]
2839 fn count(self) -> usize {
2840 self.len()
2841 }
2842
2843 #[inline]
2844 fn nth(&mut self, n: usize) -> Option<Self::Item> {
2845 if let Some(end) = n.checked_mul(self.chunk_size)
2846 && end < self.v.len()
2847 {
2848 self.v = &self.v[..self.v.len() - end];
2849 self.next()
2850 } else {
2851 self.v = &self.v[..0]; None
2853 }
2854 }
2855
2856 #[inline]
2857 fn last(mut self) -> Option<Self::Item> {
2858 self.next_back()
2859 }
2860
2861 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2862 let end = self.v.len() - idx * self.chunk_size;
2863 let start = end - self.chunk_size;
2864 unsafe { from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) }
2866 }
2867}
2868
2869#[stable(feature = "rchunks", since = "1.31.0")]
2870#[cfg(not(feature = "ferrocene_subset"))]
2871impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
2872 #[inline]
2873 fn next_back(&mut self) -> Option<&'a [T]> {
2874 if self.v.len() < self.chunk_size {
2875 None
2876 } else {
2877 let (fst, snd) = self.v.split_at(self.chunk_size);
2878 self.v = snd;
2879 Some(fst)
2880 }
2881 }
2882
2883 #[inline]
2884 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2885 let len = self.len();
2886 if n < len {
2887 let offset = (len - n) * self.chunk_size;
2890 let start = self.v.len() - offset;
2891 let end = start + self.chunk_size;
2892 let nth_back = &self.v[start..end];
2893 self.v = &self.v[end..];
2894 Some(nth_back)
2895 } else {
2896 self.v = &self.v[..0]; None
2898 }
2899 }
2900}
2901
2902#[stable(feature = "rchunks", since = "1.31.0")]
2903#[cfg(not(feature = "ferrocene_subset"))]
2904impl<'a, T> ExactSizeIterator for RChunksExact<'a, T> {
2905 fn is_empty(&self) -> bool {
2906 self.v.is_empty()
2907 }
2908}
2909
2910#[unstable(feature = "trusted_len", issue = "37572")]
2911#[cfg(not(feature = "ferrocene_subset"))]
2912unsafe impl<T> TrustedLen for RChunksExact<'_, T> {}
2913
2914#[stable(feature = "rchunks", since = "1.31.0")]
2915#[cfg(not(feature = "ferrocene_subset"))]
2916impl<T> FusedIterator for RChunksExact<'_, T> {}
2917
2918#[doc(hidden)]
2919#[unstable(feature = "trusted_random_access", issue = "none")]
2920#[cfg(not(feature = "ferrocene_subset"))]
2921unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {}
2922
2923#[doc(hidden)]
2924#[unstable(feature = "trusted_random_access", issue = "none")]
2925#[cfg(not(feature = "ferrocene_subset"))]
2926unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExact<'a, T> {
2927 const MAY_HAVE_SIDE_EFFECT: bool = false;
2928}
2929
2930#[derive(Debug)]
2950#[stable(feature = "rchunks", since = "1.31.0")]
2951#[must_use = "iterators are lazy and do nothing unless consumed"]
2952#[cfg(not(feature = "ferrocene_subset"))]
2953pub struct RChunksExactMut<'a, T: 'a> {
2954 v: *mut [T],
2961 rem: &'a mut [T],
2962 chunk_size: usize,
2963}
2964
2965#[cfg(not(feature = "ferrocene_subset"))]
2966impl<'a, T> RChunksExactMut<'a, T> {
2967 #[inline]
2968 pub(super) const fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
2969 let rem = slice.len() % chunk_size;
2970 let (fst, snd) = unsafe { slice.split_at_mut_unchecked(rem) };
2972 Self { v: snd, rem: fst, chunk_size }
2973 }
2974
2975 #[must_use = "`self` will be dropped if the result is not used"]
2979 #[stable(feature = "rchunks", since = "1.31.0")]
2980 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
2981 pub const fn into_remainder(self) -> &'a mut [T] {
2982 self.rem
2983 }
2984}
2985
2986#[stable(feature = "rchunks", since = "1.31.0")]
2987#[cfg(not(feature = "ferrocene_subset"))]
2988impl<'a, T> Iterator for RChunksExactMut<'a, T> {
2989 type Item = &'a mut [T];
2990
2991 #[inline]
2992 fn next(&mut self) -> Option<&'a mut [T]> {
2993 if self.v.len() < self.chunk_size {
2994 None
2995 } else {
2996 let len = self.v.len();
2997 let (head, tail) = unsafe { self.v.split_at_mut(len - self.chunk_size) };
2999 self.v = head;
3000 Some(unsafe { &mut *tail })
3002 }
3003 }
3004
3005 #[inline]
3006 fn size_hint(&self) -> (usize, Option<usize>) {
3007 let n = self.v.len() / self.chunk_size;
3008 (n, Some(n))
3009 }
3010
3011 #[inline]
3012 fn count(self) -> usize {
3013 self.len()
3014 }
3015
3016 #[inline]
3017 fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
3018 if let Some(end) = n.checked_mul(self.chunk_size)
3019 && end < self.v.len()
3020 {
3021 let idx = self.v.len() - end;
3022 let (fst, _) = unsafe { self.v.split_at_mut(idx) };
3024 self.v = fst;
3025 self.next()
3026 } else {
3027 self.v = &mut [];
3028 None
3029 }
3030 }
3031
3032 #[inline]
3033 fn last(mut self) -> Option<Self::Item> {
3034 self.next_back()
3035 }
3036
3037 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
3038 let end = self.v.len() - idx * self.chunk_size;
3039 let start = end - self.chunk_size;
3040 unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
3042 }
3043}
3044
3045#[stable(feature = "rchunks", since = "1.31.0")]
3046#[cfg(not(feature = "ferrocene_subset"))]
3047impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
3048 #[inline]
3049 fn next_back(&mut self) -> Option<&'a mut [T]> {
3050 if self.v.len() < self.chunk_size {
3051 None
3052 } else {
3053 let (head, tail) = unsafe { self.v.split_at_mut(self.chunk_size) };
3055 self.v = tail;
3056 Some(unsafe { &mut *head })
3058 }
3059 }
3060
3061 #[inline]
3062 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
3063 let len = self.len();
3064 if n < len {
3065 let offset = (len - n) * self.chunk_size;
3068 let start = self.v.len() - offset;
3069 let end = start + self.chunk_size;
3070 let (tmp, tail) = unsafe { self.v.split_at_mut(end) };
3072 let (_, nth_back) = unsafe { tmp.split_at_mut(start) };
3074 self.v = tail;
3075 Some(unsafe { &mut *nth_back })
3077 } else {
3078 self.v = &mut [];
3079 None
3080 }
3081 }
3082}
3083
3084#[stable(feature = "rchunks", since = "1.31.0")]
3085#[cfg(not(feature = "ferrocene_subset"))]
3086impl<T> ExactSizeIterator for RChunksExactMut<'_, T> {
3087 fn is_empty(&self) -> bool {
3088 self.v.is_empty()
3089 }
3090}
3091
3092#[unstable(feature = "trusted_len", issue = "37572")]
3093#[cfg(not(feature = "ferrocene_subset"))]
3094unsafe impl<T> TrustedLen for RChunksExactMut<'_, T> {}
3095
3096#[stable(feature = "rchunks", since = "1.31.0")]
3097#[cfg(not(feature = "ferrocene_subset"))]
3098impl<T> FusedIterator for RChunksExactMut<'_, T> {}
3099
3100#[doc(hidden)]
3101#[unstable(feature = "trusted_random_access", issue = "none")]
3102#[cfg(not(feature = "ferrocene_subset"))]
3103unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {}
3104
3105#[doc(hidden)]
3106#[unstable(feature = "trusted_random_access", issue = "none")]
3107#[cfg(not(feature = "ferrocene_subset"))]
3108unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExactMut<'a, T> {
3109 const MAY_HAVE_SIDE_EFFECT: bool = false;
3110}
3111
3112#[stable(feature = "rchunks", since = "1.31.0")]
3113#[cfg(not(feature = "ferrocene_subset"))]
3114unsafe impl<T> Send for RChunksExactMut<'_, T> where T: Send {}
3115
3116#[stable(feature = "rchunks", since = "1.31.0")]
3117#[cfg(not(feature = "ferrocene_subset"))]
3118unsafe impl<T> Sync for RChunksExactMut<'_, T> where T: Sync {}
3119
3120#[doc(hidden)]
3121#[unstable(feature = "trusted_random_access", issue = "none")]
3122#[cfg(not(feature = "ferrocene_subset"))]
3123unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {}
3124
3125#[doc(hidden)]
3126#[unstable(feature = "trusted_random_access", issue = "none")]
3127#[cfg(not(feature = "ferrocene_subset"))]
3128unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Iter<'a, T> {
3129 const MAY_HAVE_SIDE_EFFECT: bool = false;
3130}
3131
3132#[doc(hidden)]
3133#[unstable(feature = "trusted_random_access", issue = "none")]
3134#[cfg(not(feature = "ferrocene_subset"))]
3135unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> {}
3136
3137#[doc(hidden)]
3138#[unstable(feature = "trusted_random_access", issue = "none")]
3139#[cfg(not(feature = "ferrocene_subset"))]
3140unsafe impl<'a, T> TrustedRandomAccessNoCoerce for IterMut<'a, T> {
3141 const MAY_HAVE_SIDE_EFFECT: bool = false;
3142}
3143
3144#[stable(feature = "slice_group_by", since = "1.77.0")]
3151#[must_use = "iterators are lazy and do nothing unless consumed"]
3152#[cfg(not(feature = "ferrocene_subset"))]
3153pub struct ChunkBy<'a, T: 'a, P> {
3154 slice: &'a [T],
3155 predicate: P,
3156}
3157
3158#[stable(feature = "slice_group_by", since = "1.77.0")]
3159#[cfg(not(feature = "ferrocene_subset"))]
3160impl<'a, T: 'a, P> ChunkBy<'a, T, P> {
3161 pub(super) const fn new(slice: &'a [T], predicate: P) -> Self {
3162 ChunkBy { slice, predicate }
3163 }
3164}
3165
3166#[stable(feature = "slice_group_by", since = "1.77.0")]
3167#[cfg(not(feature = "ferrocene_subset"))]
3168impl<'a, T: 'a, P> Iterator for ChunkBy<'a, T, P>
3169where
3170 P: FnMut(&T, &T) -> bool,
3171{
3172 type Item = &'a [T];
3173
3174 #[inline]
3175 fn next(&mut self) -> Option<Self::Item> {
3176 if self.slice.is_empty() {
3177 None
3178 } else {
3179 let mut len = 1;
3180 let mut iter = self.slice.windows(2);
3181 while let Some([l, r]) = iter.next() {
3182 if (self.predicate)(l, r) { len += 1 } else { break }
3183 }
3184 let (head, tail) = self.slice.split_at(len);
3185 self.slice = tail;
3186 Some(head)
3187 }
3188 }
3189
3190 #[inline]
3191 fn size_hint(&self) -> (usize, Option<usize>) {
3192 if self.slice.is_empty() { (0, Some(0)) } else { (1, Some(self.slice.len())) }
3193 }
3194
3195 #[inline]
3196 fn last(mut self) -> Option<Self::Item> {
3197 self.next_back()
3198 }
3199}
3200
3201#[stable(feature = "slice_group_by", since = "1.77.0")]
3202#[cfg(not(feature = "ferrocene_subset"))]
3203impl<'a, T: 'a, P> DoubleEndedIterator for ChunkBy<'a, T, P>
3204where
3205 P: FnMut(&T, &T) -> bool,
3206{
3207 #[inline]
3208 fn next_back(&mut self) -> Option<Self::Item> {
3209 if self.slice.is_empty() {
3210 None
3211 } else {
3212 let mut len = 1;
3213 let mut iter = self.slice.windows(2);
3214 while let Some([l, r]) = iter.next_back() {
3215 if (self.predicate)(l, r) { len += 1 } else { break }
3216 }
3217 let (head, tail) = self.slice.split_at(self.slice.len() - len);
3218 self.slice = head;
3219 Some(tail)
3220 }
3221 }
3222}
3223
3224#[stable(feature = "slice_group_by", since = "1.77.0")]
3225#[cfg(not(feature = "ferrocene_subset"))]
3226impl<'a, T: 'a, P> FusedIterator for ChunkBy<'a, T, P> where P: FnMut(&T, &T) -> bool {}
3227
3228#[stable(feature = "slice_group_by_clone", since = "1.89.0")]
3229#[cfg(not(feature = "ferrocene_subset"))]
3230impl<'a, T: 'a, P: Clone> Clone for ChunkBy<'a, T, P> {
3231 fn clone(&self) -> Self {
3232 Self { slice: self.slice, predicate: self.predicate.clone() }
3233 }
3234}
3235
3236#[stable(feature = "slice_group_by", since = "1.77.0")]
3237#[cfg(not(feature = "ferrocene_subset"))]
3238impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkBy<'a, T, P> {
3239 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3240 f.debug_struct("ChunkBy").field("slice", &self.slice).finish()
3241 }
3242}
3243
3244#[stable(feature = "slice_group_by", since = "1.77.0")]
3252#[must_use = "iterators are lazy and do nothing unless consumed"]
3253#[cfg(not(feature = "ferrocene_subset"))]
3254pub struct ChunkByMut<'a, T: 'a, P> {
3255 slice: &'a mut [T],
3256 predicate: P,
3257}
3258
3259#[stable(feature = "slice_group_by", since = "1.77.0")]
3260#[cfg(not(feature = "ferrocene_subset"))]
3261impl<'a, T: 'a, P> ChunkByMut<'a, T, P> {
3262 pub(super) const fn new(slice: &'a mut [T], predicate: P) -> Self {
3263 ChunkByMut { slice, predicate }
3264 }
3265}
3266
3267#[stable(feature = "slice_group_by", since = "1.77.0")]
3268#[cfg(not(feature = "ferrocene_subset"))]
3269impl<'a, T: 'a, P> Iterator for ChunkByMut<'a, T, P>
3270where
3271 P: FnMut(&T, &T) -> bool,
3272{
3273 type Item = &'a mut [T];
3274
3275 #[inline]
3276 fn next(&mut self) -> Option<Self::Item> {
3277 if self.slice.is_empty() {
3278 None
3279 } else {
3280 let mut len = 1;
3281 let mut iter = self.slice.windows(2);
3282 while let Some([l, r]) = iter.next() {
3283 if (self.predicate)(l, r) { len += 1 } else { break }
3284 }
3285 let slice = mem::take(&mut self.slice);
3286 let (head, tail) = slice.split_at_mut(len);
3287 self.slice = tail;
3288 Some(head)
3289 }
3290 }
3291
3292 #[inline]
3293 fn size_hint(&self) -> (usize, Option<usize>) {
3294 if self.slice.is_empty() { (0, Some(0)) } else { (1, Some(self.slice.len())) }
3295 }
3296
3297 #[inline]
3298 fn last(mut self) -> Option<Self::Item> {
3299 self.next_back()
3300 }
3301}
3302
3303#[stable(feature = "slice_group_by", since = "1.77.0")]
3304#[cfg(not(feature = "ferrocene_subset"))]
3305impl<'a, T: 'a, P> DoubleEndedIterator for ChunkByMut<'a, T, P>
3306where
3307 P: FnMut(&T, &T) -> bool,
3308{
3309 #[inline]
3310 fn next_back(&mut self) -> Option<Self::Item> {
3311 if self.slice.is_empty() {
3312 None
3313 } else {
3314 let mut len = 1;
3315 let mut iter = self.slice.windows(2);
3316 while let Some([l, r]) = iter.next_back() {
3317 if (self.predicate)(l, r) { len += 1 } else { break }
3318 }
3319 let slice = mem::take(&mut self.slice);
3320 let (head, tail) = slice.split_at_mut(slice.len() - len);
3321 self.slice = head;
3322 Some(tail)
3323 }
3324 }
3325}
3326
3327#[stable(feature = "slice_group_by", since = "1.77.0")]
3328#[cfg(not(feature = "ferrocene_subset"))]
3329impl<'a, T: 'a, P> FusedIterator for ChunkByMut<'a, T, P> where P: FnMut(&T, &T) -> bool {}
3330
3331#[stable(feature = "slice_group_by", since = "1.77.0")]
3332#[cfg(not(feature = "ferrocene_subset"))]
3333impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkByMut<'a, T, P> {
3334 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3335 f.debug_struct("ChunkByMut").field("slice", &self.slice).finish()
3336 }
3337}