imgref_iter/iter/simd_windows/
mod.rs

1use std::iter::FusedIterator;
2use std::marker::PhantomData;
3use imgref::Img;
4use crate::iter::{Iter, IterMut, SimdIter, SimdIterMut};
5
6mod ptr;
7
8pub use ptr::*;
9
10#[repr(transparent)]
11#[derive(Clone, Eq, PartialEq, Debug)]
12pub struct SimdIterWindows<'a, T, const LANES: usize>(SimdIterWindowsPtr<T, LANES>, PhantomData<&'a [T]>);
13
14impl<'a, T, const LANES: usize> SimdIterWindows<'a, T, LANES> {
15	/// Wraps an [`SimdIterWindowsPtr`] in an [`SimdIterWindows`].
16	///
17	/// # Safety
18	///
19	/// The [`SimdIterWindowsPtr`] must be valid for reads and shared references.
20	#[inline]
21	pub unsafe fn wrap(ptr: SimdIterWindowsPtr<T, LANES>) -> Self {
22		Self(ptr, PhantomData)
23	}
24
25	/// Creates a new [`SimdIterWindows`] over the rows of an [`Img`].
26	#[inline]
27	pub fn rows<S: AsRef<[T]>>(buf: &'a Img<S>) -> Self {
28		unsafe { Self::wrap(SimdIterWindowsPtr::rows(buf)) }
29	}
30
31	/// Creates a new [`SimdIterWindows`] over the cols of an [`Img`].
32	#[inline]
33	pub fn cols<S: AsRef<[T]>>(buf: &'a Img<S>) -> Self {
34		unsafe { Self::wrap(SimdIterWindowsPtr::cols(buf)) }
35	}
36}
37
38#[derive(Clone, Eq, PartialEq, Debug)]
39pub enum SimdIterWindow<'a, T, const LANES: usize> {
40	Simd(SimdIter<'a, T, LANES>),
41	Single(Iter<'a, T>)
42}
43
44impl<'a, T, const LANES: usize> SimdIterWindow<'a, T, LANES> {
45	#[inline]
46	pub unsafe fn wrap(other: SimdIterWindowPtr<T, LANES>) -> Self {
47		match other {
48			SimdIterWindowPtr::Simd(simd) => Self::Simd(SimdIter::wrap(simd)),
49			SimdIterWindowPtr::Single(iter) => Self::Single(Iter::wrap(iter))
50		}
51	}
52}
53
54impl<'a, T, const LANES: usize> Iterator for SimdIterWindows<'a, T, LANES> {
55	type Item = SimdIterWindow<'a, T, LANES>;
56
57	#[inline]
58	fn next(&mut self) -> Option<Self::Item> {
59		self.0.next().map(|window| unsafe { SimdIterWindow::wrap(window) })
60	}
61
62	#[inline]
63	fn size_hint(&self) -> (usize, Option<usize>) {
64		let len = self.len();
65		(len, Some(len))
66	}
67}
68
69impl<'a, T, const LANES: usize> DoubleEndedIterator for SimdIterWindows<'a, T, LANES> {
70	#[inline]
71	fn next_back(&mut self) -> Option<Self::Item> {
72		self.0.next_back().map(|window| unsafe { SimdIterWindow::wrap(window) })
73	}
74}
75
76impl<'a, T, const LANES: usize> ExactSizeIterator for SimdIterWindows<'a, T, LANES> {
77	#[inline]
78	fn len(&self) -> usize {
79		self.0.len()
80	}
81}
82
83impl<'a, T, const LANES: usize> FusedIterator for SimdIterWindows<'a, T, LANES> {}
84
85#[repr(transparent)]
86#[derive(Eq, PartialEq, Debug)]
87pub struct SimdIterWindowsMut<'a, T, const LANES: usize>(SimdIterWindowsPtrMut<T, LANES>, PhantomData<&'a [T]>);
88
89impl<'a, T, const LANES: usize> SimdIterWindowsMut<'a, T, LANES> {
90	/// Wraps an [`SimdIterWindowsPtrMut`] in an [`SimdIterWindowsMut`].
91	///
92	/// # Safety
93	///
94	/// The [`SimdIterWindowsPtrMut`] must be valid for reads and shared references.
95	#[inline]
96	pub unsafe fn wrap(ptr: SimdIterWindowsPtrMut<T, LANES>) -> Self {
97		Self(ptr, PhantomData)
98	}
99
100	/// Creates a new [`SimdIterWindowsMut`] over the rows of an [`Img`].
101	#[inline]
102	pub fn rows<S: AsMut<[T]>>(buf: &'a mut Img<S>) -> Self {
103		unsafe { Self::wrap(SimdIterWindowsPtrMut::rows(buf)) }
104	}
105
106	/// Creates a new [`SimdIterWindowsMut`] over the cols of an [`Img`].
107	#[inline]
108	pub fn cols<S: AsMut<[T]>>(buf: &'a mut Img<S>) -> Self {
109		unsafe { Self::wrap(SimdIterWindowsPtrMut::cols(buf)) }
110	}
111}
112
113#[derive(Eq, PartialEq, Debug)]
114pub enum SimdIterWindowMut<'a, T, const LANES: usize> {
115	Simd(SimdIterMut<'a, T, LANES>),
116	Single(IterMut<'a, T>)
117}
118
119impl<'a, T, const LANES: usize> SimdIterWindowMut<'a, T, LANES> {
120	#[inline]
121	pub unsafe fn wrap(other: SimdIterWindowPtrMut<T, LANES>) -> Self {
122		match other {
123			SimdIterWindowPtrMut::Simd(simd) => Self::Simd(SimdIterMut::wrap(simd)),
124			SimdIterWindowPtrMut::Single(iter) => Self::Single(IterMut::wrap(iter))
125		}
126	}
127}
128
129impl<'a, T, const LANES: usize> Iterator for SimdIterWindowsMut<'a, T, LANES> {
130	type Item = SimdIterWindowMut<'a, T, LANES>;
131
132	#[inline]
133	fn next(&mut self) -> Option<Self::Item> {
134		self.0.next().map(|window| unsafe { SimdIterWindowMut::wrap(window) })
135	}
136
137	#[inline]
138	fn size_hint(&self) -> (usize, Option<usize>) {
139		let len = self.len();
140		(len, Some(len))
141	}
142}
143
144impl<'a, T, const LANES: usize> DoubleEndedIterator for SimdIterWindowsMut<'a, T, LANES> {
145	#[inline]
146	fn next_back(&mut self) -> Option<Self::Item> {
147		self.0.next_back().map(|window| unsafe { SimdIterWindowMut::wrap(window) })
148	}
149}
150
151impl<'a, T, const LANES: usize> ExactSizeIterator for SimdIterWindowsMut<'a, T, LANES> {
152	#[inline]
153	fn len(&self) -> usize {
154		self.0.len()
155	}
156}
157
158impl<'a, T, const LANES: usize> FusedIterator for SimdIterWindowsMut<'a, T, LANES> {}