1use crate::internal_prelude::*;
2
3pub(crate) mod diagmut;
4pub(crate) mod diagown;
5pub(crate) mod diagref;
6
7pub use diagmut::Mut;
8pub use diagown::Own;
9pub use diagref::Ref;
10
11pub type DiagRef<'a, T, Dim = usize, Stride = isize> = generic::Diag<Ref<'a, T, Dim, Stride>>;
13pub type DiagMut<'a, T, Dim = usize, Stride = isize> = generic::Diag<Mut<'a, T, Dim, Stride>>;
15pub type Diag<T, Dim = usize> = generic::Diag<Own<T, Dim>>;
17
18pub mod generic {
20	use crate::{Idx, Shape};
21	use core::fmt::Debug;
22	use core::ops::{Index, IndexMut};
23	use reborrow::*;
24
25	#[derive(Copy, Clone)]
27	#[repr(transparent)]
28	pub struct Diag<Inner>(pub Inner);
29
30	impl<Inner: Debug> Debug for Diag<Inner> {
31		#[inline(always)]
32		fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33			self.0.fmt(f)
34		}
35	}
36
37	impl<Inner> Diag<Inner> {
38		#[inline(always)]
40		pub fn from_inner_ref(inner: &Inner) -> &Self {
41			unsafe { &*(inner as *const Inner as *const Self) }
42		}
43
44		#[inline(always)]
46		pub fn from_inner_mut(inner: &mut Inner) -> &mut Self {
47			unsafe { &mut *(inner as *mut Inner as *mut Self) }
48		}
49	}
50
51	impl<Inner> core::ops::Deref for Diag<Inner> {
52		type Target = Inner;
53
54		#[inline(always)]
55		fn deref(&self) -> &Self::Target {
56			&self.0
57		}
58	}
59
60	impl<Inner> core::ops::DerefMut for Diag<Inner> {
61		#[inline(always)]
62		fn deref_mut(&mut self) -> &mut Self::Target {
63			&mut self.0
64		}
65	}
66
67	impl<'short, Inner: Reborrow<'short>> Reborrow<'short> for Diag<Inner> {
68		type Target = Diag<Inner::Target>;
69
70		#[inline(always)]
71		fn rb(&'short self) -> Self::Target {
72			Diag(self.0.rb())
73		}
74	}
75
76	impl<'short, Inner: ReborrowMut<'short>> ReborrowMut<'short> for Diag<Inner> {
77		type Target = Diag<Inner::Target>;
78
79		#[inline(always)]
80		fn rb_mut(&'short mut self) -> Self::Target {
81			Diag(self.0.rb_mut())
82		}
83	}
84
85	impl<Inner: IntoConst> IntoConst for Diag<Inner> {
86		type Target = Diag<Inner::Target>;
87
88		#[inline(always)]
89		fn into_const(self) -> Self::Target {
90			Diag(self.0.into_const())
91		}
92	}
93
94	impl<T, Dim: Shape, Stride: crate::Stride, Inner: for<'short> Reborrow<'short, Target = super::Ref<'short, T, Dim, Stride>>> Index<Idx<Dim>>
95		for Diag<Inner>
96	{
97		type Output = T;
98
99		#[inline]
100		#[track_caller]
101		fn index(&self, idx: Idx<Dim>) -> &Self::Output {
102			self.rb().column_vector().at(idx)
103		}
104	}
105
106	impl<
107		T,
108		Dim: Shape,
109		Stride: crate::Stride,
110		Inner: for<'short> Reborrow<'short, Target = super::Ref<'short, T, Dim, Stride>>
111			+ for<'short> ReborrowMut<'short, Target = super::Mut<'short, T, Dim, Stride>>,
112	> IndexMut<Idx<Dim>> for Diag<Inner>
113	{
114		#[inline]
115		#[track_caller]
116		fn index_mut(&mut self, idx: Idx<Dim>) -> &mut Self::Output {
117			self.rb_mut().column_vector_mut().at_mut(idx)
118		}
119	}
120}
121pub trait AsDiagMut: AsDiagRef {
123	fn as_diag_mut(&mut self) -> DiagMut<Self::T, Self::Dim>;
125}
126pub trait AsDiagRef {
128	type T;
130	type Dim: Shape;
132
133	fn as_diag_ref(&self) -> DiagRef<Self::T, Self::Dim>;
135}
136
137impl<T, Dim: Shape, Stride: crate::Stride> AsDiagRef for DiagRef<'_, T, Dim, Stride> {
138	type Dim = Dim;
139	type T = T;
140
141	#[inline]
142	fn as_diag_ref(&self) -> DiagRef<Self::T, Self::Dim> {
143		self.as_dyn_stride()
144	}
145}