1#[cfg(all(feature = "alloc", not(feature = "std")))]
2use alloc::vec::Vec;
3use simba::scalar::{SubsetOf, SupersetOf};
4use std::borrow::{Borrow, BorrowMut};
5use std::convert::{AsMut, AsRef, From, Into};
6
7use simba::simd::{PrimitiveSimdValue, SimdValue};
8
9use crate::base::allocator::{Allocator, SameShapeAllocator};
10use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
11#[cfg(any(feature = "std", feature = "alloc"))]
12use crate::base::dimension::Dynamic;
13use crate::base::dimension::{
14 Const, Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
15};
16use crate::base::iter::{MatrixIter, MatrixIterMut};
17use crate::base::storage::{IsContiguous, RawStorage, RawStorageMut};
18use crate::base::{
19 ArrayStorage, DVectorSlice, DVectorSliceMut, DefaultAllocator, Matrix, MatrixSlice,
20 MatrixSliceMut, OMatrix, Scalar,
21};
22#[cfg(any(feature = "std", feature = "alloc"))]
23use crate::base::{DVector, RowDVector, VecStorage};
24use crate::base::{SliceStorage, SliceStorageMut};
25use crate::constraint::DimEq;
26use crate::{IsNotStaticOne, RowSVector, SMatrix, SVector, VectorSlice, VectorSliceMut};
27use std::mem::MaybeUninit;
28
29impl<T1, T2, R1, C1, R2, C2> SubsetOf<OMatrix<T2, R2, C2>> for OMatrix<T1, R1, C1>
31where
32 R1: Dim,
33 C1: Dim,
34 R2: Dim,
35 C2: Dim,
36 T1: Scalar,
37 T2: Scalar + SupersetOf<T1>,
38 DefaultAllocator:
39 Allocator<T2, R2, C2> + Allocator<T1, R1, C1> + SameShapeAllocator<T1, R1, C1, R2, C2>,
40 ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
41{
42 #[inline]
43 fn to_superset(&self) -> OMatrix<T2, R2, C2> {
44 let (nrows, ncols) = self.shape();
45 let nrows2 = R2::from_usize(nrows);
46 let ncols2 = C2::from_usize(ncols);
47 let mut res = Matrix::uninit(nrows2, ncols2);
48
49 for i in 0..nrows {
50 for j in 0..ncols {
51 unsafe {
53 *res.get_unchecked_mut((i, j)) =
54 MaybeUninit::new(T2::from_subset(self.get_unchecked((i, j))));
55 }
56 }
57 }
58
59 unsafe { res.assume_init() }
61 }
62
63 #[inline]
64 fn is_in_subset(m: &OMatrix<T2, R2, C2>) -> bool {
65 m.iter().all(|e| e.is_in_subset())
66 }
67
68 #[inline]
69 fn from_superset_unchecked(m: &OMatrix<T2, R2, C2>) -> Self {
70 let (nrows2, ncols2) = m.shape();
71 let nrows = R1::from_usize(nrows2);
72 let ncols = C1::from_usize(ncols2);
73 let mut res = Matrix::uninit(nrows, ncols);
74
75 for i in 0..nrows2 {
76 for j in 0..ncols2 {
77 unsafe {
79 *res.get_unchecked_mut((i, j)) =
80 MaybeUninit::new(m.get_unchecked((i, j)).to_subset_unchecked())
81 }
82 }
83 }
84
85 unsafe { res.assume_init() }
86 }
87}
88
89impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> IntoIterator
90 for &'a Matrix<T, R, C, S>
91{
92 type Item = &'a T;
93 type IntoIter = MatrixIter<'a, T, R, C, S>;
94
95 #[inline]
96 fn into_iter(self) -> Self::IntoIter {
97 self.iter()
98 }
99}
100
101impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> IntoIterator
102 for &'a mut Matrix<T, R, C, S>
103{
104 type Item = &'a mut T;
105 type IntoIter = MatrixIterMut<'a, T, R, C, S>;
106
107 #[inline]
108 fn into_iter(self) -> Self::IntoIter {
109 self.iter_mut()
110 }
111}
112
113impl<T: Scalar, const D: usize> From<[T; D]> for SVector<T, D> {
114 #[inline]
115 fn from(arr: [T; D]) -> Self {
116 unsafe { Self::from_data_statically_unchecked(ArrayStorage([arr; 1])) }
117 }
118}
119
120impl<T: Scalar, const D: usize> From<SVector<T, D>> for [T; D] {
121 #[inline]
122 fn from(vec: SVector<T, D>) -> Self {
123 vec.data.0[0].clone()
125 }
126}
127
128impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const D: usize>
129 From<VectorSlice<'a, T, Const<D>, RStride, CStride>> for [T; D]
130{
131 #[inline]
132 fn from(vec: VectorSlice<'a, T, Const<D>, RStride, CStride>) -> Self {
133 vec.into_owned().into()
134 }
135}
136
137impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const D: usize>
138 From<VectorSliceMut<'a, T, Const<D>, RStride, CStride>> for [T; D]
139{
140 #[inline]
141 fn from(vec: VectorSliceMut<'a, T, Const<D>, RStride, CStride>) -> Self {
142 vec.into_owned().into()
143 }
144}
145
146impl<T: Scalar, const D: usize> From<[T; D]> for RowSVector<T, D>
147where
148 Const<D>: IsNotStaticOne,
149{
150 #[inline]
151 fn from(arr: [T; D]) -> Self {
152 SVector::<T, D>::from(arr).transpose()
153 }
154}
155
156impl<T: Scalar, const D: usize> From<RowSVector<T, D>> for [T; D]
157where
158 Const<D>: IsNotStaticOne,
159{
160 #[inline]
161 fn from(vec: RowSVector<T, D>) -> [T; D] {
162 vec.transpose().into()
163 }
164}
165
166macro_rules! impl_from_into_asref_1D(
167 ($(($NRows: ident, $NCols: ident) => $SZ: expr);* $(;)*) => {$(
168 impl<T, S> AsRef<[T; $SZ]> for Matrix<T, $NRows, $NCols, S>
169 where T: Scalar,
170 S: RawStorage<T, $NRows, $NCols> + IsContiguous {
171 #[inline]
172 fn as_ref(&self) -> &[T; $SZ] {
173 unsafe {
175 &*(self.data.ptr() as *const [T; $SZ])
176 }
177 }
178 }
179
180 impl<T, S> AsMut<[T; $SZ]> for Matrix<T, $NRows, $NCols, S>
181 where T: Scalar,
182 S: RawStorageMut<T, $NRows, $NCols> + IsContiguous {
183 #[inline]
184 fn as_mut(&mut self) -> &mut [T; $SZ] {
185 unsafe {
187 &mut *(self.data.ptr_mut() as *mut [T; $SZ])
188 }
189 }
190 }
191 )*}
192);
193
194impl_from_into_asref_1D!(
196 (U1, U1 ) => 1; (U1, U2 ) => 2; (U1, U3 ) => 3; (U1, U4 ) => 4;
198 (U1, U5 ) => 5; (U1, U6 ) => 6; (U1, U7 ) => 7; (U1, U8 ) => 8;
199 (U1, U9 ) => 9; (U1, U10) => 10; (U1, U11) => 11; (U1, U12) => 12;
200 (U1, U13) => 13; (U1, U14) => 14; (U1, U15) => 15; (U1, U16) => 16;
201
202 (U2 , U1) => 2; (U3 , U1) => 3; (U4 , U1) => 4;
204 (U5 , U1) => 5; (U6 , U1) => 6; (U7 , U1) => 7; (U8 , U1) => 8;
205 (U9 , U1) => 9; (U10, U1) => 10; (U11, U1) => 11; (U12, U1) => 12;
206 (U13, U1) => 13; (U14, U1) => 14; (U15, U1) => 15; (U16, U1) => 16;
207);
208
209impl<T: Scalar, const R: usize, const C: usize> From<[[T; R]; C]> for SMatrix<T, R, C> {
210 #[inline]
211 fn from(arr: [[T; R]; C]) -> Self {
212 unsafe { Self::from_data_statically_unchecked(ArrayStorage(arr)) }
213 }
214}
215
216impl<T: Scalar, const R: usize, const C: usize> From<SMatrix<T, R, C>> for [[T; R]; C] {
217 #[inline]
218 fn from(mat: SMatrix<T, R, C>) -> Self {
219 mat.data.0
220 }
221}
222
223impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const R: usize, const C: usize>
224 From<MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>> for [[T; R]; C]
225{
226 #[inline]
227 fn from(mat: MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
228 mat.into_owned().into()
229 }
230}
231
232impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const R: usize, const C: usize>
233 From<MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>> for [[T; R]; C]
234{
235 #[inline]
236 fn from(mat: MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
237 mat.into_owned().into()
238 }
239}
240
241macro_rules! impl_from_into_asref_borrow_2D(
242
243 (
245 ($NRows: ty, $NCols: ty) => ($SZRows: expr, $SZCols: expr);
246 $Ref:ident.$ref:ident(), $Mut:ident.$mut:ident()
247 ) => {
248 impl<T: Scalar, S> $Ref<[[T; $SZRows]; $SZCols]> for Matrix<T, $NRows, $NCols, S>
249 where S: RawStorage<T, $NRows, $NCols> + IsContiguous {
250 #[inline]
251 fn $ref(&self) -> &[[T; $SZRows]; $SZCols] {
252 unsafe {
254 &*(self.data.ptr() as *const [[T; $SZRows]; $SZCols])
255 }
256 }
257 }
258
259 impl<T: Scalar, S> $Mut<[[T; $SZRows]; $SZCols]> for Matrix<T, $NRows, $NCols, S>
260 where S: RawStorageMut<T, $NRows, $NCols> + IsContiguous {
261 #[inline]
262 fn $mut(&mut self) -> &mut [[T; $SZRows]; $SZCols] {
263 unsafe {
265 &mut *(self.data.ptr_mut() as *mut [[T; $SZRows]; $SZCols])
266 }
267 }
268 }
269 };
270
271 ($(($NRows: ty, $NCols: ty) => ($SZRows: expr, $SZCols: expr));* $(;)*) => {$(
273 impl_from_into_asref_borrow_2D!(
274 ($NRows, $NCols) => ($SZRows, $SZCols); AsRef.as_ref(), AsMut.as_mut()
275 );
276 impl_from_into_asref_borrow_2D!(
277 ($NRows, $NCols) => ($SZRows, $SZCols); Borrow.borrow(), BorrowMut.borrow_mut()
278 );
279 )*}
280);
281
282impl_from_into_asref_borrow_2D!(
284 (U2, U2) => (2, 2); (U2, U3) => (2, 3); (U2, U4) => (2, 4); (U2, U5) => (2, 5); (U2, U6) => (2, 6);
285 (U3, U2) => (3, 2); (U3, U3) => (3, 3); (U3, U4) => (3, 4); (U3, U5) => (3, 5); (U3, U6) => (3, 6);
286 (U4, U2) => (4, 2); (U4, U3) => (4, 3); (U4, U4) => (4, 4); (U4, U5) => (4, 5); (U4, U6) => (4, 6);
287 (U5, U2) => (5, 2); (U5, U3) => (5, 3); (U5, U4) => (5, 4); (U5, U5) => (5, 5); (U5, U6) => (5, 6);
288 (U6, U2) => (6, 2); (U6, U3) => (6, 3); (U6, U4) => (6, 4); (U6, U5) => (6, 5); (U6, U6) => (6, 6);
289);
290
291impl<'a, T, RStride, CStride, const R: usize, const C: usize>
292 From<MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>>
293 for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>>
294where
295 T: Scalar,
296 RStride: Dim,
297 CStride: Dim,
298{
299 fn from(matrix_slice: MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
300 matrix_slice.into_owned()
301 }
302}
303
304#[cfg(any(feature = "std", feature = "alloc"))]
305impl<'a, T, C, RStride, CStride> From<MatrixSlice<'a, T, Dynamic, C, RStride, CStride>>
306 for Matrix<T, Dynamic, C, VecStorage<T, Dynamic, C>>
307where
308 T: Scalar,
309 C: Dim,
310 RStride: Dim,
311 CStride: Dim,
312{
313 fn from(matrix_slice: MatrixSlice<'a, T, Dynamic, C, RStride, CStride>) -> Self {
314 matrix_slice.into_owned()
315 }
316}
317
318#[cfg(any(feature = "std", feature = "alloc"))]
319impl<'a, T, R, RStride, CStride> From<MatrixSlice<'a, T, R, Dynamic, RStride, CStride>>
320 for Matrix<T, R, Dynamic, VecStorage<T, R, Dynamic>>
321where
322 T: Scalar,
323 R: DimName,
324 RStride: Dim,
325 CStride: Dim,
326{
327 fn from(matrix_slice: MatrixSlice<'a, T, R, Dynamic, RStride, CStride>) -> Self {
328 matrix_slice.into_owned()
329 }
330}
331
332impl<'a, T, RStride, CStride, const R: usize, const C: usize>
333 From<MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>>
334 for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>>
335where
336 T: Scalar,
337 RStride: Dim,
338 CStride: Dim,
339{
340 fn from(matrix_slice: MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
341 matrix_slice.into_owned()
342 }
343}
344
345#[cfg(any(feature = "std", feature = "alloc"))]
346impl<'a, T, C, RStride, CStride> From<MatrixSliceMut<'a, T, Dynamic, C, RStride, CStride>>
347 for Matrix<T, Dynamic, C, VecStorage<T, Dynamic, C>>
348where
349 T: Scalar,
350 C: Dim,
351 RStride: Dim,
352 CStride: Dim,
353{
354 fn from(matrix_slice: MatrixSliceMut<'a, T, Dynamic, C, RStride, CStride>) -> Self {
355 matrix_slice.into_owned()
356 }
357}
358
359#[cfg(any(feature = "std", feature = "alloc"))]
360impl<'a, T, R, RStride, CStride> From<MatrixSliceMut<'a, T, R, Dynamic, RStride, CStride>>
361 for Matrix<T, R, Dynamic, VecStorage<T, R, Dynamic>>
362where
363 T: Scalar,
364 R: DimName,
365 RStride: Dim,
366 CStride: Dim,
367{
368 fn from(matrix_slice: MatrixSliceMut<'a, T, R, Dynamic, RStride, CStride>) -> Self {
369 matrix_slice.into_owned()
370 }
371}
372
373impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a Matrix<T, R, C, S>>
374 for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride>
375where
376 T: Scalar,
377 R: Dim,
378 C: Dim,
379 RSlice: Dim,
380 CSlice: Dim,
381 RStride: Dim,
382 CStride: Dim,
383 S: RawStorage<T, R, C>,
384 ShapeConstraint: DimEq<R, RSlice>
385 + DimEq<C, CSlice>
386 + DimEq<RStride, S::RStride>
387 + DimEq<CStride, S::CStride>,
388{
389 fn from(m: &'a Matrix<T, R, C, S>) -> Self {
390 let (row, col) = m.shape_generic();
391 let row_slice = RSlice::from_usize(row.value());
392 let col_slice = CSlice::from_usize(col.value());
393
394 let (rstride, cstride) = m.strides();
395
396 let rstride_slice = RStride::from_usize(rstride);
397 let cstride_slice = CStride::from_usize(cstride);
398
399 unsafe {
400 let data = SliceStorage::from_raw_parts(
401 m.data.ptr(),
402 (row_slice, col_slice),
403 (rstride_slice, cstride_slice),
404 );
405 Matrix::from_data_statically_unchecked(data)
406 }
407 }
408}
409
410impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
411 for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride>
412where
413 T: Scalar,
414 R: Dim,
415 C: Dim,
416 RSlice: Dim,
417 CSlice: Dim,
418 RStride: Dim,
419 CStride: Dim,
420 S: RawStorage<T, R, C>,
421 ShapeConstraint: DimEq<R, RSlice>
422 + DimEq<C, CSlice>
423 + DimEq<RStride, S::RStride>
424 + DimEq<CStride, S::CStride>,
425{
426 fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
427 let (row, col) = m.shape_generic();
428 let row_slice = RSlice::from_usize(row.value());
429 let col_slice = CSlice::from_usize(col.value());
430
431 let (rstride, cstride) = m.strides();
432
433 let rstride_slice = RStride::from_usize(rstride);
434 let cstride_slice = CStride::from_usize(cstride);
435
436 unsafe {
437 let data = SliceStorage::from_raw_parts(
438 m.data.ptr(),
439 (row_slice, col_slice),
440 (rstride_slice, cstride_slice),
441 );
442 Matrix::from_data_statically_unchecked(data)
443 }
444 }
445}
446
447impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
448 for MatrixSliceMut<'a, T, RSlice, CSlice, RStride, CStride>
449where
450 T: Scalar,
451 R: Dim,
452 C: Dim,
453 RSlice: Dim,
454 CSlice: Dim,
455 RStride: Dim,
456 CStride: Dim,
457 S: RawStorageMut<T, R, C>,
458 ShapeConstraint: DimEq<R, RSlice>
459 + DimEq<C, CSlice>
460 + DimEq<RStride, S::RStride>
461 + DimEq<CStride, S::CStride>,
462{
463 fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
464 let (row, col) = m.shape_generic();
465 let row_slice = RSlice::from_usize(row.value());
466 let col_slice = CSlice::from_usize(col.value());
467
468 let (rstride, cstride) = m.strides();
469
470 let rstride_slice = RStride::from_usize(rstride);
471 let cstride_slice = CStride::from_usize(cstride);
472
473 unsafe {
474 let data = SliceStorageMut::from_raw_parts(
475 m.data.ptr_mut(),
476 (row_slice, col_slice),
477 (rstride_slice, cstride_slice),
478 );
479 Matrix::from_data_statically_unchecked(data)
480 }
481 }
482}
483
484#[cfg(any(feature = "std", feature = "alloc"))]
485impl<'a, T: Scalar> From<Vec<T>> for DVector<T> {
486 #[inline]
487 fn from(vec: Vec<T>) -> Self {
488 Self::from_vec(vec)
489 }
490}
491
492#[cfg(any(feature = "std", feature = "alloc"))]
493impl<'a, T: Scalar> From<Vec<T>> for RowDVector<T> {
494 #[inline]
495 fn from(vec: Vec<T>) -> Self {
496 Self::from_vec(vec)
497 }
498}
499
500impl<'a, T: Scalar + Copy, R: Dim, C: Dim, S: RawStorage<T, R, C> + IsContiguous>
501 From<&'a Matrix<T, R, C, S>> for &'a [T]
502{
503 #[inline]
504 fn from(matrix: &'a Matrix<T, R, C, S>) -> Self {
505 matrix.as_slice()
506 }
507}
508
509impl<'a, T: Scalar + Copy, R: Dim, C: Dim, S: RawStorageMut<T, R, C> + IsContiguous>
510 From<&'a mut Matrix<T, R, C, S>> for &'a mut [T]
511{
512 #[inline]
513 fn from(matrix: &'a mut Matrix<T, R, C, S>) -> Self {
514 matrix.as_mut_slice()
515 }
516}
517
518impl<'a, T: Scalar + Copy> From<&'a [T]> for DVectorSlice<'a, T> {
519 #[inline]
520 fn from(slice: &'a [T]) -> Self {
521 Self::from_slice(slice, slice.len())
522 }
523}
524
525impl<'a, T: Scalar> From<DVectorSlice<'a, T>> for &'a [T] {
526 fn from(vec: DVectorSlice<'a, T>) -> &'a [T] {
527 vec.data.into_slice()
528 }
529}
530
531impl<'a, T: Scalar + Copy> From<&'a mut [T]> for DVectorSliceMut<'a, T> {
532 #[inline]
533 fn from(slice: &'a mut [T]) -> Self {
534 Self::from_slice(slice, slice.len())
535 }
536}
537
538impl<'a, T: Scalar> From<DVectorSliceMut<'a, T>> for &'a mut [T] {
539 fn from(vec: DVectorSliceMut<'a, T>) -> &'a mut [T] {
540 vec.data.into_slice_mut()
541 }
542}
543
544impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R, C>; 2]>
545 for OMatrix<T, R, C>
546where
547 T: From<[<T as SimdValue>::Element; 2]>,
548 T::Element: Scalar + SimdValue,
549 DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
550{
551 #[inline]
552 fn from(arr: [OMatrix<T::Element, R, C>; 2]) -> Self {
553 let (nrows, ncols) = arr[0].shape_generic();
554
555 Self::from_fn_generic(nrows, ncols, |i, j| {
556 [arr[0][(i, j)].clone(), arr[1][(i, j)].clone()].into()
557 })
558 }
559}
560
561impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R, C>; 4]>
562 for OMatrix<T, R, C>
563where
564 T: From<[<T as SimdValue>::Element; 4]>,
565 T::Element: Scalar + SimdValue,
566 DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
567{
568 #[inline]
569 fn from(arr: [OMatrix<T::Element, R, C>; 4]) -> Self {
570 let (nrows, ncols) = arr[0].shape_generic();
571
572 Self::from_fn_generic(nrows, ncols, |i, j| {
573 [
574 arr[0][(i, j)].clone(),
575 arr[1][(i, j)].clone(),
576 arr[2][(i, j)].clone(),
577 arr[3][(i, j)].clone(),
578 ]
579 .into()
580 })
581 }
582}
583
584impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R, C>; 8]>
585 for OMatrix<T, R, C>
586where
587 T: From<[<T as SimdValue>::Element; 8]>,
588 T::Element: Scalar + SimdValue,
589 DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
590{
591 #[inline]
592 fn from(arr: [OMatrix<T::Element, R, C>; 8]) -> Self {
593 let (nrows, ncols) = arr[0].shape_generic();
594
595 Self::from_fn_generic(nrows, ncols, |i, j| {
596 [
597 arr[0][(i, j)].clone(),
598 arr[1][(i, j)].clone(),
599 arr[2][(i, j)].clone(),
600 arr[3][(i, j)].clone(),
601 arr[4][(i, j)].clone(),
602 arr[5][(i, j)].clone(),
603 arr[6][(i, j)].clone(),
604 arr[7][(i, j)].clone(),
605 ]
606 .into()
607 })
608 }
609}
610
611impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R, C>; 16]>
612 for OMatrix<T, R, C>
613where
614 T: From<[<T as SimdValue>::Element; 16]>,
615 T::Element: Scalar + SimdValue,
616 DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
617{
618 fn from(arr: [OMatrix<T::Element, R, C>; 16]) -> Self {
619 let (nrows, ncols) = arr[0].shape_generic();
620
621 Self::from_fn_generic(nrows, ncols, |i, j| {
622 [
623 arr[0][(i, j)].clone(),
624 arr[1][(i, j)].clone(),
625 arr[2][(i, j)].clone(),
626 arr[3][(i, j)].clone(),
627 arr[4][(i, j)].clone(),
628 arr[5][(i, j)].clone(),
629 arr[6][(i, j)].clone(),
630 arr[7][(i, j)].clone(),
631 arr[8][(i, j)].clone(),
632 arr[9][(i, j)].clone(),
633 arr[10][(i, j)].clone(),
634 arr[11][(i, j)].clone(),
635 arr[12][(i, j)].clone(),
636 arr[13][(i, j)].clone(),
637 arr[14][(i, j)].clone(),
638 arr[15][(i, j)].clone(),
639 ]
640 .into()
641 })
642 }
643}