Coverage Report

Created: 2025-07-11 07:01

/rust/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/identities.rs
Line
Count
Source (jump to first uncovered line)
1
use core::num::Wrapping;
2
use core::ops::{Add, Mul};
3
4
/// Defines an additive identity element for `Self`.
5
///
6
/// # Laws
7
///
8
/// ```text
9
/// a + 0 = a       ∀ a ∈ Self
10
/// 0 + a = a       ∀ a ∈ Self
11
/// ```
12
pub trait Zero: Sized + Add<Self, Output = Self> {
13
    /// Returns the additive identity element of `Self`, `0`.
14
    /// # Purity
15
    ///
16
    /// This function should return the same result at all times regardless of
17
    /// external mutable state, for example values stored in TLS or in
18
    /// `static mut`s.
19
    // This cannot be an associated constant, because of bignums.
20
    fn zero() -> Self;
21
22
    /// Sets `self` to the additive identity element of `Self`, `0`.
23
0
    fn set_zero(&mut self) {
24
0
        *self = Zero::zero();
25
0
    }
26
27
    /// Returns `true` if `self` is equal to the additive identity.
28
    fn is_zero(&self) -> bool;
29
}
30
31
/// Defines an associated constant representing the additive identity element
32
/// for `Self`.
33
pub trait ConstZero: Zero {
34
    /// The additive identity element of `Self`, `0`.
35
    const ZERO: Self;
36
}
37
38
macro_rules! zero_impl {
39
    ($t:ty, $v:expr) => {
40
        impl Zero for $t {
41
            #[inline]
42
0
            fn zero() -> $t {
43
0
                $v
44
0
            }
Unexecuted instantiation: <usize as num_traits::identities::Zero>::zero
Unexecuted instantiation: <u8 as num_traits::identities::Zero>::zero
Unexecuted instantiation: <u16 as num_traits::identities::Zero>::zero
Unexecuted instantiation: <u32 as num_traits::identities::Zero>::zero
Unexecuted instantiation: <u64 as num_traits::identities::Zero>::zero
Unexecuted instantiation: <u128 as num_traits::identities::Zero>::zero
Unexecuted instantiation: <isize as num_traits::identities::Zero>::zero
Unexecuted instantiation: <i8 as num_traits::identities::Zero>::zero
Unexecuted instantiation: <i16 as num_traits::identities::Zero>::zero
Unexecuted instantiation: <i32 as num_traits::identities::Zero>::zero
Unexecuted instantiation: <i64 as num_traits::identities::Zero>::zero
Unexecuted instantiation: <i128 as num_traits::identities::Zero>::zero
Unexecuted instantiation: <f32 as num_traits::identities::Zero>::zero
Unexecuted instantiation: <f64 as num_traits::identities::Zero>::zero
45
            #[inline]
46
0
            fn is_zero(&self) -> bool {
47
0
                *self == $v
48
0
            }
Unexecuted instantiation: <usize as num_traits::identities::Zero>::is_zero
Unexecuted instantiation: <u8 as num_traits::identities::Zero>::is_zero
Unexecuted instantiation: <u16 as num_traits::identities::Zero>::is_zero
Unexecuted instantiation: <u32 as num_traits::identities::Zero>::is_zero
Unexecuted instantiation: <u64 as num_traits::identities::Zero>::is_zero
Unexecuted instantiation: <u128 as num_traits::identities::Zero>::is_zero
Unexecuted instantiation: <isize as num_traits::identities::Zero>::is_zero
Unexecuted instantiation: <i8 as num_traits::identities::Zero>::is_zero
Unexecuted instantiation: <i16 as num_traits::identities::Zero>::is_zero
Unexecuted instantiation: <i32 as num_traits::identities::Zero>::is_zero
Unexecuted instantiation: <i64 as num_traits::identities::Zero>::is_zero
Unexecuted instantiation: <i128 as num_traits::identities::Zero>::is_zero
Unexecuted instantiation: <f32 as num_traits::identities::Zero>::is_zero
Unexecuted instantiation: <f64 as num_traits::identities::Zero>::is_zero
49
        }
50
51
        impl ConstZero for $t {
52
            const ZERO: Self = $v;
53
        }
54
    };
55
}
56
57
zero_impl!(usize, 0);
58
zero_impl!(u8, 0);
59
zero_impl!(u16, 0);
60
zero_impl!(u32, 0);
61
zero_impl!(u64, 0);
62
zero_impl!(u128, 0);
63
64
zero_impl!(isize, 0);
65
zero_impl!(i8, 0);
66
zero_impl!(i16, 0);
67
zero_impl!(i32, 0);
68
zero_impl!(i64, 0);
69
zero_impl!(i128, 0);
70
71
zero_impl!(f32, 0.0);
72
zero_impl!(f64, 0.0);
73
74
impl<T: Zero> Zero for Wrapping<T>
75
where
76
    Wrapping<T>: Add<Output = Wrapping<T>>,
