Coverage Report

Created: 2025-08-28 06:06

/rust/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.15/src/sign.rs
Line
Count
Source (jump to first uncovered line)
1
use core::num::Wrapping;
2
use core::ops::Neg;
3
4
use float::FloatCore;
5
use Num;
6
7
/// Useful functions for signed numbers (i.e. numbers that can be negative).
8
pub trait Signed: Sized + Num + Neg<Output = Self> {
9
    /// Computes the absolute value.
10
    ///
11
    /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`.
12
    ///
13
    /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
14
    fn abs(&self) -> Self;
15
16
    /// The positive difference of two numbers.
17
    ///
18
    /// Returns `zero` if the number is less than or equal to `other`, otherwise the difference
19
    /// between `self` and `other` is returned.
20
    fn abs_sub(&self, other: &Self) -> Self;
21
22
    /// Returns the sign of the number.
23
    ///
24
    /// For `f32` and `f64`:
25
    ///
26
    /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
27
    /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
28
    /// * `NaN` if the number is `NaN`
29
    ///
30
    /// For signed integers:
31
    ///
32
    /// * `0` if the number is zero
33
    /// * `1` if the number is positive
34
    /// * `-1` if the number is negative
35
    fn signum(&self) -> Self;
36
37
    /// Returns true if the number is positive and false if the number is zero or negative.
38
    fn is_positive(&self) -> bool;
39
40
    /// Returns true if the number is negative and false if the number is zero or positive.
41
    fn is_negative(&self) -> bool;
42
}
43
44
macro_rules! signed_impl {
45
    ($($t:ty)*) => ($(
46
        impl Signed for $t {
47
            #[inline]
48
0
            fn abs(&self) -> $t {
49
0
                if self.is_negative() { -*self } else { *self }
50
0
            }
Unexecuted instantiation: <isize as num_traits::sign::Signed>::abs
Unexecuted instantiation: <i8 as num_traits::sign::Signed>::abs
Unexecuted instantiation: <i16 as num_traits::sign::Signed>::abs
Unexecuted instantiation: <i32 as num_traits::sign::Signed>::abs
Unexecuted instantiation: <i64 as num_traits::sign::Signed>::abs
Unexecuted instantiation: <i128 as num_traits::sign::Signed>::abs
51
52
            #[inline]
53
0
            fn abs_sub(&self, other: &$t) -> $t {
54
0
                if *self <= *other { 0 } else { *self - *other }
55
0
            }
Unexecuted instantiation: <isize as num_traits::sign::Signed>::abs_sub
Unexecuted instantiation: <i8 as num_traits::sign::Signed>::abs_sub
Unexecuted instantiation: <i16 as num_traits::sign::Signed>::abs_sub
Unexecuted instantiation: <i32 as num_traits::sign::Signed>::abs_sub
Unexecuted instantiation: <i64 as num_traits::sign::Signed>::abs_sub
Unexecuted instantiation: <i128 as num_traits::sign::Signed>::abs_sub
56
57
            #[inline]
58
0
            fn signum(&self) -> $t {
59
0
                match *self {
60
0
                    n if n > 0 => 1,
61
0
                    0 => 0,
62
0
                    _ => -1,
63
                }
64
0
            }
Unexecuted instantiation: <isize as num_traits::sign::Signed>::signum
Unexecuted instantiation: <i8 as num_traits::sign::Signed>::signum
Unexecuted instantiation: <i16 as num_traits::sign::Signed>::signum
Unexecuted instantiation: <i32 as num_traits::sign::Signed>::signum
Unexecuted instantiation: <i64 as num_traits::sign::Signed>::signum
Unexecuted instantiation: <i128 as num_traits::sign::Signed>::signum
65
66
            #[inline]
67
0
            fn is_positive(&self) -> bool { *self > 0 }
Unexecuted instantiation: <isize as num_traits::sign::Signed>::is_positive
Unexecuted instantiation: <i8 as num_traits::sign::Signed>::is_positive
Unexecuted instantiation: <i16 as num_traits::sign::Signed>::is_positive
Unexecuted instantiation: <i32 as num_traits::sign::Signed>::is_positive
Unexecuted instantiation: <i64 as num_traits::sign::Signed>::is_positive
Unexecuted instantiation: <i128 as num_traits::sign::Signed>::is_positive
68
69
            #[inline]
70
0
            fn is_negative(&self) -> bool { *self < 0 }
Unexecuted instantiation: <isize as num_traits::sign::Signed>::is_negative
Unexecuted instantiation: <i8 as num_traits::sign::Signed>::is_negative
Unexecuted instantiation: <i16 as num_traits::sign::Signed>::is_negative
Unexecuted instantiation: <i32 as num_traits::sign::Signed>::is_negative
Unexecuted instantiation: <i64 as num_traits::sign::Signed>::is_negative
Unexecuted instantiation: <i128 as num_traits::sign::Signed>::is_negative
71
        }
72
    )*)
73
}
74
75
signed_impl!(isize i8 i16 i32 i64);
76
77
#[cfg(has_i128)]
78
signed_impl!(i128);
79
80
impl<T: Signed> Signed for Wrapping<T>
81
where
82
    Wrapping<T>: Num + Neg<Output = Wrapping<T>>,
83
{
84
    #[inline]
85
0
    fn abs(&self) -> Self {
86
0
        Wrapping(self.0.abs())
87
0
    }
88
89
    #[inline]
90
0
    fn abs_sub(&self, other: &Self) -> Self {
91
0
        Wrapping(self.0.abs_sub(&other.0))
92
0
    }
93
94
    #[inline]
95
0
    fn signum(&self) -> Self {
96
0
        Wrapping(self.0.signum())
97
0
    }
98
99
    #[inline]
100
0
    fn is_positive(&self) -> bool {
101
0
        self.0.is_positive()
102
0
    }
103
104
    #[inline]
105
0
    fn is_negative(&self) -> bool {
106
0
        self.0.is_negative()
107
0
    }
108
}
109
110
macro_rules! signed_float_impl {
111
    ($t:ty) => {
112
        impl Signed for $t {
113
            /// Computes the absolute value. Returns `NAN` if the number is `NAN`.
114
            #[inline]
115
0
            fn abs(&self) -> $t {
116
0
                FloatCore::abs(*self)
117
0
            }
Unexecuted instantiation: <f32 as num_traits::sign::Signed>::abs
Unexecuted instantiation: <f64 as num_traits::sign::Signed>::abs
118
119
            /// The positive difference of two numbers. Returns `0.0` if the number is
120
            /// less than or equal to `other`, otherwise the difference between`self`
121
            /// and `other` is returned.
122
            #[inline]
123
0
            fn abs_sub(&self, other: &$t) -> $t {
124
0
                if *self <= *other {
125
0
                    0.
126
                } else {
127
0
                    *self - *other
128
                }
129
0
            }
Unexecuted instantiation: <f32 as num_traits::sign::Signed>::abs_sub
Unexecuted instantiation: <f64 as num_traits::sign::Signed>::abs_sub
130
131
            /// # Returns
132
            ///
133
            /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
134
            /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
135
            /// - `NAN` if the number is NaN
136
            #[inline]
137
0
            fn signum(&self) -> $t {
138
0
                FloatCore::signum(*self)
139
0
            }
Unexecuted instantiation: <f32 as num_traits::sign::Signed>::signum
Unexecuted instantiation: <f64 as num_traits::sign::Signed>::signum
140
141
            /// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
142
            #[inline]
143
0
            fn is_positive(&self) -> bool {
144
0
                FloatCore::is_sign_positive(*self)
145
0
            }
Unexecuted instantiation: <f32 as num_traits::sign::Signed>::is_positive
Unexecuted instantiation: <f64 as num_traits::sign::Signed>::is_positive
146
147
            /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`
148
            #[inline]
149
0
            fn is_negative(&self) -> bool {
150
0
                FloatCore::is_sign_negative(*self)
151
0
            }
Unexecuted instantiation: <f32 as num_traits::sign::Signed>::is_negative
Unexecuted instantiation: <f64 as num_traits::sign::Signed>::is_negative
152
        }
