1#[macro_use] mod macros;
5
6#[cfg(not(feature = "ferrocene_certified"))]
7use super::{from_raw_parts, from_raw_parts_mut};
8#[cfg(not(feature = "ferrocene_certified"))]
9use crate::hint::assert_unchecked;
10#[cfg(not(feature = "ferrocene_certified"))]
11use crate::iter::{
12 FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, UncheckedIterator,
13};
14use crate::marker::PhantomData;
15#[cfg(not(feature = "ferrocene_certified"))]
16use crate::mem::{self, SizedTypeProperties};
17use crate::num::NonZero;
18use crate::ptr::{NonNull, without_provenance, without_provenance_mut};
19#[cfg(not(feature = "ferrocene_certified"))]
20use crate::{cmp, fmt};
21
22#[cfg(feature = "ferrocene_certified")]
24#[rustfmt::skip]
25use crate::{
26 cmp,
27 iter::{TrustedLen, UncheckedIterator},
28 mem,
29 mem::SizedTypeProperties,
30};
31
32#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
33impl<T> !Iterator for [T] {}
34
35#[stable(feature = "rust1", since = "1.0.0")]
36impl<'a, T> IntoIterator for &'a [T] {
37 type Item = &'a T;
38 type IntoIter = Iter<'a, T>;
39
40 fn into_iter(self) -> Iter<'a, T> {
41 self.iter()
42 }
43}
44
45#[stable(feature = "rust1", since = "1.0.0")]
46impl<'a, T> IntoIterator for &'a mut [T] {
47 type Item = &'a mut T;
48 type IntoIter = IterMut<'a, T>;
49
50 fn into_iter(self) -> IterMut<'a, T> {
51 self.iter_mut()
52 }
53}
54
55#[stable(feature = "rust1", since = "1.0.0")]
82#[must_use = "iterators are lazy and do nothing unless consumed"]
83#[rustc_diagnostic_item = "SliceIter"]
84pub struct Iter<'a, T: 'a> {
85 ptr: NonNull<T>,
90 end_or_len: *const T,
94 _marker: PhantomData<&'a T>,
95}
96
97#[stable(feature = "core_impl_debug", since = "1.9.0")]
98#[cfg(not(feature = "ferrocene_certified"))]
99impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101 f.debug_tuple("Iter").field(&self.as_slice()).finish()
102 }
103}
104
105#[stable(feature = "rust1", since = "1.0.0")]
106unsafe impl<T: Sync> Sync for Iter<'_, T> {}
107#[stable(feature = "rust1", since = "1.0.0")]
108unsafe impl<T: Sync> Send for Iter<'_, T> {}
109
110impl<'a, T> Iter<'a, T> {
111 #[inline]
112 pub(super) const fn new(slice: &'a [T]) -> Self {
113 let len = slice.len();
114 let ptr: NonNull<T> = NonNull::from_ref(slice).cast();
115 unsafe {
117 let end_or_len =
118 if T::IS_ZST { without_provenance(len) } else { ptr.as_ptr().add(len) };
119
120 Self { ptr, end_or_len, _marker: PhantomData }
121 }
122 }
123
124 #[must_use]
151 #[stable(feature = "iter_to_slice", since = "1.4.0")]
152 #[inline]
153 #[cfg(not(feature = "ferrocene_certified"))]
154 pub fn as_slice(&self) -> &'a [T] {
155 self.make_slice()
156 }
157}
158
159iterator! {struct Iter -> *const T, &'a T, const, {}, as_ref, {
160 #[cfg(not(feature = "ferrocene_certified"))]
161 fn is_sorted_by<F>(self, mut compare: F) -> bool
162 where
163 Self: Sized,
164 F: FnMut(&Self::Item, &Self::Item) -> bool,
165 {
166 self.as_slice().is_sorted_by(|a, b| compare(&a, &b))
167 }
168}}
169
170#[stable(feature = "rust1", since = "1.0.0")]
171#[cfg(not(feature = "ferrocene_certified"))]
172impl<T> Clone for Iter<'_, T> {
173 #[inline]
174 fn clone(&self) -> Self {
175 Iter { ptr: self.ptr, end_or_len: self.end_or_len, _marker: self._marker }
176 }
177}
178
179#[stable(feature = "slice_iter_as_ref", since = "1.13.0")]
180#[cfg(not(feature = "ferrocene_certified"))]
181impl<T> AsRef<[T]> for Iter<'_, T> {
182 #[inline]
183 fn as_ref(&self) -> &[T] {
184 self.as_slice()
185 }
186}
187
188#[stable(feature = "rust1", since = "1.0.0")]
213#[must_use = "iterators are lazy and do nothing unless consumed"]
214pub struct IterMut<'a, T: 'a> {
215 ptr: NonNull<T>,
220 end_or_len: *mut T,
224 _marker: PhantomData<&'a mut T>,
225}
226
227#[stable(feature = "core_impl_debug", since = "1.9.0")]
228#[cfg(not(feature = "ferrocene_certified"))]
229impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
230 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231 f.debug_tuple("IterMut").field(&self.make_slice()).finish()
232 }
233}
234
235#[stable(feature = "rust1", since = "1.0.0")]
236unsafe impl<T: Sync> Sync for IterMut<'_, T> {}
237#[stable(feature = "rust1", since = "1.0.0")]
238unsafe impl<T: Send> Send for IterMut<'_, T> {}
239
240impl<'a, T> IterMut<'a, T> {
241 #[inline]
242 pub(super) const fn new(slice: &'a mut [T]) -> Self {
243 let len = slice.len();
244 let ptr: NonNull<T> = NonNull::from_mut(slice).cast();
245 unsafe {
262 let end_or_len =
263 if T::IS_ZST { without_provenance_mut(len) } else { ptr.as_ptr().add(len) };
264
265 Self { ptr, end_or_len, _marker: PhantomData }
266 }
267 }
268
269 #[must_use = "`self` will be dropped if the result is not used"]
296 #[stable(feature = "iter_to_slice", since = "1.4.0")]
297 #[cfg(not(feature = "ferrocene_certified"))]
298 pub fn into_slice(self) -> &'a mut [T] {
299 unsafe { from_raw_parts_mut(self.ptr.as_ptr(), len!(self)) }
303 }
304
305 #[must_use]
333 #[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")]
334 #[inline]
335 #[cfg(not(feature = "ferrocene_certified"))]
336 pub fn as_slice(&self) -> &[T] {
337 self.make_slice()
338 }
339
340 #[must_use]
369 #[unstable(feature = "slice_iter_mut_as_mut_slice", issue = "93079")]
371 #[cfg(not(feature = "ferrocene_certified"))]
372 pub fn as_mut_slice(&mut self) -> &mut [T] {
373 unsafe { from_raw_parts_mut(self.ptr.as_ptr(), len!(self)) }
377 }
378}
379
380#[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")]
381#[cfg(not(feature = "ferrocene_certified"))]
382impl<T> AsRef<[T]> for IterMut<'_, T> {
383 #[inline]
384 fn as_ref(&self) -> &[T] {
385 self.as_slice()
386 }
387}
388
389iterator! {struct IterMut -> *mut T, &'a mut T, mut, {mut}, as_mut, {}}
397
398#[doc(hidden)]
401#[cfg(not(feature = "ferrocene_certified"))]
402pub(super) trait SplitIter: DoubleEndedIterator {
403 fn finish(&mut self) -> Option<Self::Item>;
406}
407
408#[stable(feature = "rust1", since = "1.0.0")]
426#[must_use = "iterators are lazy and do nothing unless consumed"]
427#[cfg(not(feature = "ferrocene_certified"))]
428pub struct Split<'a, T: 'a, P>
429where
430 P: FnMut(&T) -> bool,
431{
432 pub(crate) v: &'a [T],
434 pred: P,
435 pub(crate) finished: bool,
437}
438
439#[cfg(not(feature = "ferrocene_certified"))]
440impl<'a, T: 'a, P: FnMut(&T) -> bool> Split<'a, T, P> {
441 #[inline]
442 pub(super) fn new(slice: &'a [T], pred: P) -> Self {
443 Self { v: slice, pred, finished: false }
444 }
445 #[unstable(feature = "split_as_slice", issue = "96137")]
456 pub fn as_slice(&self) -> &'a [T] {
457 if self.finished { &[] } else { &self.v }
458 }
459}
460
461#[stable(feature = "core_impl_debug", since = "1.9.0")]
462#[cfg(not(feature = "ferrocene_certified"))]
463impl<T: fmt::Debug, P> fmt::Debug for Split<'_, T, P>
464where
465 P: FnMut(&T) -> bool,
466{
467 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
468 f.debug_struct("Split").field("v", &self.v).field("finished", &self.finished).finish()
469 }
470}
471
472#[stable(feature = "rust1", since = "1.0.0")]
474#[cfg(not(feature = "ferrocene_certified"))]
475impl<T, P> Clone for Split<'_, T, P>
476where
477 P: Clone + FnMut(&T) -> bool,
478{
479 fn clone(&self) -> Self {
480 Split { v: self.v, pred: self.pred.clone(), finished: self.finished }
481 }
482}
483
484#[stable(feature = "rust1", since = "1.0.0")]
485#[cfg(not(feature = "ferrocene_certified"))]
486impl<'a, T, P> Iterator for Split<'a, T, P>
487where
488 P: FnMut(&T) -> bool,
489{
490 type Item = &'a [T];
491
492 #[inline]
493 fn next(&mut self) -> Option<&'a [T]> {
494 if self.finished {
495 return None;
496 }
497
498 match self.v.iter().position(|x| (self.pred)(x)) {
499 None => self.finish(),
500 Some(idx) => {
501 let (left, right) =
502 unsafe { (self.v.get_unchecked(..idx), self.v.get_unchecked(idx + 1..)) };
505 let ret = Some(left);
506 self.v = right;
507 ret
508 }
509 }
510 }
511
512 #[inline]
513 fn size_hint(&self) -> (usize, Option<usize>) {
514 if self.finished {
515 (0, Some(0))
516 } else {
517 (1, Some(self.v.len() + 1))
520 }
521 }
522}
523
524#[stable(feature = "rust1", since = "1.0.0")]
525#[cfg(not(feature = "ferrocene_certified"))]
526impl<'a, T, P> DoubleEndedIterator for Split<'a, T, P>
527where
528 P: FnMut(&T) -> bool,
529{
530 #[inline]
531 fn next_back(&mut self) -> Option<&'a [T]> {
532 if self.finished {
533 return None;
534 }
535
536 match self.v.iter().rposition(|x| (self.pred)(x)) {
537 None => self.finish(),
538 Some(idx) => {
539 let (left, right) =
540 unsafe { (self.v.get_unchecked(..idx), self.v.get_unchecked(idx + 1..)) };
543 let ret = Some(right);
544 self.v = left;
545 ret
546 }
547 }
548 }
549}
550
551#[cfg(not(feature = "ferrocene_certified"))]
552impl<'a, T, P> SplitIter for Split<'a, T, P>
553where
554 P: FnMut(&T) -> bool,
555{
556 #[inline]
557 fn finish(&mut self) -> Option<&'a [T]> {
558 if self.finished {
559 None
560 } else {
561 self.finished = true;
562 Some(self.v)
563 }
564 }
565}
566
567#[stable(feature = "fused", since = "1.26.0")]
568#[cfg(not(feature = "ferrocene_certified"))]
569impl<T, P> FusedIterator for Split<'_, T, P> where P: FnMut(&T) -> bool {}
570
571#[stable(feature = "split_inclusive", since = "1.51.0")]
590#[must_use = "iterators are lazy and do nothing unless consumed"]
591#[cfg(not(feature = "ferrocene_certified"))]
592pub struct SplitInclusive<'a, T: 'a, P>
593where
594 P: FnMut(&T) -> bool,
595{
596 v: &'a [T],
597 pred: P,
598 finished: bool,
599}
600
601#[cfg(not(feature = "ferrocene_certified"))]
602impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusive<'a, T, P> {
603 #[inline]
604 pub(super) fn new(slice: &'a [T], pred: P) -> Self {
605 let finished = slice.is_empty();
606 Self { v: slice, pred, finished }
607 }
608}
609
610#[stable(feature = "split_inclusive", since = "1.51.0")]
611#[cfg(not(feature = "ferrocene_certified"))]
612impl<T: fmt::Debug, P> fmt::Debug for SplitInclusive<'_, T, P>
613where
614 P: FnMut(&T) -> bool,
615{
616 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
617 f.debug_struct("SplitInclusive")
618 .field("v", &self.v)
619 .field("finished", &self.finished)
620 .finish()
621 }
622}
623
624#[stable(feature = "split_inclusive", since = "1.51.0")]
626#[cfg(not(feature = "ferrocene_certified"))]
627impl<T, P> Clone for SplitInclusive<'_, T, P>
628where
629 P: Clone + FnMut(&T) -> bool,
630{
631 fn clone(&self) -> Self {
632 SplitInclusive { v: self.v, pred: self.pred.clone(), finished: self.finished }
633 }
634}
635
636#[stable(feature = "split_inclusive", since = "1.51.0")]
637#[cfg(not(feature = "ferrocene_certified"))]
638impl<'a, T, P> Iterator for SplitInclusive<'a, T, P>
639where
640 P: FnMut(&T) -> bool,
641{
642 type Item = &'a [T];
643
644 #[inline]
645 fn next(&mut self) -> Option<&'a [T]> {
646 if self.finished {
647 return None;
648 }
649
650 let idx =
651 self.v.iter().position(|x| (self.pred)(x)).map(|idx| idx + 1).unwrap_or(self.v.len());
652 if idx == self.v.len() {
653 self.finished = true;
654 }
655 let ret = Some(&self.v[..idx]);
656 self.v = &self.v[idx..];
657 ret
658 }
659
660 #[inline]
661 fn size_hint(&self) -> (usize, Option<usize>) {
662 if self.finished {
663 (0, Some(0))
664 } else {
665 (1, Some(cmp::max(1, self.v.len())))
669 }
670 }
671}
672
673#[stable(feature = "split_inclusive", since = "1.51.0")]
674#[cfg(not(feature = "ferrocene_certified"))]
675impl<'a, T, P> DoubleEndedIterator for SplitInclusive<'a, T, P>
676where
677 P: FnMut(&T) -> bool,
678{
679 #[inline]
680 fn next_back(&mut self) -> Option<&'a [T]> {
681 if self.finished {
682 return None;
683 }
684
685 let remainder = if self.v.is_empty() { &[] } else { &self.v[..(self.v.len() - 1)] };
689 let idx = remainder.iter().rposition(|x| (self.pred)(x)).map(|idx| idx + 1).unwrap_or(0);
690 if idx == 0 {
691 self.finished = true;
692 }
693 let ret = Some(&self.v[idx..]);
694 self.v = &self.v[..idx];
695 ret
696 }
697}
698
699#[stable(feature = "split_inclusive", since = "1.51.0")]
700#[cfg(not(feature = "ferrocene_certified"))]
701impl<T, P> FusedIterator for SplitInclusive<'_, T, P> where P: FnMut(&T) -> bool {}
702
703#[stable(feature = "rust1", since = "1.0.0")]
718#[must_use = "iterators are lazy and do nothing unless consumed"]
719#[cfg(not(feature = "ferrocene_certified"))]
720pub struct SplitMut<'a, T: 'a, P>
721where
722 P: FnMut(&T) -> bool,
723{
724 v: &'a mut [T],
725 pred: P,
726 finished: bool,
727}
728
729#[cfg(not(feature = "ferrocene_certified"))]
730impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitMut<'a, T, P> {
731 #[inline]
732 pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
733 Self { v: slice, pred, finished: false }
734 }
735}
736
737#[stable(feature = "core_impl_debug", since = "1.9.0")]
738#[cfg(not(feature = "ferrocene_certified"))]
739impl<T: fmt::Debug, P> fmt::Debug for SplitMut<'_, T, P>
740where
741 P: FnMut(&T) -> bool,
742{
743 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
744 f.debug_struct("SplitMut").field("v", &self.v).field("finished", &self.finished).finish()
745 }
746}
747
748#[cfg(not(feature = "ferrocene_certified"))]
749impl<'a, T, P> SplitIter for SplitMut<'a, T, P>
750where
751 P: FnMut(&T) -> bool,
752{
753 #[inline]
754 fn finish(&mut self) -> Option<&'a mut [T]> {
755 if self.finished {
756 None
757 } else {
758 self.finished = true;
759 Some(mem::take(&mut self.v))
760 }
761 }
762}
763
764#[stable(feature = "rust1", since = "1.0.0")]
765#[cfg(not(feature = "ferrocene_certified"))]
766impl<'a, T, P> Iterator for SplitMut<'a, T, P>
767where
768 P: FnMut(&T) -> bool,
769{
770 type Item = &'a mut [T];
771
772 #[inline]
773 fn next(&mut self) -> Option<&'a mut [T]> {
774 if self.finished {
775 return None;
776 }
777
778 match self.v.iter().position(|x| (self.pred)(x)) {
779 None => self.finish(),
780 Some(idx) => {
781 let tmp = mem::take(&mut self.v);
782 let (head, tail) = tmp.split_at_mut(idx + 1);
786 self.v = tail;
787 Some(&mut head[..idx])
789 }
790 }
791 }
792
793 #[inline]
794 fn size_hint(&self) -> (usize, Option<usize>) {
795 if self.finished {
796 (0, Some(0))
797 } else {
798 (1, Some(self.v.len() + 1))
801 }
802 }
803}
804
805#[stable(feature = "rust1", since = "1.0.0")]
806#[cfg(not(feature = "ferrocene_certified"))]
807impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P>
808where
809 P: FnMut(&T) -> bool,
810{
811 #[inline]
812 fn next_back(&mut self) -> Option<&'a mut [T]> {
813 if self.finished {
814 return None;
815 }
816
817 let idx_opt = {
818 let pred = &mut self.pred;
820 self.v.iter().rposition(|x| (*pred)(x))
821 };
822 match idx_opt {
823 None => self.finish(),
824 Some(idx) => {
825 let tmp = mem::take(&mut self.v);
826 let (head, tail) = tmp.split_at_mut(idx);
827 self.v = head;
828 Some(&mut tail[1..])
829 }
830 }
831 }
832}
833
834#[stable(feature = "fused", since = "1.26.0")]
835#[cfg(not(feature = "ferrocene_certified"))]
836impl<T, P> FusedIterator for SplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
837
838#[stable(feature = "split_inclusive", since = "1.51.0")]
854#[must_use = "iterators are lazy and do nothing unless consumed"]
855#[cfg(not(feature = "ferrocene_certified"))]
856pub struct SplitInclusiveMut<'a, T: 'a, P>
857where
858 P: FnMut(&T) -> bool,
859{
860 v: &'a mut [T],
861 pred: P,
862 finished: bool,
863}
864
865#[cfg(not(feature = "ferrocene_certified"))]
866impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusiveMut<'a, T, P> {
867 #[inline]
868 pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
869 let finished = slice.is_empty();
870 Self { v: slice, pred, finished }
871 }
872}
873
874#[stable(feature = "split_inclusive", since = "1.51.0")]
875#[cfg(not(feature = "ferrocene_certified"))]
876impl<T: fmt::Debug, P> fmt::Debug for SplitInclusiveMut<'_, T, P>
877where
878 P: FnMut(&T) -> bool,
879{
880 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
881 f.debug_struct("SplitInclusiveMut")
882 .field("v", &self.v)
883 .field("finished", &self.finished)
884 .finish()
885 }
886}
887
888#[stable(feature = "split_inclusive", since = "1.51.0")]
889#[cfg(not(feature = "ferrocene_certified"))]
890impl<'a, T, P> Iterator for SplitInclusiveMut<'a, T, P>
891where
892 P: FnMut(&T) -> bool,
893{
894 type Item = &'a mut [T];
895
896 #[inline]
897 fn next(&mut self) -> Option<&'a mut [T]> {
898 if self.finished {
899 return None;
900 }
901
902 let idx_opt = {
903 let pred = &mut self.pred;
905 self.v.iter().position(|x| (*pred)(x))
906 };
907 let idx = idx_opt.map(|idx| idx + 1).unwrap_or(self.v.len());
908 if idx == self.v.len() {
909 self.finished = true;
910 }
911 let tmp = mem::take(&mut self.v);
912 let (head, tail) = tmp.split_at_mut(idx);
913 self.v = tail;
914 Some(head)
915 }
916
917 #[inline]
918 fn size_hint(&self) -> (usize, Option<usize>) {
919 if self.finished {
920 (0, Some(0))
921 } else {
922 (1, Some(cmp::max(1, self.v.len())))
926 }
927 }
928}
929
930#[stable(feature = "split_inclusive", since = "1.51.0")]
931#[cfg(not(feature = "ferrocene_certified"))]
932impl<'a, T, P> DoubleEndedIterator for SplitInclusiveMut<'a, T, P>
933where
934 P: FnMut(&T) -> bool,
935{
936 #[inline]
937 fn next_back(&mut self) -> Option<&'a mut [T]> {
938 if self.finished {
939 return None;
940 }
941
942 let idx_opt = if self.v.is_empty() {
943 None
944 } else {
945 let pred = &mut self.pred;
947
948 let remainder = &self.v[..(self.v.len() - 1)];
952 remainder.iter().rposition(|x| (*pred)(x))
953 };
954 let idx = idx_opt.map(|idx| idx + 1).unwrap_or(0);
955 if idx == 0 {
956 self.finished = true;
957 }
958 let tmp = mem::take(&mut self.v);
959 let (head, tail) = tmp.split_at_mut(idx);
960 self.v = head;
961 Some(tail)
962 }
963}
964
965#[stable(feature = "split_inclusive", since = "1.51.0")]
966#[cfg(not(feature = "ferrocene_certified"))]
967impl<T, P> FusedIterator for SplitInclusiveMut<'_, T, P> where P: FnMut(&T) -> bool {}
968
969#[stable(feature = "slice_rsplit", since = "1.27.0")]
987#[must_use = "iterators are lazy and do nothing unless consumed"]
988#[cfg(not(feature = "ferrocene_certified"))]
989pub struct RSplit<'a, T: 'a, P>
990where
991 P: FnMut(&T) -> bool,
992{
993 inner: Split<'a, T, P>,
994}
995
996#[cfg(not(feature = "ferrocene_certified"))]
997impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplit<'a, T, P> {
998 #[inline]
999 pub(super) fn new(slice: &'a [T], pred: P) -> Self {
1000 Self { inner: Split::new(slice, pred) }
1001 }
1002}
1003
1004#[stable(feature = "slice_rsplit", since = "1.27.0")]
1005#[cfg(not(feature = "ferrocene_certified"))]
1006impl<T: fmt::Debug, P> fmt::Debug for RSplit<'_, T, P>
1007where
1008 P: FnMut(&T) -> bool,
1009{
1010 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1011 f.debug_struct("RSplit")
1012 .field("v", &self.inner.v)
1013 .field("finished", &self.inner.finished)
1014 .finish()
1015 }
1016}
1017
1018#[stable(feature = "slice_rsplit", since = "1.27.0")]
1020#[cfg(not(feature = "ferrocene_certified"))]
1021impl<T, P> Clone for RSplit<'_, T, P>
1022where
1023 P: Clone + FnMut(&T) -> bool,
1024{
1025 fn clone(&self) -> Self {
1026 RSplit { inner: self.inner.clone() }
1027 }
1028}
1029
1030#[stable(feature = "slice_rsplit", since = "1.27.0")]
1031#[cfg(not(feature = "ferrocene_certified"))]
1032impl<'a, T, P> Iterator for RSplit<'a, T, P>
1033where
1034 P: FnMut(&T) -> bool,
1035{
1036 type Item = &'a [T];
1037
1038 #[inline]
1039 fn next(&mut self) -> Option<&'a [T]> {
1040 self.inner.next_back()
1041 }
1042
1043 #[inline]
1044 fn size_hint(&self) -> (usize, Option<usize>) {
1045 self.inner.size_hint()
1046 }
1047}
1048
1049#[stable(feature = "slice_rsplit", since = "1.27.0")]
1050#[cfg(not(feature = "ferrocene_certified"))]
1051impl<'a, T, P> DoubleEndedIterator for RSplit<'a, T, P>
1052where
1053 P: FnMut(&T) -> bool,
1054{
1055 #[inline]
1056 fn next_back(&mut self) -> Option<&'a [T]> {
1057 self.inner.next()
1058 }
1059}
1060
1061#[stable(feature = "slice_rsplit", since = "1.27.0")]
1062#[cfg(not(feature = "ferrocene_certified"))]
1063impl<'a, T, P> SplitIter for RSplit<'a, T, P>
1064where
1065 P: FnMut(&T) -> bool,
1066{
1067 #[inline]
1068 fn finish(&mut self) -> Option<&'a [T]> {
1069 self.inner.finish()
1070 }
1071}
1072
1073#[stable(feature = "slice_rsplit", since = "1.27.0")]
1074#[cfg(not(feature = "ferrocene_certified"))]
1075impl<T, P> FusedIterator for RSplit<'_, T, P> where P: FnMut(&T) -> bool {}
1076
1077#[stable(feature = "slice_rsplit", since = "1.27.0")]
1092#[must_use = "iterators are lazy and do nothing unless consumed"]
1093#[cfg(not(feature = "ferrocene_certified"))]
1094pub struct RSplitMut<'a, T: 'a, P>
1095where
1096 P: FnMut(&T) -> bool,
1097{
1098 inner: SplitMut<'a, T, P>,
1099}
1100
1101#[cfg(not(feature = "ferrocene_certified"))]
1102impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitMut<'a, T, P> {
1103 #[inline]
1104 pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
1105 Self { inner: SplitMut::new(slice, pred) }
1106 }
1107}
1108
1109#[stable(feature = "slice_rsplit", since = "1.27.0")]
1110#[cfg(not(feature = "ferrocene_certified"))]
1111impl<T: fmt::Debug, P> fmt::Debug for RSplitMut<'_, T, P>
1112where
1113 P: FnMut(&T) -> bool,
1114{
1115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1116 f.debug_struct("RSplitMut")
1117 .field("v", &self.inner.v)
1118 .field("finished", &self.inner.finished)
1119 .finish()
1120 }
1121}
1122
1123#[stable(feature = "slice_rsplit", since = "1.27.0")]
1124#[cfg(not(feature = "ferrocene_certified"))]
1125impl<'a, T, P> SplitIter for RSplitMut<'a, T, P>
1126where
1127 P: FnMut(&T) -> bool,
1128{
1129 #[inline]
1130 fn finish(&mut self) -> Option<&'a mut [T]> {
1131 self.inner.finish()
1132 }
1133}
1134
1135#[stable(feature = "slice_rsplit", since = "1.27.0")]
1136#[cfg(not(feature = "ferrocene_certified"))]
1137impl<'a, T, P> Iterator for RSplitMut<'a, T, P>
1138where
1139 P: FnMut(&T) -> bool,
1140{
1141 type Item = &'a mut [T];
1142
1143 #[inline]
1144 fn next(&mut self) -> Option<&'a mut [T]> {
1145 self.inner.next_back()
1146 }
1147
1148 #[inline]
1149 fn size_hint(&self) -> (usize, Option<usize>) {
1150 self.inner.size_hint()
1151 }
1152}
1153
1154#[stable(feature = "slice_rsplit", since = "1.27.0")]
1155#[cfg(not(feature = "ferrocene_certified"))]
1156impl<'a, T, P> DoubleEndedIterator for RSplitMut<'a, T, P>
1157where
1158 P: FnMut(&T) -> bool,
1159{
1160 #[inline]
1161 fn next_back(&mut self) -> Option<&'a mut [T]> {
1162 self.inner.next()
1163 }
1164}
1165
1166#[stable(feature = "slice_rsplit", since = "1.27.0")]
1167#[cfg(not(feature = "ferrocene_certified"))]
1168impl<T, P> FusedIterator for RSplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
1169
1170#[derive(Debug)]
1174#[cfg(not(feature = "ferrocene_certified"))]
1175struct GenericSplitN<I> {
1176 iter: I,
1177 count: usize,
1178}
1179
1180#[cfg(not(feature = "ferrocene_certified"))]
1181impl<T, I: SplitIter<Item = T>> Iterator for GenericSplitN<I> {
1182 type Item = T;
1183
1184 #[inline]
1185 fn next(&mut self) -> Option<T> {
1186 match self.count {
1187 0 => None,
1188 1 => {
1189 self.count -= 1;
1190 self.iter.finish()
1191 }
1192 _ => {
1193 self.count -= 1;
1194 self.iter.next()
1195 }
1196 }
1197 }
1198
1199 #[inline]
1200 fn size_hint(&self) -> (usize, Option<usize>) {
1201 let (lower, upper_opt) = self.iter.size_hint();
1202 (
1203 cmp::min(self.count, lower),
1204 Some(upper_opt.map_or(self.count, |upper| cmp::min(self.count, upper))),
1205 )
1206 }
1207}
1208
1209#[stable(feature = "rust1", since = "1.0.0")]
1227#[must_use = "iterators are lazy and do nothing unless consumed"]
1228#[cfg(not(feature = "ferrocene_certified"))]
1229pub struct SplitN<'a, T: 'a, P>
1230where
1231 P: FnMut(&T) -> bool,
1232{
1233 inner: GenericSplitN<Split<'a, T, P>>,
1234}
1235
1236#[cfg(not(feature = "ferrocene_certified"))]
1237impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitN<'a, T, P> {
1238 #[inline]
1239 pub(super) fn new(s: Split<'a, T, P>, n: usize) -> Self {
1240 Self { inner: GenericSplitN { iter: s, count: n } }
1241 }
1242}
1243
1244#[stable(feature = "core_impl_debug", since = "1.9.0")]
1245#[cfg(not(feature = "ferrocene_certified"))]
1246impl<T: fmt::Debug, P> fmt::Debug for SplitN<'_, T, P>
1247where
1248 P: FnMut(&T) -> bool,
1249{
1250 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1251 f.debug_struct("SplitN").field("inner", &self.inner).finish()
1252 }
1253}
1254
1255#[stable(feature = "rust1", since = "1.0.0")]
1274#[must_use = "iterators are lazy and do nothing unless consumed"]
1275#[cfg(not(feature = "ferrocene_certified"))]
1276pub struct RSplitN<'a, T: 'a, P>
1277where
1278 P: FnMut(&T) -> bool,
1279{
1280 inner: GenericSplitN<RSplit<'a, T, P>>,
1281}
1282
1283#[cfg(not(feature = "ferrocene_certified"))]
1284impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitN<'a, T, P> {
1285 #[inline]
1286 pub(super) fn new(s: RSplit<'a, T, P>, n: usize) -> Self {
1287 Self { inner: GenericSplitN { iter: s, count: n } }
1288 }
1289}
1290
1291#[stable(feature = "core_impl_debug", since = "1.9.0")]
1292#[cfg(not(feature = "ferrocene_certified"))]
1293impl<T: fmt::Debug, P> fmt::Debug for RSplitN<'_, T, P>
1294where
1295 P: FnMut(&T) -> bool,
1296{
1297 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1298 f.debug_struct("RSplitN").field("inner", &self.inner).finish()
1299 }
1300}
1301
1302#[stable(feature = "rust1", since = "1.0.0")]
1317#[must_use = "iterators are lazy and do nothing unless consumed"]
1318#[cfg(not(feature = "ferrocene_certified"))]
1319pub struct SplitNMut<'a, T: 'a, P>
1320where
1321 P: FnMut(&T) -> bool,
1322{
1323 inner: GenericSplitN<SplitMut<'a, T, P>>,
1324}
1325
1326#[cfg(not(feature = "ferrocene_certified"))]
1327impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitNMut<'a, T, P> {
1328 #[inline]
1329 pub(super) fn new(s: SplitMut<'a, T, P>, n: usize) -> Self {
1330 Self { inner: GenericSplitN { iter: s, count: n } }
1331 }
1332}
1333
1334#[stable(feature = "core_impl_debug", since = "1.9.0")]
1335#[cfg(not(feature = "ferrocene_certified"))]
1336impl<T: fmt::Debug, P> fmt::Debug for SplitNMut<'_, T, P>
1337where
1338 P: FnMut(&T) -> bool,
1339{
1340 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1341 f.debug_struct("SplitNMut").field("inner", &self.inner).finish()
1342 }
1343}
1344
1345#[stable(feature = "rust1", since = "1.0.0")]
1361#[must_use = "iterators are lazy and do nothing unless consumed"]
1362#[cfg(not(feature = "ferrocene_certified"))]
1363pub struct RSplitNMut<'a, T: 'a, P>
1364where
1365 P: FnMut(&T) -> bool,
1366{
1367 inner: GenericSplitN<RSplitMut<'a, T, P>>,
1368}
1369
1370#[cfg(not(feature = "ferrocene_certified"))]
1371impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitNMut<'a, T, P> {
1372 #[inline]
1373 pub(super) fn new(s: RSplitMut<'a, T, P>, n: usize) -> Self {
1374 Self { inner: GenericSplitN { iter: s, count: n } }
1375 }
1376}
1377
1378#[stable(feature = "core_impl_debug", since = "1.9.0")]
1379#[cfg(not(feature = "ferrocene_certified"))]
1380impl<T: fmt::Debug, P> fmt::Debug for RSplitNMut<'_, T, P>
1381where
1382 P: FnMut(&T) -> bool,
1383{
1384 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1385 f.debug_struct("RSplitNMut").field("inner", &self.inner).finish()
1386 }
1387}
1388
1389#[cfg(not(feature = "ferrocene_certified"))]
1390forward_iterator! { SplitN: T, &'a [T] }
1391#[cfg(not(feature = "ferrocene_certified"))]
1392forward_iterator! { RSplitN: T, &'a [T] }
1393#[cfg(not(feature = "ferrocene_certified"))]
1394forward_iterator! { SplitNMut: T, &'a mut [T] }
1395#[cfg(not(feature = "ferrocene_certified"))]
1396forward_iterator! { RSplitNMut: T, &'a mut [T] }
1397
1398#[cfg_attr(not(feature = "ferrocene_certified"), derive(Debug))]
1416#[stable(feature = "rust1", since = "1.0.0")]
1417#[must_use = "iterators are lazy and do nothing unless consumed"]
1418pub struct Windows<'a, T: 'a> {
1419 v: &'a [T],
1420 size: NonZero<usize>,
1421}
1422
1423impl<'a, T: 'a> Windows<'a, T> {
1424 #[inline]
1425 pub(super) const fn new(slice: &'a [T], size: NonZero<usize>) -> Self {
1426 Self { v: slice, size }
1427 }
1428}
1429
1430#[stable(feature = "rust1", since = "1.0.0")]
1432#[cfg(not(feature = "ferrocene_certified"))]
1433impl<T> Clone for Windows<'_, T> {
1434 fn clone(&self) -> Self {
1435 Windows { v: self.v, size: self.size }
1436 }
1437}
1438
1439#[stable(feature = "rust1", since = "1.0.0")]
1440impl<'a, T> Iterator for Windows<'a, T> {
1441 type Item = &'a [T];
1442
1443 #[inline]
1444 fn next(&mut self) -> Option<&'a [T]> {
1445 if self.size.get() > self.v.len() {
1446 None
1447 } else {
1448 let ret = Some(&self.v[..self.size.get()]);
1449 self.v = &self.v[1..];
1450 ret
1451 }
1452 }
1453
1454 #[inline]
1455 fn size_hint(&self) -> (usize, Option<usize>) {
1456 if self.size.get() > self.v.len() {
1457 (0, Some(0))
1458 } else {
1459 let size = self.v.len() - self.size.get() + 1;
1460 (size, Some(size))
1461 }
1462 }
1463
1464 #[inline]
1465 #[cfg(not(feature = "ferrocene_certified"))]
1466 fn count(self) -> usize {
1467 self.len()
1468 }
1469
1470 #[inline]
1471 fn nth(&mut self, n: usize) -> Option<Self::Item> {
1472 let size = self.size.get();
1473 if let Some(rest) = self.v.get(n..)
1474 && let Some(nth) = rest.get(..size)
1475 {
1476 self.v = &rest[1..];
1477 Some(nth)
1478 } else {
1479 self.v = &self.v[..0]; None
1482 }
1483 }
1484
1485 #[inline]
1486 #[cfg(not(feature = "ferrocene_certified"))]
1487 fn last(self) -> Option<Self::Item> {
1488 if self.size.get() > self.v.len() {
1489 None
1490 } else {
1491 let start = self.v.len() - self.size.get();
1492 Some(&self.v[start..])
1493 }
1494 }
1495
1496 #[cfg(not(feature = "ferrocene_certified"))]
1497 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
1498 unsafe { from_raw_parts(self.v.as_ptr().add(idx), self.size.get()) }
1503 }
1504}
1505
1506#[stable(feature = "rust1", since = "1.0.0")]
1507#[cfg(not(feature = "ferrocene_certified"))]
1508impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
1509 #[inline]
1510 fn next_back(&mut self) -> Option<&'a [T]> {
1511 if self.size.get() > self.v.len() {
1512 None
1513 } else {
1514 let ret = Some(&self.v[self.v.len() - self.size.get()..]);
1515 self.v = &self.v[..self.v.len() - 1];
1516 ret
1517 }
1518 }
1519
1520 #[inline]
1521 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1522 let (end, overflow) = self.v.len().overflowing_sub(n);
1523 if end < self.size.get() || overflow {
1524 self.v = &self.v[..0]; None
1526 } else {
1527 let ret = &self.v[end - self.size.get()..end];
1528 self.v = &self.v[..end - 1];
1529 Some(ret)
1530 }
1531 }
1532}
1533
1534#[stable(feature = "rust1", since = "1.0.0")]
1535#[cfg(not(feature = "ferrocene_certified"))]
1536impl<T> ExactSizeIterator for Windows<'_, T> {}
1537
1538#[unstable(feature = "trusted_len", issue = "37572")]
1539#[cfg(not(feature = "ferrocene_certified"))]
1540unsafe impl<T> TrustedLen for Windows<'_, T> {}
1541
1542#[stable(feature = "fused", since = "1.26.0")]
1543#[cfg(not(feature = "ferrocene_certified"))]
1544impl<T> FusedIterator for Windows<'_, T> {}
1545
1546#[doc(hidden)]
1547#[unstable(feature = "trusted_random_access", issue = "none")]
1548#[cfg(not(feature = "ferrocene_certified"))]
1549unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {}
1550
1551#[doc(hidden)]
1552#[unstable(feature = "trusted_random_access", issue = "none")]
1553#[cfg(not(feature = "ferrocene_certified"))]
1554unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Windows<'a, T> {
1555 const MAY_HAVE_SIDE_EFFECT: bool = false;
1556}
1557
1558#[cfg_attr(not(feature = "ferrocene_certified"), derive(Debug))]
1580#[stable(feature = "rust1", since = "1.0.0")]
1581#[must_use = "iterators are lazy and do nothing unless consumed"]
1582pub struct Chunks<'a, T: 'a> {
1583 v: &'a [T],
1584 chunk_size: usize,
1585}
1586
1587impl<'a, T: 'a> Chunks<'a, T> {
1588 #[inline]
1589 pub(super) const fn new(slice: &'a [T], size: usize) -> Self {
1590 Self { v: slice, chunk_size: size }
1591 }
1592}
1593
1594#[stable(feature = "rust1", since = "1.0.0")]
1596#[cfg(not(feature = "ferrocene_certified"))]
1597impl<T> Clone for Chunks<'_, T> {
1598 fn clone(&self) -> Self {
1599 Chunks { v: self.v, chunk_size: self.chunk_size }
1600 }
1601}
1602
1603#[stable(feature = "rust1", since = "1.0.0")]
1604impl<'a, T> Iterator for Chunks<'a, T> {
1605 type Item = &'a [T];
1606
1607 #[inline]
1608 fn next(&mut self) -> Option<&'a [T]> {
1609 if self.v.is_empty() {
1610 None
1611 } else {
1612 let chunksz = cmp::min(self.v.len(), self.chunk_size);
1613 let (fst, snd) = self.v.split_at(chunksz);
1614 self.v = snd;
1615 Some(fst)
1616 }
1617 }
1618
1619 #[inline]
1620 fn size_hint(&self) -> (usize, Option<usize>) {
1621 if self.v.is_empty() {
1622 (0, Some(0))
1623 } else {
1624 let n = self.v.len() / self.chunk_size;
1625 let rem = self.v.len() % self.chunk_size;
1626 let n = if rem > 0 { n + 1 } else { n };
1627 (n, Some(n))
1628 }
1629 }
1630
1631 #[inline]
1632 #[cfg(not(feature = "ferrocene_certified"))]
1633 fn count(self) -> usize {
1634 self.len()
1635 }
1636
1637 #[inline]
1638 fn nth(&mut self, n: usize) -> Option<Self::Item> {
1639 let (start, overflow) = n.overflowing_mul(self.chunk_size);
1640 let chunk_start = &self.v[start.min(self.v.len())..];
1642 let (nth, remainder) = chunk_start.split_at(self.chunk_size.min(chunk_start.len()));
1643 if !overflow && start < self.v.len() {
1644 self.v = remainder;
1645 Some(nth)
1646 } else {
1647 self.v = &self.v[..0]; None
1649 }
1650 }
1651
1652 #[inline]
1653 #[cfg(not(feature = "ferrocene_certified"))]
1654 fn last(self) -> Option<Self::Item> {
1655 if self.v.is_empty() {
1656 None
1657 } else {
1658 let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
1659 Some(&self.v[start..])
1660 }
1661 }
1662
1663 #[cfg(not(feature = "ferrocene_certified"))]
1664 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
1665 let start = idx * self.chunk_size;
1666 unsafe {
1674 let len = cmp::min(self.v.len().unchecked_sub(start), self.chunk_size);
1675 from_raw_parts(self.v.as_ptr().add(start), len)
1676 }
1677 }
1678}
1679
1680#[stable(feature = "rust1", since = "1.0.0")]
1681#[cfg(not(feature = "ferrocene_certified"))]
1682impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
1683 #[inline]
1684 fn next_back(&mut self) -> Option<&'a [T]> {
1685 if self.v.is_empty() {
1686 None
1687 } else {
1688 let remainder = self.v.len() % self.chunk_size;
1689 let chunksz = if remainder != 0 { remainder } else { self.chunk_size };
1690 let (fst, snd) = unsafe { self.v.split_at_unchecked(self.v.len() - chunksz) };
1705 self.v = fst;
1706 Some(snd)
1707 }
1708 }
1709
1710 #[inline]
1711 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1712 let len = self.len();
1713 if n >= len {
1714 self.v = &self.v[..0]; None
1716 } else {
1717 let start = (len - 1 - n) * self.chunk_size;
1718 let end = match start.checked_add(self.chunk_size) {
1719 Some(res) => cmp::min(self.v.len(), res),
1720 None => self.v.len(),
1721 };
1722 let nth_back = &self.v[start..end];
1723 self.v = &self.v[..start];
1724 Some(nth_back)
1725 }
1726 }
1727}
1728
1729#[stable(feature = "rust1", since = "1.0.0")]
1730#[cfg(not(feature = "ferrocene_certified"))]
1731impl<T> ExactSizeIterator for Chunks<'_, T> {}
1732
1733#[unstable(feature = "trusted_len", issue = "37572")]
1734#[cfg(not(feature = "ferrocene_certified"))]
1735unsafe impl<T> TrustedLen for Chunks<'_, T> {}
1736
1737#[stable(feature = "fused", since = "1.26.0")]
1738#[cfg(not(feature = "ferrocene_certified"))]
1739impl<T> FusedIterator for Chunks<'_, T> {}
1740
1741#[doc(hidden)]
1742#[unstable(feature = "trusted_random_access", issue = "none")]
1743#[cfg(not(feature = "ferrocene_certified"))]
1744unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {}
1745
1746#[doc(hidden)]
1747#[unstable(feature = "trusted_random_access", issue = "none")]
1748#[cfg(not(feature = "ferrocene_certified"))]
1749unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Chunks<'a, T> {
1750 const MAY_HAVE_SIDE_EFFECT: bool = false;
1751}
1752
1753#[derive(Debug)]
1771#[stable(feature = "rust1", since = "1.0.0")]
1772#[must_use = "iterators are lazy and do nothing unless consumed"]
1773#[cfg(not(feature = "ferrocene_certified"))]
1774pub struct ChunksMut<'a, T: 'a> {
1775 v: *mut [T],
1782 chunk_size: usize,
1783 _marker: PhantomData<&'a mut T>,
1784}
1785
1786#[cfg(not(feature = "ferrocene_certified"))]
1787impl<'a, T: 'a> ChunksMut<'a, T> {
1788 #[inline]
1789 pub(super) const fn new(slice: &'a mut [T], size: usize) -> Self {
1790 Self { v: slice, chunk_size: size, _marker: PhantomData }
1791 }
1792}
1793
1794#[stable(feature = "rust1", since = "1.0.0")]
1795#[cfg(not(feature = "ferrocene_certified"))]
1796impl<'a, T> Iterator for ChunksMut<'a, T> {
1797 type Item = &'a mut [T];
1798
1799 #[inline]
1800 fn next(&mut self) -> Option<&'a mut [T]> {
1801 if self.v.is_empty() {
1802 None
1803 } else {
1804 let sz = cmp::min(self.v.len(), self.chunk_size);
1805 let (head, tail) = unsafe { self.v.split_at_mut(sz) };
1807 self.v = tail;
1808 Some(unsafe { &mut *head })
1810 }
1811 }
1812
1813 #[inline]
1814 fn size_hint(&self) -> (usize, Option<usize>) {
1815 if self.v.is_empty() {
1816 (0, Some(0))
1817 } else {
1818 let n = self.v.len() / self.chunk_size;
1819 let rem = self.v.len() % self.chunk_size;
1820 let n = if rem > 0 { n + 1 } else { n };
1821 (n, Some(n))
1822 }
1823 }
1824
1825 #[inline]
1826 fn count(self) -> usize {
1827 self.len()
1828 }
1829
1830 #[inline]
1831 fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
1832 let (start, overflow) = n.overflowing_mul(self.chunk_size);
1833 if start >= self.v.len() || overflow {
1834 self.v = &mut [];
1835 None
1836 } else {
1837 let end = match start.checked_add(self.chunk_size) {
1838 Some(sum) => cmp::min(self.v.len(), sum),
1839 None => self.v.len(),
1840 };
1841 let (head, tail) = unsafe { self.v.split_at_mut(end) };
1843 let (_, nth) = unsafe { head.split_at_mut(start) };
1845 self.v = tail;
1846 Some(unsafe { &mut *nth })
1848 }
1849 }
1850
1851 #[inline]
1852 fn last(self) -> Option<Self::Item> {
1853 if self.v.is_empty() {
1854 None
1855 } else {
1856 let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
1857 Some(unsafe { &mut *self.v.get_unchecked_mut(start..) })
1859 }
1860 }
1861
1862 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
1863 let start = idx * self.chunk_size;
1864 unsafe {
1871 let len = cmp::min(self.v.len().unchecked_sub(start), self.chunk_size);
1872 from_raw_parts_mut(self.v.as_mut_ptr().add(start), len)
1873 }
1874 }
1875}
1876
1877#[stable(feature = "rust1", since = "1.0.0")]
1878#[cfg(not(feature = "ferrocene_certified"))]
1879impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
1880 #[inline]
1881 fn next_back(&mut self) -> Option<&'a mut [T]> {
1882 if self.v.is_empty() {
1883 None
1884 } else {
1885 let remainder = self.v.len() % self.chunk_size;
1886 let sz = if remainder != 0 { remainder } else { self.chunk_size };
1887 let len = self.v.len();
1888 let (head, tail) = unsafe { self.v.split_at_mut_unchecked(len - sz) };
1890 self.v = head;
1891 Some(unsafe { &mut *tail })
1893 }
1894 }
1895
1896 #[inline]
1897 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1898 let len = self.len();
1899 if n >= len {
1900 self.v = &mut [];
1901 None
1902 } else {
1903 let start = (len - 1 - n) * self.chunk_size;
1904 let end = match start.checked_add(self.chunk_size) {
1905 Some(res) => cmp::min(self.v.len(), res),
1906 None => self.v.len(),
1907 };
1908 let (temp, _tail) = unsafe { self.v.split_at_mut(end) };
1910 let (head, nth_back) = unsafe { temp.split_at_mut(start) };
1912 self.v = head;
1913 Some(unsafe { &mut *nth_back })
1915 }
1916 }
1917}
1918
1919#[stable(feature = "rust1", since = "1.0.0")]
1920#[cfg(not(feature = "ferrocene_certified"))]
1921impl<T> ExactSizeIterator for ChunksMut<'_, T> {}
1922
1923#[unstable(feature = "trusted_len", issue = "37572")]
1924#[cfg(not(feature = "ferrocene_certified"))]
1925unsafe impl<T> TrustedLen for ChunksMut<'_, T> {}
1926
1927#[stable(feature = "fused", since = "1.26.0")]
1928#[cfg(not(feature = "ferrocene_certified"))]
1929impl<T> FusedIterator for ChunksMut<'_, T> {}
1930
1931#[doc(hidden)]
1932#[unstable(feature = "trusted_random_access", issue = "none")]
1933#[cfg(not(feature = "ferrocene_certified"))]
1934unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {}
1935
1936#[doc(hidden)]
1937#[unstable(feature = "trusted_random_access", issue = "none")]
1938#[cfg(not(feature = "ferrocene_certified"))]
1939unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksMut<'a, T> {
1940 const MAY_HAVE_SIDE_EFFECT: bool = false;
1941}
1942
1943#[stable(feature = "rust1", since = "1.0.0")]
1944#[cfg(not(feature = "ferrocene_certified"))]
1945unsafe impl<T> Send for ChunksMut<'_, T> where T: Send {}
1946
1947#[stable(feature = "rust1", since = "1.0.0")]
1948#[cfg(not(feature = "ferrocene_certified"))]
1949unsafe impl<T> Sync for ChunksMut<'_, T> where T: Sync {}
1950
1951#[derive(Debug)]
1974#[stable(feature = "chunks_exact", since = "1.31.0")]
1975#[must_use = "iterators are lazy and do nothing unless consumed"]
1976#[cfg(not(feature = "ferrocene_certified"))]
1977pub struct ChunksExact<'a, T: 'a> {
1978 v: &'a [T],
1979 rem: &'a [T],
1980 chunk_size: usize,
1981}
1982
1983#[cfg(not(feature = "ferrocene_certified"))]
1984impl<'a, T> ChunksExact<'a, T> {
1985 #[inline]
1986 pub(super) const fn new(slice: &'a [T], chunk_size: usize) -> Self {
1987 let rem = slice.len() % chunk_size;
1988 let fst_len = slice.len() - rem;
1989 let (fst, snd) = unsafe { slice.split_at_unchecked(fst_len) };
1991 Self { v: fst, rem: snd, chunk_size }
1992 }
1993
1994 #[must_use]
2012 #[stable(feature = "chunks_exact", since = "1.31.0")]
2013 pub fn remainder(&self) -> &'a [T] {
2014 self.rem
2015 }
2016}
2017
2018#[stable(feature = "chunks_exact", since = "1.31.0")]
2020#[cfg(not(feature = "ferrocene_certified"))]
2021impl<T> Clone for ChunksExact<'_, T> {
2022 fn clone(&self) -> Self {
2023 ChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size }
2024 }
2025}
2026
2027#[stable(feature = "chunks_exact", since = "1.31.0")]
2028#[cfg(not(feature = "ferrocene_certified"))]
2029impl<'a, T> Iterator for ChunksExact<'a, T> {
2030 type Item = &'a [T];
2031
2032 #[inline]
2033 fn next(&mut self) -> Option<&'a [T]> {
2034 if self.v.len() < self.chunk_size {
2035 None
2036 } else {
2037 let (fst, snd) = self.v.split_at(self.chunk_size);
2038 self.v = snd;
2039 Some(fst)
2040 }
2041 }
2042
2043 #[inline]
2044 fn size_hint(&self) -> (usize, Option<usize>) {
2045 let n = self.v.len() / self.chunk_size;
2046 (n, Some(n))
2047 }
2048
2049 #[inline]
2050 fn count(self) -> usize {
2051 self.len()
2052 }
2053
2054 #[inline]
2055 fn nth(&mut self, n: usize) -> Option<Self::Item> {
2056 let (start, overflow) = n.overflowing_mul(self.chunk_size);
2057 if start >= self.v.len() || overflow {
2058 self.v = &self.v[..0]; None
2060 } else {
2061 let (_, snd) = self.v.split_at(start);
2062 self.v = snd;
2063 self.next()
2064 }
2065 }
2066
2067 #[inline]
2068 fn last(mut self) -> Option<Self::Item> {
2069 self.next_back()
2070 }
2071
2072 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2073 let start = idx * self.chunk_size;
2074 unsafe { from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) }
2076 }
2077}
2078
2079#[stable(feature = "chunks_exact", since = "1.31.0")]
2080#[cfg(not(feature = "ferrocene_certified"))]
2081impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
2082 #[inline]
2083 fn next_back(&mut self) -> Option<&'a [T]> {
2084 if self.v.len() < self.chunk_size {
2085 None
2086 } else {
2087 let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
2088 self.v = fst;
2089 Some(snd)
2090 }
2091 }
2092
2093 #[inline]
2094 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2095 let len = self.len();
2096 if n >= len {
2097 self.v = &self.v[..0]; None
2099 } else {
2100 let start = (len - 1 - n) * self.chunk_size;
2101 let end = start + self.chunk_size;
2102 let nth_back = &self.v[start..end];
2103 self.v = &self.v[..start];
2104 Some(nth_back)
2105 }
2106 }
2107}
2108
2109#[stable(feature = "chunks_exact", since = "1.31.0")]
2110#[cfg(not(feature = "ferrocene_certified"))]
2111impl<T> ExactSizeIterator for ChunksExact<'_, T> {
2112 fn is_empty(&self) -> bool {
2113 self.v.is_empty()
2114 }
2115}
2116
2117#[unstable(feature = "trusted_len", issue = "37572")]
2118#[cfg(not(feature = "ferrocene_certified"))]
2119unsafe impl<T> TrustedLen for ChunksExact<'_, T> {}
2120
2121#[stable(feature = "chunks_exact", since = "1.31.0")]
2122#[cfg(not(feature = "ferrocene_certified"))]
2123impl<T> FusedIterator for ChunksExact<'_, T> {}
2124
2125#[doc(hidden)]
2126#[unstable(feature = "trusted_random_access", issue = "none")]
2127#[cfg(not(feature = "ferrocene_certified"))]
2128unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {}
2129
2130#[doc(hidden)]
2131#[unstable(feature = "trusted_random_access", issue = "none")]
2132#[cfg(not(feature = "ferrocene_certified"))]
2133unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExact<'a, T> {
2134 const MAY_HAVE_SIDE_EFFECT: bool = false;
2135}
2136
2137#[derive(Debug)]
2157#[stable(feature = "chunks_exact", since = "1.31.0")]
2158#[must_use = "iterators are lazy and do nothing unless consumed"]
2159#[cfg(not(feature = "ferrocene_certified"))]
2160pub struct ChunksExactMut<'a, T: 'a> {
2161 v: *mut [T],
2168 rem: &'a mut [T], chunk_size: usize,
2170 _marker: PhantomData<&'a mut T>,
2171}
2172
2173#[cfg(not(feature = "ferrocene_certified"))]
2174impl<'a, T> ChunksExactMut<'a, T> {
2175 #[inline]
2176 pub(super) const fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
2177 let rem = slice.len() % chunk_size;
2178 let fst_len = slice.len() - rem;
2179 let (fst, snd) = unsafe { slice.split_at_mut_unchecked(fst_len) };
2181 Self { v: fst, rem: snd, chunk_size, _marker: PhantomData }
2182 }
2183
2184 #[must_use = "`self` will be dropped if the result is not used"]
2188 #[stable(feature = "chunks_exact", since = "1.31.0")]
2189 pub fn into_remainder(self) -> &'a mut [T] {
2190 self.rem
2191 }
2192}
2193
2194#[stable(feature = "chunks_exact", since = "1.31.0")]
2195#[cfg(not(feature = "ferrocene_certified"))]
2196impl<'a, T> Iterator for ChunksExactMut<'a, T> {
2197 type Item = &'a mut [T];
2198
2199 #[inline]
2200 fn next(&mut self) -> Option<&'a mut [T]> {
2201 if self.v.len() < self.chunk_size {
2202 None
2203 } else {
2204 let (head, tail) = unsafe { self.v.split_at_mut(self.chunk_size) };
2206 self.v = tail;
2207 Some(unsafe { &mut *head })
2209 }
2210 }
2211
2212 #[inline]
2213 fn size_hint(&self) -> (usize, Option<usize>) {
2214 let n = self.v.len() / self.chunk_size;
2215 (n, Some(n))
2216 }
2217
2218 #[inline]
2219 fn count(self) -> usize {
2220 self.len()
2221 }
2222
2223 #[inline]
2224 fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
2225 let (start, overflow) = n.overflowing_mul(self.chunk_size);
2226 if start >= self.v.len() || overflow {
2227 self.v = &mut [];
2228 None
2229 } else {
2230 let (_, snd) = unsafe { self.v.split_at_mut(start) };
2232 self.v = snd;
2233 self.next()
2234 }
2235 }
2236
2237 #[inline]
2238 fn last(mut self) -> Option<Self::Item> {
2239 self.next_back()
2240 }
2241
2242 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2243 let start = idx * self.chunk_size;
2244 unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
2246 }
2247}
2248
2249#[stable(feature = "chunks_exact", since = "1.31.0")]
2250#[cfg(not(feature = "ferrocene_certified"))]
2251impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
2252 #[inline]
2253 fn next_back(&mut self) -> Option<&'a mut [T]> {
2254 if self.v.len() < self.chunk_size {
2255 None
2256 } else {
2257 let (head, tail) = unsafe { self.v.split_at_mut(self.v.len() - self.chunk_size) };
2259 self.v = head;
2260 Some(unsafe { &mut *tail })
2262 }
2263 }
2264
2265 #[inline]
2266 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2267 let len = self.len();
2268 if n >= len {
2269 self.v = &mut [];
2270 None
2271 } else {
2272 let start = (len - 1 - n) * self.chunk_size;
2273 let end = start + self.chunk_size;
2274 let (temp, _tail) = unsafe { mem::replace(&mut self.v, &mut []).split_at_mut(end) };
2276 let (head, nth_back) = unsafe { temp.split_at_mut(start) };
2278 self.v = head;
2279 Some(unsafe { &mut *nth_back })
2281 }
2282 }
2283}
2284
2285#[stable(feature = "chunks_exact", since = "1.31.0")]
2286#[cfg(not(feature = "ferrocene_certified"))]
2287impl<T> ExactSizeIterator for ChunksExactMut<'_, T> {
2288 fn is_empty(&self) -> bool {
2289 self.v.is_empty()
2290 }
2291}
2292
2293#[unstable(feature = "trusted_len", issue = "37572")]
2294#[cfg(not(feature = "ferrocene_certified"))]
2295unsafe impl<T> TrustedLen for ChunksExactMut<'_, T> {}
2296
2297#[stable(feature = "chunks_exact", since = "1.31.0")]
2298#[cfg(not(feature = "ferrocene_certified"))]
2299impl<T> FusedIterator for ChunksExactMut<'_, T> {}
2300
2301#[doc(hidden)]
2302#[unstable(feature = "trusted_random_access", issue = "none")]
2303#[cfg(not(feature = "ferrocene_certified"))]
2304unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {}
2305
2306#[doc(hidden)]
2307#[unstable(feature = "trusted_random_access", issue = "none")]
2308#[cfg(not(feature = "ferrocene_certified"))]
2309unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExactMut<'a, T> {
2310 const MAY_HAVE_SIDE_EFFECT: bool = false;
2311}
2312
2313#[stable(feature = "chunks_exact", since = "1.31.0")]
2314#[cfg(not(feature = "ferrocene_certified"))]
2315unsafe impl<T> Send for ChunksExactMut<'_, T> where T: Send {}
2316
2317#[stable(feature = "chunks_exact", since = "1.31.0")]
2318#[cfg(not(feature = "ferrocene_certified"))]
2319unsafe impl<T> Sync for ChunksExactMut<'_, T> where T: Sync {}
2320
2321#[derive(Debug, Clone, Copy)]
2342#[unstable(feature = "array_windows", issue = "75027")]
2343#[must_use = "iterators are lazy and do nothing unless consumed"]
2344#[cfg(not(feature = "ferrocene_certified"))]
2345pub struct ArrayWindows<'a, T: 'a, const N: usize> {
2346 v: &'a [T],
2347}
2348
2349#[cfg(not(feature = "ferrocene_certified"))]
2350impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> {
2351 #[inline]
2352 pub(super) const fn new(slice: &'a [T]) -> Self {
2353 Self { v: slice }
2354 }
2355}
2356
2357#[unstable(feature = "array_windows", issue = "75027")]
2358#[cfg(not(feature = "ferrocene_certified"))]
2359impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
2360 type Item = &'a [T; N];
2361
2362 #[inline]
2363 fn next(&mut self) -> Option<Self::Item> {
2364 let ret = self.v.first_chunk();
2365 if ret.is_some() {
2366 self.v = &self.v[1..];
2367 }
2368 ret
2369 }
2370
2371 #[inline]
2372 fn size_hint(&self) -> (usize, Option<usize>) {
2373 let size = self.v.len().saturating_sub(N - 1);
2374 (size, Some(size))
2375 }
2376
2377 #[inline]
2378 fn count(self) -> usize {
2379 self.len()
2380 }
2381
2382 #[inline]
2383 fn nth(&mut self, n: usize) -> Option<Self::Item> {
2384 let idx = n.min(self.v.len());
2385 self.v = &self.v[idx..];
2386 self.next()
2387 }
2388
2389 #[inline]
2390 fn last(self) -> Option<Self::Item> {
2391 self.v.last_chunk()
2392 }
2393}
2394
2395#[unstable(feature = "array_windows", issue = "75027")]
2396#[cfg(not(feature = "ferrocene_certified"))]
2397impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> {
2398 #[inline]
2399 fn next_back(&mut self) -> Option<&'a [T; N]> {
2400 let ret = self.v.last_chunk();
2401 if ret.is_some() {
2402 self.v = &self.v[..self.v.len() - 1];
2403 }
2404 ret
2405 }
2406
2407 #[inline]
2408 fn nth_back(&mut self, n: usize) -> Option<&'a [T; N]> {
2409 let idx = self.v.len().saturating_sub(n);
2410 self.v = &self.v[..idx];
2411 self.next_back()
2412 }
2413}
2414
2415#[unstable(feature = "array_windows", issue = "75027")]
2416#[cfg(not(feature = "ferrocene_certified"))]
2417impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
2418 fn is_empty(&self) -> bool {
2419 self.v.len() < N
2420 }
2421}
2422
2423#[derive(Debug)]
2445#[stable(feature = "rchunks", since = "1.31.0")]
2446#[must_use = "iterators are lazy and do nothing unless consumed"]
2447#[cfg(not(feature = "ferrocene_certified"))]
2448pub struct RChunks<'a, T: 'a> {
2449 v: &'a [T],
2450 chunk_size: usize,
2451}
2452
2453#[cfg(not(feature = "ferrocene_certified"))]
2454impl<'a, T: 'a> RChunks<'a, T> {
2455 #[inline]
2456 pub(super) const fn new(slice: &'a [T], size: usize) -> Self {
2457 Self { v: slice, chunk_size: size }
2458 }
2459}
2460
2461#[stable(feature = "rchunks", since = "1.31.0")]
2463#[cfg(not(feature = "ferrocene_certified"))]
2464impl<T> Clone for RChunks<'_, T> {
2465 fn clone(&self) -> Self {
2466 RChunks { v: self.v, chunk_size: self.chunk_size }
2467 }
2468}
2469
2470#[stable(feature = "rchunks", since = "1.31.0")]
2471#[cfg(not(feature = "ferrocene_certified"))]
2472impl<'a, T> Iterator for RChunks<'a, T> {
2473 type Item = &'a [T];
2474
2475 #[inline]
2476 fn next(&mut self) -> Option<&'a [T]> {
2477 if self.v.is_empty() {
2478 None
2479 } else {
2480 let len = self.v.len();
2481 let chunksz = cmp::min(len, self.chunk_size);
2482 let (fst, snd) = unsafe { self.v.split_at_unchecked(len - chunksz) };
2488 self.v = fst;
2489 Some(snd)
2490 }
2491 }
2492
2493 #[inline]
2494 fn size_hint(&self) -> (usize, Option<usize>) {
2495 if self.v.is_empty() {
2496 (0, Some(0))
2497 } else {
2498 let n = self.v.len() / self.chunk_size;
2499 let rem = self.v.len() % self.chunk_size;
2500 let n = if rem > 0 { n + 1 } else { n };
2501 (n, Some(n))
2502 }
2503 }
2504
2505 #[inline]
2506 fn count(self) -> usize {
2507 self.len()
2508 }
2509
2510 #[inline]
2511 fn nth(&mut self, n: usize) -> Option<Self::Item> {
2512 let (end, overflow) = n.overflowing_mul(self.chunk_size);
2513 if end >= self.v.len() || overflow {
2514 self.v = &self.v[..0]; None
2516 } else {
2517 let end = self.v.len() - end;
2519 let start = match end.checked_sub(self.chunk_size) {
2520 Some(sum) => sum,
2521 None => 0,
2522 };
2523 let nth = &self.v[start..end];
2524 self.v = &self.v[0..start];
2525 Some(nth)
2526 }
2527 }
2528
2529 #[inline]
2530 fn last(self) -> Option<Self::Item> {
2531 if self.v.is_empty() {
2532 None
2533 } else {
2534 let rem = self.v.len() % self.chunk_size;
2535 let end = if rem == 0 { self.chunk_size } else { rem };
2536 Some(&self.v[0..end])
2537 }
2538 }
2539
2540 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2541 let end = self.v.len() - idx * self.chunk_size;
2542 let start = match end.checked_sub(self.chunk_size) {
2543 None => 0,
2544 Some(start) => start,
2545 };
2546 unsafe { from_raw_parts(self.v.as_ptr().add(start), end - start) }
2548 }
2549}
2550
2551#[stable(feature = "rchunks", since = "1.31.0")]
2552#[cfg(not(feature = "ferrocene_certified"))]
2553impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
2554 #[inline]
2555 fn next_back(&mut self) -> Option<&'a [T]> {
2556 if self.v.is_empty() {
2557 None
2558 } else {
2559 let remainder = self.v.len() % self.chunk_size;
2560 let chunksz = if remainder != 0 { remainder } else { self.chunk_size };
2561 let (fst, snd) = unsafe { self.v.split_at_unchecked(chunksz) };
2563 self.v = snd;
2564 Some(fst)
2565 }
2566 }
2567
2568 #[inline]
2569 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2570 let len = self.len();
2571 if n >= len {
2572 self.v = &self.v[..0]; None
2574 } else {
2575 let offset_from_end = (len - 1 - n) * self.chunk_size;
2577 let end = self.v.len() - offset_from_end;
2578 let start = end.saturating_sub(self.chunk_size);
2579 let nth_back = &self.v[start..end];
2580 self.v = &self.v[end..];
2581 Some(nth_back)
2582 }
2583 }
2584}
2585
2586#[stable(feature = "rchunks", since = "1.31.0")]
2587#[cfg(not(feature = "ferrocene_certified"))]
2588impl<T> ExactSizeIterator for RChunks<'_, T> {}
2589
2590#[unstable(feature = "trusted_len", issue = "37572")]
2591#[cfg(not(feature = "ferrocene_certified"))]
2592unsafe impl<T> TrustedLen for RChunks<'_, T> {}
2593
2594#[stable(feature = "rchunks", since = "1.31.0")]
2595#[cfg(not(feature = "ferrocene_certified"))]
2596impl<T> FusedIterator for RChunks<'_, T> {}
2597
2598#[doc(hidden)]
2599#[unstable(feature = "trusted_random_access", issue = "none")]
2600#[cfg(not(feature = "ferrocene_certified"))]
2601unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {}
2602
2603#[doc(hidden)]
2604#[unstable(feature = "trusted_random_access", issue = "none")]
2605#[cfg(not(feature = "ferrocene_certified"))]
2606unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunks<'a, T> {
2607 const MAY_HAVE_SIDE_EFFECT: bool = false;
2608}
2609
2610#[derive(Debug)]
2628#[stable(feature = "rchunks", since = "1.31.0")]
2629#[must_use = "iterators are lazy and do nothing unless consumed"]
2630#[cfg(not(feature = "ferrocene_certified"))]
2631pub struct RChunksMut<'a, T: 'a> {
2632 v: *mut [T],
2639 chunk_size: usize,
2640 _marker: PhantomData<&'a mut T>,
2641}
2642
2643#[cfg(not(feature = "ferrocene_certified"))]
2644impl<'a, T: 'a> RChunksMut<'a, T> {
2645 #[inline]
2646 pub(super) const fn new(slice: &'a mut [T], size: usize) -> Self {
2647 Self { v: slice, chunk_size: size, _marker: PhantomData }
2648 }
2649}
2650
2651#[stable(feature = "rchunks", since = "1.31.0")]
2652#[cfg(not(feature = "ferrocene_certified"))]
2653impl<'a, T> Iterator for RChunksMut<'a, T> {
2654 type Item = &'a mut [T];
2655
2656 #[inline]
2657 fn next(&mut self) -> Option<&'a mut [T]> {
2658 if self.v.is_empty() {
2659 None
2660 } else {
2661 let sz = cmp::min(self.v.len(), self.chunk_size);
2662 let len = self.v.len();
2663 let (head, tail) = unsafe { self.v.split_at_mut_unchecked(len - sz) };
2669 self.v = head;
2670 Some(unsafe { &mut *tail })
2672 }
2673 }
2674
2675 #[inline]
2676 fn size_hint(&self) -> (usize, Option<usize>) {
2677 if self.v.is_empty() {
2678 (0, Some(0))
2679 } else {
2680 let n = self.v.len() / self.chunk_size;
2681 let rem = self.v.len() % self.chunk_size;
2682 let n = if rem > 0 { n + 1 } else { n };
2683 (n, Some(n))
2684 }
2685 }
2686
2687 #[inline]
2688 fn count(self) -> usize {
2689 self.len()
2690 }
2691
2692 #[inline]
2693 fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
2694 let (end, overflow) = n.overflowing_mul(self.chunk_size);
2695 if end >= self.v.len() || overflow {
2696 self.v = &mut [];
2697 None
2698 } else {
2699 let end = self.v.len() - end;
2701 let start = match end.checked_sub(self.chunk_size) {
2702 Some(sum) => sum,
2703 None => 0,
2704 };
2705 let (head, tail) = unsafe { self.v.split_at_mut(start) };
2708 let (nth, _) = unsafe { tail.split_at_mut(end - start) };
2711 self.v = head;
2712 Some(unsafe { &mut *nth })
2714 }
2715 }
2716
2717 #[inline]
2718 fn last(self) -> Option<Self::Item> {
2719 if self.v.is_empty() {
2720 None
2721 } else {
2722 let rem = self.v.len() % self.chunk_size;
2723 let end = if rem == 0 { self.chunk_size } else { rem };
2724 Some(unsafe { &mut *self.v.get_unchecked_mut(0..end) })
2726 }
2727 }
2728
2729 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2730 let end = self.v.len() - idx * self.chunk_size;
2731 let start = match end.checked_sub(self.chunk_size) {
2732 None => 0,
2733 Some(start) => start,
2734 };
2735 unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start) }
2738 }
2739}
2740
2741#[stable(feature = "rchunks", since = "1.31.0")]
2742#[cfg(not(feature = "ferrocene_certified"))]
2743impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
2744 #[inline]
2745 fn next_back(&mut self) -> Option<&'a mut [T]> {
2746 if self.v.is_empty() {
2747 None
2748 } else {
2749 let remainder = self.v.len() % self.chunk_size;
2750 let sz = if remainder != 0 { remainder } else { self.chunk_size };
2751 let (head, tail) = unsafe { self.v.split_at_mut_unchecked(sz) };
2753 self.v = tail;
2754 Some(unsafe { &mut *head })
2756 }
2757 }
2758
2759 #[inline]
2760 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2761 let len = self.len();
2762 if n >= len {
2763 self.v = &mut [];
2764 None
2765 } else {
2766 let offset_from_end = (len - 1 - n) * self.chunk_size;
2768 let end = self.v.len() - offset_from_end;
2769 let start = end.saturating_sub(self.chunk_size);
2770 let (tmp, tail) = unsafe { self.v.split_at_mut(end) };
2772 let (_, nth_back) = unsafe { tmp.split_at_mut(start) };
2774 self.v = tail;
2775 Some(unsafe { &mut *nth_back })
2777 }
2778 }
2779}
2780
2781#[stable(feature = "rchunks", since = "1.31.0")]
2782#[cfg(not(feature = "ferrocene_certified"))]
2783impl<T> ExactSizeIterator for RChunksMut<'_, T> {}
2784
2785#[unstable(feature = "trusted_len", issue = "37572")]
2786#[cfg(not(feature = "ferrocene_certified"))]
2787unsafe impl<T> TrustedLen for RChunksMut<'_, T> {}
2788
2789#[stable(feature = "rchunks", since = "1.31.0")]
2790#[cfg(not(feature = "ferrocene_certified"))]
2791impl<T> FusedIterator for RChunksMut<'_, T> {}
2792
2793#[doc(hidden)]
2794#[unstable(feature = "trusted_random_access", issue = "none")]
2795#[cfg(not(feature = "ferrocene_certified"))]
2796unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {}
2797
2798#[doc(hidden)]
2799#[unstable(feature = "trusted_random_access", issue = "none")]
2800#[cfg(not(feature = "ferrocene_certified"))]
2801unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksMut<'a, T> {
2802 const MAY_HAVE_SIDE_EFFECT: bool = false;
2803}
2804
2805#[stable(feature = "rchunks", since = "1.31.0")]
2806#[cfg(not(feature = "ferrocene_certified"))]
2807unsafe impl<T> Send for RChunksMut<'_, T> where T: Send {}
2808
2809#[stable(feature = "rchunks", since = "1.31.0")]
2810#[cfg(not(feature = "ferrocene_certified"))]
2811unsafe impl<T> Sync for RChunksMut<'_, T> where T: Sync {}
2812
2813#[derive(Debug)]
2836#[stable(feature = "rchunks", since = "1.31.0")]
2837#[must_use = "iterators are lazy and do nothing unless consumed"]
2838#[cfg(not(feature = "ferrocene_certified"))]
2839pub struct RChunksExact<'a, T: 'a> {
2840 v: &'a [T],
2841 rem: &'a [T],
2842 chunk_size: usize,
2843}
2844
2845#[cfg(not(feature = "ferrocene_certified"))]
2846impl<'a, T> RChunksExact<'a, T> {
2847 #[inline]
2848 pub(super) const fn new(slice: &'a [T], chunk_size: usize) -> Self {
2849 let rem = slice.len() % chunk_size;
2850 let (fst, snd) = unsafe { slice.split_at_unchecked(rem) };
2852 Self { v: snd, rem: fst, chunk_size }
2853 }
2854
2855 #[must_use]
2873 #[stable(feature = "rchunks", since = "1.31.0")]
2874 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
2875 pub const fn remainder(&self) -> &'a [T] {
2876 self.rem
2877 }
2878}
2879
2880#[stable(feature = "rchunks", since = "1.31.0")]
2882#[cfg(not(feature = "ferrocene_certified"))]
2883impl<'a, T> Clone for RChunksExact<'a, T> {
2884 fn clone(&self) -> RChunksExact<'a, T> {
2885 RChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size }
2886 }
2887}
2888
2889#[stable(feature = "rchunks", since = "1.31.0")]
2890#[cfg(not(feature = "ferrocene_certified"))]
2891impl<'a, T> Iterator for RChunksExact<'a, T> {
2892 type Item = &'a [T];
2893
2894 #[inline]
2895 fn next(&mut self) -> Option<&'a [T]> {
2896 if self.v.len() < self.chunk_size {
2897 None
2898 } else {
2899 let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
2900 self.v = fst;
2901 Some(snd)
2902 }
2903 }
2904
2905 #[inline]
2906 fn size_hint(&self) -> (usize, Option<usize>) {
2907 let n = self.v.len() / self.chunk_size;
2908 (n, Some(n))
2909 }
2910
2911 #[inline]
2912 fn count(self) -> usize {
2913 self.len()
2914 }
2915
2916 #[inline]
2917 fn nth(&mut self, n: usize) -> Option<Self::Item> {
2918 let (end, overflow) = n.overflowing_mul(self.chunk_size);
2919 if end >= self.v.len() || overflow {
2920 self.v = &self.v[..0]; None
2922 } else {
2923 let (fst, _) = self.v.split_at(self.v.len() - end);
2924 self.v = fst;
2925 self.next()
2926 }
2927 }
2928
2929 #[inline]
2930 fn last(mut self) -> Option<Self::Item> {
2931 self.next_back()
2932 }
2933
2934 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2935 let end = self.v.len() - idx * self.chunk_size;
2936 let start = end - self.chunk_size;
2937 unsafe { from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) }
2939 }
2940}
2941
2942#[stable(feature = "rchunks", since = "1.31.0")]
2943#[cfg(not(feature = "ferrocene_certified"))]
2944impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
2945 #[inline]
2946 fn next_back(&mut self) -> Option<&'a [T]> {
2947 if self.v.len() < self.chunk_size {
2948 None
2949 } else {
2950 let (fst, snd) = self.v.split_at(self.chunk_size);
2951 self.v = snd;
2952 Some(fst)
2953 }
2954 }
2955
2956 #[inline]
2957 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2958 let len = self.len();
2959 if n >= len {
2960 self.v = &self.v[..0]; None
2962 } else {
2963 let offset = (len - n) * self.chunk_size;
2966 let start = self.v.len() - offset;
2967 let end = start + self.chunk_size;
2968 let nth_back = &self.v[start..end];
2969 self.v = &self.v[end..];
2970 Some(nth_back)
2971 }
2972 }
2973}
2974
2975#[stable(feature = "rchunks", since = "1.31.0")]
2976#[cfg(not(feature = "ferrocene_certified"))]
2977impl<'a, T> ExactSizeIterator for RChunksExact<'a, T> {
2978 fn is_empty(&self) -> bool {
2979 self.v.is_empty()
2980 }
2981}
2982
2983#[unstable(feature = "trusted_len", issue = "37572")]
2984#[cfg(not(feature = "ferrocene_certified"))]
2985unsafe impl<T> TrustedLen for RChunksExact<'_, T> {}
2986
2987#[stable(feature = "rchunks", since = "1.31.0")]
2988#[cfg(not(feature = "ferrocene_certified"))]
2989impl<T> FusedIterator for RChunksExact<'_, T> {}
2990
2991#[doc(hidden)]
2992#[unstable(feature = "trusted_random_access", issue = "none")]
2993#[cfg(not(feature = "ferrocene_certified"))]
2994unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {}
2995
2996#[doc(hidden)]
2997#[unstable(feature = "trusted_random_access", issue = "none")]
2998#[cfg(not(feature = "ferrocene_certified"))]
2999unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExact<'a, T> {
3000 const MAY_HAVE_SIDE_EFFECT: bool = false;
3001}
3002
3003#[derive(Debug)]
3023#[stable(feature = "rchunks", since = "1.31.0")]
3024#[must_use = "iterators are lazy and do nothing unless consumed"]
3025#[cfg(not(feature = "ferrocene_certified"))]
3026pub struct RChunksExactMut<'a, T: 'a> {
3027 v: *mut [T],
3034 rem: &'a mut [T],
3035 chunk_size: usize,
3036}
3037
3038#[cfg(not(feature = "ferrocene_certified"))]
3039impl<'a, T> RChunksExactMut<'a, T> {
3040 #[inline]
3041 pub(super) const fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
3042 let rem = slice.len() % chunk_size;
3043 let (fst, snd) = unsafe { slice.split_at_mut_unchecked(rem) };
3045 Self { v: snd, rem: fst, chunk_size }
3046 }
3047
3048 #[must_use = "`self` will be dropped if the result is not used"]
3052 #[stable(feature = "rchunks", since = "1.31.0")]
3053 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
3054 pub const fn into_remainder(self) -> &'a mut [T] {
3055 self.rem
3056 }
3057}
3058
3059#[stable(feature = "rchunks", since = "1.31.0")]
3060#[cfg(not(feature = "ferrocene_certified"))]
3061impl<'a, T> Iterator for RChunksExactMut<'a, T> {
3062 type Item = &'a mut [T];
3063
3064 #[inline]
3065 fn next(&mut self) -> Option<&'a mut [T]> {
3066 if self.v.len() < self.chunk_size {
3067 None
3068 } else {
3069 let len = self.v.len();
3070 let (head, tail) = unsafe { self.v.split_at_mut(len - self.chunk_size) };
3072 self.v = head;
3073 Some(unsafe { &mut *tail })
3075 }
3076 }
3077
3078 #[inline]
3079 fn size_hint(&self) -> (usize, Option<usize>) {
3080 let n = self.v.len() / self.chunk_size;
3081 (n, Some(n))
3082 }
3083
3084 #[inline]
3085 fn count(self) -> usize {
3086 self.len()
3087 }
3088
3089 #[inline]
3090 fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
3091 let (end, overflow) = n.overflowing_mul(self.chunk_size);
3092 if end >= self.v.len() || overflow {
3093 self.v = &mut [];
3094 None
3095 } else {
3096 let len = self.v.len();
3097 let (fst, _) = unsafe { self.v.split_at_mut(len - end) };
3099 self.v = fst;
3100 self.next()
3101 }
3102 }
3103
3104 #[inline]
3105 fn last(mut self) -> Option<Self::Item> {
3106 self.next_back()
3107 }
3108
3109 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
3110 let end = self.v.len() - idx * self.chunk_size;
3111 let start = end - self.chunk_size;
3112 unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
3114 }
3115}
3116
3117#[stable(feature = "rchunks", since = "1.31.0")]
3118#[cfg(not(feature = "ferrocene_certified"))]
3119impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
3120 #[inline]
3121 fn next_back(&mut self) -> Option<&'a mut [T]> {
3122 if self.v.len() < self.chunk_size {
3123 None
3124 } else {
3125 let (head, tail) = unsafe { self.v.split_at_mut(self.chunk_size) };
3127 self.v = tail;
3128 Some(unsafe { &mut *head })
3130 }
3131 }
3132
3133 #[inline]
3134 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
3135 let len = self.len();
3136 if n >= len {
3137 self.v = &mut [];
3138 None
3139 } else {
3140 let offset = (len - n) * self.chunk_size;
3143 let start = self.v.len() - offset;
3144 let end = start + self.chunk_size;
3145 let (tmp, tail) = unsafe { self.v.split_at_mut(end) };
3147 let (_, nth_back) = unsafe { tmp.split_at_mut(start) };
3149 self.v = tail;
3150 Some(unsafe { &mut *nth_back })
3152 }
3153 }
3154}
3155
3156#[stable(feature = "rchunks", since = "1.31.0")]
3157#[cfg(not(feature = "ferrocene_certified"))]
3158impl<T> ExactSizeIterator for RChunksExactMut<'_, T> {
3159 fn is_empty(&self) -> bool {
3160 self.v.is_empty()
3161 }
3162}
3163
3164#[unstable(feature = "trusted_len", issue = "37572")]
3165#[cfg(not(feature = "ferrocene_certified"))]
3166unsafe impl<T> TrustedLen for RChunksExactMut<'_, T> {}
3167
3168#[stable(feature = "rchunks", since = "1.31.0")]
3169#[cfg(not(feature = "ferrocene_certified"))]
3170impl<T> FusedIterator for RChunksExactMut<'_, T> {}
3171
3172#[doc(hidden)]
3173#[unstable(feature = "trusted_random_access", issue = "none")]
3174#[cfg(not(feature = "ferrocene_certified"))]
3175unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {}
3176
3177#[doc(hidden)]
3178#[unstable(feature = "trusted_random_access", issue = "none")]
3179#[cfg(not(feature = "ferrocene_certified"))]
3180unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExactMut<'a, T> {
3181 const MAY_HAVE_SIDE_EFFECT: bool = false;
3182}
3183
3184#[stable(feature = "rchunks", since = "1.31.0")]
3185#[cfg(not(feature = "ferrocene_certified"))]
3186unsafe impl<T> Send for RChunksExactMut<'_, T> where T: Send {}
3187
3188#[stable(feature = "rchunks", since = "1.31.0")]
3189#[cfg(not(feature = "ferrocene_certified"))]
3190unsafe impl<T> Sync for RChunksExactMut<'_, T> where T: Sync {}
3191
3192#[doc(hidden)]
3193#[unstable(feature = "trusted_random_access", issue = "none")]
3194#[cfg(not(feature = "ferrocene_certified"))]
3195unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {}
3196
3197#[doc(hidden)]
3198#[unstable(feature = "trusted_random_access", issue = "none")]
3199#[cfg(not(feature = "ferrocene_certified"))]
3200unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Iter<'a, T> {
3201 const MAY_HAVE_SIDE_EFFECT: bool = false;
3202}
3203
3204#[doc(hidden)]
3205#[unstable(feature = "trusted_random_access", issue = "none")]
3206#[cfg(not(feature = "ferrocene_certified"))]
3207unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> {}
3208
3209#[doc(hidden)]
3210#[unstable(feature = "trusted_random_access", issue = "none")]
3211#[cfg(not(feature = "ferrocene_certified"))]
3212unsafe impl<'a, T> TrustedRandomAccessNoCoerce for IterMut<'a, T> {
3213 const MAY_HAVE_SIDE_EFFECT: bool = false;
3214}
3215
3216#[stable(feature = "slice_group_by", since = "1.77.0")]
3223#[must_use = "iterators are lazy and do nothing unless consumed"]
3224#[cfg(not(feature = "ferrocene_certified"))]
3225pub struct ChunkBy<'a, T: 'a, P> {
3226 slice: &'a [T],
3227 predicate: P,
3228}
3229
3230#[stable(feature = "slice_group_by", since = "1.77.0")]
3231#[cfg(not(feature = "ferrocene_certified"))]
3232impl<'a, T: 'a, P> ChunkBy<'a, T, P> {
3233 pub(super) const fn new(slice: &'a [T], predicate: P) -> Self {
3234 ChunkBy { slice, predicate }
3235 }
3236}
3237
3238#[stable(feature = "slice_group_by", since = "1.77.0")]
3239#[cfg(not(feature = "ferrocene_certified"))]
3240impl<'a, T: 'a, P> Iterator for ChunkBy<'a, T, P>
3241where
3242 P: FnMut(&T, &T) -> bool,
3243{
3244 type Item = &'a [T];
3245
3246 #[inline]
3247 fn next(&mut self) -> Option<Self::Item> {
3248 if self.slice.is_empty() {
3249 None
3250 } else {
3251 let mut len = 1;
3252 let mut iter = self.slice.windows(2);
3253 while let Some([l, r]) = iter.next() {
3254 if (self.predicate)(l, r) { len += 1 } else { break }
3255 }
3256 let (head, tail) = self.slice.split_at(len);
3257 self.slice = tail;
3258 Some(head)
3259 }
3260 }
3261
3262 #[inline]
3263 fn size_hint(&self) -> (usize, Option<usize>) {
3264 if self.slice.is_empty() { (0, Some(0)) } else { (1, Some(self.slice.len())) }
3265 }
3266
3267 #[inline]
3268 fn last(mut self) -> Option<Self::Item> {
3269 self.next_back()
3270 }
3271}
3272
3273#[stable(feature = "slice_group_by", since = "1.77.0")]
3274#[cfg(not(feature = "ferrocene_certified"))]
3275impl<'a, T: 'a, P> DoubleEndedIterator for ChunkBy<'a, T, P>
3276where
3277 P: FnMut(&T, &T) -> bool,
3278{
3279 #[inline]
3280 fn next_back(&mut self) -> Option<Self::Item> {
3281 if self.slice.is_empty() {
3282 None
3283 } else {
3284 let mut len = 1;
3285 let mut iter = self.slice.windows(2);
3286 while let Some([l, r]) = iter.next_back() {
3287 if (self.predicate)(l, r) { len += 1 } else { break }
3288 }
3289 let (head, tail) = self.slice.split_at(self.slice.len() - len);
3290 self.slice = head;
3291 Some(tail)
3292 }
3293 }
3294}
3295
3296#[stable(feature = "slice_group_by", since = "1.77.0")]
3297#[cfg(not(feature = "ferrocene_certified"))]
3298impl<'a, T: 'a, P> FusedIterator for ChunkBy<'a, T, P> where P: FnMut(&T, &T) -> bool {}
3299
3300#[stable(feature = "slice_group_by_clone", since = "1.89.0")]
3301#[cfg(not(feature = "ferrocene_certified"))]
3302impl<'a, T: 'a, P: Clone> Clone for ChunkBy<'a, T, P> {
3303 fn clone(&self) -> Self {
3304 Self { slice: self.slice, predicate: self.predicate.clone() }
3305 }
3306}
3307
3308#[stable(feature = "slice_group_by", since = "1.77.0")]
3309#[cfg(not(feature = "ferrocene_certified"))]
3310impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkBy<'a, T, P> {
3311 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3312 f.debug_struct("ChunkBy").field("slice", &self.slice).finish()
3313 }
3314}
3315
3316#[stable(feature = "slice_group_by", since = "1.77.0")]
3324#[must_use = "iterators are lazy and do nothing unless consumed"]
3325#[cfg(not(feature = "ferrocene_certified"))]
3326pub struct ChunkByMut<'a, T: 'a, P> {
3327 slice: &'a mut [T],
3328 predicate: P,
3329}
3330
3331#[stable(feature = "slice_group_by", since = "1.77.0")]
3332#[cfg(not(feature = "ferrocene_certified"))]
3333impl<'a, T: 'a, P> ChunkByMut<'a, T, P> {
3334 pub(super) const fn new(slice: &'a mut [T], predicate: P) -> Self {
3335 ChunkByMut { slice, predicate }
3336 }
3337}
3338
3339#[stable(feature = "slice_group_by", since = "1.77.0")]
3340#[cfg(not(feature = "ferrocene_certified"))]
3341impl<'a, T: 'a, P> Iterator for ChunkByMut<'a, T, P>
3342where
3343 P: FnMut(&T, &T) -> bool,
3344{
3345 type Item = &'a mut [T];
3346
3347 #[inline]
3348 fn next(&mut self) -> Option<Self::Item> {
3349 if self.slice.is_empty() {
3350 None
3351 } else {
3352 let mut len = 1;
3353 let mut iter = self.slice.windows(2);
3354 while let Some([l, r]) = iter.next() {
3355 if (self.predicate)(l, r) { len += 1 } else { break }
3356 }
3357 let slice = mem::take(&mut self.slice);
3358 let (head, tail) = slice.split_at_mut(len);
3359 self.slice = tail;
3360 Some(head)
3361 }
3362 }
3363
3364 #[inline]
3365 fn size_hint(&self) -> (usize, Option<usize>) {
3366 if self.slice.is_empty() { (0, Some(0)) } else { (1, Some(self.slice.len())) }
3367 }
3368
3369 #[inline]
3370 fn last(mut self) -> Option<Self::Item> {
3371 self.next_back()
3372 }
3373}
3374
3375#[stable(feature = "slice_group_by", since = "1.77.0")]
3376#[cfg(not(feature = "ferrocene_certified"))]
3377impl<'a, T: 'a, P> DoubleEndedIterator for ChunkByMut<'a, T, P>
3378where
3379 P: FnMut(&T, &T) -> bool,
3380{
3381 #[inline]
3382 fn next_back(&mut self) -> Option<Self::Item> {
3383 if self.slice.is_empty() {
3384 None
3385 } else {
3386 let mut len = 1;
3387 let mut iter = self.slice.windows(2);
3388 while let Some([l, r]) = iter.next_back() {
3389 if (self.predicate)(l, r) { len += 1 } else { break }
3390 }
3391 let slice = mem::take(&mut self.slice);
3392 let (head, tail) = slice.split_at_mut(slice.len() - len);
3393 self.slice = head;
3394 Some(tail)
3395 }
3396 }
3397}
3398
3399#[stable(feature = "slice_group_by", since = "1.77.0")]
3400#[cfg(not(feature = "ferrocene_certified"))]
3401impl<'a, T: 'a, P> FusedIterator for ChunkByMut<'a, T, P> where P: FnMut(&T, &T) -> bool {}
3402
3403#[stable(feature = "slice_group_by", since = "1.77.0")]
3404#[cfg(not(feature = "ferrocene_certified"))]
3405impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkByMut<'a, T, P> {
3406 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3407 f.debug_struct("ChunkByMut").field("slice", &self.slice).finish()
3408 }
3409}