use std::cmp::Ordering;
use std::ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign};
use num::Num;
use num::traits::AsPrimitive;
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct VecX<T, const N: usize>
where
T: Sized + Send,
{
pub data: [T; N],
}
impl<T, const N: usize> Default for VecX<T, N>
where
T: Default + Copy + Sized + Send,
{
fn default() -> Self {
Self { data: [T::default(); N] }
}
}
impl<T, const N: usize> VecX<T, N>
where
T: Default + Copy + Sized + Send,
{
pub fn new(data: [T; N]) -> Self {
Self { data }
}
#[deprecated]
pub fn new_with(value: T) -> Self
where
T: Copy,
{
Self { data: [value; N] }
}
pub fn into<U>(self) -> VecX<U, N>
where
T: Into<U>,
U: Sized + Send,
{
let data: [U; N] = self.data.map(|v| v.into());
VecX { data }
}
pub fn as_<U>(&self) -> VecX<U, N>
where
U: AsPrimitive<T> + Sized + Send,
T: AsPrimitive<U>,
{
let data: [U; N] = self.data.map(|v| v.as_());
VecX { data }
}
pub fn fit<const M: usize>(&self) -> VecX<T, M>
where
T: Default + Copy,
{
let mut data = [T::default(); M];
(0..N.min(M)).for_each(|i| data[i] = self.data[i]);
VecX { data }
}
pub fn batch<U, F>(self, callback: F) -> VecX<U, N>
where
U: Sized + Send,
F: Fn(T) -> U,
{
let data = self.data.map(callback);
VecX { data }
}
pub fn batch_with<U, V, F>(self, other: VecX<U, N>, callback: F) -> VecX<V, N>
where
T: Copy,
U: Copy + Sized + Send,
V: Default + Copy + Sized + Send,
F: Fn(T, U) -> V,
{
let mut data = [V::default(); N];
(0..N).for_each(|i| data[i] = callback(self.data[i], other.data[i]));
VecX { data }
}
}
impl<T, const N: usize> From<T> for VecX<T, N>
where
T: Sized + Send + Copy,
{
fn from(value: T) -> Self {
Self { data: [value; N] }
}
}
impl<T, const N: usize> From<[T; N]> for VecX<T, N>
where
T: Sized + Send + Copy,
{
fn from(data: [T; N]) -> Self {
Self { data }
}
}
impl<T, const N: usize> Index<usize> for VecX<T, N>
where
T: Sized + Send,
{
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.data[index]
}
}
impl<T, const N: usize> IndexMut<usize> for VecX<T, N>
where
T: Sized + Send,
{
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.data[index]
}
}
impl<T, U, const N: usize> Add<VecX<U, N>> for VecX<T, N>
where
T: Num + Copy + Sized + Send,
U: Num + Copy + Into<T> + Sized + Send,
{
type Output = Self;
fn add(mut self, rhs: VecX<U, N>) -> Self::Output {
(0..N).for_each(|i| self.data[i] = self.data[i] + rhs.data[i].into());
self
}
}
impl<T, U, const N: usize> Add<U> for VecX<T, N>
where
T: Num + Copy + Sized + Send,
U: Num + Copy + Into<T> + Sized + Send,
{
type Output = Self;
fn add(mut self, rhs: U) -> Self::Output {
(0..N).for_each(|i| self.data[i] = self.data[i] + rhs.into());
self
}
}
impl<T, U, const N: usize> Sub<VecX<U, N>> for VecX<T, N>
where
T: Num + Copy + Sized + Send,
U: Num + Copy + Into<T> + Sized + Send,
{
type Output = Self;
fn sub(mut self, rhs: VecX<U, N>) -> Self::Output {
(0..N).for_each(|i| self.data[i] = self.data[i] - rhs.data[i].into());
self
}
}
impl<T, U, const N: usize> Sub<U> for VecX<T, N>
where
T: Num + Copy + Sized + Send,
U: Num + Copy + Into<T> + Sized + Send,
{
type Output = Self;
fn sub(mut self, rhs: U) -> Self::Output {
(0..N).for_each(|i| self.data[i] = self.data[i] - rhs.into());
self
}
}
impl<T, U, const N: usize> Mul<VecX<U, N>> for VecX<T, N>
where
T: Num + Copy + Sized + Send,
U: Num + Copy + Into<T> + Sized + Send,
{
type Output = Self;
fn mul(mut self, rhs: VecX<U, N>) -> Self::Output {
(0..N).for_each(|i| self.data[i] = self.data[i] * rhs.data[i].into());
self
}
}
impl<T, U, const N: usize> Mul<U> for VecX<T, N>
where
T: Num + Copy + Sized + Send,
U: Num + Copy + Into<T> + Sized + Send,
{
type Output = Self;
fn mul(mut self, rhs: U) -> Self::Output {
(0..N).for_each(|i| self.data[i] = self.data[i] * rhs.into());
self
}
}
impl<T, U, const N: usize> Div<VecX<U, N>> for VecX<T, N>
where
T: Num + Copy + Sized + Send,
U: Num + Copy + Into<T> + Sized + Send,
{
type Output = Self;
fn div(mut self, rhs: VecX<U, N>) -> Self::Output {
(0..N).for_each(|i| self.data[i] = self.data[i] / rhs.data[i].into());
self
}
}
impl<T, U, const N: usize> Div<U> for VecX<T, N>
where
T: Num + Copy + Sized + Send,
U: Num + Copy + Into<T> + Sized + Send,
{
type Output = Self;
fn div(mut self, rhs: U) -> Self::Output {
(0..N).for_each(|i| self.data[i] = self.data[i] / rhs.into());
self
}
}
impl<T, U, const N: usize> Rem<VecX<U, N>> for VecX<T, N>
where
T: Num + Copy + Sized + Send,
U: Num + Copy + Into<T> + Sized + Send,
{
type Output = Self;
fn rem(mut self, rhs: VecX<U, N>) -> Self::Output {
(0..N).for_each(|i| self.data[i] = self.data[i] % rhs.data[i].into());
self
}
}
impl<T, U, const N: usize> Rem<U> for VecX<T, N>
where
T: Num + Copy + Sized + Send,
U: Num + Copy + Into<T> + Sized + Send,
{
type Output = Self;
fn rem(mut self, rhs: U) -> Self::Output {
(0..N).for_each(|i| self.data[i] = self.data[i] % rhs.into());
self
}
}
impl<T, U, const N: usize> AddAssign<VecX<U, N>> for VecX<T, N>
where
T: Num + AddAssign + Copy + Sized + Send,
U: Num + AddAssign + Copy + Into<T> + Sized + Send,
{
fn add_assign(&mut self, rhs: VecX<U, N>) {
(0..N).for_each(|i| self.data[i] += rhs.data[i].into());
}
}
impl<T, U, const N: usize> AddAssign<U> for VecX<T, N>
where
T: Num + AddAssign + Copy + Sized + Send,
U: Num + AddAssign + Copy + Into<T> + Sized + Send,
{
fn add_assign(&mut self, rhs: U) {
(0..N).for_each(|i| self.data[i] += rhs.into());
}
}
impl<T, U, const N: usize> SubAssign<VecX<U, N>> for VecX<T, N>
where
T: Num + SubAssign + Copy + Sized + Send,
U: Num + SubAssign + Copy + Into<T> + Sized + Send,
{
fn sub_assign(&mut self, rhs: VecX<U, N>) {
(0..N).for_each(|i| self.data[i] -= rhs.data[i].into());
}
}
impl<T, U, const N: usize> SubAssign<U> for VecX<T, N>
where
T: Num + SubAssign + Copy + Sized + Send,
U: Num + SubAssign + Copy + Into<T> + Sized + Send,
{
fn sub_assign(&mut self, rhs: U) {
(0..N).for_each(|i| self.data[i] -= rhs.into());
}
}
impl<T, U, const N: usize> MulAssign<VecX<U, N>> for VecX<T, N>
where
T: Num + MulAssign + Copy + Sized + Send,
U: Num + MulAssign + Copy + Into<T> + Sized + Send,
{
fn mul_assign(&mut self, rhs: VecX<U, N>) {
(0..N).for_each(|i| self.data[i] *= rhs.data[i].into());
}
}
impl<T, U, const N: usize> MulAssign<U> for VecX<T, N>
where
T: Num + MulAssign + Copy + Sized + Send,
U: Num + MulAssign + Copy + Into<T> + Sized + Send,
{
fn mul_assign(&mut self, rhs: U) {
(0..N).for_each(|i| self.data[i] *= rhs.into());
}
}
impl<T, U, const N: usize> DivAssign<VecX<U, N>> for VecX<T, N>
where
T: Num + DivAssign + Copy + Sized + Send,
U: Num + DivAssign + Copy + Into<T> + Sized + Send,
{
fn div_assign(&mut self, rhs: VecX<U, N>) {
(0..N).for_each(|i| self.data[i] /= rhs.data[i].into());
}
}
impl<T, U, const N: usize> DivAssign<U> for VecX<T, N>
where
T: Num + DivAssign + Copy + Sized + Send,
U: Num + DivAssign + Copy + Into<T> + Sized + Send,
{
fn div_assign(&mut self, rhs: U) {
(0..N).for_each(|i| self.data[i] /= rhs.into());
}
}
impl<T, U, const N: usize> RemAssign<VecX<U, N>> for VecX<T, N>
where
T: Num + RemAssign + Copy + Sized + Send,
U: Num + RemAssign + Copy + Into<T> + Sized + Send,
{
fn rem_assign(&mut self, rhs: VecX<U, N>) {
(0..N).for_each(|i| self.data[i] %= rhs.data[i].into());
}
}
impl<T, U, const N: usize> RemAssign<U> for VecX<T, N>
where
T: Num + RemAssign + Copy + Sized + Send,
U: Num + RemAssign + Copy + Into<T> + Sized + Send,
{
fn rem_assign(&mut self, rhs: U) {
(0..N).for_each(|i| self.data[i] %= rhs.into());
}
}
impl<T, const N: usize> PartialOrd for VecX<T, N>
where
T: Num + PartialOrd + Copy + Sized + Send,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
if self == other {
Some(Ordering::Equal)
} else {
if self.data.iter().zip(other.data).all(|(a, b)| { *a >= b }) {
return Some(Ordering::Greater);
}
if self.data.iter().zip(other.data).all(|(a, b)| { *a <= b }) {
return Some(Ordering::Less);
}
None
}
}
}