//! Implements `PartialOrd` for vector types. //! //! This implements a lexicographical order. macro_rules! impl_cmp_partial_ord { ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { impl $id { /// Returns a wrapper that implements `PartialOrd`. #[inline] pub fn partial_lex_ord(&self) -> LexicographicallyOrdered<$id> { LexicographicallyOrdered(*self) } } impl crate::cmp::PartialOrd> for LexicographicallyOrdered<$id> { #[inline] fn partial_cmp( &self, other: &Self, ) -> Option { if PartialEq::eq(self, other) { Some(crate::cmp::Ordering::Equal) } else if PartialOrd::lt(self, other) { Some(crate::cmp::Ordering::Less) } else if PartialOrd::gt(self, other) { Some(crate::cmp::Ordering::Greater) } else { None } } #[inline] fn lt(&self, other: &Self) -> bool { let m_lt = self.0.lt(other.0); let m_eq = self.0.eq(other.0); for i in 0..$id::lanes() { if m_eq.extract(i) { continue; } return m_lt.extract(i); } false } #[inline] fn le(&self, other: &Self) -> bool { self.lt(other) | PartialEq::eq(self, other) } #[inline] fn ge(&self, other: &Self) -> bool { self.gt(other) | PartialEq::eq(self, other) } #[inline] fn gt(&self, other: &Self) -> bool { let m_gt = self.0.gt(other.0); let m_eq = self.0.eq(other.0); for i in 0..$id::lanes() { if m_eq.extract(i) { continue; } return m_gt.extract(i); } false } } }; } macro_rules! test_cmp_partial_ord_int { ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { test_if!{ $test_tt: paste::item! { pub mod [<$id _cmp_PartialOrd>] { use super::*; #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn partial_lex_ord() { use crate::testing::utils::{test_cmp}; // constant values let a = $id::splat(0); let b = $id::splat(1); test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), Some(crate::cmp::Ordering::Less)); test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), Some(crate::cmp::Ordering::Greater)); test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), Some(crate::cmp::Ordering::Equal)); test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), Some(crate::cmp::Ordering::Equal)); // variable values: a = [0, 1, 2, 3]; b = [3, 2, 1, 0] let mut a = $id::splat(0); let mut b = $id::splat(0); for i in 0..$id::lanes() { a = a.replace(i, i as $elem_ty); b = b.replace(i, ($id::lanes() - i) as $elem_ty); } test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), Some(crate::cmp::Ordering::Less)); test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), Some(crate::cmp::Ordering::Greater)); test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), Some(crate::cmp::Ordering::Equal)); test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), Some(crate::cmp::Ordering::Equal)); // variable values: a = [0, 1, 2, 3]; b = [0, 1, 2, 4] let mut b = a; b = b.replace( $id::lanes() - 1, a.extract($id::lanes() - 1) + 1 as $elem_ty ); test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), Some(crate::cmp::Ordering::Less)); test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), Some(crate::cmp::Ordering::Greater)); test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), Some(crate::cmp::Ordering::Equal)); test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), Some(crate::cmp::Ordering::Equal)); if $id::lanes() > 2 { // variable values a = [0, 1, 0, 0]; b = [0, 1, 2, 3] let b = a; let mut a = $id::splat(0); a = a.replace(1, 1 as $elem_ty); test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), Some(crate::cmp::Ordering::Less)); test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), Some(crate::cmp::Ordering::Greater)); test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), Some(crate::cmp::Ordering::Equal)); test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), Some(crate::cmp::Ordering::Equal)); // variable values: a = [0, 1, 2, 3]; b = [0, 1, 3, 2] let mut b = a; b = b.replace( 2, a.extract($id::lanes() - 1) + 1 as $elem_ty ); test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), Some(crate::cmp::Ordering::Less)); test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), Some(crate::cmp::Ordering::Greater)); test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), Some(crate::cmp::Ordering::Equal)); test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), Some(crate::cmp::Ordering::Equal)); } } } } } }; } macro_rules! test_cmp_partial_ord_mask { ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { test_if!{ $test_tt: paste::item! { pub mod [<$id _cmp_PartialOrd>] { use super::*; #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn partial_lex_ord() { use crate::testing::utils::{test_cmp}; use crate::cmp::Ordering; // constant values let a = $id::splat(false); let b = $id::splat(true); test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), Some(Ordering::Less)); test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), Some(Ordering::Greater)); test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), Some(Ordering::Equal)); test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), Some(Ordering::Equal)); // variable values: // a = [false, false, false, false]; // b = [false, false, false, true] let a = $id::splat(false); let mut b = $id::splat(false); b = b.replace($id::lanes() - 1, true); test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), Some(Ordering::Less)); test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), Some(Ordering::Greater)); test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), Some(Ordering::Equal)); test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), Some(Ordering::Equal)); // variable values: // a = [true, true, true, false]; // b = [true, true, true, true] let mut a = $id::splat(true); let b = $id::splat(true); a = a.replace($id::lanes() - 1, false); test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), Some(Ordering::Less)); test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), Some(Ordering::Greater)); test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), Some(Ordering::Equal)); test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), Some(Ordering::Equal)); if $id::lanes() > 2 { // variable values // a = [false, true, false, false]; // b = [false, true, true, true] let mut a = $id::splat(false); let mut b = $id::splat(true); a = a.replace(1, true); b = b.replace(0, false); test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), Some(Ordering::Less)); test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), Some(Ordering::Greater)); test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), Some(Ordering::Equal)); test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), Some(Ordering::Equal)); } } } } } }; }