]> git.lizzy.rs Git - rust.git/blob - src/libstd/num/uint_macros.rs
Honor hidden doc attribute of derivable trait methods
[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 = Vec::new();
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.move_iter().collect()) }
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 str::StrSlice;
238     use u16;
239
240     #[test]
241     fn test_overflows() {
242         assert!(MAX > 0);
243         assert!(MIN <= 0);
244         assert_eq!(MIN + MAX + 1, 0);
245     }
246
247     #[test]
248     fn test_num() {
249         num::test_num(10 as $T, 2 as $T);
250     }
251
252     #[test]
253     fn test_bitwise() {
254         assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T)));
255         assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(&(0b1010 as $T)));
256         assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(&(0b1010 as $T)));
257         assert_eq!(0b1110 as $T, (0b0111 as $T).shl(&(1 as $T)));
258         assert_eq!(0b0111 as $T, (0b1110 as $T).shr(&(1 as $T)));
259         assert_eq!(MAX - (0b1011 as $T), (0b1011 as $T).not());
260     }
261
262     #[test]
263     fn test_count_ones() {
264         assert_eq!((0b0101100 as $T).count_ones(), 3);
265         assert_eq!((0b0100001 as $T).count_ones(), 2);
266         assert_eq!((0b1111001 as $T).count_ones(), 5);
267     }
268
269     #[test]
270     fn test_count_zeros() {
271         assert_eq!((0b0101100 as $T).count_zeros(), BITS as $T - 3);
272         assert_eq!((0b0100001 as $T).count_zeros(), BITS as $T - 2);
273         assert_eq!((0b1111001 as $T).count_zeros(), BITS as $T - 5);
274     }
275
276     #[test]
277     pub fn test_to_str() {
278         assert_eq!((0 as $T).to_str_radix(10u), "0".to_owned());
279         assert_eq!((1 as $T).to_str_radix(10u), "1".to_owned());
280         assert_eq!((2 as $T).to_str_radix(10u), "2".to_owned());
281         assert_eq!((11 as $T).to_str_radix(10u), "11".to_owned());
282         assert_eq!((11 as $T).to_str_radix(16u), "b".to_owned());
283         assert_eq!((255 as $T).to_str_radix(16u), "ff".to_owned());
284         assert_eq!((0xff as $T).to_str_radix(10u), "255".to_owned());
285     }
286
287     #[test]
288     pub fn test_from_str() {
289         assert_eq!(from_str::<$T>("0"), Some(0u as $T));
290         assert_eq!(from_str::<$T>("3"), Some(3u as $T));
291         assert_eq!(from_str::<$T>("10"), Some(10u as $T));
292         assert_eq!(from_str::<u32>("123456789"), Some(123456789 as u32));
293         assert_eq!(from_str::<$T>("00100"), Some(100u as $T));
294
295         assert!(from_str::<$T>("").is_none());
296         assert!(from_str::<$T>(" ").is_none());
297         assert!(from_str::<$T>("x").is_none());
298     }
299
300     #[test]
301     pub fn test_parse_bytes() {
302         use str::StrSlice;
303         assert_eq!(parse_bytes("123".as_bytes(), 10u), Some(123u as $T));
304         assert_eq!(parse_bytes("1001".as_bytes(), 2u), Some(9u as $T));
305         assert_eq!(parse_bytes("123".as_bytes(), 8u), Some(83u as $T));
306         assert_eq!(u16::parse_bytes("123".as_bytes(), 16u), Some(291u as u16));
307         assert_eq!(u16::parse_bytes("ffff".as_bytes(), 16u), Some(65535u as u16));
308         assert_eq!(parse_bytes("z".as_bytes(), 36u), Some(35u as $T));
309
310         assert!(parse_bytes("Z".as_bytes(), 10u).is_none());
311         assert!(parse_bytes("_".as_bytes(), 2u).is_none());
312     }
313
314     #[test]
315     fn test_uint_to_str_overflow() {
316         let mut u8_val: u8 = 255_u8;
317         assert_eq!(u8_val.to_str(), "255".to_owned());
318
319         u8_val += 1 as u8;
320         assert_eq!(u8_val.to_str(), "0".to_owned());
321
322         let mut u16_val: u16 = 65_535_u16;
323         assert_eq!(u16_val.to_str(), "65535".to_owned());
324
325         u16_val += 1 as u16;
326         assert_eq!(u16_val.to_str(), "0".to_owned());
327
328         let mut u32_val: u32 = 4_294_967_295_u32;
329         assert_eq!(u32_val.to_str(), "4294967295".to_owned());
330
331         u32_val += 1 as u32;
332         assert_eq!(u32_val.to_str(), "0".to_owned());
333
334         let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
335         assert_eq!(u64_val.to_str(), "18446744073709551615".to_owned());
336
337         u64_val += 1 as u64;
338         assert_eq!(u64_val.to_str(), "0".to_owned());
339     }
340
341     #[test]
342     fn test_uint_from_str_overflow() {
343         let mut u8_val: u8 = 255_u8;
344         assert_eq!(from_str::<u8>("255"), Some(u8_val));
345         assert!(from_str::<u8>("256").is_none());
346
347         u8_val += 1 as u8;
348         assert_eq!(from_str::<u8>("0"), Some(u8_val));
349         assert!(from_str::<u8>("-1").is_none());
350
351         let mut u16_val: u16 = 65_535_u16;
352         assert_eq!(from_str::<u16>("65535"), Some(u16_val));
353         assert!(from_str::<u16>("65536").is_none());
354
355         u16_val += 1 as u16;
356         assert_eq!(from_str::<u16>("0"), Some(u16_val));
357         assert!(from_str::<u16>("-1").is_none());
358
359         let mut u32_val: u32 = 4_294_967_295_u32;
360         assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
361         assert!(from_str::<u32>("4294967296").is_none());
362
363         u32_val += 1 as u32;
364         assert_eq!(from_str::<u32>("0"), Some(u32_val));
365         assert!(from_str::<u32>("-1").is_none());
366
367         let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
368         assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
369         assert!(from_str::<u64>("18446744073709551616").is_none());
370
371         u64_val += 1 as u64;
372         assert_eq!(from_str::<u64>("0"), Some(u64_val));
373         assert!(from_str::<u64>("-1").is_none());
374     }
375
376     #[test]
377     #[should_fail]
378     pub fn to_str_radix1() {
379         100u.to_str_radix(1u);
380     }
381
382     #[test]
383     #[should_fail]
384     pub fn to_str_radix37() {
385         100u.to_str_radix(37u);
386     }
387
388     #[test]
389     fn test_unsigned_checked_div() {
390         assert_eq!(10u.checked_div(&2), Some(5));
391         assert_eq!(5u.checked_div(&0), None);
392     }
393 }
394
395 ))