1use std::iter::FusedIterator;
2use std::marker::PhantomData;
3use imgref::Img;
4use crate::iter::{Iter, IterMut, IterPtr, IterPtrMut};
5
6mod ptr;
7
8pub use ptr::*;
9
10#[repr(transparent)]
11#[derive(Copy, Clone, Eq, PartialEq, Debug)]
12pub struct SimdIter<'a, T, const LANES: usize>(SimdIterPtr<T, LANES>, PhantomData<&'a [T]>);
13
14#[allow(clippy::missing_safety_doc)]
15impl<'a, T, const LANES: usize> SimdIter<'a, T, LANES> {
16 #[inline]
22 pub unsafe fn wrap(ptr: SimdIterPtr<T, LANES>) -> Self {
23 Self(ptr, PhantomData)
24 }
25
26 #[inline]
36 pub unsafe fn new(iter: Iter<'a, T>, gap: usize) -> Self {
37 Self::wrap(SimdIterPtr::new(iter.into_inner(), gap))
38 }
39
40 #[inline]
50 pub unsafe fn new_ptr(iter: IterPtr<T>, gap: usize) -> Self {
51 Self::wrap(SimdIterPtr::new(iter, gap))
52 }
53
54 #[inline]
60 pub fn rows<S: AsRef<[T]>>(buf: &Img<S>, row: usize) -> Self {
61 unsafe { Self::wrap(SimdIterPtr::rows(buf, row)) }
62 }
63
64 #[inline]
75 pub unsafe fn rows_ptr(buf: Img<*const [T]>, row: usize) -> Self {
76 Self::wrap(SimdIterPtr::rows_ptr(buf, row))
77 }
78
79 #[inline]
88 pub unsafe fn rows_ptr_unchecked(buf: Img<*const [T]>, row: usize) -> Self {
89 Self::wrap(SimdIterPtr::rows_ptr_unchecked(buf, row))
90 }
91
92 #[inline]
98 pub fn cols<S: AsRef<[T]>>(buf: &Img<S>, col: usize) -> Self {
99 unsafe { Self::wrap(SimdIterPtr::cols(buf, col)) }
100 }
101
102 #[inline]
113 pub unsafe fn cols_ptr(buf: Img<*const [T]>, col: usize) -> Self {
114 Self::wrap(SimdIterPtr::cols_ptr(buf, col))
115 }
116
117 #[inline]
126 pub unsafe fn cols_ptr_unchecked(buf: Img<*const [T]>, col: usize) -> Self {
127 Self::wrap(SimdIterPtr::cols_ptr_unchecked(buf, col))
128 }
129
130 #[inline]
132 pub fn into_inner(self) -> SimdIterPtr<T, LANES> {
133 self.0
134 }
135}
136
137impl<'a, T, const LANES: usize> Iterator for SimdIter<'a, T, LANES> {
138 type Item = [&'a T; LANES];
139
140 #[inline]
141 fn next(&mut self) -> Option<Self::Item> {
142 self.0.next().map(|arr| arr.map(|ptr| unsafe { &*ptr }))
143 }
144
145 #[inline]
146 fn size_hint(&self) -> (usize, Option<usize>) {
147 self.0.size_hint()
148 }
149}
150
151impl<'a, T, const LANES: usize> DoubleEndedIterator for SimdIter<'a, T, LANES> {
152 #[inline]
153 fn next_back(&mut self) -> Option<Self::Item> {
154 self.0.next_back().map(|arr| arr.map(|ptr| unsafe { &*ptr }))
155 }
156}
157
158impl<'a, T, const LANES: usize> ExactSizeIterator for SimdIter<'a, T, LANES> {
159 #[inline]
160 fn len(&self) -> usize {
161 self.0.len()
162 }
163}
164
165impl<'a, T, const LANES: usize> FusedIterator for SimdIter<'a, T, LANES> {}
166
167#[repr(transparent)]
168#[derive(Eq, PartialEq, Debug)]
169pub struct SimdIterMut<'a, T, const LANES: usize>(SimdIterPtrMut<T, LANES>, PhantomData<&'a mut [T]>);
170
171#[allow(clippy::missing_safety_doc)]
172impl<'a, T, const LANES: usize> SimdIterMut<'a, T, LANES> {
173 #[inline]
179 pub unsafe fn wrap(ptr: SimdIterPtrMut<T, LANES>) -> Self {
180 Self(ptr, PhantomData)
181 }
182
183 #[inline]
193 pub unsafe fn new(iter: IterMut<'a, T>, gap: usize) -> Self {
194 Self::wrap(SimdIterPtrMut::new(iter.into_inner(), gap))
195 }
196
197 #[inline]
207 pub unsafe fn new_ptr(iter: IterPtrMut<T>, gap: usize) -> Self {
208 Self::wrap(SimdIterPtrMut::new(iter, gap))
209 }
210
211 #[inline]
217 pub fn rows<S: AsMut<[T]>>(buf: &mut Img<S>, row: usize) -> Self {
218 unsafe { Self::wrap(SimdIterPtrMut::rows(buf, row)) }
219 }
220
221 #[inline]
232 pub unsafe fn rows_ptr(buf: Img<*mut [T]>, row: usize) -> Self {
233 Self::wrap(SimdIterPtrMut::rows_ptr(buf, row))
234 }
235
236 #[inline]
245 pub unsafe fn rows_ptr_unchecked(buf: Img<*mut [T]>, row: usize) -> Self {
246 Self::wrap(SimdIterPtrMut::rows_ptr_unchecked(buf, row))
247 }
248
249 #[inline]
255 pub fn cols<S: AsMut<[T]>>(buf: &mut Img<S>, col: usize) -> Self {
256 unsafe { Self::wrap(SimdIterPtrMut::cols(buf, col)) }
257 }
258
259 #[inline]
270 pub unsafe fn cols_ptr(buf: Img<*mut [T]>, col: usize) -> Self {
271 Self::wrap(SimdIterPtrMut::cols_ptr(buf, col))
272 }
273
274 #[inline]
283 pub unsafe fn cols_ptr_unchecked(buf: Img<*mut [T]>, col: usize) -> Self {
284 Self::wrap(SimdIterPtrMut::cols_ptr_unchecked(buf, col))
285 }
286
287 #[inline]
289 pub fn into_inner(self) -> SimdIterPtrMut<T, LANES> {
290 self.0
291 }
292}
293
294impl<'a, T, const LANES: usize> Iterator for SimdIterMut<'a, T, LANES> {
295 type Item = [&'a mut T; LANES];
296
297 #[inline]
298 fn next(&mut self) -> Option<Self::Item> {
299 self.0.next().map(|arr| arr.map(|ptr| unsafe { &mut *ptr }))
300 }
301
302 #[inline]
303 fn size_hint(&self) -> (usize, Option<usize>) {
304 self.0.size_hint()
305 }
306}
307
308impl<'a, T, const LANES: usize> DoubleEndedIterator for SimdIterMut<'a, T, LANES> {
309 #[inline]
310 fn next_back(&mut self) -> Option<Self::Item> {
311 self.0.next_back().map(|arr| arr.map(|ptr| unsafe { &mut *ptr }))
312 }
313}
314
315impl<'a, T, const LANES: usize> ExactSizeIterator for SimdIterMut<'a, T, LANES> {
316 #[inline]
317 fn len(&self) -> usize {
318 self.0.len()
319 }
320}
321
322impl<'a, T, const LANES: usize> FusedIterator for SimdIterMut<'a, T, LANES> {}