1 // Copyright 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.
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.
11 use core::convert::TryFrom;
12 use core::cmp::PartialEq;
14 use core::marker::Copy;
15 use core::ops::{Add, Sub, Mul, Div, Rem};
16 use core::option::Option;
17 use core::option::Option::{Some, None};
39 /// Helper function for testing numeric operations
40 pub fn test_num<T>(ten: T, two: T) where
42 + Add<Output=T> + Sub<Output=T>
43 + Mul<Output=T> + Div<Output=T>
44 + Rem<Output=T> + Debug
47 assert_eq!(ten.add(two), ten + two);
48 assert_eq!(ten.sub(two), ten - two);
49 assert_eq!(ten.mul(two), ten * two);
50 assert_eq!(ten.div(two), ten / two);
51 assert_eq!(ten.rem(two), ten % two);
55 fn from_str_issue7588() {
56 let u : Option<u8> = u8::from_str_radix("1000", 10).ok();
58 let s : Option<i16> = i16::from_str_radix("80000", 10).ok();
63 fn test_int_from_str_overflow() {
64 let mut i8_val: i8 = 127;
65 assert_eq!("127".parse::<i8>().ok(), Some(i8_val));
66 assert_eq!("128".parse::<i8>().ok(), None);
68 i8_val = i8_val.wrapping_add(1);
69 assert_eq!("-128".parse::<i8>().ok(), Some(i8_val));
70 assert_eq!("-129".parse::<i8>().ok(), None);
72 let mut i16_val: i16 = 32_767;
73 assert_eq!("32767".parse::<i16>().ok(), Some(i16_val));
74 assert_eq!("32768".parse::<i16>().ok(), None);
76 i16_val = i16_val.wrapping_add(1);
77 assert_eq!("-32768".parse::<i16>().ok(), Some(i16_val));
78 assert_eq!("-32769".parse::<i16>().ok(), None);
80 let mut i32_val: i32 = 2_147_483_647;
81 assert_eq!("2147483647".parse::<i32>().ok(), Some(i32_val));
82 assert_eq!("2147483648".parse::<i32>().ok(), None);
84 i32_val = i32_val.wrapping_add(1);
85 assert_eq!("-2147483648".parse::<i32>().ok(), Some(i32_val));
86 assert_eq!("-2147483649".parse::<i32>().ok(), None);
88 let mut i64_val: i64 = 9_223_372_036_854_775_807;
89 assert_eq!("9223372036854775807".parse::<i64>().ok(), Some(i64_val));
90 assert_eq!("9223372036854775808".parse::<i64>().ok(), None);
92 i64_val = i64_val.wrapping_add(1);
93 assert_eq!("-9223372036854775808".parse::<i64>().ok(), Some(i64_val));
94 assert_eq!("-9223372036854775809".parse::<i64>().ok(), None);
98 fn test_leading_plus() {
99 assert_eq!("+127".parse::<u8>().ok(), Some(127));
100 assert_eq!("+9223372036854775807".parse::<i64>().ok(), Some(9223372036854775807));
105 assert_eq!("--129".parse::<i8>().ok(), None);
106 assert_eq!("++129".parse::<i8>().ok(), None);
107 assert_eq!("Съешь".parse::<u8>().ok(), None);
112 assert_eq!("-".parse::<i8>().ok(), None);
113 assert_eq!("+".parse::<i8>().ok(), None);
114 assert_eq!("".parse::<u8>().ok(), None);
117 macro_rules! test_impl_from {
118 ($fn_name: ident, $Small: ty, $Large: ty) => {
121 let small_max = <$Small>::max_value();
122 let small_min = <$Small>::min_value();
123 let large_max: $Large = small_max.into();
124 let large_min: $Large = small_min.into();
125 assert_eq!(large_max as $Small, small_max);
126 assert_eq!(large_min as $Small, small_min);
131 // Unsigned -> Unsigned
132 test_impl_from! { test_u8u16, u8, u16 }
133 test_impl_from! { test_u8u32, u8, u32 }
134 test_impl_from! { test_u8u64, u8, u64 }
135 test_impl_from! { test_u8usize, u8, usize }
136 test_impl_from! { test_u16u32, u16, u32 }
137 test_impl_from! { test_u16u64, u16, u64 }
138 test_impl_from! { test_u32u64, u32, u64 }
141 test_impl_from! { test_i8i16, i8, i16 }
142 test_impl_from! { test_i8i32, i8, i32 }
143 test_impl_from! { test_i8i64, i8, i64 }
144 test_impl_from! { test_i8isize, i8, isize }
145 test_impl_from! { test_i16i32, i16, i32 }
146 test_impl_from! { test_i16i64, i16, i64 }
147 test_impl_from! { test_i32i64, i32, i64 }
149 // Unsigned -> Signed
150 test_impl_from! { test_u8i16, u8, i16 }
151 test_impl_from! { test_u8i32, u8, i32 }
152 test_impl_from! { test_u8i64, u8, i64 }
153 test_impl_from! { test_u16i32, u16, i32 }
154 test_impl_from! { test_u16i64, u16, i64 }
155 test_impl_from! { test_u32i64, u32, i64 }
158 test_impl_from! { test_i8f32, i8, f32 }
159 test_impl_from! { test_i8f64, i8, f64 }
160 test_impl_from! { test_i16f32, i16, f32 }
161 test_impl_from! { test_i16f64, i16, f64 }
162 test_impl_from! { test_i32f64, i32, f64 }
165 test_impl_from! { test_u8f32, u8, f32 }
166 test_impl_from! { test_u8f64, u8, f64 }
167 test_impl_from! { test_u16f32, u16, f32 }
168 test_impl_from! { test_u16f64, u16, f64 }
169 test_impl_from! { test_u32f64, u32, f64 }
172 #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
177 let max: f64 = f32::MAX.into();
178 assert_eq!(max as f32, f32::MAX);
179 assert!(max.is_normal());
181 let min: f64 = f32::MIN.into();
182 assert_eq!(min as f32, f32::MIN);
183 assert!(min.is_normal());
185 let min_positive: f64 = f32::MIN_POSITIVE.into();
186 assert_eq!(min_positive as f32, f32::MIN_POSITIVE);
187 assert!(min_positive.is_normal());
189 let epsilon: f64 = f32::EPSILON.into();
190 assert_eq!(epsilon as f32, f32::EPSILON);
191 assert!(epsilon.is_normal());
193 let zero: f64 = (0.0f32).into();
194 assert_eq!(zero as f32, 0.0f32);
195 assert!(zero.is_sign_positive());
197 let neg_zero: f64 = (-0.0f32).into();
198 assert_eq!(neg_zero as f32, -0.0f32);
199 assert!(neg_zero.is_sign_negative());
201 let infinity: f64 = f32::INFINITY.into();
202 assert_eq!(infinity as f32, f32::INFINITY);
203 assert!(infinity.is_infinite());
204 assert!(infinity.is_sign_positive());
206 let neg_infinity: f64 = f32::NEG_INFINITY.into();
207 assert_eq!(neg_infinity as f32, f32::NEG_INFINITY);
208 assert!(neg_infinity.is_infinite());
209 assert!(neg_infinity.is_sign_negative());
211 let nan: f64 = f32::NAN.into();
212 assert!(nan.is_nan());
215 macro_rules! test_impl_try_from_always_ok {
216 ($fn_name:ident, $source:ty, $target: ty) => {
219 let max = <$source>::max_value();
220 let min = <$source>::min_value();
221 let zero: $source = 0;
222 assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(),
224 assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(),
226 assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
232 test_impl_try_from_always_ok! { test_try_u8u8, u8, u8 }
233 test_impl_try_from_always_ok! { test_try_u8u16, u8, u16 }
234 test_impl_try_from_always_ok! { test_try_u8u32, u8, u32 }
235 test_impl_try_from_always_ok! { test_try_u8u64, u8, u64 }
236 test_impl_try_from_always_ok! { test_try_u8i16, u8, i16 }
237 test_impl_try_from_always_ok! { test_try_u8i32, u8, i32 }
238 test_impl_try_from_always_ok! { test_try_u8i64, u8, i64 }
240 test_impl_try_from_always_ok! { test_try_u16u16, u16, u16 }
241 test_impl_try_from_always_ok! { test_try_u16u32, u16, u32 }
242 test_impl_try_from_always_ok! { test_try_u16u64, u16, u64 }
243 test_impl_try_from_always_ok! { test_try_u16i32, u16, i32 }
244 test_impl_try_from_always_ok! { test_try_u16i64, u16, i64 }
246 test_impl_try_from_always_ok! { test_try_u32u32, u32, u32 }
247 test_impl_try_from_always_ok! { test_try_u32u64, u32, u64 }
248 test_impl_try_from_always_ok! { test_try_u32i64, u32, i64 }
250 test_impl_try_from_always_ok! { test_try_u64u64, u64, u64 }
252 test_impl_try_from_always_ok! { test_try_i8i8, i8, i8 }
253 test_impl_try_from_always_ok! { test_try_i8i16, i8, i16 }
254 test_impl_try_from_always_ok! { test_try_i8i32, i8, i32 }
255 test_impl_try_from_always_ok! { test_try_i8i64, i8, i64 }
257 test_impl_try_from_always_ok! { test_try_i16i16, i16, i16 }
258 test_impl_try_from_always_ok! { test_try_i16i32, i16, i32 }
259 test_impl_try_from_always_ok! { test_try_i16i64, i16, i64 }
261 test_impl_try_from_always_ok! { test_try_i32i32, i32, i32 }
262 test_impl_try_from_always_ok! { test_try_i32i64, i32, i64 }
264 test_impl_try_from_always_ok! { test_try_i64i64, i64, i64 }
266 macro_rules! test_impl_try_from_signed_to_unsigned_upper_ok {
267 ($fn_name:ident, $source:ty, $target:ty) => {
270 let max = <$source>::max_value();
271 let min = <$source>::min_value();
272 let zero: $source = 0;
273 let neg_one: $source = -1;
274 assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(),
276 assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
277 assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
279 assert!(<$target as TryFrom<$source>>::try_from(neg_one).is_err());
284 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u8, i8, u8 }
285 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u16, i8, u16 }
286 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u32, i8, u32 }
287 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u64, i8, u64 }
289 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u16, i16, u16 }
290 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u32, i16, u32 }
291 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u64, i16, u64 }
293 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u32, i32, u32 }
294 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u64, i32, u64 }
296 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64u64, i64, u64 }
298 macro_rules! test_impl_try_from_unsigned_to_signed_upper_err {
299 ($fn_name:ident, $source:ty, $target:ty) => {
302 let max = <$source>::max_value();
303 let min = <$source>::min_value();
304 let zero: $source = 0;
305 assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
306 assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(),
308 assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
314 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u8i8, u8, i8 }
316 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16i8, u16, i8 }
317 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16i16, u16, i16 }
319 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i8, u32, i8 }
320 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i16, u32, i16 }
321 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i32, u32, i32 }
323 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i8, u64, i8 }
324 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i16, u64, i16 }
325 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i32, u64, i32 }
326 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i64, u64, i64 }
328 macro_rules! test_impl_try_from_same_sign_err {
329 ($fn_name:ident, $source:ty, $target:ty) => {
332 let max = <$source>::max_value();
333 let min = <$source>::min_value();
334 let zero: $source = 0;
335 let t_max = <$target>::max_value();
336 let t_min = <$target>::min_value();
337 assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
339 assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
341 assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
343 assert_eq!(<$target as TryFrom<$source>>::try_from(t_max as $source)
346 assert_eq!(<$target as TryFrom<$source>>::try_from(t_min as $source)
353 test_impl_try_from_same_sign_err! { test_try_u16u8, u16, u8 }
355 test_impl_try_from_same_sign_err! { test_try_u32u8, u32, u8 }
356 test_impl_try_from_same_sign_err! { test_try_u32u16, u32, u16 }
358 test_impl_try_from_same_sign_err! { test_try_u64u8, u64, u8 }
359 test_impl_try_from_same_sign_err! { test_try_u64u16, u64, u16 }
360 test_impl_try_from_same_sign_err! { test_try_u64u32, u64, u32 }
362 test_impl_try_from_same_sign_err! { test_try_i16i8, i16, i8 }
364 test_impl_try_from_same_sign_err! { test_try_i32i8, i32, i8 }
365 test_impl_try_from_same_sign_err! { test_try_i32i16, i32, i16 }
367 test_impl_try_from_same_sign_err! { test_try_i64i8, i64, i8 }
368 test_impl_try_from_same_sign_err! { test_try_i64i16, i64, i16 }
369 test_impl_try_from_same_sign_err! { test_try_i64i32, i64, i32 }
371 macro_rules! test_impl_try_from_signed_to_unsigned_err {
372 ($fn_name:ident, $source:ty, $target:ty) => {
375 let max = <$source>::max_value();
376 let min = <$source>::min_value();
377 let zero: $source = 0;
378 let t_max = <$target>::max_value();
379 let t_min = <$target>::min_value();
380 assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
381 assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
382 assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
384 assert_eq!(<$target as TryFrom<$source>>::try_from(t_max as $source)
387 assert_eq!(<$target as TryFrom<$source>>::try_from(t_min as $source)
394 test_impl_try_from_signed_to_unsigned_err! { test_try_i16u8, i16, u8 }
396 test_impl_try_from_signed_to_unsigned_err! { test_try_i32u8, i32, u8 }
397 test_impl_try_from_signed_to_unsigned_err! { test_try_i32u16, i32, u16 }
399 test_impl_try_from_signed_to_unsigned_err! { test_try_i64u8, i64, u8 }
400 test_impl_try_from_signed_to_unsigned_err! { test_try_i64u16, i64, u16 }
401 test_impl_try_from_signed_to_unsigned_err! { test_try_i64u32, i64, u32 }