1use {
18 crate::SCell,
19 num_traits::{
20 CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedSub, Num, One, Signed,
21 Zero,
22 },
23 std::{
24 ops::{Add, Div, Mul, Not, Rem, Sub},
25 str::FromStr,
26 },
27};
28
29impl<T> SCell<T> {
31 pub fn new(data: T) -> Self {
33 SCell { data }
34 }
35 pub fn get_data(&self) -> &T {
37 &self.data
38 }
39}
40
41impl<T: Zero> SCell<T> {
43 pub fn zero() -> Self {
45 SCell::new(T::zero())
46 }
47 pub fn is_zero(&self) -> bool {
49 self.data.is_zero()
50 }
51}
52impl<T: One + PartialEq> SCell<T> {
53 pub fn one() -> Self {
55 SCell::new(T::one())
56 }
57 pub fn is_one(&self) -> bool {
59 self.data.is_one()
60 }
61}
62
63ops!(+=, add, Add);
65ops!(-=, sub, Sub);
66ops!(*=, mul, Mul);
67ops!(/=, div, Div);
68ops!(%=, rem, Rem);
69ops!(neg);
70
71impl<T: Num + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + CheckedRem> SCell<T> {
73 pub fn from_str_radix(str: &str, radix: u32) -> Result<Self, T::FromStrRadixErr> {
75 let data = T::from_str_radix(str, radix)?;
76 Ok(SCell { data })
77 }
78}
79
80impl<
82 T: Signed
83 + CheckedAdd
84 + CheckedSub
85 + CheckedMul
86 + CheckedDiv
87 + CheckedRem
88 + CheckedNeg
89 + Ord
90 + Copy,
91 > SCell<T>
92{
93 pub fn abs(&self) -> Option<Self> {
95 if *self < Self::zero() {
96 -*self
97 } else {
98 Some(*self)
99 }
100 }
101 pub fn abs_sub(&self, other: &Self) -> Option<Self> {
103 if *self <= *other {
104 Some(Self::zero())
105 } else {
106 *self - *other
107 }
108 }
109 pub fn signum(&self) -> Self {
111 SCell {
112 data: self.data.signum(),
113 }
114 }
115 pub fn is_positive(&self) -> bool {
117 self.data.is_positive()
118 }
119 pub fn is_negative(&self) -> bool {
121 self.data.is_negative()
122 }
123}
124
125impl<T: FromStr> FromStr for SCell<T> {
127 type Err = T::Err;
128 fn from_str(s: &str) -> Result<Self, Self::Err> {
129 Ok(SCell::new(T::from_str(s)?))
130 }
131}
132
133impl<T: Not> Not for SCell<T> {
135 type Output = SCell<T::Output>;
136 fn not(self) -> Self::Output {
137 SCell::new(!self.data)
138 }
139}