@@ -123,6 +123,8 @@ pub use core::slice::{from_raw_parts, from_raw_parts_mut};
123123pub use core:: slice:: { from_ref, from_ref_mut} ;
124124#[ unstable( feature = "slice_get_slice" , issue = "35729" ) ]
125125pub use core:: slice:: SliceIndex ;
126+ #[ unstable( feature = "exact_chunks" , issue = "47115" ) ]
127+ pub use core:: slice:: { ExactChunks , ExactChunksMut } ;
126128
127129////////////////////////////////////////////////////////////////////////////////
128130// Basic slice extension methods
@@ -611,6 +613,9 @@ impl<T> [T] {
611613 /// not divide the length of the slice, then the last chunk will
612614 /// not have length `chunk_size`.
613615 ///
616+ /// See [`exact_chunks`] for a variant of this iterator that returns chunks
617+ /// of always exactly `chunk_size` elements.
618+ ///
614619 /// # Panics
615620 ///
616621 /// Panics if `chunk_size` is 0.
@@ -631,11 +636,44 @@ impl<T> [T] {
631636 core_slice:: SliceExt :: chunks ( self , chunk_size)
632637 }
633638
639+ /// Returns an iterator over `chunk_size` elements of the slice at a
640+ /// time. The chunks are slices and do not overlap. If `chunk_size` does
641+ /// not divide the length of the slice, then the last up to `chunk_size-1`
642+ /// elements will be omitted.
643+ ///
644+ /// Due to each chunk having exactly `chunk_size` elements, the compiler
645+ /// can often optimize the resulting code better than in the case of
646+ /// [`chunks`].
647+ ///
648+ /// # Panics
649+ ///
650+ /// Panics if `chunk_size` is 0.
651+ ///
652+ /// # Examples
653+ ///
654+ /// ```
655+ /// #![feature(exact_chunks)]
656+ ///
657+ /// let slice = ['l', 'o', 'r', 'e', 'm'];
658+ /// let mut iter = slice.exact_chunks(2);
659+ /// assert_eq!(iter.next().unwrap(), &['l', 'o']);
660+ /// assert_eq!(iter.next().unwrap(), &['r', 'e']);
661+ /// assert!(iter.next().is_none());
662+ /// ```
663+ #[ unstable( feature = "exact_chunks" , issue = "47115" ) ]
664+ #[ inline]
665+ pub fn exact_chunks ( & self , chunk_size : usize ) -> ExactChunks < T > {
666+ core_slice:: SliceExt :: exact_chunks ( self , chunk_size)
667+ }
668+
634669 /// Returns an iterator over `chunk_size` elements of the slice at a time.
635670 /// The chunks are mutable slices, and do not overlap. If `chunk_size` does
636671 /// not divide the length of the slice, then the last chunk will not
637672 /// have length `chunk_size`.
638673 ///
674+ /// See [`exact_chunks_mut`] for a variant of this iterator that returns chunks
675+ /// of always exactly `chunk_size` elements.
676+ ///
639677 /// # Panics
640678 ///
641679 /// Panics if `chunk_size` is 0.
@@ -660,6 +698,42 @@ impl<T> [T] {
660698 core_slice:: SliceExt :: chunks_mut ( self , chunk_size)
661699 }
662700
701+ /// Returns an iterator over `chunk_size` elements of the slice at a time.
702+ /// The chunks are mutable slices, and do not overlap. If `chunk_size` does
703+ /// not divide the length of the slice, then the last up to `chunk_size-1`
704+ /// elements will be omitted.
705+ ///
706+ ///
707+ /// Due to each chunk having exactly `chunk_size` elements, the compiler
708+ /// can often optimize the resulting code better than in the case of
709+ /// [`chunks_mut`].
710+ ///
711+ /// # Panics
712+ ///
713+ /// Panics if `chunk_size` is 0.
714+ ///
715+ /// # Examples
716+ ///
717+ /// ```
718+ /// #![feature(exact_chunks)]
719+ ///
720+ /// let v = &mut [0, 0, 0, 0, 0];
721+ /// let mut count = 1;
722+ ///
723+ /// for chunk in v.exact_chunks_mut(2) {
724+ /// for elem in chunk.iter_mut() {
725+ /// *elem += count;
726+ /// }
727+ /// count += 1;
728+ /// }
729+ /// assert_eq!(v, &[1, 1, 2, 2, 0]);
730+ /// ```
731+ #[ unstable( feature = "exact_chunks" , issue = "47115" ) ]
732+ #[ inline]
733+ pub fn exact_chunks_mut ( & mut self , chunk_size : usize ) -> ExactChunksMut < T > {
734+ core_slice:: SliceExt :: exact_chunks_mut ( self , chunk_size)
735+ }
736+
663737 /// Divides one slice into two at an index.
664738 ///
665739 /// The first will contain all indices from `[0, mid)` (excluding
0 commit comments