#[cfg(feature = "std")] use std::convert::{From, Into};
#[cfg(feature = "std")] use std::str::FromStr;
#[cfg(feature = "std")] use std::ops::{Add, Sub, Not, Mul, Div, Shr, Shl, BitAnd, BitOr, BitXor, Rem};
#[cfg(feature = "std")] use std::cmp::Ordering;
#[cfg(feature = "std")] use std::fmt;
#[cfg(not(feature = "std"))] use core::convert::{From, Into};
#[cfg(not(feature = "std"))] use core::str::FromStr;
#[cfg(not(feature = "std"))] use core::ops::{Add, Sub, Not, Mul, Div, Shr, Shl, BitAnd, BitOr, BitXor, Rem};
#[cfg(not(feature = "std"))] use core::cmp::Ordering;
#[cfg(not(feature = "std"))] use core::fmt;
#[cfg(feature = "string")]
use hexutil::ParseHexError;
#[cfg(feature = "rlp")]
use rlp::{Encodable, Decodable, RlpStream, DecoderError, UntrustedRlp};
use super::{U512, U256, H256, H160};
#[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)]
pub struct M256(pub U256);
impl M256 {
pub fn zero() -> M256 { M256(U256::zero()) }
pub fn one() -> M256 { M256(U256::one()) }
pub fn max_value() -> M256 { M256(U256::max_value()) }
pub fn min_value() -> M256 { M256(U256::min_value()) }
pub fn bits(self) -> usize { self.0.bits() }
pub fn log2floor(self) -> usize { self.0.log2floor() }
pub fn as_u32(&self) -> u32 {
self.0.as_u32()
}
pub fn as_u64(&self) -> u64 {
self.0.as_u64()
}
pub fn as_usize(&self) -> usize {
self.0.as_usize()
}
#[inline]
pub fn byte(&self, index: usize) -> u8 {
self.0.byte(index)
}
#[inline]
pub fn index(&self, index: usize) -> u8 {
self.0.index(index)
}
}
impl Default for M256 { fn default() -> M256 { M256::zero() } }
#[cfg(feature = "string")]
impl FromStr for M256 {
type Err = ParseHexError;
fn from_str(s: &str) -> Result<M256, ParseHexError> {
U256::from_str(s).map(|s| M256(s))
}
}
#[cfg(feature = "rlp")]
impl Encodable for M256 {
fn rlp_append(&self, s: &mut RlpStream) {
self.0.rlp_append(s);
}
}
#[cfg(feature = "rlp")]
impl Decodable for M256 {
fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
Ok(M256(U256::decode(rlp)?))
}
}
impl From<u64> for M256 { fn from(val: u64) -> M256 { M256(U256::from(val)) } }
impl Into<u64> for M256 { fn into(self) -> u64 { self.0.into() } }
impl From<usize> for M256 { fn from(val: usize) -> M256 { M256(U256::from(val)) } }
impl<'a> From<&'a [u8]> for M256 { fn from(val: &'a [u8]) -> M256 { M256(U256::from(val)) } }
impl From<bool> for M256 {
fn from(val: bool) -> M256 {
if val {
M256::one()
} else {
M256::zero()
}
}
}
impl From<U256> for M256 { fn from(val: U256) -> M256 { M256(val) } }
impl Into<U256> for M256 { fn into(self) -> U256 { self.0 } }
impl From<U512> for M256 { fn from(val: U512) -> M256 { M256(val.into()) } }
impl Into<U512> for M256 { fn into(self) -> U512 { self.0.into() } }
impl From<i32> for M256 { fn from(val: i32) -> M256 { (val as u64).into() } }
impl From<H256> for M256 {
fn from(val: H256) -> M256 {
let inter: U256 = val.into();
inter.into()
}
}
impl From<M256> for H256 {
fn from(val: M256) -> H256 {
let inter: U256 = val.into();
inter.into()
}
}
impl From<H160> for M256 {
fn from(val: H160) -> M256 {
let inter: H256 = val.into();
inter.into()
}
}
impl From<M256> for H160 {
fn from(val: M256) -> H160 {
let inter: H256 = val.into();
inter.into()
}
}
impl Ord for M256 { fn cmp(&self, other: &M256) -> Ordering { self.0.cmp(&other.0) } }
impl PartialOrd for M256 {
fn partial_cmp(&self, other: &M256) -> Option<Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl BitAnd<M256> for M256 {
type Output = M256;
fn bitand(self, other: M256) -> M256 {
M256(self.0.bitand(other.0))
}
}
impl BitOr<M256> for M256 {
type Output = M256;
fn bitor(self, other: M256) -> M256 {
M256(self.0.bitor(other.0))
}
}
impl BitXor<M256> for M256 {
type Output = M256;
fn bitxor(self, other: M256) -> M256 {
M256(self.0.bitxor(other.0))
}
}
impl Shl<usize> for M256 {
type Output = M256;
fn shl(self, shift: usize) -> M256 {
M256(self.0.shl(shift))
}
}
impl Shr<usize> for M256 {
type Output = M256;
fn shr(self, shift: usize) -> M256 {
M256(self.0.shr(shift))
}
}
impl Add<M256> for M256 {
type Output = M256;
fn add(self, other: M256) -> M256 {
let (o, _) = self.0.overflowing_add(other.0);
M256(o)
}
}
impl Sub<M256> for M256 {
type Output = M256;
fn sub(self, other: M256) -> M256 {
if self.0 >= other.0 {
M256(self.0 - other.0)
} else {
M256(U256::max_value() - other.0 + self.0 + U256::from(1u64))
}
}
}
impl Mul<M256> for M256 {
type Output = M256;
fn mul(self, other: M256) -> M256 {
let (o, _) = self.0.overflowing_mul(other.0);
M256(o)
}
}
impl Div for M256 {
type Output = M256;
fn div(self, other: M256) -> M256 {
if other == M256::zero() {
M256::zero()
} else {
M256(self.0.div(other.0))
}
}
}
impl Rem for M256 {
type Output = M256;
fn rem(self, other: M256) -> M256 {
if other == M256::zero() {
M256::zero()
} else {
M256(self.0.rem(other.0))
}
}
}
impl Not for M256 {
type Output = M256;
fn not(self) -> M256 {
M256(self.0.not())
}
}
impl fmt::LowerHex for M256 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:x}", self.0)
}
}
impl fmt::UpperHex for M256 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:X}", self.0)
}
}
#[cfg(test)]
mod tests {
use super::M256;
use std::str::FromStr;
#[test]
pub fn sub() {
assert_eq!(M256::from_str("0000000000000000000000000000000000000000000000000000000000000000").unwrap() - M256::from_str("0000000000000000000000000000000100000000000000000000000000000000").unwrap(), M256::from_str("ffffffffffffffffffffffffffffffff00000000000000000000000000000000").unwrap());
assert_eq!(M256::from_str("0000000000000000000000000000000000000000000000000000000000000000").unwrap() - M256::from_str("0000000000000000000000000000000000000000000000000000000000000001").unwrap(), M256::from_str("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap());
assert_eq!(M256::from_str("0000000000000000000000000000000000000000000000000000000000000000").unwrap() - M256::from_str("8000000000000000000000000000000000000000000000000000000000000000").unwrap(), M256::from_str("8000000000000000000000000000000000000000000000000000000000000000").unwrap());
}
}