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