]> git.proxmox.com Git - rustc.git/blob - src/vendor/num-traits/src/sign.rs
New upstream version 1.17.0+dfsg1
[rustc.git] / src / vendor / num-traits / src / sign.rs
1 use std::ops::Neg;
2 use std::{f32, f64};
3
4 use Num;
5
6 /// Useful functions for signed numbers (i.e. numbers that can be negative).
7 pub trait Signed: Sized + Num + Neg<Output = Self> {
8 /// Computes the absolute value.
9 ///
10 /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`.
11 ///
12 /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
13 fn abs(&self) -> Self;
14
15 /// The positive difference of two numbers.
16 ///
17 /// Returns `zero` if the number is less than or equal to `other`, otherwise the difference
18 /// between `self` and `other` is returned.
19 fn abs_sub(&self, other: &Self) -> Self;
20
21 /// Returns the sign of the number.
22 ///
23 /// For `f32` and `f64`:
24 ///
25 /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
26 /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
27 /// * `NaN` if the number is `NaN`
28 ///
29 /// For signed integers:
30 ///
31 /// * `0` if the number is zero
32 /// * `1` if the number is positive
33 /// * `-1` if the number is negative
34 fn signum(&self) -> Self;
35
36 /// Returns true if the number is positive and false if the number is zero or negative.
37 fn is_positive(&self) -> bool;
38
39 /// Returns true if the number is negative and false if the number is zero or positive.
40 fn is_negative(&self) -> bool;
41 }
42
43 macro_rules! signed_impl {
44 ($($t:ty)*) => ($(
45 impl Signed for $t {
46 #[inline]
47 fn abs(&self) -> $t {
48 if self.is_negative() { -*self } else { *self }
49 }
50
51 #[inline]
52 fn abs_sub(&self, other: &$t) -> $t {
53 if *self <= *other { 0 } else { *self - *other }
54 }
55
56 #[inline]
57 fn signum(&self) -> $t {
58 match *self {
59 n if n > 0 => 1,
60 0 => 0,
61 _ => -1,
62 }
63 }
64
65 #[inline]
66 fn is_positive(&self) -> bool { *self > 0 }
67
68 #[inline]
69 fn is_negative(&self) -> bool { *self < 0 }
70 }
71 )*)
72 }
73
74 signed_impl!(isize i8 i16 i32 i64);
75
76 macro_rules! signed_float_impl {
77 ($t:ty, $nan:expr, $inf:expr, $neg_inf:expr) => {
78 impl Signed for $t {
79 /// Computes the absolute value. Returns `NAN` if the number is `NAN`.
80 #[inline]
81 fn abs(&self) -> $t {
82 <$t>::abs(*self)
83 }
84
85 /// The positive difference of two numbers. Returns `0.0` if the number is
86 /// less than or equal to `other`, otherwise the difference between`self`
87 /// and `other` is returned.
88 #[inline]
89 #[allow(deprecated)]
90 fn abs_sub(&self, other: &$t) -> $t {
91 <$t>::abs_sub(*self, *other)
92 }
93
94 /// # Returns
95 ///
96 /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
97 /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
98 /// - `NAN` if the number is NaN
99 #[inline]
100 fn signum(&self) -> $t {
101 <$t>::signum(*self)
102 }
103
104 /// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
105 #[inline]
106 fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == $inf }
107
108 /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`
109 #[inline]
110 fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == $neg_inf }
111 }
112 }
113 }
114
115 signed_float_impl!(f32, f32::NAN, f32::INFINITY, f32::NEG_INFINITY);
116 signed_float_impl!(f64, f64::NAN, f64::INFINITY, f64::NEG_INFINITY);
117
118 /// Computes the absolute value.
119 ///
120 /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`
121 ///
122 /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
123 #[inline(always)]
124 pub fn abs<T: Signed>(value: T) -> T {
125 value.abs()
126 }
127
128 /// The positive difference of two numbers.
129 ///
130 /// Returns zero if `x` is less than or equal to `y`, otherwise the difference
131 /// between `x` and `y` is returned.
132 #[inline(always)]
133 pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
134 x.abs_sub(&y)
135 }
136
137 /// Returns the sign of the number.
138 ///
139 /// For `f32` and `f64`:
140 ///
141 /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
142 /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
143 /// * `NaN` if the number is `NaN`
144 ///
145 /// For signed integers:
146 ///
147 /// * `0` if the number is zero
148 /// * `1` if the number is positive
149 /// * `-1` if the number is negative
150 #[inline(always)] pub fn signum<T: Signed>(value: T) -> T { value.signum() }
151
152 /// A trait for values which cannot be negative
153 pub trait Unsigned: Num {}
154
155 macro_rules! empty_trait_impl {
156 ($name:ident for $($t:ty)*) => ($(
157 impl $name for $t {}
158 )*)
159 }
160
161 empty_trait_impl!(Unsigned for usize u8 u16 u32 u64);