77
{
78
0
    fn is_zero(&self) -> bool {
79
0
        self.0.is_zero()
80
0
    }
81
82
0
    fn set_zero(&mut self) {
83
0
        self.0.set_zero();
84
0
    }
85
86
0
    fn zero() -> Self {
87
0
        Wrapping(T::zero())
88
0
    }
89
}
90
91
impl<T: ConstZero> ConstZero for Wrapping<T>
92
where
93
    Wrapping<T>: Add<Output = Wrapping<T>>,
94
{
95
    const ZERO: Self = Wrapping(T::ZERO);
96
}
97
98
/// Defines a multiplicative identity element for `Self`.
99
///
100
/// # Laws
101
///
102
/// ```text
103
/// a * 1 = a       ∀ a ∈ Self
104
/// 1 * a = a       ∀ a ∈ Self
105
/// ```
106
pub trait One: Sized + Mul<Self, Output = Self> {
107
    /// Returns the multiplicative identity element of `Self`, `1`.
108
    ///
109
    /// # Purity
110
    ///
111
    /// This function should return the same result at all times regardless of
112
    /// external mutable state, for example values stored in TLS or in
113
    /// `static mut`s.
114
    // This cannot be an associated constant, because of bignums.
115
    fn one() -> Self;
116
117
    /// Sets `self` to the multiplicative identity element of `Self`, `1`.
118
0
    fn set_one(&mut self) {
119
0
        *self = One::one();
120
0
    }
121
122
    /// Returns `true` if `self` is equal to the multiplicative identity.
123
    ///
124
    /// For performance reasons, it's best to implement this manually.
125
    /// After a semver bump, this method will be required, and the
126
    /// `where Self: PartialEq` bound will be removed.
127
    #[inline]
128
0
    fn is_one(&self) -> bool
129
0
    where
130
0
        Self: PartialEq,
131
0
    {
132
0
        *self == Self::one()
133
0
    }
134
}
135
136
/// Defines an associated constant representing the multiplicative identity
137
/// element for `Self`.
138
pub trait ConstOne: One {
139
    /// The multiplicative identity element of `Self`, `1`.
140
    const ONE: Self;
141
}
142
143
macro_rules! one_impl {
144
    ($t:ty, $v:expr) => {
145
        impl One for $t {
146
            #[inline]
147
0
            fn one() -> $t {
148
0
                $v
149
0
            }
Unexecuted instantiation: <f32 as num_traits::identities::One>::one
Unexecuted instantiation: <f64 as num_traits::identities::One>::one
Unexecuted instantiation: <usize as num_traits::identities::One>::one
Unexecuted instantiation: <u8 as num_traits::identities::One>::one
Unexecuted instantiation: <u16 as num_traits::identities::One>::one
Unexecuted instantiation: <u32 as num_traits::identities::One>::one
Unexecuted instantiation: <u64 as num_traits::identities::One>::one
Unexecuted instantiation: <u128 as num_traits::identities::One>::one
Unexecuted instantiation: <isize as num_traits::identities::One>::one
Unexecuted instantiation: <i8 as num_traits::identities::One>::one
Unexecuted instantiation: <i16 as num_traits::identities::One>::one
Unexecuted instantiation: <i32 as num_traits::identities::One>::one
Unexecuted instantiation: <i64 as num_traits::identities::One>::one
Unexecuted instantiation: <i128 as num_traits::identities::One>::one
150
            #[inline]
151
0
            fn is_one(&self) -> bool {
152
0
                *self == $v
153
0
            }
Unexecuted instantiation: <usize as num_traits::identities::One>::is_one
Unexecuted instantiation: <u8 as num_traits::identities::One>::is_one
Unexecuted instantiation: <u16 as num_traits::identities::One>::is_one
Unexecuted instantiation: <u32 as num_traits::identities::One>::is_one
Unexecuted instantiation: <u64 as num_traits::identities::One>::is_one
Unexecuted instantiation: <u128 as num_traits::identities::One>::is_one
Unexecuted instantiation: <isize as num_traits::identities::One>::is_one
Unexecuted instantiation: <i8 as num_traits::identities::One>::is_one
Unexecuted instantiation: <i16 as num_traits::identities::One>::is_one
Unexecuted instantiation: <i32 as num_traits::identities::One>::is_one
Unexecuted instantiation: <i64 as num_traits::identities::One>::is_one
Unexecuted instantiation: <i128 as num_traits::identities::One>::is_one
Unexecuted instantiation: <f32 as num_traits::identities::One>::is_one
Unexecuted instantiation: <f64 as num_traits::identities::One>::is_one
154
        }
155
156
        impl ConstOne for $t {
157
            const ONE: Self = $v;
158
        }
159
    };
160
}
161
162
one_impl!(usize, 1);
163
one_impl!(u8, 1);
164
one_impl!(u16, 1);
165
one_impl!(u32, 1);
166
one_impl!(u64, 1);
167
one_impl!(u128, 1);
168
169
one_impl!(isize, 1);
170
one_impl!(i8, 1);
171
one_impl!(i16, 1);
172
one_impl!(i32, 1);
173
one_impl!(i64, 1);
174
one_impl!(i128, 1);
175
176
one_impl!(f32, 1.0);
177
one_impl!(f64, 1.0);
178
179
impl<T: One> One for Wrapping<T>
180
where
181
    Wrapping<T>: Mul<Output = Wrapping<T>>,
