|
18 | 18 | use crate::arith::derive_arith; |
19 | 19 | use crate::bigint::div::div_rem; |
20 | 20 | use num_bigint::BigInt; |
21 | | -use num_traits::{FromPrimitive, ToPrimitive, cast::AsPrimitive}; |
| 21 | +use num_traits::{ |
| 22 | + cast::AsPrimitive, CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedSub, FromPrimitive, |
| 23 | + Num, One, Signed, ToPrimitive, Zero, |
| 24 | +}; |
22 | 25 | use std::cmp::Ordering; |
23 | 26 | use std::num::ParseIntError; |
24 | 27 | use std::ops::{BitAnd, BitOr, BitXor, Neg, Shl, Shr}; |
@@ -860,6 +863,103 @@ impl ToPrimitive for i256 { |
860 | 863 | } |
861 | 864 | } |
862 | 865 |
|
| 866 | +// num_traits checked implementations |
| 867 | + |
| 868 | +impl CheckedNeg for i256 { |
| 869 | + fn checked_neg(&self) -> Option<Self> { |
| 870 | + (*self).checked_neg() |
| 871 | + } |
| 872 | +} |
| 873 | + |
| 874 | +impl CheckedAdd for i256 { |
| 875 | + fn checked_add(&self, v: &i256) -> Option<Self> { |
| 876 | + (*self).checked_add(*v) |
| 877 | + } |
| 878 | +} |
| 879 | + |
| 880 | +impl CheckedSub for i256 { |
| 881 | + fn checked_sub(&self, v: &i256) -> Option<Self> { |
| 882 | + (*self).checked_sub(*v) |
| 883 | + } |
| 884 | +} |
| 885 | + |
| 886 | +impl CheckedDiv for i256 { |
| 887 | + fn checked_div(&self, v: &i256) -> Option<Self> { |
| 888 | + (*self).checked_sub(*v) |
| 889 | + } |
| 890 | +} |
| 891 | + |
| 892 | +impl CheckedMul for i256 { |
| 893 | + fn checked_mul(&self, v: &i256) -> Option<Self> { |
| 894 | + (*self).checked_mul(*v) |
| 895 | + } |
| 896 | +} |
| 897 | + |
| 898 | +impl CheckedRem for i256 { |
| 899 | + fn checked_rem(&self, v: &i256) -> Option<Self> { |
| 900 | + (*self).checked_rem(*v) |
| 901 | + } |
| 902 | +} |
| 903 | + |
| 904 | +impl Zero for i256 { |
| 905 | + fn zero() -> Self { |
| 906 | + i256::ZERO |
| 907 | + } |
| 908 | + |
| 909 | + fn is_zero(&self) -> bool { |
| 910 | + *self == i256::ZERO |
| 911 | + } |
| 912 | +} |
| 913 | + |
| 914 | +impl One for i256 { |
| 915 | + fn one() -> Self { |
| 916 | + i256::ONE |
| 917 | + } |
| 918 | + |
| 919 | + fn is_one(&self) -> bool { |
| 920 | + *self == i256::ONE |
| 921 | + } |
| 922 | +} |
| 923 | + |
| 924 | +impl Num for i256 { |
| 925 | + type FromStrRadixErr = ParseI256Error; |
| 926 | + |
| 927 | + fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> { |
| 928 | + if radix == 10 { |
| 929 | + str.parse() |
| 930 | + } else { |
| 931 | + // Parsing from non-10 baseseeÎ is not supported |
| 932 | + Err(ParseI256Error {}) |
| 933 | + } |
| 934 | + } |
| 935 | +} |
| 936 | + |
| 937 | +impl Signed for i256 { |
| 938 | + fn abs(&self) -> Self { |
| 939 | + self.wrapping_abs() |
| 940 | + } |
| 941 | + |
| 942 | + fn abs_sub(&self, other: &Self) -> Self { |
| 943 | + if self > other { |
| 944 | + self.wrapping_sub(*other) |
| 945 | + } else { |
| 946 | + i256::ZERO |
| 947 | + } |
| 948 | + } |
| 949 | + |
| 950 | + fn signum(&self) -> Self { |
| 951 | + (*self).signum() |
| 952 | + } |
| 953 | + |
| 954 | + fn is_positive(&self) -> bool { |
| 955 | + (*self).is_positive() |
| 956 | + } |
| 957 | + |
| 958 | + fn is_negative(&self) -> bool { |
| 959 | + (*self).is_negative() |
| 960 | + } |
| 961 | +} |
| 962 | + |
863 | 963 | #[cfg(all(test, not(miri)))] // llvm.x86.subborrow.64 not supported by MIRI |
864 | 964 | mod tests { |
865 | 965 | use super::*; |
@@ -1327,4 +1427,22 @@ mod tests { |
1327 | 1427 | let out = big_neg.to_f64().unwrap(); |
1328 | 1428 | assert!(out.is_finite() && out.is_sign_negative()); |
1329 | 1429 | } |
| 1430 | + |
| 1431 | + #[test] |
| 1432 | + fn test_num_traits() { |
| 1433 | + let value = i256::from_i128(-5); |
| 1434 | + assert_eq!( |
| 1435 | + <i256 as CheckedNeg>::checked_neg(&value), |
| 1436 | + Some(i256::from_i128(5)) |
| 1437 | + ); |
| 1438 | + |
| 1439 | + assert_eq!( |
| 1440 | + <i256 as CheckedAdd>::checked_add(&value, &value), |
| 1441 | + Some(i256::from_i128(-10)) |
| 1442 | + ); |
| 1443 | + |
| 1444 | + assert_eq!(<i256 as Signed>::abs(&value), i256::from_i128(5)); |
| 1445 | + |
| 1446 | + assert_eq!(<i256 as One>::one(), i256::from_i128(1)); |
| 1447 | + } |
1330 | 1448 | } |
0 commit comments