use std::iter::FusedIterator;
use std::marker::PhantomData;
use imgref::Img;
use crate::iter::{Iter, IterMut, IterPtr, IterPtrMut};
mod ptr;
pub use ptr::*;
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub struct SimdIter<'a, T, const LANES: usize>(SimdIterPtr<T, LANES>, PhantomData<&'a [T]>);
#[allow(clippy::missing_safety_doc)]
impl<'a, T, const LANES: usize> SimdIter<'a, T, LANES> {
#[inline]
pub unsafe fn wrap(ptr: SimdIterPtr<T, LANES>) -> Self {
Self(ptr, PhantomData)
}
#[inline]
pub unsafe fn new(iter: Iter<'a, T>, gap: usize) -> Self {
Self::wrap(SimdIterPtr::new(iter.into_inner(), gap))
}
#[inline]
pub unsafe fn new_ptr(iter: IterPtr<T>, gap: usize) -> Self {
Self::wrap(SimdIterPtr::new(iter, gap))
}
#[inline]
pub fn rows<S: AsRef<[T]>>(buf: &Img<S>, row: usize) -> Self {
unsafe { Self::wrap(SimdIterPtr::rows(buf, row)) }
}
#[inline]
pub unsafe fn rows_ptr(buf: Img<*const [T]>, row: usize) -> Self {
Self::wrap(SimdIterPtr::rows_ptr(buf, row))
}
#[inline]
pub unsafe fn rows_ptr_unchecked(buf: Img<*const [T]>, row: usize) -> Self {
Self::wrap(SimdIterPtr::rows_ptr_unchecked(buf, row))
}
#[inline]
pub fn cols<S: AsRef<[T]>>(buf: &Img<S>, col: usize) -> Self {
unsafe { Self::wrap(SimdIterPtr::cols(buf, col)) }
}
#[inline]
pub unsafe fn cols_ptr(buf: Img<*const [T]>, col: usize) -> Self {
Self::wrap(SimdIterPtr::cols_ptr(buf, col))
}
#[inline]
pub unsafe fn cols_ptr_unchecked(buf: Img<*const [T]>, col: usize) -> Self {
Self::wrap(SimdIterPtr::cols_ptr_unchecked(buf, col))
}
#[inline]
pub fn into_inner(self) -> SimdIterPtr<T, LANES> {
self.0
}
}
impl<'a, T, const LANES: usize> Iterator for SimdIter<'a, T, LANES> {
type Item = [&'a T; LANES];
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|arr| arr.map(|ptr| unsafe { &*ptr }))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
impl<'a, T, const LANES: usize> DoubleEndedIterator for SimdIter<'a, T, LANES> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(|arr| arr.map(|ptr| unsafe { &*ptr }))
}
}
impl<'a, T, const LANES: usize> ExactSizeIterator for SimdIter<'a, T, LANES> {
#[inline]
fn len(&self) -> usize {
self.0.len()
}
}
impl<'a, T, const LANES: usize> FusedIterator for SimdIter<'a, T, LANES> {}
#[repr(transparent)]
#[derive(Eq, PartialEq, Debug)]
pub struct SimdIterMut<'a, T, const LANES: usize>(SimdIterPtrMut<T, LANES>, PhantomData<&'a mut [T]>);
#[allow(clippy::missing_safety_doc)]
impl<'a, T, const LANES: usize> SimdIterMut<'a, T, LANES> {
#[inline]
pub unsafe fn wrap(ptr: SimdIterPtrMut<T, LANES>) -> Self {
Self(ptr, PhantomData)
}
#[inline]
pub unsafe fn new(iter: IterMut<'a, T>, gap: usize) -> Self {
Self::wrap(SimdIterPtrMut::new(iter.into_inner(), gap))
}
#[inline]
pub unsafe fn new_ptr(iter: IterPtrMut<T>, gap: usize) -> Self {
Self::wrap(SimdIterPtrMut::new(iter, gap))
}
#[inline]
pub fn rows<S: AsMut<[T]>>(buf: &mut Img<S>, row: usize) -> Self {
unsafe { Self::wrap(SimdIterPtrMut::rows(buf, row)) }
}
#[inline]
pub unsafe fn rows_ptr(buf: Img<*mut [T]>, row: usize) -> Self {
Self::wrap(SimdIterPtrMut::rows_ptr(buf, row))
}
#[inline]
pub unsafe fn rows_ptr_unchecked(buf: Img<*mut [T]>, row: usize) -> Self {
Self::wrap(SimdIterPtrMut::rows_ptr_unchecked(buf, row))
}
#[inline]
pub fn cols<S: AsMut<[T]>>(buf: &mut Img<S>, col: usize) -> Self {
unsafe { Self::wrap(SimdIterPtrMut::cols(buf, col)) }
}
#[inline]
pub unsafe fn cols_ptr(buf: Img<*mut [T]>, col: usize) -> Self {
Self::wrap(SimdIterPtrMut::cols_ptr(buf, col))
}
#[inline]
pub unsafe fn cols_ptr_unchecked(buf: Img<*mut [T]>, col: usize) -> Self {
Self::wrap(SimdIterPtrMut::cols_ptr_unchecked(buf, col))
}
#[inline]
pub fn into_inner(self) -> SimdIterPtrMut<T, LANES> {
self.0
}
}
impl<'a, T, const LANES: usize> Iterator for SimdIterMut<'a, T, LANES> {
type Item = [&'a mut T; LANES];
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|arr| arr.map(|ptr| unsafe { &mut *ptr }))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
impl<'a, T, const LANES: usize> DoubleEndedIterator for SimdIterMut<'a, T, LANES> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(|arr| arr.map(|ptr| unsafe { &mut *ptr }))
}
}
impl<'a, T, const LANES: usize> ExactSizeIterator for SimdIterMut<'a, T, LANES> {
#[inline]
fn len(&self) -> usize {
self.0.len()
}
}
impl<'a, T, const LANES: usize> FusedIterator for SimdIterMut<'a, T, LANES> {}