use std::iter::FusedIterator;
use std::marker::PhantomData;
use imgref::Img;
use crate::iter::{Iter, IterMut, SimdIter, SimdIterMut};
mod ptr;
pub use ptr::*;
#[repr(transparent)]
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct SimdIterWindows<'a, T, const LANES: usize>(SimdIterWindowsPtr<T, LANES>, PhantomData<&'a [T]>);
impl<'a, T, const LANES: usize> SimdIterWindows<'a, T, LANES> {
#[inline]
pub unsafe fn wrap(ptr: SimdIterWindowsPtr<T, LANES>) -> Self {
Self(ptr, PhantomData)
}
#[inline]
pub fn rows<S: AsRef<[T]>>(buf: &'a Img<S>) -> Self {
unsafe { Self::wrap(SimdIterWindowsPtr::rows(buf)) }
}
#[inline]
pub fn cols<S: AsRef<[T]>>(buf: &'a Img<S>) -> Self {
unsafe { Self::wrap(SimdIterWindowsPtr::cols(buf)) }
}
}
#[derive(Clone, Eq, PartialEq, Debug)]
pub enum SimdIterWindow<'a, T, const LANES: usize> {
Simd(SimdIter<'a, T, LANES>),
Single(Iter<'a, T>)
}
impl<'a, T, const LANES: usize> SimdIterWindow<'a, T, LANES> {
#[inline]
pub unsafe fn wrap(other: SimdIterWindowPtr<T, LANES>) -> Self {
match other {
SimdIterWindowPtr::Simd(simd) => Self::Simd(SimdIter::wrap(simd)),
SimdIterWindowPtr::Single(iter) => Self::Single(Iter::wrap(iter))
}
}
}
impl<'a, T, const LANES: usize> Iterator for SimdIterWindows<'a, T, LANES> {
type Item = SimdIterWindow<'a, T, LANES>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|window| unsafe { SimdIterWindow::wrap(window) })
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
}
impl<'a, T, const LANES: usize> DoubleEndedIterator for SimdIterWindows<'a, T, LANES> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(|window| unsafe { SimdIterWindow::wrap(window) })
}
}
impl<'a, T, const LANES: usize> ExactSizeIterator for SimdIterWindows<'a, T, LANES> {
#[inline]
fn len(&self) -> usize {
self.0.len()
}
}
impl<'a, T, const LANES: usize> FusedIterator for SimdIterWindows<'a, T, LANES> {}
#[repr(transparent)]
#[derive(Eq, PartialEq, Debug)]
pub struct SimdIterWindowsMut<'a, T, const LANES: usize>(SimdIterWindowsPtrMut<T, LANES>, PhantomData<&'a [T]>);
impl<'a, T, const LANES: usize> SimdIterWindowsMut<'a, T, LANES> {
#[inline]
pub unsafe fn wrap(ptr: SimdIterWindowsPtrMut<T, LANES>) -> Self {
Self(ptr, PhantomData)
}
#[inline]
pub fn rows<S: AsMut<[T]>>(buf: &'a mut Img<S>) -> Self {
unsafe { Self::wrap(SimdIterWindowsPtrMut::rows(buf)) }
}
#[inline]
pub fn cols<S: AsMut<[T]>>(buf: &'a mut Img<S>) -> Self {
unsafe { Self::wrap(SimdIterWindowsPtrMut::cols(buf)) }
}
}
#[derive(Eq, PartialEq, Debug)]
pub enum SimdIterWindowMut<'a, T, const LANES: usize> {
Simd(SimdIterMut<'a, T, LANES>),
Single(IterMut<'a, T>)
}
impl<'a, T, const LANES: usize> SimdIterWindowMut<'a, T, LANES> {
#[inline]
pub unsafe fn wrap(other: SimdIterWindowPtrMut<T, LANES>) -> Self {
match other {
SimdIterWindowPtrMut::Simd(simd) => Self::Simd(SimdIterMut::wrap(simd)),
SimdIterWindowPtrMut::Single(iter) => Self::Single(IterMut::wrap(iter))
}
}
}
impl<'a, T, const LANES: usize> Iterator for SimdIterWindowsMut<'a, T, LANES> {
type Item = SimdIterWindowMut<'a, T, LANES>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|window| unsafe { SimdIterWindowMut::wrap(window) })
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
}
impl<'a, T, const LANES: usize> DoubleEndedIterator for SimdIterWindowsMut<'a, T, LANES> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back().map(|window| unsafe { SimdIterWindowMut::wrap(window) })
}
}
impl<'a, T, const LANES: usize> ExactSizeIterator for SimdIterWindowsMut<'a, T, LANES> {
#[inline]
fn len(&self) -> usize {
self.0.len()
}
}
impl<'a, T, const LANES: usize> FusedIterator for SimdIterWindowsMut<'a, T, LANES> {}