Skip to main content

relp_num/
one.rs

1//! # One
2//!
3//! A type that is always one.
4use std::fmt;
5use std::ops::{Add, AddAssign, Div, };
6use std::ops::Mul;
7
8use crate::{NonZero, Sign, Signed};
9
10/// # One
11///
12/// A ZST who's value is always `1`.
13///
14/// Can be used when a type from the `MatrixProvider` can only have the value `1`, such as with some
15/// certain network problems, where the cost of a path might always equal `1`. Storing a rational
16/// number in such a matrix would waste both space and time; this type stores the coefficient in no
17/// space at all, and [`Absorb`](crate::Absorb) applies it to a wide accumulator without ever
18/// materialising a `1`: multiplying by it is a clone, adding it is a single increment.
19///
20/// This type is zero-sized.
21///
22/// # Absent traits
23///
24/// There is deliberately no [`Neg`](std::ops::Neg) and no [`Negateable`](crate::Negateable) impl:
25/// `-1` is not a value this type can represent, so negation would have to lie about its result.
26/// Use [`SignedOne`](crate::fixed::SignedOne) when the coefficient can have either sign.
27#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
28pub struct One;
29
30impl num_traits::One for One {
31    #[inline]
32    fn one() -> Self {
33        Self
34    }
35}
36
37impl Mul<One> for One {
38    type Output = Self;
39
40    #[inline]
41    fn mul(self, _rhs: One) -> Self::Output {
42        Self
43    }
44}
45
46/// The only value of this type is `1`, which is positive.
47impl Signed for One {
48    #[inline]
49    fn signum(&self) -> Sign {
50        Sign::Positive
51    }
52}
53
54impl NonZero for One {
55    #[inline]
56    fn is_not_zero(&self) -> bool {
57        true
58    }
59}
60
61/// Debug forwards to `Display`, because `1` reads better in test output than `One`.
62impl fmt::Debug for One {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        fmt::Display::fmt(&self, f)
65    }
66}
67
68impl fmt::Display for One {
69    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70        f.write_str("1")
71    }
72}
73
74macro_rules! define_ops {
75    ($primitive:ident) => {
76        impl From<One> for $primitive {
77            fn from(_: One) -> Self {
78                1
79            }
80        }
81
82        impl From<&One> for $primitive {
83            fn from(_: &One) -> Self {
84                1
85            }
86        }
87
88        impl Add<One> for $primitive {
89            type Output = Self;
90
91            fn add(self, _: One) -> Self::Output {
92                self + 1
93            }
94        }
95
96        impl Add<&One> for $primitive {
97            type Output = Self;
98
99            fn add(self, _: &One) -> Self::Output {
100                self + 1
101            }
102        }
103
104        impl AddAssign<&One> for $primitive {
105            fn add_assign(&mut self, _: &One) {
106                *self += 1;
107            }
108        }
109
110        impl Mul<One> for $primitive {
111            type Output = Self;
112
113            fn mul(self, _: One) -> Self::Output {
114                self
115            }
116        }
117
118        impl Mul<&One> for $primitive {
119            type Output = Self;
120
121            fn mul(self, _: &One) -> Self::Output {
122                self
123            }
124        }
125
126        impl Mul<&One> for &$primitive {
127            type Output = $primitive;
128
129            fn mul(self, _: &One) -> Self::Output {
130                *self
131            }
132        }
133
134        impl Div<One> for $primitive {
135            type Output = Self;
136
137            fn div(self, _: One) -> Self::Output {
138                self
139            }
140        }
141
142        impl Div<&One> for $primitive {
143            type Output = Self;
144
145            fn div(self, _: &One) -> Self::Output {
146                self
147            }
148        }
149    }
150}
151
152define_ops!(i8);
153define_ops!(i16);
154define_ops!(i32);
155define_ops!(i64);
156define_ops!(i128);
157define_ops!(u8);
158define_ops!(u16);
159define_ops!(u32);
160define_ops!(u64);
161define_ops!(u128);
162
163#[cfg(test)]
164mod test {
165    use std::cmp::Ordering;
166
167    use crate::{NonZero, Sign, Signed};
168    use crate::fixed::One;
169
170    #[test]
171    fn test_one() {
172        assert_eq!(<One as num_traits::One>::one(), One);
173        assert_eq!(One * One, One);
174    }
175
176    /// Constructing a unit struct through `Default` is exactly what is under test here.
177    #[test]
178    #[allow(clippy::default_constructed_unit_structs)]
179    fn test_default() {
180        assert_eq!(One::default(), One);
181    }
182
183    #[test]
184    fn test_signum() {
185        assert_eq!(One.signum(), Sign::Positive);
186        assert!(One.is_positive());
187        assert!(!One.is_negative());
188    }
189
190    #[test]
191    fn test_non_zero() {
192        assert!(One.is_not_zero());
193    }
194
195    #[test]
196    fn test_ord() {
197        assert_eq!(One.cmp(&One), Ordering::Equal);
198        assert_eq!(One.partial_cmp(&One), Some(Ordering::Equal));
199        assert_eq!(One, One);
200    }
201
202    #[test]
203    fn test_display() {
204        assert_eq!(One.to_string(), "1");
205        assert_eq!(format!("{One:?}"), "1");
206    }
207
208    #[test]
209    fn test_integer() {
210        assert_eq!(1 + One, 2);
211        assert_eq!(-1 + One, 0);
212        assert_eq!(33 / One, 33);
213        assert_eq!(-33 / &One, -33);
214        assert_eq!(894 * One, 894);
215        assert_eq!(-894 * &One, -894);
216        assert_eq!(0_u8 * &One, 0);
217    }
218}