faer/col/
mod.rs

1use crate::internal_prelude::*;
2use crate::utils::bound::{One, Zero};
3use core::ptr::NonNull;
4
5/// represents a type that can be used to slice a column, such as an index or a range of indices
6pub trait ColIndex<RowRange> {
7	/// sliced view type
8	type Target;
9
10	/// slice `this` using `row`
11	fn get(this: Self, row: RowRange) -> Self::Target;
12	/// slice `this` using `row`, without bound checks
13	unsafe fn get_unchecked(this: Self, row: RowRange) -> Self::Target;
14}
15
16struct ColView<T: ?Sized, Rows, RStride> {
17	ptr: NonNull<T>,
18	nrows: Rows,
19	row_stride: RStride,
20}
21
22impl<T: ?Sized, Rows: Copy, RStride: Copy> Copy for ColView<T, Rows, RStride> {}
23impl<T: ?Sized, Rows: Copy, RStride: Copy> Clone for ColView<T, Rows, RStride> {
24	#[inline]
25	fn clone(&self) -> Self {
26		*self
27	}
28}
29
30mod col_index;
31
32pub(crate) mod colmut;
33pub(crate) mod colown;
34pub(crate) mod colref;
35
36pub use colmut::Mut;
37pub use colown::Own;
38pub use colref::Ref;
39use mat::AsMat;
40
41/// immutable view over a column vector, similar to an immutable reference to a strided
42/// [prim@slice]
43///
44/// # note
45///
46/// unlike a slice, the data pointed to by `ColRef<'_, T>` is allowed to be partially or fully
47/// uninitialized under certain conditions. in this case, care must be taken to not perform any
48/// operations that read the uninitialized values, or form references to them, either directly or
49/// indirectly through any of the numerical library routines, unless it is explicitly permitted
50pub type ColRef<'a, T, Rows = usize, RStride = isize> = generic::Col<Ref<'a, T, Rows, RStride>>;
51
52/// mutable view over a column vector, similar to a mutable reference to a strided
53/// [prim@slice]
54///
55/// # note
56///
57/// unlike a slice, the data pointed to by `ColMut<'_, T>` is allowed to be partially or fully
58/// uninitialized under certain conditions. in this case, care must be taken to not perform any
59/// operations that read the uninitialized values, or form references to them, either directly or
60/// indirectly through any of the numerical library routines, unless it is explicitly permitted
61pub type ColMut<'a, T, Rows = usize, RStride = isize> = generic::Col<Mut<'a, T, Rows, RStride>>;
62
63/// heap allocated resizable column vector.
64///
65/// # note
66///
67/// the memory layout of `Col` is guaranteed to be column-major, meaning that it has a row stride
68/// of `1`.
69pub type Col<T, Rows = usize> = generic::Col<Own<T, Rows>>;
70
71/// generic `Col` wrapper
72pub mod generic {
73	use crate::{Idx, Shape, Stride};
74	use core::fmt::Debug;
75	use core::ops::{Index, IndexMut};
76	use reborrow::*;
77
78	/// generic `Col` wrapper
79	#[derive(Copy, Clone)]
80	#[repr(transparent)]
81	pub struct Col<Inner>(pub Inner);
82
83	impl<Inner: Debug> Debug for Col<Inner> {
84		#[inline(always)]
85		fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
86			self.0.fmt(f)
87		}
88	}
89
90	impl<Inner> Col<Inner> {
91		/// wrap by reference
92		#[inline(always)]
93		pub fn from_inner_ref(inner: &Inner) -> &Self {
94			unsafe { &*(inner as *const Inner as *const Self) }
95		}
96
97		/// wrap by mutable reference
98		#[inline(always)]
99		pub fn from_inner_mut(inner: &mut Inner) -> &mut Self {
100			unsafe { &mut *(inner as *mut Inner as *mut Self) }
101		}
102	}
103
104	impl<Inner> core::ops::Deref for Col<Inner> {
105		type Target = Inner;
106
107		#[inline(always)]
108		fn deref(&self) -> &Self::Target {
109			&self.0
110		}
111	}
112
113	impl<Inner> core::ops::DerefMut for Col<Inner> {
114		#[inline(always)]
115		fn deref_mut(&mut self) -> &mut Self::Target {
116			&mut self.0
117		}
118	}
119
120	impl<'short, Inner: Reborrow<'short>> Reborrow<'short> for Col<Inner> {
121		type Target = Col<Inner::Target>;
122
123		#[inline(always)]
124		fn rb(&'short self) -> Self::Target {
125			Col(self.0.rb())
126		}
127	}
128
129	impl<'short, Inner: ReborrowMut<'short>> ReborrowMut<'short> for Col<Inner> {
130		type Target = Col<Inner::Target>;
131
132		#[inline(always)]
133		fn rb_mut(&'short mut self) -> Self::Target {
134			Col(self.0.rb_mut())
135		}
136	}
137
138	impl<Inner: IntoConst> IntoConst for Col<Inner> {
139		type Target = Col<Inner::Target>;
140
141		#[inline(always)]
142		fn into_const(self) -> Self::Target {
143			Col(self.0.into_const())
144		}
145	}
146
147	impl<T, Rows: Shape, RStride: Stride, Inner: for<'short> Reborrow<'short, Target = super::Ref<'short, T, Rows, RStride>>> Index<Idx<Rows>>
148		for Col<Inner>
149	{
150		type Output = T;
151
152		#[inline]
153		#[track_caller]
154		fn index(&self, row: Idx<Rows>) -> &Self::Output {
155			self.rb().at(row)
156		}
157	}
158
159	impl<
160		T,
161		Rows: Shape,
162		RStride: Stride,
163		Inner: for<'short> Reborrow<'short, Target = super::Ref<'short, T, Rows, RStride>>
164			+ for<'short> ReborrowMut<'short, Target = super::Mut<'short, T, Rows, RStride>>,
165	> IndexMut<Idx<Rows>> for Col<Inner>
166	{
167		#[inline]
168		#[track_caller]
169		fn index_mut(&mut self, row: Idx<Rows>) -> &mut Self::Output {
170			self.rb_mut().at_mut(row)
171		}
172	}
173}
174
175/// trait for types that can be converted to a column view
176pub trait AsColMut: AsColRef {
177	/// returns a view over `self`
178	fn as_col_mut(&mut self) -> ColMut<'_, Self::T, Self::Rows>;
179}
180/// trait for types that can be converted to a column view
181pub trait AsColRef: AsMatRef<Cols = One> {
182	/// returns a view over `self`
183	fn as_col_ref(&self) -> ColRef<'_, Self::T, Self::Rows>;
184}
185
186impl<M: AsMatRef<Cols = One>> AsColRef for M {
187	#[inline]
188	fn as_col_ref(&self) -> ColRef<'_, Self::T, Self::Rows> {
189		self.as_mat_ref().col(Zero)
190	}
191}
192
193impl<M: AsMatMut<Cols = One>> AsColMut for M {
194	#[inline]
195	fn as_col_mut(&mut self) -> ColMut<'_, Self::T, Self::Rows> {
196		self.as_mat_mut().col_mut(Zero)
197	}
198}
199
200impl<T, Rows: Shape, Rs: Stride> AsMatRef for ColRef<'_, T, Rows, Rs> {
201	type Cols = One;
202	type Owned = Col<T, Rows>;
203	type Rows = Rows;
204	type T = T;
205
206	#[inline]
207	fn as_mat_ref(&self) -> MatRef<Self::T, Self::Rows, Self::Cols> {
208		self.as_dyn_stride().as_mat().as_col_shape(One)
209	}
210}
211
212impl<T, Rows: Shape, Rs: Stride> AsMatRef for ColMut<'_, T, Rows, Rs> {
213	type Cols = One;
214	type Owned = Col<T, Rows>;
215	type Rows = Rows;
216	type T = T;
217
218	#[inline]
219	fn as_mat_ref(&self) -> MatRef<Self::T, Self::Rows, Self::Cols> {
220		self.rb().as_dyn_stride().as_mat().as_col_shape(One)
221	}
222}
223
224impl<T, Rows: Shape> AsMatRef for Col<T, Rows> {
225	type Cols = One;
226	type Owned = Col<T, Rows>;
227	type Rows = Rows;
228	type T = T;
229
230	#[inline]
231	fn as_mat_ref(&self) -> MatRef<Self::T, Self::Rows, Self::Cols> {
232		self.as_dyn_stride().as_mat().as_col_shape(One)
233	}
234}
235
236impl<T, Rows: Shape, Rs: Stride> AsMatMut for ColMut<'_, T, Rows, Rs> {
237	#[inline]
238	fn as_mat_mut(&mut self) -> MatMut<Self::T, Self::Rows, Self::Cols> {
239		self.rb_mut().as_dyn_stride_mut().as_mat_mut().as_col_shape_mut(One)
240	}
241}
242
243impl<T, Rows: Shape> AsMatMut for Col<T, Rows> {
244	#[inline]
245	fn as_mat_mut(&mut self) -> MatMut<Self::T, Self::Rows, Self::Cols> {
246		self.as_dyn_stride_mut().as_mat_mut().as_col_shape_mut(One)
247	}
248}
249
250impl<T, Rows: Shape> AsMat<T> for Col<T, Rows> {
251	#[inline]
252	fn zeros(rows: Rows, _: One) -> Self
253	where
254		T: ComplexField,
255	{
256		Col::zeros(rows)
257	}
258
259	#[track_caller]
260	#[inline]
261	fn truncate(&mut self, rows: Self::Rows, _: One) {
262		self.truncate(rows)
263	}
264}