use crate::{assert, col::*, row::*, utils::slice::*, Conj, Shape};
use coe::Coerce;
use core::{marker::PhantomData, ptr::NonNull};
use faer_entity::*;
use reborrow::*;
#[repr(C)]
struct MatImpl<E: Entity, R: Shape = usize, C: Shape = usize> {
ptr: GroupCopyFor<E, NonNull<E::Unit>>,
nrows: R,
ncols: C,
row_stride: isize,
col_stride: isize,
}
#[repr(C)]
struct MatOwnImpl<E: Entity, R: Shape = usize, C: Shape = usize> {
ptr: GroupCopyFor<E, NonNull<E::Unit>>,
nrows: R,
ncols: C,
}
unsafe impl<E: Entity, R: Shape, C: Shape> Sync for MatImpl<E, R, C> {}
unsafe impl<E: Entity, R: Shape, C: Shape> Send for MatImpl<E, R, C> {}
unsafe impl<E: Entity, R: Shape, C: Shape> Sync for MatOwnImpl<E, R, C> {}
unsafe impl<E: Entity, R: Shape, C: Shape> Send for MatOwnImpl<E, R, C> {}
impl<E: Entity, R: Shape, C: Shape> Copy for MatImpl<E, R, C> {}
impl<E: Entity, R: Shape, C: Shape> Clone for MatImpl<E, R, C> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}
pub trait MatIndex<RowRange, ColRange>: crate::seal::Seal + Sized {
type Target;
#[allow(clippy::missing_safety_doc)]
unsafe fn get_unchecked(this: Self, row: RowRange, col: ColRange) -> Self::Target {
<Self as MatIndex<RowRange, ColRange>>::get(this, row, col)
}
fn get(this: Self, row: RowRange, col: ColRange) -> Self::Target;
}
pub trait AsMatRef<E: Entity> {
type R: Shape;
type C: Shape;
fn as_mat_ref(&self) -> MatRef<'_, E, Self::R, Self::C>;
}
pub trait AsMatMut<E: Entity>: AsMatRef<E> {
fn as_mat_mut(&mut self) -> MatMut<'_, E, Self::R, Self::C>;
}
pub trait As2D<E: Entity> {
fn as_2d_ref(&self) -> MatRef<'_, E>;
}
impl<E: Entity, T: As2D<E>> As2D<E> for &T {
fn as_2d_ref(&self) -> MatRef<'_, E> {
(**self).as_2d_ref()
}
}
impl<E: Entity, T: As2D<E>> As2D<E> for &mut T {
fn as_2d_ref(&self) -> MatRef<'_, E> {
(**self).as_2d_ref()
}
}
pub trait As2DMut<E: Entity>: As2D<E> {
fn as_2d_mut(&mut self) -> MatMut<'_, E>;
}
impl<E: Entity, T: As2DMut<E>> As2DMut<E> for &mut T {
fn as_2d_mut(&mut self) -> MatMut<'_, E> {
(**self).as_2d_mut()
}
}
impl<E: Entity, T: AsMatRef<E>> AsMatRef<E> for &T {
type R = T::R;
type C = T::C;
fn as_mat_ref(&self) -> MatRef<'_, E, Self::R, Self::C> {
(**self).as_mat_ref()
}
}
impl<E: Entity, T: AsMatRef<E>> AsMatRef<E> for &mut T {
type R = T::R;
type C = T::C;
fn as_mat_ref(&self) -> MatRef<'_, E, Self::R, Self::C> {
(**self).as_mat_ref()
}
}
impl<E: Entity, T: AsMatMut<E>> AsMatMut<E> for &mut T {
fn as_mat_mut(&mut self) -> MatMut<'_, E, Self::R, Self::C> {
(**self).as_mat_mut()
}
}
impl<'a, FromE: Entity, ToE: Entity> Coerce<MatRef<'a, ToE>> for MatRef<'a, FromE> {
#[inline(always)]
fn coerce(self) -> MatRef<'a, ToE> {
assert!(coe::is_same::<FromE, ToE>());
unsafe { transmute_unchecked::<MatRef<'a, FromE>, MatRef<'a, ToE>>(self) }
}
}
impl<'a, FromE: Entity, ToE: Entity> Coerce<MatMut<'a, ToE>> for MatMut<'a, FromE> {
#[inline(always)]
fn coerce(self) -> MatMut<'a, ToE> {
assert!(coe::is_same::<FromE, ToE>());
unsafe { transmute_unchecked::<MatMut<'a, FromE>, MatMut<'a, ToE>>(self) }
}
}
mod mat_index;
mod matref;
pub use matref::{
from_column_major_slice, from_column_major_slice_generic, from_column_major_slice_with_stride,
from_column_major_slice_with_stride_generic, from_raw_parts, from_ref, from_ref_generic,
from_repeated_col, from_repeated_ref, from_repeated_ref_generic, from_repeated_row,
from_row_major_slice, from_row_major_slice_generic, from_row_major_slice_with_stride,
from_row_major_slice_with_stride_generic, MatRef,
};
mod matmut;
pub use matmut::{
from_column_major_slice_mut, from_column_major_slice_mut_generic,
from_column_major_slice_with_stride_mut, from_column_major_slice_with_stride_mut_generic,
from_mut, from_mut_generic, from_raw_parts_mut, from_row_major_slice_mut,
from_row_major_slice_mut_generic, from_row_major_slice_with_stride_mut,
from_row_major_slice_with_stride_mut_generic, MatMut,
};
mod matown;
pub use matown::Mat;
pub(crate) mod matalloc;
#[track_caller]
#[inline]
fn from_slice_assert(nrows: usize, ncols: usize, len: usize) {
let size = usize::checked_mul(nrows, ncols).unwrap_or(usize::MAX);
assert!(size == len);
}
#[track_caller]
#[inline]
fn from_strided_column_major_slice_assert(
nrows: usize,
ncols: usize,
col_stride: usize,
len: usize,
) {
if nrows > 0 && ncols > 0 {
let last = usize::checked_mul(col_stride, ncols - 1)
.and_then(|last_col| last_col.checked_add(nrows - 1))
.unwrap_or(usize::MAX);
assert!(last < len);
}
}
#[track_caller]
#[inline]
fn from_strided_column_major_slice_mut_assert(
nrows: usize,
ncols: usize,
col_stride: usize,
len: usize,
) {
if nrows > 0 && ncols > 0 {
let last = usize::checked_mul(col_stride, ncols - 1)
.and_then(|last_col| last_col.checked_add(nrows - 1))
.unwrap_or(usize::MAX);
assert!(all(col_stride >= nrows, last < len));
}
}
#[cfg(test)]
mod tests {
use super::*;
use equator::assert;
#[test]
fn test_from_ref() {
let x = crate::mat![[1.0, 2.0], [3.0, 4.0]];
let c = 100.0;
let sum = crate::mat![[101.0, 102.0], [103.0, 104.0]];
crate::dbgf!("6.2?", &sum);
assert!(&x + from_repeated_ref(&c, x.nrows(), x.ncols()) == sum);
}
#[test]
fn test_from_mut() {
let mut c = 100.0;
from_mut::<f64>(&mut c).fill(3.0);
assert!(c == 3.0);
}
#[test]
fn test_alloc() {
let mut a = crate::Mat::<f64>::zeros(2, 2);
a.reserve_exact(32, 0);
a.reserve_exact(33, 1);
a.resize_with(40, 1, |_, _| 0.0);
a.resize_with(50, 2, |_, _| 0.0);
a.resize_with(60, 1, |_, _| 0.0);
}
#[test]
fn test_int() {
let mut m = Mat::full(3, 4, 0u32);
m[(0, 0)] = 3;
}
}