153
    };
154
}
155
156
signed_float_impl!(f32);
157
signed_float_impl!(f64);
158
159
/// Computes the absolute value.
160
///
161
/// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`
162
///
163
/// For signed integers, `::MIN` will be returned if the number is `::MIN`.
164
#[inline(always)]
165
0
pub fn abs<T: Signed>(value: T) -> T {
166
0
    value.abs()
167
0
}
168
169
/// The positive difference of two numbers.
170
///
171
/// Returns zero if `x` is less than or equal to `y`, otherwise the difference
172
/// between `x` and `y` is returned.
173
#[inline(always)]
174
0
pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
175
0
    x.abs_sub(&y)
176
0
}
177
178
/// Returns the sign of the number.
179
///
180
/// For `f32` and `f64`:
181
///
182
/// * `1.0` if the number is positive, `+0.0` or `INFINITY`
183
/// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
184
/// * `NaN` if the number is `NaN`
185
///
186
/// For signed integers:
187
///
188
/// * `0` if the number is zero
189
/// * `1` if the number is positive
190
/// * `-1` if the number is negative
191
#[inline(always)]
192
0
pub fn signum<T: Signed>(value: T) -> T {
193
0
    value.signum()
194
0
}
195
196
/// A trait for values which cannot be negative
197
pub trait Unsigned: Num {}
198
199
macro_rules! empty_trait_impl {
200
    ($name:ident for $($t:ty)*) => ($(
201
        impl $name for $t {}
202
    )*)
203
}
204
205
empty_trait_impl!(Unsigned for usize u8 u16 u32 u64);
206
#[cfg(has_i128)]
207
empty_trait_impl!(Unsigned for u128);
208
209
impl<T: Unsigned> Unsigned for Wrapping<T> where Wrapping<T>: Num {}
210
211
#[test]
212
fn unsigned_wrapping_is_unsigned() {
213
    fn require_unsigned<T: Unsigned>(_: &T) {}
214
    require_unsigned(&Wrapping(42_u32));
215
}
216
217
// Commenting this out since it doesn't compile on Rust 1.8,
218
// because on this version Wrapping doesn't implement Neg and therefore can't
219
// implement Signed.
220
// #[test]
221
// fn signed_wrapping_is_signed() {
222
//     fn require_signed<T: Signed>(_: &T) {}
223
//     require_signed(&Wrapping(-42));
224
// }