use std::fmt::{Debug, Display};
use std::ops::{Add, BitAnd, BitAndAssign, BitOr, BitOrAssign, Shl, Shr, Sub};
use crate::constants::Bitlen;
use crate::data_types::Latent;
pub const fn calc_max_bytes(precision: Bitlen) -> usize {
if precision == 0 {
0
} else {
((precision + 14) / 8) as usize
}
}
pub const fn calc_max_u64s_for_writing(precision: Bitlen) -> usize {
if precision == 0 {
0
} else if precision <= 56 {
1
} else if precision <= 113 {
2
} else {
3
}
}
pub trait ReadWriteUint:
Add<Output = Self>
+ BitAnd<Output = Self>
+ BitOr<Output = Self>
+ BitAndAssign
+ BitOrAssign
+ Copy
+ Debug
+ Display
+ Shl<Bitlen, Output = Self>
+ Shr<Bitlen, Output = Self>
+ Sub<Output = Self>
{
const ONE: Self;
const BITS: Bitlen;
const MAX_U64S: usize = calc_max_u64s_for_writing(Self::BITS);
const MAX_BYTES: usize = calc_max_bytes(Self::BITS);
fn from_u32(x: u32) -> Self;
fn from_u64(x: u64) -> Self;
fn to_u64(self) -> u64;
}
impl ReadWriteUint for usize {
const ONE: Self = 1;
const BITS: Bitlen = usize::BITS;
#[inline]
fn from_u32(x: u32) -> Self {
x as Self
}
#[inline]
fn from_u64(x: u64) -> Self {
x as Self
}
#[inline]
fn to_u64(self) -> u64 {
self as u64
}
}
impl<L: Latent> ReadWriteUint for L {
const ONE: Self = <Self as Latent>::ONE;
const BITS: Bitlen = <Self as Latent>::BITS;
#[inline]
fn from_u32(x: u32) -> Self {
<Self as Latent>::from_u32(x)
}
#[inline]
fn from_u64(x: u64) -> Self {
<Self as Latent>::from_u64(x)
}
#[inline]
fn to_u64(self) -> u64 {
<Self as Latent>::to_u64(self)
}
}