182
{
183
0
    fn set_one(&mut self) {
184
0
        self.0.set_one();
185
0
    }
186
187
0
    fn one() -> Self {
188
0
        Wrapping(T::one())
189
0
    }
190
}
191
192
impl<T: ConstOne> ConstOne for Wrapping<T>
193
where
194
    Wrapping<T>: Mul<Output = Wrapping<T>>,
195
{
196
    const ONE: Self = Wrapping(T::ONE);
197
}
198
199
// Some helper functions provided for backwards compatibility.
200
201
/// Returns the additive identity, `0`.
202
#[inline(always)]
203
0
pub fn zero<T: Zero>() -> T {
204
0
    Zero::zero()
205
0
}
206
207
/// Returns the multiplicative identity, `1`.
208
#[inline(always)]
209
0
pub fn one<T: One>() -> T {
210
0
    One::one()
211
0
}
212
213
#[test]
214
fn wrapping_identities() {
215
    macro_rules! test_wrapping_identities {
216
        ($($t:ty)+) => {
217
            $(
218
                assert_eq!(zero::<$t>(), zero::<Wrapping<$t>>().0);
219
                assert_eq!(one::<$t>(), one::<Wrapping<$t>>().0);
220
                assert_eq!((0 as $t).is_zero(), Wrapping(0 as $t).is_zero());
221
                assert_eq!((1 as $t).is_zero(), Wrapping(1 as $t).is_zero());
222
            )+
223
        };
224
    }
225
226
    test_wrapping_identities!(isize i8 i16 i32 i64 usize u8 u16 u32 u64);
227
}
228
229
#[test]
230
fn wrapping_is_zero() {
231
    fn require_zero<T: Zero>(_: &T) {}
232
    require_zero(&Wrapping(42));
233
}
234
#[test]
235
fn wrapping_is_one() {
236
    fn require_one<T: One>(_: &T) {}
237
    require_one(&Wrapping(42));
238
}