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}