use crate::named::Named;
use crate::num::basic::unsigneds::PrimitiveUnsigned;
use crate::num::conversion::traits::ExactFrom;
use crate::num::logic::traits::SignificantBits;
use crate::vector::Vector;
use alloc::vec;
use alloc::vec::Vec;
use core::fmt::{self, Debug, Formatter};
use core::ops::Deref;
pub mod access;
pub mod arithmetic;
pub mod comparison;
pub mod conversion;
pub mod exhaustive;
pub mod extend;
pub mod logic;
#[cfg(feature = "random")]
pub mod random;
pub mod select_coordinates;
#[derive(Clone, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct UnsignedVector<T: PrimitiveUnsigned> {
pub elements: Vec<T>,
}
impl<T: PrimitiveUnsigned> Vector for UnsignedVector<T> {
type Element = T;
type ElementOutput<'a>
= T
where
Self: 'a;
#[inline]
fn from_elements(xs: &[T]) -> Self {
Self {
elements: xs.to_vec(),
}
}
#[inline]
fn from_owned_elements(xs: Vec<T>) -> Self {
Self { elements: xs }
}
#[inline]
fn zero(dimension: u64) -> Self {
Self {
elements: vec![T::ZERO; usize::exact_from(dimension)],
}
}
fn standard_basis_vector(dimension: u64, index: u64) -> Self {
assert!(
index < dimension,
"the index {index} is not less than the dimension {dimension}"
);
let mut v = Self::zero(dimension);
v.elements[usize::exact_from(index)] = T::ONE;
v
}
#[inline]
fn push(&mut self, x: T) {
self.elements.push(x);
}
#[inline]
fn set_dimension(&mut self, dimension: u64) {
self.elements.resize(usize::exact_from(dimension), T::ZERO);
}
#[inline]
fn set_zero(&mut self) {
self.elements.fill(T::ZERO);
}
#[inline]
fn sort(&mut self) {
self.elements.sort_unstable();
}
#[inline]
fn to_elements(&self) -> Vec<T> {
self.elements.clone()
}
#[inline]
fn into_elements(self) -> Vec<T> {
self.elements
}
#[inline]
fn elements_ref(&self) -> &[T] {
&self.elements
}
#[inline]
fn dimension(&self) -> u64 {
u64::exact_from(self.elements.len())
}
#[inline]
fn pivot(&self) -> Option<T> {
self.elements.iter().find(|&&x| x != T::ZERO).copied()
}
#[inline]
fn pivot_index(&self) -> Option<u64> {
self.elements
.iter()
.position(|&x| x != T::ZERO)
.map(u64::exact_from)
}
#[inline]
fn height_index(&self) -> Option<u64> {
self.elements
.iter()
.enumerate()
.rev()
.max_by(|(_, x), (_, y)| x.cmp(y))
.map(|(i, _)| u64::exact_from(i))
}
#[inline]
fn is_zero(&self) -> bool {
self.elements.iter().all(|&x| x == T::ZERO)
}
fn standard_basis_index(&self) -> Option<u64> {
let index = self.pivot_index()?;
let i = usize::exact_from(index);
if self.elements[i] == T::ONE && self.elements[i + 1..].iter().all(|&x| x == T::ZERO) {
Some(index)
} else {
None
}
}
#[inline]
fn max_bits(&self) -> (u64, bool) {
let mut or = T::ZERO;
for &x in &self.elements {
or |= x;
}
(or.significant_bits(), false)
}
fn sum_max_bits(&self) -> (u64, u64) {
let mut sum = T::ZERO;
let mut carries = 0u64;
let mut or = T::ZERO;
for &x in &self.elements {
let overflow;
(sum, overflow) = sum.overflowing_add(x);
if overflow {
carries += 1;
}
or |= x;
}
let sum_bits = if carries == 0 {
sum.significant_bits()
} else {
T::WIDTH + carries.significant_bits()
};
(sum_bits, or.significant_bits())
}
}
macro_rules! impl_named_unsigned_vector {
($t:ident, $name:expr) => {
impl Named for UnsignedVector<$t> {
const NAME: &'static str = $name;
}
};
}
impl_named_unsigned_vector!(u8, "UnsignedVector<u8>");
impl_named_unsigned_vector!(u16, "UnsignedVector<u16>");
impl_named_unsigned_vector!(u32, "UnsignedVector<u32>");
impl_named_unsigned_vector!(u64, "UnsignedVector<u64>");
impl_named_unsigned_vector!(u128, "UnsignedVector<u128>");
impl_named_unsigned_vector!(usize, "UnsignedVector<usize>");
#[derive(Clone, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct ShortlexUnsignedVector<T: PrimitiveUnsigned>(pub UnsignedVector<T>);
#[derive(Clone, Eq, Hash, PartialEq)]
pub struct ShortlexUnsignedVectorRef<'a, T: PrimitiveUnsigned>(pub &'a UnsignedVector<T>);
impl<T: PrimitiveUnsigned> ShortlexUnsignedVector<T> {
pub const fn as_ref(&self) -> ShortlexUnsignedVectorRef<'_, T> {
ShortlexUnsignedVectorRef(&self.0)
}
}
impl<T: PrimitiveUnsigned> Deref for ShortlexUnsignedVector<T> {
type Target = UnsignedVector<T>;
fn deref(&self) -> &UnsignedVector<T> {
&self.0
}
}
impl<T: PrimitiveUnsigned> Deref for ShortlexUnsignedVectorRef<'_, T> {
type Target = UnsignedVector<T>;
fn deref(&self) -> &UnsignedVector<T> {
self.0
}
}
impl<T: PrimitiveUnsigned> Debug for ShortlexUnsignedVector<T> {
#[inline]
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_tuple("ShortlexUnsignedVector")
.field(&self.0)
.finish()
}
}
impl<T: PrimitiveUnsigned> Debug for ShortlexUnsignedVectorRef<'_, T> {
#[inline]
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_tuple("ShortlexUnsignedVectorRef")
.field(self.0)
.finish()
}
}