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>> {}