use std::{
cmp::{Ordering, PartialEq, PartialOrd},
fmt::{Display, Formatter, Result as FmtResult},
ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign},
};
use bitvec::{prelude::*, vec::BitVec};
use num_traits::{FromPrimitive, NumCast, One, ToPrimitive, Zero};
use crate::signed::SignedIntegerExtendable;
#[derive(Clone, Debug, Ord, Eq)]
pub struct UnsignedIntegerExtendable(pub(crate) BitVec);
impl UnsignedIntegerExtendable {
pub fn to_signed(&self) -> SignedIntegerExtendable {
let mut bits = self.0.clone();
bits.insert(0, false);
SignedIntegerExtendable(bits)
}
}
impl Display for UnsignedIntegerExtendable {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
self.to_signed().fmt(f)
}
}
impl PartialEq for UnsignedIntegerExtendable {
fn eq(&self, other: &Self) -> bool {
self.to_signed().eq(&other.to_signed())
}
}
impl PartialOrd for UnsignedIntegerExtendable {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.to_signed().partial_cmp(&other.to_signed())
}
}
impl Zero for UnsignedIntegerExtendable {
fn zero() -> Self {
Self(bitvec![0])
}
fn set_zero(&mut self) {
*self = Self::zero();
}
fn is_zero(&self) -> bool {
self.0.iter().all(|b| !*b)
}
}
impl One for UnsignedIntegerExtendable {
fn one() -> Self {
Self(bitvec![1])
}
fn set_one(&mut self) {
*self = Self::one();
}
fn is_one(&self) -> bool {
*self.0.first().unwrap() && self.0.iter().rev().skip(1).all(|b| !*b)
}
}
impl Add for UnsignedIntegerExtendable {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
(self.to_signed() + rhs.to_signed()).to_unsigned()
}
}
impl AddAssign for UnsignedIntegerExtendable {
fn add_assign(&mut self, rhs: Self) {
*self = (self.clone().to_signed() + rhs.clone().to_signed()).to_unsigned();
}
}
impl Sub for UnsignedIntegerExtendable {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
(self.to_signed() - rhs.to_signed()).to_unsigned()
}
}
impl SubAssign for UnsignedIntegerExtendable {
fn sub_assign(&mut self, rhs: Self) {
*self = (self.clone().to_signed() - rhs.clone().to_signed()).to_unsigned();
}
}
impl Mul for UnsignedIntegerExtendable {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
(self.to_signed() * rhs.to_signed()).to_unsigned()
}
}
impl MulAssign for UnsignedIntegerExtendable {
fn mul_assign(&mut self, rhs: Self) {
*self = (self.clone().to_signed() * rhs.clone().to_signed()).to_unsigned();
}
}
impl Div for UnsignedIntegerExtendable {
type Output = Self;
fn div(self, rhs: Self) -> Self::Output {
(self.to_signed() / rhs.to_signed()).to_unsigned()
}
}
impl DivAssign for UnsignedIntegerExtendable {
fn div_assign(&mut self, rhs: Self) {
*self = (self.clone().to_signed() / rhs.clone().to_signed()).to_unsigned();
}
}
impl Rem for UnsignedIntegerExtendable {
type Output = Self;
fn rem(self, rhs: Self) -> Self::Output {
(self.to_signed() % rhs.to_signed()).to_unsigned()
}
}
impl RemAssign for UnsignedIntegerExtendable {
fn rem_assign(&mut self, rhs: Self) {
*self = (self.clone().to_signed() % rhs.clone().to_signed()).to_unsigned();
}
}
impl NumCast for UnsignedIntegerExtendable {
fn from<T: ToPrimitive>(n: T) -> Option<Self> {
NumCast::from(n).and_then(|s: SignedIntegerExtendable| Some(s.to_unsigned()))
}
}
impl FromPrimitive for UnsignedIntegerExtendable {
fn from_isize(_n: isize) -> Option<Self> {
unimplemented!()
}
fn from_i8(_n: i8) -> Option<Self> {
unimplemented!()
}
fn from_i16(_n: i16) -> Option<Self> {
unimplemented!()
}
fn from_i32(_n: i32) -> Option<Self> {
unimplemented!()
}
fn from_i64(_n: i64) -> Option<Self> {
unimplemented!()
}
fn from_i128(_n: i128) -> Option<Self> {
unimplemented!()
}
fn from_usize(n: usize) -> Option<Self> {
SignedIntegerExtendable::from_usize(n).and_then(|s| Some(s.to_unsigned()))
}
fn from_u8(_n: u8) -> Option<Self> {
unimplemented!()
}
fn from_u16(_n: u16) -> Option<Self> {
unimplemented!()
}
fn from_u32(_n: u32) -> Option<Self> {
unimplemented!()
}
fn from_u64(_n: u64) -> Option<Self> {
unimplemented!()
}
fn from_u128(_n: u128) -> Option<Self> {
unimplemented!()
}
fn from_f32(_n: f32) -> Option<Self> {
unimplemented!()
}
fn from_f64(_n: f64) -> Option<Self> {
unimplemented!()
}
}
impl ToPrimitive for UnsignedIntegerExtendable {
fn to_isize(&self) -> Option<isize> {
unimplemented!()
}
fn to_i8(&self) -> Option<i8> {
unimplemented!()
}
fn to_i16(&self) -> Option<i16> {
unimplemented!()
}
fn to_i32(&self) -> Option<i32> {
unimplemented!()
}
fn to_i64(&self) -> Option<i64> {
unimplemented!()
}
fn to_i128(&self) -> Option<i128> {
unimplemented!()
}
fn to_usize(&self) -> Option<usize> {
unimplemented!()
}
fn to_u8(&self) -> Option<u8> {
unimplemented!()
}
fn to_u16(&self) -> Option<u16> {
unimplemented!()
}
fn to_u32(&self) -> Option<u32> {
unimplemented!()
}
fn to_u64(&self) -> Option<u64> {
unimplemented!()
}
fn to_u128(&self) -> Option<u128> {
unimplemented!()
}
fn to_f32(&self) -> Option<f32> {
unimplemented!()
}
fn to_f64(&self) -> Option<f64> {
unimplemented!()
}
}