]> git.lizzy.rs Git - rust.git/blob - src/libstd/num/uint_macros.rs
Convert most code to new inner attribute syntax.
[rust.git] / src / libstd / num / uint_macros.rs
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! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (
15
16 pub static BITS : uint = $bits;
17 pub static BYTES : uint = ($bits / 8);
18
19 pub static MIN: $T = 0 as $T;
20 pub static MAX: $T = 0 as $T - 1 as $T;
21
22 impl CheckedDiv for $T {
23     #[inline]
24     fn checked_div(&self, v: &$T) -> Option<$T> {
25         if *v == 0 {
26             None
27         } else {
28             Some(self / *v)
29         }
30     }
31 }
32
33 impl Num for $T {}
34
35 #[cfg(not(test))]
36 impl Ord for $T {
37     #[inline]
38     fn lt(&self, other: &$T) -> bool { (*self) < (*other) }
39 }
40
41 #[cfg(not(test))]
42 impl Eq for $T {
43     #[inline]
44     fn eq(&self, other: &$T) -> bool { return (*self) == (*other); }
45 }
46
47 impl Default for $T {
48     #[inline]
49     fn default() -> $T { 0 }
50 }
51
52 impl Zero for $T {
53     #[inline]
54     fn zero() -> $T { 0 }
55
56     #[inline]
57     fn is_zero(&self) -> bool { *self == 0 }
58 }
59
60 impl One for $T {
61     #[inline]
62     fn one() -> $T { 1 }
63 }
64
65 #[cfg(not(test))]
66 impl Add<$T,$T> for $T {
67     #[inline]
68     fn add(&self, other: &$T) -> $T { *self + *other }
69 }
70
71 #[cfg(not(test))]
72 impl Sub<$T,$T> for $T {
73     #[inline]
74     fn sub(&self, other: &$T) -> $T { *self - *other }
75 }
76
77 #[cfg(not(test))]
78 impl Mul<$T,$T> for $T {
79     #[inline]
80     fn mul(&self, other: &$T) -> $T { *self * *other }
81 }
82
83 #[cfg(not(test))]
84 impl Div<$T,$T> for $T {
85     #[inline]
86     fn div(&self, other: &$T) -> $T { *self / *other }
87 }
88
89 #[cfg(not(test))]
90 impl Rem<$T,$T> for $T {
91     #[inline]
92     fn rem(&self, other: &$T) -> $T { *self % *other }
93 }
94
95 #[cfg(not(test))]
96 impl Neg<$T> for $T {
97     #[inline]
98     fn neg(&self) -> $T { -*self }
99 }
100
101 impl Unsigned for $T {}
102
103 #[cfg(not(test))]
104 impl BitOr<$T,$T> for $T {
105     #[inline]
106     fn bitor(&self, other: &$T) -> $T { *self | *other }
107 }
108
109 #[cfg(not(test))]
110 impl BitAnd<$T,$T> for $T {
111     #[inline]
112     fn bitand(&self, other: &$T) -> $T { *self & *other }
113 }
114
115 #[cfg(not(test))]
116 impl BitXor<$T,$T> for $T {
117     #[inline]
118     fn bitxor(&self, other: &$T) -> $T { *self ^ *other }
119 }
120
121 #[cfg(not(test))]
122 impl Shl<$T,$T> for $T {
123     #[inline]
124     fn shl(&self, other: &$T) -> $T { *self << *other }
125 }
126
127 #[cfg(not(test))]
128 impl Shr<$T,$T> for $T {
129     #[inline]
130     fn shr(&self, other: &$T) -> $T { *self >> *other }
131 }
132
133 #[cfg(not(test))]
134 impl Not<$T> for $T {
135     #[inline]
136     fn not(&self) -> $T { !*self }
137 }
138
139 impl Bounded for $T {
140     #[inline]
141     fn min_value() -> $T { MIN }
142
143     #[inline]
144     fn max_value() -> $T { MAX }
145 }
146
147 impl Int for $T {}
148
149 // String conversion functions and impl str -> num
150
151 /// Parse a byte slice as a number in the given base.
152 #[inline]
153 pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<$T> {
154     strconv::from_str_bytes_common(buf, radix, false, false, false,
155                                    strconv::ExpNone, false, false)
156 }
157
158 impl FromStr for $T {
159     #[inline]
160     fn from_str(s: &str) -> Option<$T> {
161         strconv::from_str_common(s, 10u, false, false, false,
162                                  strconv::ExpNone, false, false)
163     }
164 }
165
166 impl FromStrRadix for $T {
167     #[inline]
168     fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
169         strconv::from_str_common(s, radix, false, false, false,
170                                  strconv::ExpNone, false, false)
171     }
172 }
173
174 // String conversion functions and impl num -> str
175
176 /// Convert to a string as a byte slice in a given base.
177 #[inline]
178 pub fn to_str_bytes<U>(n: $T, radix: uint, f: |v: &[u8]| -> U) -> U {
179     // The radix can be as low as 2, so we need at least 64 characters for a
180     // base 2 number.
181     let mut buf = [0u8, ..64];
182     let mut cur = 0;
183     strconv::int_to_str_bytes_common(n, radix, strconv::SignNone, |i| {
184         buf[cur] = i;
185         cur += 1;
186     });
187     f(buf.slice(0, cur))
188 }
189
190 impl ToStrRadix for $T {
191     /// Convert to a string in a given base.
192     #[inline]
193     fn to_str_radix(&self, radix: uint) -> ~str {
194         let mut buf = ~[];
195         strconv::int_to_str_bytes_common(*self, radix, strconv::SignNone, |i| {
196             buf.push(i);
197         });
198         // We know we generated valid utf-8, so we don't need to go through that
199         // check.
200         unsafe { str::raw::from_utf8_owned(buf) }
201     }
202 }
203
204 impl Primitive for $T {}
205
206 impl Bitwise for $T {
207     /// Returns the number of ones in the binary representation of the number.
208     #[inline]
209     fn count_ones(&self) -> $T {
210         (*self as $T_SIGNED).count_ones() as $T
211     }
212
213     /// Returns the number of leading zeros in the in the binary representation
214     /// of the number.
215     #[inline]
216     fn leading_zeros(&self) -> $T {
217         (*self as $T_SIGNED).leading_zeros() as $T
218     }
219
220     /// Returns the number of trailing zeros in the in the binary representation
221     /// of the number.
222     #[inline]
223     fn trailing_zeros(&self) -> $T {
224         (*self as $T_SIGNED).trailing_zeros() as $T
225     }
226 }
227
228 #[cfg(test)]
229 mod tests {
230     use prelude::*;
231     use super::*;
232
233     use num;
234     use num::CheckedDiv;
235     use num::Bitwise;
236     use num::ToStrRadix;
237     use u16;
238
239     #[test]
240     fn test_overflows() {
241         assert!(MAX > 0);
242         assert!(MIN <= 0);
243         assert_eq!(MIN + MAX + 1, 0);
244     }
245
246     #[test]
247     fn test_num() {
248         num::test_num(10 as $T, 2 as $T);
249     }
250
251     #[test]
252     fn test_bitwise() {
253         assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T)));
254         assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(&(0b1010 as $T)));
255         assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(&(0b1010 as $T)));
256         assert_eq!(0b1110 as $T, (0b0111 as $T).shl(&(1 as $T)));
257         assert_eq!(0b0111 as $T, (0b1110 as $T).shr(&(1 as $T)));
258         assert_eq!(MAX - (0b1011 as $T), (0b1011 as $T).not());
259     }
260
261     #[test]
262     fn test_count_ones() {
263         assert_eq!((0b0101100 as $T).count_ones(), 3);
264         assert_eq!((0b0100001 as $T).count_ones(), 2);
265         assert_eq!((0b1111001 as $T).count_ones(), 5);
266     }
267
268     #[test]
269     fn test_count_zeros() {
270         assert_eq!((0b0101100 as $T).count_zeros(), BITS as $T - 3);
271         assert_eq!((0b0100001 as $T).count_zeros(), BITS as $T - 2);
272         assert_eq!((0b1111001 as $T).count_zeros(), BITS as $T - 5);
273     }
274
275     #[test]
276     pub fn test_to_str() {
277         assert_eq!((0 as $T).to_str_radix(10u), ~"0");
278         assert_eq!((1 as $T).to_str_radix(10u), ~"1");
279         assert_eq!((2 as $T).to_str_radix(10u), ~"2");
280         assert_eq!((11 as $T).to_str_radix(10u), ~"11");
281         assert_eq!((11 as $T).to_str_radix(16u), ~"b");
282         assert_eq!((255 as $T).to_str_radix(16u), ~"ff");
283         assert_eq!((0xff as $T).to_str_radix(10u), ~"255");
284     }
285
286     #[test]
287     pub fn test_from_str() {
288         assert_eq!(from_str::<$T>("0"), Some(0u as $T));
289         assert_eq!(from_str::<$T>("3"), Some(3u as $T));
290         assert_eq!(from_str::<$T>("10"), Some(10u as $T));
291         assert_eq!(from_str::<u32>("123456789"), Some(123456789 as u32));
292         assert_eq!(from_str::<$T>("00100"), Some(100u as $T));
293
294         assert!(from_str::<$T>("").is_none());
295         assert!(from_str::<$T>(" ").is_none());
296         assert!(from_str::<$T>("x").is_none());
297     }
298
299     #[test]
300     pub fn test_parse_bytes() {
301         use str::StrSlice;
302         assert_eq!(parse_bytes("123".as_bytes(), 10u), Some(123u as $T));
303         assert_eq!(parse_bytes("1001".as_bytes(), 2u), Some(9u as $T));
304         assert_eq!(parse_bytes("123".as_bytes(), 8u), Some(83u as $T));
305         assert_eq!(u16::parse_bytes("123".as_bytes(), 16u), Some(291u as u16));
306         assert_eq!(u16::parse_bytes("ffff".as_bytes(), 16u), Some(65535u as u16));
307         assert_eq!(parse_bytes("z".as_bytes(), 36u), Some(35u as $T));
308
309         assert!(parse_bytes("Z".as_bytes(), 10u).is_none());
310         assert!(parse_bytes("_".as_bytes(), 2u).is_none());
311     }
312
313     #[test]
314     fn test_uint_to_str_overflow() {
315         let mut u8_val: u8 = 255_u8;
316         assert_eq!(u8_val.to_str(), ~"255");
317
318         u8_val += 1 as u8;
319         assert_eq!(u8_val.to_str(), ~"0");
320
321         let mut u16_val: u16 = 65_535_u16;
322         assert_eq!(u16_val.to_str(), ~"65535");
323
324         u16_val += 1 as u16;
325         assert_eq!(u16_val.to_str(), ~"0");
326
327         let mut u32_val: u32 = 4_294_967_295_u32;
328         assert_eq!(u32_val.to_str(), ~"4294967295");
329
330         u32_val += 1 as u32;
331         assert_eq!(u32_val.to_str(), ~"0");
332
333         let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
334         assert_eq!(u64_val.to_str(), ~"18446744073709551615");
335
336         u64_val += 1 as u64;
337         assert_eq!(u64_val.to_str(), ~"0");
338     }
339
340     #[test]
341     fn test_uint_from_str_overflow() {
342         let mut u8_val: u8 = 255_u8;
343         assert_eq!(from_str::<u8>("255"), Some(u8_val));
344         assert!(from_str::<u8>("256").is_none());
345
346         u8_val += 1 as u8;
347         assert_eq!(from_str::<u8>("0"), Some(u8_val));
348         assert!(from_str::<u8>("-1").is_none());
349
350         let mut u16_val: u16 = 65_535_u16;
351         assert_eq!(from_str::<u16>("65535"), Some(u16_val));
352         assert!(from_str::<u16>("65536").is_none());
353
354         u16_val += 1 as u16;
355         assert_eq!(from_str::<u16>("0"), Some(u16_val));
356         assert!(from_str::<u16>("-1").is_none());
357
358         let mut u32_val: u32 = 4_294_967_295_u32;
359         assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
360         assert!(from_str::<u32>("4294967296").is_none());
361
362         u32_val += 1 as u32;
363         assert_eq!(from_str::<u32>("0"), Some(u32_val));
364         assert!(from_str::<u32>("-1").is_none());
365
366         let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
367         assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
368         assert!(from_str::<u64>("18446744073709551616").is_none());
369
370         u64_val += 1 as u64;
371         assert_eq!(from_str::<u64>("0"), Some(u64_val));
372         assert!(from_str::<u64>("-1").is_none());
373     }
374
375     #[test]
376     #[should_fail]
377     pub fn to_str_radix1() {
378         100u.to_str_radix(1u);
379     }
380
381     #[test]
382     #[should_fail]
383     pub fn to_str_radix37() {
384         100u.to_str_radix(37u);
385     }
386
387     #[test]
388     fn test_unsigned_checked_div() {
389         assert_eq!(10u.checked_div(&2), Some(5));
390         assert_eq!(5u.checked_div(&0), None);
391     }
392 }
393
394 ))