devela/num/traits/
mod.rs

1// devela::num::trait
2//
3//!
4//
5
6use crate::{sf, Deref, DerefMut, NumError as E, NumResult as Result};
7#[cfg(doc)]
8use E::{NotImplemented, NotSupported};
9
10mod constants; // ExtNumConst
11pub use constants::*;
12
13mod impls;
14
15sf! {
16    impl<T: Num> NumRef<'_> for &T { type Own = T; }
17    impl<T: Num> NumRef<'_> for &mut T { type Own = T; }
18}
19
20/// Common trait for numeric types.
21///
22/// # Notes
23/// - Every method has a default implementation that returns [`NotImplemented`].
24/// - Specific implementations can customize the operations it wants to support.
25/// - Any operations specifically not supported should ideally return [`NotSupported`].
26///
27/// - Most methods come in two variants, starting with different prefixes:
28///   - `num_*` methods take the arguments by value.
29///   - `num_ref_*` methods take the arguments by reference.
30///
31/// - This trait tries to offer the same methods everywhere, giving a result when possible.
32/// - Operations are generally supported if they can be valid for some values.
33/// E.g. `num_abs` for unsigned types is only valid for `0`.
34///
35/// See also [`NumRef`] which is automatically implemented for `Num` references.
36#[rustfmt::skip]
37#[cfg_attr(feature = "nightly_doc", doc(notable_trait))]
38#[allow(unused_variables, reason = "default implementation is not implemented")]
39pub trait Num {
40    /// The internal representation of this numeric type.
41    type Inner;
42
43    /// The output type for operations.
44    type Out;
45
46    /// The right hand side type for operations.
47    type Rhs;
48
49    /// Returns the inner `self` representation.
50    #[must_use]
51    fn num_into(self) -> Self::Inner;
52
53    /// Returns `Self` if given a valid `value`.
54    fn num_from(value: Self::Inner) -> Result<Self>
55        where Self: Sized { E::ni() }
56    /// Returns `Self` if given a valid `&value`.
57    fn num_from_ref(value: &Self::Inner) -> Result<Self>
58        where Self: Sized { E::ni() }
59
60    /// Sets `self` to the given valid `value`.
61    fn num_set(&mut self, value: Self::Inner) -> Result<()> { E::ni() }
62    /// Sets `self` to the given valid `&value`.
63    fn num_set_ref(&mut self, value: &Self::Inner) -> Result<()> { E::ni() }
64
65    /* Identities */
66
67    /// Returns `true` if `self` is zero.
68    fn num_is_zero(&self) -> Result<bool> { E::ni() }
69    /// Returns the number zero.
70    fn num_get_zero() -> Result<Self> where Self: Sized { E::ni() }
71    /// Sets `self` to `0`.
72    fn num_set_zero(&mut self) -> Result<()> { E::ni() }
73
74    /// Returns `true` if `self` is one.
75    fn num_is_one(&self) -> Result<bool> { E::ni() }
76    /// Returns the number one.
77    fn num_get_one() -> Result<Self> where Self: Sized { E::ni() }
78    /// Sets the number to one.
79    fn num_set_one(&mut self) -> Result<()> { E::ni() }
80
81    /* Operations */
82
83    /// Computes `self + rhs` (addition).
84    fn num_add(self, rhs: Self::Rhs) -> Result<Self::Out> where Self: Sized { E::ni() }
85    /// *Like [`num_add`][Self::num_add] but takes the arguments by reference.*
86    fn num_ref_add(&self, rhs: &Self::Rhs) -> Result<Self::Out> { E::ni() }
87    /// Computes `&mut self += rhs;` (addition).
88    fn num_ref_add_assign(&mut self, rhs: &Self::Rhs) -> Result<()> { E::ni() }
89
90    /// Computes `self - rhs` (subtraction).
91    fn num_sub(self, rhs: Self::Rhs) -> Result<Self::Out> where Self: Sized { E::ni() }
92    /// *Like [`num_sub`][Self::num_sub] but takes the arguments by reference.*
93    fn num_ref_sub(&self, rhs: &Self::Rhs) -> Result<Self::Out> { E::ni() }
94    /// Computes `&mut self -= rhs;` (subtraction).
95    fn num_ref_sub_assign(&mut self, rhs: &Self::Rhs) -> Result<()> { E::ni() }
96
97    /// Computes `self * rhs` (multiplication).
98    fn num_mul(self, rhs: Self::Rhs) -> Result<Self::Out> where Self: Sized { E::ni() }
99    /// *Like [`num_mul`][Self::num_mul] but takes the arguments by reference.*
100    fn num_ref_mul(&self, rhs: &Self::Rhs) -> Result<Self::Out> { E::ni() }
101    /// Computes `&mut self *= rhs;` (multiplication).
102    fn num_ref_mul_assign(&mut self, rhs: &Self::Rhs) -> Result<()> { E::ni() }
103
104    /// Computes `self / rhs` (division).
105    fn num_div(self, rhs: Self::Rhs) -> Result<Self::Out> where Self: Sized { E::ni() }
106    /// *Like [`num_div`][Self::num_div] but takes the arguments by reference.*
107    fn num_ref_div(&self, rhs: &Self::Rhs) -> Result<Self::Out> { E::ni() }
108    /// Computes `&mut self /= rhs;` (division).
109    fn num_ref_div_assign(&mut self, rhs: &Self::Rhs) -> Result<()> { E::ni() }
110
111    /// Computes `self % rhs` (remainder).
112    fn num_rem(self, rhs: Self::Rhs) -> Result<Self::Out> where Self: Sized { E::ni() }
113    /// *Like [`num_rem`][Self::num_rem] but takes the arguments by reference.*
114    fn num_ref_rem(&self, rhs: &Self::Rhs) -> Result<Self::Out> { E::ni() }
115    /// Computes `&mut self %= rhs;` (remainder).
116    fn num_ref_rem_assign(&mut self, rhs: &Self::Rhs) -> Result<()> { E::ni() }
117
118    /// Computes `-self` (additive inverse).
119    fn num_neg(self) -> Result<Self::Out> where Self: Sized { E::ni() }
120    /// *Like [`num_neg`][Self::num_neg] but takes the arguments by reference.*
121    fn num_ref_neg(&self) -> Result<Self::Out> { E::ni() }
122
123    /// Computes `|self|` (absolute value).
124    fn num_abs(self) -> Result<Self::Out> where Self: Sized { E::ni() }
125    /// *Like [`num_abs`][Self::num_abs] but takes the arguments by reference.*
126    fn num_ref_abs(&self) -> Result<Self::Out> { E::ni() }
127}
128
129/// Common auto-trait for referenced numeric types.
130///
131/// It is automatically implemented for references of types implementing [`Num`].
132/// Mutable operations are only available for exclusive (`&mut`) references.
133#[rustfmt::skip]
134#[cfg_attr(feature = "nightly_doc", doc(notable_trait))]
135pub trait NumRef<'a> where Self: Deref<Target = Self::Own> {
136    /// The owned version of this numeric type.
137    type Own: Num;
138
139    /// Returns the owned version of `self`, if it can be cloned.
140    fn num_to_owned(&self) -> Result<Self::Own> where Self::Own: Clone { Ok((*self).clone()) }
141
142    /// Sets `self` to a valid `value`.
143    fn num_set(&mut self, value: <Self::Own as Num>::Inner) -> Result<()>
144        where Self: DerefMut<Target = Self::Own> { self.deref_mut().num_set(value) }
145
146    /// Sets `self` to a valid `&value`.
147    fn num_set_ref(&mut self, value: &<Self::Own as Num>::Inner) -> Result<()>
148        where Self: DerefMut<Target = Self::Own> { self.deref_mut().num_set_ref(value) }
149
150    /* Identities */
151
152    /// Returns `true` if `self` is zero.
153    fn num_is_zero(&self) -> Result<bool> { self.deref().num_is_zero() }
154    /// Returns the number zero.
155    fn num_get_zero() -> Result<Self::Own> { Self::Own::num_get_zero() }
156    /// Sets `self` to zero.
157    fn num_set_zero(&mut self) -> Result<()>
158        where Self: DerefMut<Target = Self::Own> { self.deref_mut().num_set_zero() }
159
160    /// Returns `true` if `self` is one.
161    fn num_is_one(&self) -> Result<bool> { self.deref().num_is_one() }
162    /// Returns the number one.
163    fn num_get_one() -> Result<Self::Own> { Self::Own::num_get_one() }
164    /// Sets the number to one.
165    fn num_set_one(&mut self) -> Result<()>
166        where Self: DerefMut<Target = Self::Own> { self.deref_mut().num_set_one() }
167
168    /* Operations */
169
170    /// Computes `&self + &rhs`.
171    fn num_ref_add(&self, rhs: &<Self::Own as Num>::Rhs) -> Result<<Self::Own as Num>::Out> {
172        self.deref().num_ref_add(rhs) }
173    /// Computes `&mut self += &rhs`.
174    fn num_ref_add_assign(&mut self, rhs: &<Self::Own as Num>::Rhs) -> Result<()>
175    where Self: DerefMut<Target = Self::Own> { self.deref_mut().num_ref_add_assign(rhs) }
176
177    /// Computes `&self - &rhs`.
178    fn num_ref_sub(&self, rhs: &<Self::Own as Num>::Rhs) -> Result<<Self::Own as Num>::Out> {
179        self.deref().num_ref_sub(rhs) }
180    /// Computes `&mut self -= &rhs`.
181    fn num_ref_sub_assign(&mut self, rhs: &<Self::Own as Num>::Rhs) -> Result<()>
182    where Self: DerefMut<Target = Self::Own> { self.deref_mut().num_ref_sub_assign(rhs) }
183
184    /// Computes `&self * &rhs`.
185    fn num_ref_mul(&self, rhs: &<Self::Own as Num>::Rhs) -> Result<<Self::Own as Num>::Out> {
186        self.deref().num_ref_mul(rhs) }
187    /// Computes `&mut self *= &rhs`.
188    fn num_ref_mul_assign(&mut self, rhs: &<Self::Own as Num>::Rhs) -> Result<()>
189    where Self: DerefMut<Target = Self::Own> { self.deref_mut().num_ref_mul_assign(rhs) }
190
191    /// Computes `&self / &rhs`.
192    fn num_ref_div(&self, rhs: &<Self::Own as Num>::Rhs) -> Result<<Self::Own as Num>::Out> {
193        self.deref().num_ref_div(rhs) }
194    /// Computes `&mut self /= &rhs`.
195    fn num_ref_div_assign(&mut self, rhs: &<Self::Own as Num>::Rhs) -> Result<()>
196    where Self: DerefMut<Target = Self::Own> { self.deref_mut().num_ref_div_assign(rhs) }
197
198    /// Computes `&self % &rhs`.
199    fn num_ref_rem(&self, rhs: &<Self::Own as Num>::Rhs) -> Result<<Self::Own as Num>::Out> {
200        self.deref().num_ref_rem(rhs) }
201    /// Computes `&mut self %= &rhs`.
202    fn num_ref_rem_assign(&mut self, rhs: &<Self::Own as Num>::Rhs) -> Result<()>
203    where Self: DerefMut<Target = Self::Own> { self.deref_mut().num_ref_rem_assign(rhs) }
204
205    /// Computes `- &self`.
206    fn num_ref_neg(&self) -> Result<<Self::Own as Num>::Out> { self.deref().num_ref_neg() }
207
208    /// Computes the absolute value of `&self`.
209    fn num_ref_abs(&self) -> Result<<Self::Own as Num>::Out> { self.deref().num_ref_abs() }
210}