#![allow(unstable_name_collisions)]
#![cfg_attr(
feature = "unstable",
feature(
trusted_len,
trusted_random_access,
min_specialization,
exact_size_is_empty
)
)]
#![no_std]
use core::{iter::FusedIterator, slice::IterMut};
#[derive(Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct ArrayChunks<'a, T: 'a, const N: usize> {
iter: core::slice::Iter<'a, [T; N]>,
rem: &'a [T],
}
impl<'a, T, const N: usize> ArrayChunks<'a, T, N> {
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
pub fn new(slice: &'a [T]) -> Self {
let (array_slice, rem) = slice.as_chunks();
Self {
iter: array_slice.iter(),
rem,
}
}
#[must_use]
pub fn remainder(&self) -> &'a [T] {
self.rem
}
}
impl<T, const N: usize> Clone for ArrayChunks<'_, T, N> {
fn clone(&self) -> Self {
ArrayChunks {
iter: self.iter.clone(),
rem: self.rem,
}
}
}
impl<'a, T, const N: usize> Iterator for ArrayChunks<'a, T, N> {
type Item = &'a [T; N];
#[inline]
fn next(&mut self) -> Option<&'a [T; N]> {
self.iter.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline]
fn count(self) -> usize {
self.iter.count()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth(n)
}
#[inline]
fn last(self) -> Option<Self::Item> {
self.iter.last()
}
#[cfg(feature = "unstable")]
unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> &'a [T; N] {
unsafe { self.iter.__iterator_get_unchecked(i) }
}
}
impl<'a, T, const N: usize> DoubleEndedIterator for ArrayChunks<'a, T, N> {
#[inline]
fn next_back(&mut self) -> Option<&'a [T; N]> {
self.iter.next_back()
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth_back(n)
}
}
impl<T, const N: usize> ExactSizeIterator for ArrayChunks<'_, T, N> {
#[cfg(feature = "unstable")]
fn is_empty(&self) -> bool {
self.iter.is_empty()
}
}
#[cfg(feature = "unstable")]
unsafe impl<T, const N: usize> core::iter::TrustedLen for ArrayChunks<'_, T, N> {}
impl<T, const N: usize> FusedIterator for ArrayChunks<'_, T, N> {}
#[doc(hidden)]
#[cfg(feature = "unstable")]
unsafe impl<'a, T, const N: usize> core::iter::TrustedRandomAccess for ArrayChunks<'a, T, N> {}
#[doc(hidden)]
#[cfg(feature = "unstable")]
unsafe impl<'a, T, const N: usize> core::iter::TrustedRandomAccessNoCoerce
for ArrayChunks<'a, T, N>
{
const MAY_HAVE_SIDE_EFFECT: bool = false;
}
#[derive(Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct ArrayChunksMut<'a, T: 'a, const N: usize> {
iter: IterMut<'a, [T; N]>,
rem: &'a mut [T],
}
impl<'a, T, const N: usize> ArrayChunksMut<'a, T, N> {
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
pub fn new(slice: &'a mut [T]) -> Self {
let (array_slice, rem) = slice.as_chunks_mut();
Self {
iter: array_slice.iter_mut(),
rem,
}
}
#[must_use = "`self` will be dropped if the result is not used"]
pub fn into_remainder(self) -> &'a mut [T] {
self.rem
}
}
impl<'a, T, const N: usize> Iterator for ArrayChunksMut<'a, T, N> {
type Item = &'a mut [T; N];
#[inline]
fn next(&mut self) -> Option<&'a mut [T; N]> {
self.iter.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline]
fn count(self) -> usize {
self.iter.count()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth(n)
}
#[inline]
fn last(self) -> Option<Self::Item> {
self.iter.last()
}
#[cfg(feature = "unstable")]
unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> &'a mut [T; N] {
unsafe { self.iter.__iterator_get_unchecked(i) }
}
}
impl<'a, T, const N: usize> DoubleEndedIterator for ArrayChunksMut<'a, T, N> {
#[inline]
fn next_back(&mut self) -> Option<&'a mut [T; N]> {
self.iter.next_back()
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth_back(n)
}
}
impl<T, const N: usize> ExactSizeIterator for ArrayChunksMut<'_, T, N> {
#[cfg(feature = "unstable")]
fn is_empty(&self) -> bool {
self.iter.is_empty()
}
}
#[cfg(feature = "unstable")]
unsafe impl<T, const N: usize> core::iter::TrustedLen for ArrayChunksMut<'_, T, N> {}
impl<T, const N: usize> FusedIterator for ArrayChunksMut<'_, T, N> {}
#[doc(hidden)]
#[cfg(feature = "unstable")]
unsafe impl<'a, T, const N: usize> core::iter::TrustedRandomAccess for ArrayChunksMut<'a, T, N> {}
#[doc(hidden)]
#[cfg(feature = "unstable")]
unsafe impl<'a, T, const N: usize> core::iter::TrustedRandomAccessNoCoerce
for ArrayChunksMut<'a, T, N>
{
const MAY_HAVE_SIDE_EFFECT: bool = false;
}
pub trait ExtensionTrait<T> {
#[track_caller]
fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>;
#[track_caller]
fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>;
}
impl<T> ExtensionTrait<T> for [T] {
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N> {
assert!(N != 0, "chunk size must be non-zero");
ArrayChunksMut::new(self)
}
#[inline]
#[cfg_attr(debug_assertions, track_caller)]
fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N> {
assert!(N != 0, "chunk size must be non-zero");
ArrayChunks::new(self)
}
}