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