acme_tensor/shape/
rank.rs1use core::borrow::Borrow;
9use core::ops::{Deref, DerefMut, Not};
10use num::traits::{Num, One, Zero};
11#[cfg(feature = "serde")]
12use serde::{Deserialize, Serialize};
13
14pub trait IntoRank {
15 fn into_rank(self) -> Rank;
16}
17
18impl IntoRank for usize {
19 fn into_rank(self) -> Rank {
20 Rank::new(self)
21 }
22}
23
24#[cfg_attr(feature = "serde", derive(Deserialize, Serialize,))]
25#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
26pub struct Rank(pub(crate) usize);
27
28impl Rank {
29 pub fn new(rank: usize) -> Self {
30 Self(rank)
31 }
32
33 pub const fn scalar() -> Self {
34 Self(0)
35 }
36
37 pub fn into_inner(self) -> usize {
38 self.0
39 }
40
41 pub fn is_scalar(&self) -> bool {
42 self.0 == 0
43 }
44
45 pub fn rank(&self) -> usize {
46 self.0
47 }
48}
49
50impl std::fmt::Display for Rank {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 write!(f, "{}", self.0)
53 }
54}
55
56impl AsRef<usize> for Rank {
57 fn as_ref(&self) -> &usize {
58 &self.0
59 }
60}
61
62impl AsMut<usize> for Rank {
63 fn as_mut(&mut self) -> &mut usize {
64 &mut self.0
65 }
66}
67
68impl Borrow<usize> for Rank {
69 fn borrow(&self) -> &usize {
70 &self.0
71 }
72}
73
74impl Deref for Rank {
75 type Target = usize;
76
77 fn deref(&self) -> &Self::Target {
78 &self.0
79 }
80}
81
82impl DerefMut for Rank {
83 fn deref_mut(&mut self) -> &mut Self::Target {
84 &mut self.0
85 }
86}
87
88impl From<usize> for Rank {
89 fn from(rank: usize) -> Self {
90 Self(rank)
91 }
92}
93
94impl From<Rank> for usize {
95 fn from(rank: Rank) -> Self {
96 rank.0
97 }
98}
99
100unsafe impl Send for Rank {}
101
102unsafe impl Sync for Rank {}
103
104impl_partial_eq!(Rank -> 0: [usize]);
105
106macro_rules! impl_std_ops {
107 ($(($trait:tt, $method:ident, $e:tt)),*) => {
108 $(
109 impl_std_ops!($trait, $method, $e);
110 )*
111 };
112 ($trait:tt, $method:ident, $e:tt) => {
113 impl core::ops::$trait<usize> for Rank {
114 type Output = Rank;
115
116 fn $method(self, rhs: usize) -> Self::Output {
117 let rank = self.0 $e rhs;
118 Rank(rank)
119 }
120 }
121
122 impl<'a> core::ops::$trait<usize> for &'a Rank {
123 type Output = Rank;
124
125 fn $method(self, rhs: usize) -> Self::Output {
126 let rank = self.0 $e rhs;
127 Rank(rank)
128 }
129 }
130
131 impl core::ops::$trait for Rank {
132 type Output = Rank;
133
134 fn $method(self, rhs: Rank) -> Self::Output {
135 let rank = self.0 $e rhs.0;
136 Rank(rank)
137 }
138 }
139
140 impl<'a> core::ops::$trait<Rank> for &'a Rank {
141 type Output = Rank;
142
143 fn $method(self, rhs: Rank) -> Self::Output {
144 let rank = self.0 $e rhs.0;
145 Rank(rank)
146 }
147 }
148
149 impl<'a> core::ops::$trait<&'a Rank> for Rank {
150 type Output = Rank;
151
152 fn $method(self, rhs: &'a Rank) -> Self::Output {
153 let rank = self.0 $e rhs.0;
154 Rank(rank)
155 }
156 }
157
158 impl<'a> core::ops::$trait<&'a Rank> for &'a Rank {
159 type Output = Rank;
160
161 fn $method(self, rhs: &'a Rank) -> Self::Output {
162 let rank = self.0 $e rhs.0;
163 Rank(rank)
164 }
165 }
166 };
167}
168
169impl_std_ops!((Add, add, +), (Sub, sub, -), (Mul, mul, *), (Div, div, /), (Rem, rem, %));
170
171impl Not for Rank {
172 type Output = Rank;
173
174 fn not(self) -> Self::Output {
175 Rank(!self.0)
176 }
177}
178
179impl Num for Rank {
180 type FromStrRadixErr = <usize as Num>::FromStrRadixErr;
181
182 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
183 usize::from_str_radix(str, radix).map(Rank)
184 }
185}
186
187impl One for Rank {
188 fn one() -> Self {
189 Self(1)
190 }
191}
192
193impl Zero for Rank {
194 fn zero() -> Self {
195 Self(0)
196 }
197
198 fn is_zero(&self) -> bool {
199 self.0 == 0
200 }
201}