1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![macro_escape]
12 #![doc(hidden)]
13
14 macro_rules! int_module (($T:ty, $bits:expr) => (
15
16 // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
17 // calling the `mem::size_of` function.
18 pub static BITS : uint = $bits;
19 // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
20 // calling the `mem::size_of` function.
21 pub static BYTES : uint = ($bits / 8);
22
23 // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
24 // calling the `Bounded::min_value` function.
25 pub static MIN: $T = (-1 as $T) << (BITS - 1);
26 // FIXME(#9837): Compute MIN like this so the high bits that shouldn't exist are 0.
27 // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
28 // calling the `Bounded::max_value` function.
29 pub static MAX: $T = !MIN;
30
31 #[cfg(not(test))]
32 impl Ord for $T {
33 #[inline]
34 fn lt(&self, other: &$T) -> bool { *self < *other }
35 }
36 #[cfg(not(test))]
37 impl TotalEq for $T {}
38 #[cfg(not(test))]
39 impl Eq for $T {
40 #[inline]
41 fn eq(&self, other: &$T) -> bool { *self == *other }
42 }
43 #[cfg(not(test))]
44 impl TotalOrd for $T {
45 #[inline]
46 fn cmp(&self, other: &$T) -> Ordering {
47 if *self < *other { Less }
48 else if *self > *other { Greater }
49 else { Equal }
50 }
51 }
52
53 impl Num for $T {}
54
55 impl Zero for $T {
56 #[inline]
57 fn zero() -> $T { 0 }
58
59 #[inline]
60 fn is_zero(&self) -> bool { *self == 0 }
61 }
62
63 impl One for $T {
64 #[inline]
65 fn one() -> $T { 1 }
66 }
67
68 #[cfg(not(test))]
69 impl Add<$T,$T> for $T {
70 #[inline]
71 fn add(&self, other: &$T) -> $T { *self + *other }
72 }
73
74 #[cfg(not(test))]
75 impl Sub<$T,$T> for $T {
76 #[inline]
77 fn sub(&self, other: &$T) -> $T { *self - *other }
78 }
79
80 #[cfg(not(test))]
81 impl Mul<$T,$T> for $T {
82 #[inline]
83 fn mul(&self, other: &$T) -> $T { *self * *other }
84 }
85
86 #[cfg(not(test))]
87 impl Div<$T,$T> for $T {
88 /// Integer division, truncated towards 0.
89 ///
90 /// # Examples
91 ///
92 /// ~~~
93 /// assert!( 8 / 3 == 2);
94 /// assert!( 8 / -3 == -2);
95 /// assert!(-8 / 3 == -2);
96 /// assert!(-8 / -3 == 2);
97 ///
98 /// assert!( 1 / 2 == 0);
99 /// assert!( 1 / -2 == 0);
100 /// assert!(-1 / 2 == 0);
101 /// assert!(-1 / -2 == 0);
102 /// ~~~
103 #[inline]
104 fn div(&self, other: &$T) -> $T { *self / *other }
105 }
106
107 #[cfg(not(test))]
108 impl Rem<$T,$T> for $T {
109 /// Returns the integer remainder after division, satisfying:
110 ///
111 /// ~~~
112 /// # let n = 1;
113 /// # let d = 2;
114 /// assert!((n / d) * d + (n % d) == n)
115 /// ~~~
116 ///
117 /// # Examples
118 ///
119 /// ~~~
120 /// assert!( 8 % 3 == 2);
121 /// assert!( 8 % -3 == 2);
122 /// assert!(-8 % 3 == -2);
123 /// assert!(-8 % -3 == -2);
124 ///
125 /// assert!( 1 % 2 == 1);
126 /// assert!( 1 % -2 == 1);
127 /// assert!(-1 % 2 == -1);
128 /// assert!(-1 % -2 == -1);
129 /// ~~~
130 #[inline]
131 fn rem(&self, other: &$T) -> $T { *self % *other }
132 }
133
134 #[cfg(not(test))]
135 impl Neg<$T> for $T {
136 #[inline]
137 fn neg(&self) -> $T { -*self }
138 }
139
140 impl Signed for $T {
141 /// Computes the absolute value
142 #[inline]
143 fn abs(&self) -> $T {
144 if self.is_negative() { -*self } else { *self }
145 }
146
147 ///
148 /// The positive difference of two numbers. Returns `0` if the number is less than or
149 /// equal to `other`, otherwise the difference between`self` and `other` is returned.
150 ///
151 #[inline]
152 fn abs_sub(&self, other: &$T) -> $T {
153 if *self <= *other { 0 } else { *self - *other }
154 }
155
156 ///
157 /// # Returns
158 ///
159 /// - `0` if the number is zero
160 /// - `1` if the number is positive
161 /// - `-1` if the number is negative
162 ///
163 #[inline]
164 fn signum(&self) -> $T {
165 match *self {
166 n if n > 0 => 1,
167 0 => 0,
168 _ => -1,
169 }
170 }
171
172 /// Returns true if the number is positive
173 #[inline]
174 fn is_positive(&self) -> bool { *self > 0 }
175
176 /// Returns true if the number is negative
177 #[inline]
178 fn is_negative(&self) -> bool { *self < 0 }
179 }
180
181 #[cfg(not(test))]
182 impl BitOr<$T,$T> for $T {
183 #[inline]
184 fn bitor(&self, other: &$T) -> $T { *self | *other }
185 }
186
187 #[cfg(not(test))]
188 impl BitAnd<$T,$T> for $T {
189 #[inline]
190 fn bitand(&self, other: &$T) -> $T { *self & *other }
191 }
192
193 #[cfg(not(test))]
194 impl BitXor<$T,$T> for $T {
195 #[inline]
196 fn bitxor(&self, other: &$T) -> $T { *self ^ *other }
197 }
198
199 #[cfg(not(test))]
200 impl Shl<$T,$T> for $T {
201 #[inline]
202 fn shl(&self, other: &$T) -> $T { *self << *other }
203 }
204
205 #[cfg(not(test))]
206 impl Shr<$T,$T> for $T {
207 #[inline]
208 fn shr(&self, other: &$T) -> $T { *self >> *other }
209 }
210
211 #[cfg(not(test))]
212 impl Not<$T> for $T {
213 #[inline]
214 fn not(&self) -> $T { !*self }
215 }
216
217 impl Bounded for $T {
218 #[inline]
219 fn min_value() -> $T { MIN }
220
221 #[inline]
222 fn max_value() -> $T { MAX }
223 }
224
225 impl CheckedDiv for $T {
226 #[inline]
227 fn checked_div(&self, v: &$T) -> Option<$T> {
228 if *v == 0 || (*self == MIN && *v == -1) {
229 None
230 } else {
231 Some(self / *v)
232 }
233 }
234 }
235
236 impl Default for $T {
237 #[inline]
238 fn default() -> $T { 0 }
239 }
240
241 impl Int for $T {}
242
243 impl Primitive for $T {}
244
245 #[cfg(test)]
246 mod tests {
247 use prelude::*;
248 use super::*;
249
250 use int;
251 use num;
252 use num::Bitwise;
253 use num::CheckedDiv;
254
255 #[test]
256 fn test_overflows() {
257 assert!(MAX > 0);
258 assert!(MIN <= 0);
259 assert!(MIN + MAX + 1 == 0);
260 }
261
262 #[test]
263 fn test_num() {
264 num::test_num(10 as $T, 2 as $T);
265 }
266
267 #[test]
268 pub fn test_abs() {
269 assert!((1 as $T).abs() == 1 as $T);
270 assert!((0 as $T).abs() == 0 as $T);
271 assert!((-1 as $T).abs() == 1 as $T);
272 }
273
274 #[test]
275 fn test_abs_sub() {
276 assert!((-1 as $T).abs_sub(&(1 as $T)) == 0 as $T);
277 assert!((1 as $T).abs_sub(&(1 as $T)) == 0 as $T);
278 assert!((1 as $T).abs_sub(&(0 as $T)) == 1 as $T);
279 assert!((1 as $T).abs_sub(&(-1 as $T)) == 2 as $T);
280 }
281
282 #[test]
283 fn test_signum() {
284 assert!((1 as $T).signum() == 1 as $T);
285 assert!((0 as $T).signum() == 0 as $T);
286 assert!((-0 as $T).signum() == 0 as $T);
287 assert!((-1 as $T).signum() == -1 as $T);
288 }
289
290 #[test]
291 fn test_is_positive() {
292 assert!((1 as $T).is_positive());
293 assert!(!(0 as $T).is_positive());
294 assert!(!(-0 as $T).is_positive());
295 assert!(!(-1 as $T).is_positive());
296 }
297
298 #[test]
299 fn test_is_negative() {
300 assert!(!(1 as $T).is_negative());
301 assert!(!(0 as $T).is_negative());
302 assert!(!(-0 as $T).is_negative());
303 assert!((-1 as $T).is_negative());
304 }
305
306 #[test]
307 fn test_bitwise() {
308 assert!(0b1110 as $T == (0b1100 as $T).bitor(&(0b1010 as $T)));
309 assert!(0b1000 as $T == (0b1100 as $T).bitand(&(0b1010 as $T)));
310 assert!(0b0110 as $T == (0b1100 as $T).bitxor(&(0b1010 as $T)));
311 assert!(0b1110 as $T == (0b0111 as $T).shl(&(1 as $T)));
312 assert!(0b0111 as $T == (0b1110 as $T).shr(&(1 as $T)));
313 assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
314 }
315
316 #[test]
317 fn test_count_ones() {
318 assert!((0b0101100 as $T).count_ones() == 3);
319 assert!((0b0100001 as $T).count_ones() == 2);
320 assert!((0b1111001 as $T).count_ones() == 5);
321 }
322
323 #[test]
324 fn test_count_zeros() {
325 assert!((0b0101100 as $T).count_zeros() == BITS as $T - 3);
326 assert!((0b0100001 as $T).count_zeros() == BITS as $T - 2);
327 assert!((0b1111001 as $T).count_zeros() == BITS as $T - 5);
328 }
329
330 #[test]
331 fn test_signed_checked_div() {
332 assert!(10i.checked_div(&2) == Some(5));
333 assert!(5i.checked_div(&0) == None);
334 assert!(int::MIN.checked_div(&-1) == None);
335 }
336 }
337
338 ))