#![allow(unused_qualifications)]
#[allow(clippy::useless_attribute)]
#[allow(clippy::wildcard_imports)]
use std::prelude::v1::*;
#[cfg(feature = "parity_codec")]
use parity_scale_codec::{Decode, Encode};
#[cfg(any(test, feature = "proptest"))]
use proptest_derive::Arbitrary;
use std::{cmp::Ordering, u64};
#[derive(PartialEq, Eq, Clone, Default, Hash)]
#[cfg_attr(feature = "parity_codec", derive(Encode, Decode))]
#[cfg_attr(any(test, feature = "proptest"), derive(Arbitrary))]
#[cfg_attr(any(test, feature = "proptest"), proptest(no_params))]
pub struct U256([u64; 4]);
impl U256 {
pub const MAX: Self = Self::from_limbs([
u64::max_value(),
u64::max_value(),
u64::max_value(),
u64::max_value(),
]);
pub const ONE: Self = Self::from_limbs([1, 0, 0, 0]);
pub const ZERO: Self = Self::from_limbs([0, 0, 0, 0]);
#[inline(always)]
pub const fn from_limbs(limbs: [u64; 4]) -> Self {
Self(limbs)
}
#[inline(always)]
pub const fn as_limbs(&self) -> &[u64; 4] {
&self.0
}
#[inline(always)]
pub fn limb(&self, index: usize) -> u64 {
self.0.get(index).cloned().unwrap_or_default()
}
#[inline(always)]
pub fn set_limb(&mut self, index: usize, value: u64) {
if let Some(elem) = self.0.get_mut(index) {
*elem = value;
} else {
panic!("Limb out of range.")
}
}
}
impl PartialOrd for U256 {
#[inline(always)]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for U256 {
#[inline(always)]
fn cmp(&self, other: &Self) -> Ordering {
let t = self.limb(3).cmp(&other.limb(3));
if t != Ordering::Equal {
return t;
}
let t = self.limb(2).cmp(&other.limb(2));
if t != Ordering::Equal {
return t;
}
let t = self.limb(1).cmp(&other.limb(1));
if t != Ordering::Equal {
return t;
}
self.limb(0).cmp(&other.limb(0))
}
}
#[cfg(test)]
mod tests {
use super::*;
use zkp_macros_decl::u256h;
#[allow(dead_code)]
const TEST_CONST: U256 =
u256h!("0800000000000010ffffffffffffffffffffffffffffffffffffffffffffffff");
}