use crate::num::Sign::{self}; #[cfg(all(feature = "alloc", not(feature = "std")))] extern crate alloc; #[cfg(all(feature = "alloc", not(feature = "std")))] use alloc::string::*; #[cfg(all(feature = "alloc", not(feature = "std")))] use alloc::vec::*; use core::convert::TryInto; use core::prelude::v1::*; #[cfg(feature = "std")] use std::prelude::v1::*; use super::BigInt; macro_rules! impl_from_smaller { ($(($s: ty, $u: ty)),* ) => { $( impl From<$s> for BigInt { /// Create a `BigInt` from a signed integer primitive fn from(n: $s) -> Self { let sign = if n < 0 { Sign::Negative } else { Sign::Positive }; let n = n.abs(); let raw: usize = <$s>::try_into(n).unwrap(); Self { inner: vec![raw], sign, } } } impl From<$u> for BigInt { /// Create a `BigInt` from an unsigned integer primitive fn from(n: $u) -> Self { let mut new = Self::empty(); new.inner.push(n as usize); new } } )* } } macro_rules! impl_from_larger { ($(($s: ty, $u: ty)),* ) => { $( impl From<$s> for BigInt { /// Create a `BigInt` from a signed integer primitive fn from(n: $s) -> Self { let target_radix: $s = (usize::MAX as $s) + 1; let sign = if n < 0 { Sign::Negative } else { Sign::Positive }; let n = n.abs(); let mut quotient = n / target_radix; let mut rem = n % target_radix; if quotient == 0 { Self::from(rem as usize) } else { let mut inner: Vec = vec![rem as usize]; loop { rem = quotient % target_radix; quotient /= target_radix; inner.push(rem as usize); if (quotient == 0) { break; } } BigInt { inner, sign, } } } } impl From<$u> for BigInt { /// Create a `BigInt` from an unsigned integer primitive fn from(n: $u) -> Self { let target_radix: $u = (usize::MAX as $u) + 1; let mut quotient = n / target_radix; let mut rem = n % target_radix; if quotient == 0 { Self::from(rem as usize) } else { let mut inner: Vec = vec![rem as usize]; loop { rem = quotient % target_radix; quotient /= target_radix; inner.push(rem as usize); if (quotient == 0) { break; } } BigInt { inner, sign: Sign::Positive } } } } )* }; } #[cfg(target_pointer_width = "16")] impl_from_larger!((i32, u32), (i64, u64), (i128, u128)); #[cfg(target_pointer_width = "16")] impl_from_smaller!((i8, u8), (i16, u16)); #[cfg(target_pointer_width = "32")] impl_from_larger!((i64, u64), (i128, u128)); #[cfg(target_pointer_width = "32")] impl_from_smaller!((i8, u8), (i16, u16), (i32, u32)); #[cfg(target_pointer_width = "64")] impl_from_larger!((i128, u128)); #[cfg(target_pointer_width = "64")] impl_from_smaller!((i8, u8), (i16, u16), (i32, u32), (i64, u64)); #[cfg(target_pointer_width = "128")] impl_from_smaller!((i8, u8), (i16, u16), (i32, u32), (i64, u64), (i128, u128)); impl From for BigInt { fn from(n: usize) -> Self { Self { inner: vec![n], sign: Sign::default(), } } } impl From for BigInt { fn from(n: isize) -> Self { let sign = if n < 0 { Sign::Negative } else { Sign::Positive }; let n = n.abs(); let raw: usize = isize::try_into(n).expect("Unable to convert isize value into usize."); Self { inner: vec![raw], sign, } } } impl From<&str> for BigInt { fn from(s: &str) -> Self { Self::from_str(s, 10) } } impl From for BigInt { fn from(s: String) -> Self { Self::from_str(&s, 10) } }