1use std::iter::FusedIterator;
2use imgref::Img;
3use crate::iter::{IterPtr, IterPtrMut};
4
5#[derive(Copy, Clone, Eq, PartialEq, Debug)]
6pub struct SimdIterPtr<T, const LANES: usize>(IterPtr<T>, usize);
7
8impl<T, const LANES: usize> SimdIterPtr<T, LANES> {
9 #[inline]
19 pub unsafe fn new(iter: IterPtr<T>, gap: usize) -> Self {
20 Self(iter, gap)
21 }
22
23 #[inline]
34 pub unsafe fn rows<S: AsRef<[T]>>(buf: &Img<S>, row: usize) -> Self {
35 let (width, height, stride) = (buf.width(), buf.height(), buf.stride());
36 let buf = buf.buf().as_ref() as *const [T];
37 let buf = Img::new_stride(buf, width, height, stride);
38 Self::rows_ptr(buf, row)
39 }
40
41 #[inline]
55 pub unsafe fn rows_ptr(buf: Img<*const [T]>, row: usize) -> Self {
56 IterPtr::assert_slice_enough(buf);
57 assert!(row + LANES <= buf.height());
58 Self::rows_ptr_unchecked(buf, row)
59 }
60
61 #[inline]
70 pub unsafe fn rows_ptr_unchecked(buf: Img<*const [T]>, row: usize) -> Self {
71 let gap = buf.stride();
72 Self::new(IterPtr::row_ptr(buf, row), gap)
73 }
74
75 #[inline]
86 pub unsafe fn cols<S: AsRef<[T]>>(buf: &Img<S>, col: usize) -> Self {
87 let (width, height, stride) = (buf.width(), buf.height(), buf.stride());
88 let buf = buf.buf().as_ref() as *const [T];
89 let buf = Img::new_stride(buf, width, height, stride);
90 Self::cols_ptr(buf, col)
91 }
92
93 #[inline]
107 pub unsafe fn cols_ptr(buf: Img<*const [T]>, col: usize) -> Self {
108 IterPtr::assert_slice_enough(buf);
109 assert!(col + LANES <= buf.width());
110 Self::cols_ptr_unchecked(buf, col)
111 }
112
113 #[inline]
122 pub unsafe fn cols_ptr_unchecked(buf: Img<*const [T]>, col: usize) -> Self {
123 Self::new(IterPtr::col_ptr(buf, col), 1)
124 }
125
126 pub fn into_inner(self) -> IterPtr<T> {
128 self.0
129 }
130
131 #[inline]
132 fn expand(&self, one: *const T) -> [*const T; LANES] {
133 let mut countup = 0usize..;
134 [(); LANES].map(move |_| unsafe { one.add(self.1 * countup.next().unwrap()) })
135 }
136}
137
138impl<T, const LANES: usize> Iterator for SimdIterPtr<T, LANES> {
139 type Item = [*const T; LANES];
140
141 #[inline]
142 fn next(&mut self) -> Option<Self::Item> {
143 self.0.next().map(|ptr| self.expand(ptr))
144 }
145
146 #[inline]
147 fn size_hint(&self) -> (usize, Option<usize>) {
148 self.0.size_hint()
149 }
150}
151
152impl<T, const LANES: usize> DoubleEndedIterator for SimdIterPtr<T, LANES> {
153 #[inline]
154 fn next_back(&mut self) -> Option<Self::Item> {
155 self.0.next_back().map(|ptr| self.expand(ptr))
156 }
157}
158
159impl<T, const LANES: usize> ExactSizeIterator for SimdIterPtr<T, LANES> {
160 #[inline]
161 fn len(&self) -> usize {
162 self.0.len()
163 }
164}
165
166impl<T, const LANES: usize> FusedIterator for SimdIterPtr<T, LANES> {}
167
168#[derive(Copy, Clone, Eq, PartialEq, Debug)]
169pub struct SimdIterPtrMut<T, const LANES: usize>(IterPtrMut<T>, usize);
170
171impl<T, const LANES: usize> SimdIterPtrMut<T, LANES> {
172 #[inline]
182 pub unsafe fn new(iter: IterPtrMut<T>, gap: usize) -> Self {
183 Self(iter, gap)
184 }
185
186 #[inline]
197 pub unsafe fn rows<S: AsMut<[T]>>(buf: &mut Img<S>, row: usize) -> Self {
198 let (width, height, stride) = (buf.width(), buf.height(), buf.stride());
199 let buf = buf.buf_mut().as_mut() as *mut [T];
200 let buf = Img::new_stride(buf, width, height, stride);
201 Self::rows_ptr(buf, row)
202 }
203
204 #[inline]
218 pub unsafe fn rows_ptr(buf: Img<*mut [T]>, row: usize) -> Self {
219 IterPtrMut::assert_slice_enough(buf);
220 assert!(row + LANES <= buf.height());
221 Self::rows_ptr_unchecked(buf, row)
222 }
223
224 #[inline]
233 pub unsafe fn rows_ptr_unchecked(buf: Img<*mut [T]>, row: usize) -> Self {
234 let gap = buf.stride();
235 Self::new(IterPtrMut::row_ptr(buf, row), gap)
236 }
237
238 #[inline]
249 pub unsafe fn cols<S: AsMut<[T]>>(buf: &mut Img<S>, col: usize) -> Self {
250 let (width, height, stride) = (buf.width(), buf.height(), buf.stride());
251 let buf = buf.buf_mut().as_mut() as *mut [T];
252 let buf = Img::new_stride(buf, width, height, stride);
253 Self::cols_ptr(buf, col)
254 }
255
256 #[inline]
270 pub unsafe fn cols_ptr(buf: Img<*mut [T]>, col: usize) -> Self {
271 IterPtrMut::assert_slice_enough(buf);
272 assert!(col + LANES <= buf.width());
273 Self::cols_ptr_unchecked(buf, col)
274 }
275
276 #[inline]
285 pub unsafe fn cols_ptr_unchecked(buf: Img<*mut [T]>, col: usize) -> Self {
286 Self::new(IterPtrMut::col_ptr(buf, col), 1)
287 }
288
289 pub fn into_inner(self) -> IterPtrMut<T> {
291 self.0
292 }
293
294 #[inline]
295 fn expand(&self, one: *mut T) -> [*mut T; LANES] {
296 let mut countup = 0usize..;
297 [(); LANES].map(move |_| unsafe { one.add(self.1 * countup.next().unwrap()) })
298 }
299}
300
301impl<T, const LANES: usize> Iterator for SimdIterPtrMut<T, LANES> {
302 type Item = [*mut T; LANES];
303
304 #[inline]
305 fn next(&mut self) -> Option<Self::Item> {
306 self.0.next().map(|ptr| self.expand(ptr))
307 }
308
309 #[inline]
310 fn size_hint(&self) -> (usize, Option<usize>) {
311 self.0.size_hint()
312 }
313}
314
315impl<T, const LANES: usize> DoubleEndedIterator for SimdIterPtrMut<T, LANES> {
316 #[inline]
317 fn next_back(&mut self) -> Option<Self::Item> {
318 self.0.next_back().map(|ptr| self.expand(ptr))
319 }
320}
321
322impl<T, const LANES: usize> ExactSizeIterator for SimdIterPtrMut<T, LANES> {
323 #[inline]
324 fn len(&self) -> usize {
325 self.0.len()
326 }
327}
328
329impl<T, const LANES: usize> FusedIterator for SimdIterPtrMut<T, LANES> {}