use std::ops::BitOr;
use std::ops::Rem;
use std::ops::Shl;
use std::ops::Shr;
use std::ops::Sub;
use arbitrary::unstructured::Int;
use num_traits::CheckedAdd;
use num_traits::WrappingAdd;
use num_traits::WrappingSub;
use primitive_types::U256;
use crate::i256;
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub struct U256Wrapper(U256);
impl Sub for U256Wrapper {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
U256Wrapper(self.0 - rhs.0)
}
}
impl Rem for U256Wrapper {
type Output = Self;
fn rem(self, rhs: Self) -> Self::Output {
U256Wrapper(self.0 % rhs.0)
}
}
impl Shr for U256Wrapper {
type Output = Self;
fn shr(self, rhs: Self) -> Self::Output {
U256Wrapper(self.0 >> rhs.0)
}
}
impl Shl<usize> for U256Wrapper {
type Output = Self;
fn shl(self, rhs: usize) -> Self::Output {
U256Wrapper(self.0 << rhs)
}
}
impl BitOr for U256Wrapper {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
U256Wrapper(self.0 | rhs.0)
}
}
impl Int for U256Wrapper {
type Unsigned = Self;
const ZERO: Self = U256Wrapper(U256::zero());
const ONE: Self = U256Wrapper(U256::one());
const MAX: Self = U256Wrapper(U256::max_value());
fn from_u8(b: u8) -> Self {
Self(U256::from(b))
}
fn from_usize(u: usize) -> Self {
Self(U256::from(u))
}
fn checked_add(self, rhs: Self) -> Option<Self> {
self.0.checked_add(rhs.0).map(U256Wrapper)
}
fn wrapping_add(self, rhs: Self) -> Self {
let (v, _) = self.0.overflowing_add(rhs.0);
U256Wrapper(v)
}
fn wrapping_sub(self, rhs: Self) -> Self {
let (v, _) = self.0.overflowing_sub(rhs.0);
U256Wrapper(v)
}
fn to_unsigned(self) -> Self::Unsigned {
self
}
fn from_unsigned(unsigned: Self::Unsigned) -> Self {
unsigned
}
}
impl Int for i256 {
type Unsigned = U256Wrapper;
const ZERO: Self = i256::ZERO;
const ONE: Self = i256::ONE;
const MAX: Self = i256::MAX;
fn from_u8(b: u8) -> Self {
Self::from_i128(b as i128)
}
fn from_usize(u: usize) -> Self {
Self::from_i128(u as i128)
}
fn checked_add(self, rhs: Self) -> Option<Self> {
<Self as CheckedAdd>::checked_add(&self, &rhs)
}
fn wrapping_add(self, rhs: Self) -> Self {
<Self as WrappingAdd>::wrapping_add(&self, &rhs)
}
fn wrapping_sub(self, rhs: Self) -> Self {
<Self as WrappingSub>::wrapping_sub(&self, &rhs)
}
fn to_unsigned(self) -> Self::Unsigned {
let bytes = self.to_le_bytes(); U256Wrapper(U256::from_little_endian(&bytes))
}
fn from_unsigned(unsigned: Self::Unsigned) -> Self {
let bytes = unsigned.0.to_little_endian();
i256::from_le_bytes(bytes)
}
}