1 //! Implements `PartialOrd` for vector types. 2 //! 3 //! This implements a lexicographical order. 4 5 macro_rules! impl_cmp_partial_ord { 6 ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { 7 impl $id { 8 /// Returns a wrapper that implements `PartialOrd`. 9 #[inline] 10 pub fn partial_lex_ord(&self) -> LexicographicallyOrdered<$id> { 11 LexicographicallyOrdered(*self) 12 } 13 } 14 15 impl crate::cmp::PartialOrd<LexicographicallyOrdered<$id>> 16 for LexicographicallyOrdered<$id> 17 { 18 #[inline] 19 fn partial_cmp( 20 &self, other: &Self, 21 ) -> Option<crate::cmp::Ordering> { 22 if PartialEq::eq(self, other) { 23 Some(crate::cmp::Ordering::Equal) 24 } else if PartialOrd::lt(self, other) { 25 Some(crate::cmp::Ordering::Less) 26 } else if PartialOrd::gt(self, other) { 27 Some(crate::cmp::Ordering::Greater) 28 } else { 29 None 30 } 31 } 32 #[inline] 33 fn lt(&self, other: &Self) -> bool { 34 let m_lt = self.0.lt(other.0); 35 let m_eq = self.0.eq(other.0); 36 for i in 0..$id::lanes() { 37 if m_eq.extract(i) { 38 continue; 39 } 40 return m_lt.extract(i); 41 } 42 false 43 } 44 #[inline] 45 fn le(&self, other: &Self) -> bool { 46 self.lt(other) | PartialEq::eq(self, other) 47 } 48 #[inline] 49 fn ge(&self, other: &Self) -> bool { 50 self.gt(other) | PartialEq::eq(self, other) 51 } 52 #[inline] 53 fn gt(&self, other: &Self) -> bool { 54 let m_gt = self.0.gt(other.0); 55 let m_eq = self.0.eq(other.0); 56 for i in 0..$id::lanes() { 57 if m_eq.extract(i) { 58 continue; 59 } 60 return m_gt.extract(i); 61 } 62 false 63 } 64 } 65 }; 66 } 67 68 macro_rules! test_cmp_partial_ord_int { 69 ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { 70 test_if!{ 71 $test_tt: 72 paste::item! { 73 pub mod [<$id _cmp_PartialOrd>] { 74 use super::*; 75 #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] 76 fn partial_lex_ord() { 77 use crate::testing::utils::{test_cmp}; 78 // constant values 79 let a = $id::splat(0); 80 let b = $id::splat(1); 81 82 test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), 83 Some(crate::cmp::Ordering::Less)); 84 test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), 85 Some(crate::cmp::Ordering::Greater)); 86 test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), 87 Some(crate::cmp::Ordering::Equal)); 88 test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), 89 Some(crate::cmp::Ordering::Equal)); 90 91 // variable values: a = [0, 1, 2, 3]; b = [3, 2, 1, 0] 92 let mut a = $id::splat(0); 93 let mut b = $id::splat(0); 94 for i in 0..$id::lanes() { 95 a = a.replace(i, i as $elem_ty); 96 b = b.replace(i, ($id::lanes() - i) as $elem_ty); 97 } 98 test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), 99 Some(crate::cmp::Ordering::Less)); 100 test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), 101 Some(crate::cmp::Ordering::Greater)); 102 test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), 103 Some(crate::cmp::Ordering::Equal)); 104 test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), 105 Some(crate::cmp::Ordering::Equal)); 106 107 // variable values: a = [0, 1, 2, 3]; b = [0, 1, 2, 4] 108 let mut b = a; 109 b = b.replace( 110 $id::lanes() - 1, 111 a.extract($id::lanes() - 1) + 1 as $elem_ty 112 ); 113 test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), 114 Some(crate::cmp::Ordering::Less)); 115 test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), 116 Some(crate::cmp::Ordering::Greater)); 117 test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), 118 Some(crate::cmp::Ordering::Equal)); 119 test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), 120 Some(crate::cmp::Ordering::Equal)); 121 122 if $id::lanes() > 2 { 123 // variable values a = [0, 1, 0, 0]; b = [0, 1, 2, 3] 124 let b = a; 125 let mut a = $id::splat(0); 126 a = a.replace(1, 1 as $elem_ty); 127 test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), 128 Some(crate::cmp::Ordering::Less)); 129 test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), 130 Some(crate::cmp::Ordering::Greater)); 131 test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), 132 Some(crate::cmp::Ordering::Equal)); 133 test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), 134 Some(crate::cmp::Ordering::Equal)); 135 136 // variable values: a = [0, 1, 2, 3]; b = [0, 1, 3, 2] 137 let mut b = a; 138 b = b.replace( 139 2, a.extract($id::lanes() - 1) + 1 as $elem_ty 140 ); 141 test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), 142 Some(crate::cmp::Ordering::Less)); 143 test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), 144 Some(crate::cmp::Ordering::Greater)); 145 test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), 146 Some(crate::cmp::Ordering::Equal)); 147 test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), 148 Some(crate::cmp::Ordering::Equal)); 149 } 150 } 151 } 152 } 153 } 154 }; 155 } 156 157 macro_rules! test_cmp_partial_ord_mask { 158 ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { 159 test_if!{ 160 $test_tt: 161 paste::item! { 162 pub mod [<$id _cmp_PartialOrd>] { 163 use super::*; 164 #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] 165 fn partial_lex_ord() { 166 use crate::testing::utils::{test_cmp}; 167 use crate::cmp::Ordering; 168 169 // constant values 170 let a = $id::splat(false); 171 let b = $id::splat(true); 172 173 test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), 174 Some(Ordering::Less)); 175 test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), 176 Some(Ordering::Greater)); 177 test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), 178 Some(Ordering::Equal)); 179 test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), 180 Some(Ordering::Equal)); 181 182 // variable values: 183 // a = [false, false, false, false]; 184 // b = [false, false, false, true] 185 let a = $id::splat(false); 186 let mut b = $id::splat(false); 187 b = b.replace($id::lanes() - 1, true); 188 test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), 189 Some(Ordering::Less)); 190 test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), 191 Some(Ordering::Greater)); 192 test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), 193 Some(Ordering::Equal)); 194 test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), 195 Some(Ordering::Equal)); 196 197 // variable values: 198 // a = [true, true, true, false]; 199 // b = [true, true, true, true] 200 let mut a = $id::splat(true); 201 let b = $id::splat(true); 202 a = a.replace($id::lanes() - 1, false); 203 test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), 204 Some(Ordering::Less)); 205 test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), 206 Some(Ordering::Greater)); 207 test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), 208 Some(Ordering::Equal)); 209 test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), 210 Some(Ordering::Equal)); 211 212 if $id::lanes() > 2 { 213 // variable values 214 // a = [false, true, false, false]; 215 // b = [false, true, true, true] 216 let mut a = $id::splat(false); 217 let mut b = $id::splat(true); 218 a = a.replace(1, true); 219 b = b.replace(0, false); 220 test_cmp(a.partial_lex_ord(), b.partial_lex_ord(), 221 Some(Ordering::Less)); 222 test_cmp(b.partial_lex_ord(), a.partial_lex_ord(), 223 Some(Ordering::Greater)); 224 test_cmp(a.partial_lex_ord(), a.partial_lex_ord(), 225 Some(Ordering::Equal)); 226 test_cmp(b.partial_lex_ord(), b.partial_lex_ord(), 227 Some(Ordering::Equal)); 228 } 229 } 230 } 231 } 232 } 233 }; 234 } 235