use crate::arr::Arr;
use crate::backend::Backend;
use std::cmp::Ordering;
impl<B1, B2, T, const D: &'static [usize]> PartialEq<Arr<B2, T, D>> for Arr<B1, T, D>
where
B1: Backend<T>,
B2: Backend<T>,
T: PartialEq,
{
fn eq(&self, other: &Arr<B2, T, D>) -> bool {
self.storage().as_vec() == other.storage().as_vec()
}
}
impl<B, T, const D: &'static [usize]> Arr<B, T, D>
where
B: Backend<T>,
T: PartialOrd + Clone,
{
#[must_use]
pub fn partial_cmp(&self, other: &Self) -> Arr<Vec<Option<Ordering>>, Option<Ordering>, D> {
self.iter()
.zip(other)
.map(|(x, y)| x.partial_cmp(y))
.collect()
}
#[must_use]
pub fn lt(&self, other: &Self) -> Arr<Vec<bool>, bool, D> {
self.iter().zip(other).map(|(x, y)| x < y).collect()
}
#[must_use]
pub fn le(&self, other: &Self) -> Arr<Vec<bool>, bool, D> {
self.iter().zip(other).map(|(x, y)| x <= y).collect()
}
#[must_use]
pub fn gt(&self, other: &Self) -> Arr<Vec<bool>, bool, D> {
self.iter().zip(other).map(|(x, y)| x > y).collect()
}
#[must_use]
pub fn ge(&self, other: &Self) -> Arr<Vec<bool>, bool, D> {
self.iter().zip(other).map(|(x, y)| x >= y).collect()
}
#[must_use]
pub fn eq(&self, other: &Self) -> Arr<Vec<bool>, bool, D> {
self.iter().zip(other).map(|(x, y)| x == y).collect()
}
#[must_use]
pub fn ne(&self, other: &Self) -> Arr<Vec<bool>, bool, D> {
self.iter().zip(other).map(|(x, y)| x != y).collect()
}
}
impl<B, T, const D: &'static [usize]> Arr<B, T, D>
where
B: Backend<T>,
T: Ord,
{
#[must_use]
#[allow(clippy::should_implement_trait)]
pub fn cmp(&self, other: &Self) -> Arr<Vec<Ordering>, Ordering, D> {
self.iter().zip(other).map(|(x, y)| x.cmp(y)).collect()
}
#[must_use]
pub fn max<'a>(&'a self, other: &'a Self) -> Arr<Vec<&'a T>, &'a T, D> {
self.iter().zip(other).map(|(x, y)| x.max(y)).collect()
}
#[must_use]
pub fn max_cloned(&self, other: &Self) -> Self
where
T: Clone,
{
self.iter()
.zip(other)
.map(|(x, y)| x.max(y))
.cloned()
.collect()
}
#[must_use]
pub fn min<'a>(&'a self, other: &'a Self) -> Arr<Vec<&'a T>, &'a T, D> {
self.iter().zip(other).map(|(x, y)| x.min(y)).collect()
}
#[must_use]
pub fn min_cloned(&self, other: &Self) -> Self
where
T: Clone,
{
self.iter()
.zip(other)
.map(|(x, y)| x.min(y))
.cloned()
.collect()
}
#[must_use]
pub fn clamp<'a>(&'a self, start: &'a T, end: &'a T) -> Arr<Vec<&'a T>, &'a T, D> {
self.iter()
.map(|x| {
if x < start {
start
} else if x > end {
end
} else {
x
}
})
.collect()
}
#[must_use]
pub fn clamp_cloned(&self, start: &T, end: &T) -> Self
where
T: Clone,
{
self.iter()
.map(|x| {
if x < start {
start
} else if x > end {
end
} else {
x
}
})
.cloned()
.collect()
}
}
#[cfg(test)]
mod test {
use crate::arr::Arr;
use std::cmp::Ordering;
#[test]
fn partial_cmp_1() {
let a = Arr::<_, _, { &[3] }>::from([1, 2, 3]);
let b = Arr::<_, _, { &[3] }>::from([3, 2, 1]);
let expect = Arr::<_, _, { &[3] }>::from([
Some(Ordering::Less),
Some(Ordering::Equal),
Some(Ordering::Greater),
]);
assert!(a.partial_cmp(&b) == expect);
}
#[test]
fn partial_cmp_2() {
let a = Arr::<_, _, { &[3] }>::from([f32::NAN, 3., 1.]);
let b = Arr::<_, _, { &[3] }>::from([3., 2., f32::NAN]);
let expect = Arr::<_, _, { &[3] }>::from([None, Some(Ordering::Greater), None]);
assert!(a.partial_cmp(&b) == expect);
}
#[test]
fn partial_cmp_ops() {
let a = Arr::<_, _, { &[3] }>::from([1., 2., 3.]);
let b = Arr::<_, _, { &[3] }>::from([3., 2., 1.]);
let lt = Arr::<_, _, { &[3] }>::from([true, false, false]);
let le = Arr::<_, _, { &[3] }>::from([true, true, false]);
let eq = Arr::<_, _, { &[3] }>::from([false, true, false]);
let gt = Arr::<_, _, { &[3] }>::from([false, false, true]);
let ge = Arr::<_, _, { &[3] }>::from([false, true, true]);
let ne = Arr::<_, _, { &[3] }>::from([true, false, true]);
assert_eq!(a.lt(&b), lt);
assert_eq!(a.le(&b), le);
assert_eq!(a.eq(&b), eq);
assert_eq!(a.gt(&b), gt);
assert_eq!(a.ge(&b), ge);
assert_eq!(a.ne(&b), ne);
}
#[test]
fn total_cmp() {
let a = Arr::<_, _, { &[3] }>::from([1, 2, 3]);
let b = Arr::<_, _, { &[3] }>::from([3, 2, 1]);
assert!(
a.partial_cmp(&b)
.iter()
.map(|x| x.unwrap())
.collect::<Arr<Vec<_>, _, _>>()
== a.cmp(&b)
);
}
#[test]
fn min_max_ref() {
let a = Arr::<_, _, { &[3] }>::from([1, 2, 3]);
let b = Arr::<_, _, { &[3] }>::from([3, 2, 1]);
let min = Arr::<_, _, { &[3] }>::from([&1, &2, &1]);
let max = Arr::<_, _, { &[3] }>::from([&3, &2, &3]);
assert!(a.min(&b) == min);
assert!(a.max(&b) == max);
}
#[test]
fn min_max() {
let a = Arr::<_, _, { &[3] }>::from([1, 2, 3]);
let b = Arr::<_, _, { &[3] }>::from([3, 2, 1]);
let min = Arr::<_, _, { &[3] }>::from([1, 2, 1]);
let max = Arr::<_, _, { &[3] }>::from([3, 2, 3]);
assert_eq!(a.min_cloned(&b), min);
assert_eq!(a.max_cloned(&b), max);
}
#[test]
fn clamp_ref() {
let a = Arr::<_, _, { &[5] }>::from([1, 2, 3, 4, 5]);
let expect = Arr::<_, _, { &[5] }>::from([&2, &2, &3, &4, &4]);
assert!(a.clamp(&2, &4) == expect);
}
#[test]
fn clamp() {
let a = Arr::<_, _, { &[5] }>::from([1, 2, 3, 4, 5]);
let expect = Arr::<_, _, { &[5] }>::from([2, 2, 3, 4, 4]);
assert_eq!(a.clamp_cloned(&2, &4), expect);
}
}