use crate::internal_prelude::*;
pub(crate) mod diagmut;
pub(crate) mod diagown;
pub(crate) mod diagref;
pub use diagmut::Mut;
pub use diagown::Own;
pub use diagref::Ref;
pub type DiagRef<'a, T, Dim = usize, Stride = isize> =
generic::Diag<Ref<'a, T, Dim, Stride>>;
pub type DiagMut<'a, T, Dim = usize, Stride = isize> =
generic::Diag<Mut<'a, T, Dim, Stride>>;
pub type Diag<T, Dim = usize> = generic::Diag<Own<T, Dim>>;
#[doc(hidden)]
pub mod generic {
use crate::{Idx, Shape};
use core::fmt::Debug;
use core::ops::{Index, IndexMut};
use reborrow::*;
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct Diag<Inner>(pub Inner);
impl<Inner: Debug> Debug for Diag<Inner> {
#[inline(always)]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.0.fmt(f)
}
}
impl<Inner> Diag<Inner> {
#[inline(always)]
pub fn from_inner_ref(inner: &Inner) -> &Self {
unsafe { &*(inner as *const Inner as *const Self) }
}
#[inline(always)]
pub fn from_inner_mut(inner: &mut Inner) -> &mut Self {
unsafe { &mut *(inner as *mut Inner as *mut Self) }
}
}
impl<Inner> core::ops::Deref for Diag<Inner> {
type Target = Inner;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<Inner> core::ops::DerefMut for Diag<Inner> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<'short, Inner: Reborrow<'short>> Reborrow<'short> for Diag<Inner> {
type Target = Diag<Inner::Target>;
#[inline(always)]
fn rb(&'short self) -> Self::Target {
Diag(self.0.rb())
}
}
impl<'short, Inner: ReborrowMut<'short>> ReborrowMut<'short> for Diag<Inner> {
type Target = Diag<Inner::Target>;
#[inline(always)]
fn rb_mut(&'short mut self) -> Self::Target {
Diag(self.0.rb_mut())
}
}
impl<Inner: IntoConst> IntoConst for Diag<Inner> {
type Target = Diag<Inner::Target>;
#[inline(always)]
fn into_const(self) -> Self::Target {
Diag(self.0.into_const())
}
}
impl<
T,
Dim: Shape,
Stride: crate::Stride,
Inner: for<'short> Reborrow<
'short,
Target = super::Ref<'short, T, Dim, Stride>,
>,
> Index<Idx<Dim>> for Diag<Inner>
{
type Output = T;
#[inline]
#[track_caller]
fn index(&self, idx: Idx<Dim>) -> &Self::Output {
self.rb().column_vector().at(idx)
}
}
impl<
T,
Dim: Shape,
Stride: crate::Stride,
Inner: for<'short> Reborrow<
'short,
Target = super::Ref<'short, T, Dim, Stride>,
> + for<'short> ReborrowMut<
'short,
Target = super::Mut<'short, T, Dim, Stride>,
>,
> IndexMut<Idx<Dim>> for Diag<Inner>
{
#[inline]
#[track_caller]
fn index_mut(&mut self, idx: Idx<Dim>) -> &mut Self::Output {
self.rb_mut().column_vector_mut().at_mut(idx)
}
}
}
pub trait AsDiagMut: AsDiagRef {
fn as_diag_mut(&mut self) -> DiagMut<'_, Self::T, Self::Dim>;
}
pub trait AsDiagRef {
type T;
type Dim: Shape;
fn as_diag_ref(&self) -> DiagRef<'_, Self::T, Self::Dim>;
}
impl<T, Dim: Shape, Stride: crate::Stride> AsDiagRef
for DiagRef<'_, T, Dim, Stride>
{
type Dim = Dim;
type T = T;
#[inline]
fn as_diag_ref(&self) -> DiagRef<'_, Self::T, Self::Dim> {
self.as_dyn_stride()
}
}
impl<T, Dim: Shape, Stride: crate::Stride> AsDiagRef
for DiagMut<'_, T, Dim, Stride>
{
type Dim = Dim;
type T = T;
#[inline]
fn as_diag_ref(&self) -> DiagRef<'_, Self::T, Self::Dim> {
self.rb().as_dyn_stride()
}
}
impl<T, Dim: Shape, Stride: crate::Stride> AsDiagMut
for DiagMut<'_, T, Dim, Stride>
{
#[inline]
fn as_diag_mut(&mut self) -> DiagMut<'_, Self::T, Self::Dim> {
self.rb_mut().as_dyn_stride_mut()
}
}
impl<M: AsDiagRef> AsDiagRef for &M {
type Dim = M::Dim;
type T = M::T;
#[inline]
fn as_diag_ref(&self) -> DiagRef<'_, Self::T, Self::Dim> {
(**self).as_diag_ref()
}
}
impl<M: AsDiagRef> AsDiagRef for &mut M {
type Dim = M::Dim;
type T = M::T;
#[inline]
fn as_diag_ref(&self) -> DiagRef<'_, Self::T, Self::Dim> {
(**self).as_diag_ref()
}
}
impl<M: AsDiagMut> AsDiagMut for &mut M {
#[inline]
fn as_diag_mut(&mut self) -> DiagMut<'_, Self::T, Self::Dim> {
(**self).as_diag_mut()
}
}