easy_ml/matrices/views/
traits.rs

1/*!
2 * Trait implementations for [MatrixRef] and [MatrixMut].
3 *
4 * These implementations are written here but Rust docs will display them on the
5 * traits' pages.
6 *
7 * An owned or referenced [Matrix] is a MatrixRef, and a MatrixMut if not a shared
8 * reference, Therefore, you can pass a Matrix to any function which takes a MatrixRef.
9 *
10 * Boxed MatrixRef and MatrixMut values also implement MatrixRef and MatrixMut respectively.
11 *
12 * All MatrixRef and MatrixMut implementations for Matrices are also [NoInteriorMutability].
13 *
14 * Since a Matrix always stores its data in row major order,
15 * [`data_layout()`](MatrixRef::data_layout) will return
16 * [`DataLayout::RowMajor`], but third party matrix types implementing
17 * MatrixRef/MatrixMut may use a column major layout.
18 */
19
20use crate::matrices::views::{DataLayout, MatrixMut, MatrixRef, NoInteriorMutability};
21use crate::matrices::{Column, Matrix, Row};
22
23// # Safety
24//
25// The type implementing MatrixRef must implement it correctly, so by delegating to it
26// without changing any indexes or introducing interior mutability, we implement MatrixRef
27// correctly as well.
28/**
29 * If some type implements MatrixRef, then a reference to it implements MatrixRef as well
30 */
31unsafe impl<'source, T, S> MatrixRef<T> for &'source S
32where
33    S: MatrixRef<T>,
34{
35    fn try_get_reference(&self, row: Row, column: Column) -> Option<&T> {
36        MatrixRef::try_get_reference(*self, row, column)
37    }
38
39    fn view_rows(&self) -> Row {
40        MatrixRef::view_rows(*self)
41    }
42
43    fn view_columns(&self) -> Column {
44        MatrixRef::view_columns(*self)
45    }
46
47    unsafe fn get_reference_unchecked(&self, row: Row, column: Column) -> &T {
48        unsafe { MatrixRef::get_reference_unchecked(*self, row, column) }
49    }
50
51    fn data_layout(&self) -> DataLayout {
52        DataLayout::RowMajor
53    }
54}
55
56// # Safety
57//
58// The type implementing NoInteriorMutability must implement it correctly, so by delegating to it
59// without changing any indexes or introducing interior mutability, we implement
60// NoInteriorMutability correctly as well.
61/**
62 * If some type implements NoInteriorMutability, then a reference to it implements
63 * NoInteriorMutability as well. The reverse would not be true, since a type that does
64 * have interior mutability would remain interiorly mutable behind a shared reference. However,
65 * since this type promises not to have interior mutability, taking a shared reference can't
66 * introduce any.
67 */
68unsafe impl<'source, S> NoInteriorMutability for &'source S where S: NoInteriorMutability {}
69
70// # Safety
71//
72// The type implementing MatrixRef must implement it correctly, so by delegating to it
73// without changing any indexes or introducing interior mutability, we implement MatrixRef
74// correctly as well.
75/**
76 * If some type implements MatrixRef, then an exclusive reference to it implements MatrixRef
77 * as well
78 */
79unsafe impl<'source, T, S> MatrixRef<T> for &'source mut S
80where
81    S: MatrixRef<T>,
82{
83    fn try_get_reference(&self, row: Row, column: Column) -> Option<&T> {
84        MatrixRef::try_get_reference(*self, row, column)
85    }
86
87    fn view_rows(&self) -> Row {
88        MatrixRef::view_rows(*self)
89    }
90
91    fn view_columns(&self) -> Column {
92        MatrixRef::view_columns(*self)
93    }
94
95    unsafe fn get_reference_unchecked(&self, row: Row, column: Column) -> &T {
96        unsafe { MatrixRef::get_reference_unchecked(*self, row, column) }
97    }
98
99    fn data_layout(&self) -> DataLayout {
100        DataLayout::RowMajor
101    }
102}
103
104// # Safety
105//
106// The type implementing MatrixMut must implement it correctly, so by delegating to it
107// without changing any indexes or introducing interior mutability, we implement MatrixMut
108// correctly as well.
109/**
110 * If some type implements MatrixMut, then an exclusive reference to it implements MatrixMut
111 * as well
112 */
113unsafe impl<'source, T, S> MatrixMut<T> for &'source mut S
114where
115    S: MatrixMut<T>,
116{
117    fn try_get_reference_mut(&mut self, row: Row, column: Column) -> Option<&mut T> {
118        MatrixMut::try_get_reference_mut(*self, row, column)
119    }
120
121    unsafe fn get_reference_unchecked_mut(&mut self, row: Row, column: Column) -> &mut T {
122        unsafe { MatrixMut::get_reference_unchecked_mut(*self, row, column) }
123    }
124}
125
126// # Safety
127//
128// The type implementing NoInteriorMutability must implement it correctly, so by delegating to it
129// without changing any indexes or introducing interior mutability, we implement
130// NoInteriorMutability correctly as well.
131/**
132 * If some type implements NoInteriorMutability, then an exclusive reference to it implements
133 * NoInteriorMutability as well. The reverse would not be true, since a type that does
134 * have interior mutability would remain interiorly mutable behind an exclusive reference. However,
135 * since this type promises not to have interior mutability, taking an exclusive reference can't
136 * introduce any.
137 */
138unsafe impl<'source, S> NoInteriorMutability for &'source mut S {}
139
140// # Safety
141//
142// Since we hold an owned Matrix we know it is not possible to mutate the size of the matrix
143// out from under us.
144/**
145 * A Matrix implements MatrixRef.
146 */
147unsafe impl<T> MatrixRef<T> for Matrix<T> {
148    fn try_get_reference(&self, row: Row, column: Column) -> Option<&T> {
149        Matrix::_try_get_reference(self, row, column)
150    }
151
152    fn view_rows(&self) -> Row {
153        Matrix::rows(self)
154    }
155
156    fn view_columns(&self) -> Column {
157        Matrix::columns(self)
158    }
159
160    unsafe fn get_reference_unchecked(&self, row: Row, column: Column) -> &T {
161        unsafe { Matrix::_get_reference_unchecked(self, row, column) }
162    }
163
164    fn data_layout(&self) -> DataLayout {
165        DataLayout::RowMajor
166    }
167}
168
169// # Safety
170//
171// Since we hold an owned Matrix we know it is not possible to mutate the size of the matrix
172// out from under us.
173/**
174 * A Matrix implements MatrixMut.
175 */
176unsafe impl<T> MatrixMut<T> for Matrix<T> {
177    fn try_get_reference_mut(&mut self, row: Row, column: Column) -> Option<&mut T> {
178        Matrix::_try_get_reference_mut(self, row, column)
179    }
180
181    unsafe fn get_reference_unchecked_mut(&mut self, row: Row, column: Column) -> &mut T {
182        unsafe { Matrix::_get_reference_unchecked_mut(self, row, column) }
183    }
184}
185
186// # Safety
187//
188// We promise to never implement interior mutability for Matrix.
189/**
190 * A Matrix implements NoInteriorMutability.
191 */
192unsafe impl<T> NoInteriorMutability for Matrix<T> {}
193
194// # Safety
195//
196// Since the MatrixRef we box must implement MatrixRef correctly, so do we by delegating to it,
197// as a box doesn't introduce any interior mutability.
198/**
199 * A box of a MatrixRef also implements MatrixRef.
200 */
201unsafe impl<T, S> MatrixRef<T> for Box<S>
202where
203    S: MatrixRef<T>,
204{
205    fn try_get_reference(&self, row: Row, column: Column) -> Option<&T> {
206        self.as_ref().try_get_reference(row, column)
207    }
208
209    fn view_rows(&self) -> Row {
210        self.as_ref().view_rows()
211    }
212
213    fn view_columns(&self) -> Column {
214        self.as_ref().view_columns()
215    }
216
217    unsafe fn get_reference_unchecked(&self, row: Row, column: Column) -> &T {
218        unsafe { self.as_ref().get_reference_unchecked(row, column) }
219    }
220
221    fn data_layout(&self) -> DataLayout {
222        self.as_ref().data_layout()
223    }
224}
225
226// # Safety
227//
228// Since the MatrixMut we box must implement MatrixMut correctly, so do we by delegating to it,
229// as a box doesn't introduce any interior mutability.
230/**
231 * A box of a MatrixMut also implements MatrixMut.
232 */
233unsafe impl<T, S> MatrixMut<T> for Box<S>
234where
235    S: MatrixMut<T>,
236{
237    fn try_get_reference_mut(&mut self, row: Row, column: Column) -> Option<&mut T> {
238        self.as_mut().try_get_reference_mut(row, column)
239    }
240
241    unsafe fn get_reference_unchecked_mut(&mut self, row: Row, column: Column) -> &mut T {
242        unsafe { self.as_mut().get_reference_unchecked_mut(row, column) }
243    }
244}
245
246// # Safety
247//
248// Box doesn't introduce any interior mutability, so we can implement if it the type we box does.
249/**
250 * A box of a NoInteriorMutability also implements NoInteriorMutability
251 */
252unsafe impl<S> NoInteriorMutability for Box<S> where S: NoInteriorMutability {}
253
254// # Safety
255//
256// Since the MatrixRef we box must implement MatrixRef correctly, so do we by delegating to it,
257// as a box doesn't introduce any interior mutability.
258/**
259 * A box of a dynamic MatrixRef also implements MatrixRef.
260 */
261unsafe impl<T> MatrixRef<T> for Box<dyn MatrixRef<T>> {
262    fn try_get_reference(&self, row: Row, column: Column) -> Option<&T> {
263        self.as_ref().try_get_reference(row, column)
264    }
265
266    fn view_rows(&self) -> Row {
267        self.as_ref().view_rows()
268    }
269
270    fn view_columns(&self) -> Column {
271        self.as_ref().view_columns()
272    }
273
274    unsafe fn get_reference_unchecked(&self, row: Row, column: Column) -> &T {
275        unsafe { self.as_ref().get_reference_unchecked(row, column) }
276    }
277
278    fn data_layout(&self) -> DataLayout {
279        self.as_ref().data_layout()
280    }
281}
282
283// # Safety
284//
285// Since the MatrixMut we box must implement MatrixRef correctly, so do we by delegating to it,
286// as a box doesn't introduce any interior mutability.
287/**
288 * A box of a dynamic MatrixMut also implements MatrixRef.
289 */
290unsafe impl<T> MatrixRef<T> for Box<dyn MatrixMut<T>> {
291    fn try_get_reference(&self, row: Row, column: Column) -> Option<&T> {
292        self.as_ref().try_get_reference(row, column)
293    }
294
295    fn view_rows(&self) -> Row {
296        self.as_ref().view_rows()
297    }
298
299    fn view_columns(&self) -> Column {
300        self.as_ref().view_columns()
301    }
302
303    unsafe fn get_reference_unchecked(&self, row: Row, column: Column) -> &T {
304        unsafe { self.as_ref().get_reference_unchecked(row, column) }
305    }
306
307    fn data_layout(&self) -> DataLayout {
308        self.as_ref().data_layout()
309    }
310}
311
312// # Safety
313//
314// Since the MatrixMut we box must implement MatrixMut correctly, so do we by delegating to it,
315// as a box doesn't introduce any interior mutability.
316/**
317 * A box of a dynamic MatrixMut also implements MatrixMut.
318 */
319unsafe impl<T> MatrixMut<T> for Box<dyn MatrixMut<T>> {
320    fn try_get_reference_mut(&mut self, row: Row, column: Column) -> Option<&mut T> {
321        self.as_mut().try_get_reference_mut(row, column)
322    }
323
324    unsafe fn get_reference_unchecked_mut(&mut self, row: Row, column: Column) -> &mut T {
325        unsafe { self.as_mut().get_reference_unchecked_mut(row, column) }
326    }
327}
328
329// # Safety
330//
331// Box doesn't introduce any interior mutability, so we can implement if it the type we box does.
332/**
333 * A box of a dynamic NoInteriorMutability also implements NoInteriorMutability
334 */
335unsafe impl NoInteriorMutability for Box<dyn NoInteriorMutability> {}
336
337// # Safety
338//
339// Box doesn't introduce any interior mutability, so we can implement if it the type we box does.
340/**
341 * A box of a dynamic MatrixRef also implements NoInteriorMutability, since NoInteriorMutability
342 * is supertrait of MatrixRef
343 */
344unsafe impl<T> NoInteriorMutability for Box<dyn MatrixRef<T>> {}
345
346// # Safety
347//
348// Box doesn't introduce any interior mutability, so we can implement if it the type we box does.
349/**
350 * A box of a dynamic MatrixMut also implements NoInteriorMutability, since NoInteriorMutability
351 * is supertrait of MatrixMut
352 */
353unsafe impl<T> NoInteriorMutability for Box<dyn MatrixMut<T>> {}