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