(
zelf: &Py<Self>,
other: &PyObject,
op: PyComparisonOp,
vm: &VirtualMachine,
)
| 1196 | |
| 1197 | impl Comparable for PyArray { |
| 1198 | fn cmp( |
| 1199 | zelf: &Py<Self>, |
| 1200 | other: &PyObject, |
| 1201 | op: PyComparisonOp, |
| 1202 | vm: &VirtualMachine, |
| 1203 | ) -> PyResult<PyComparisonValue> { |
| 1204 | // TODO: deduplicate this logic with sequence::cmp in sequence.rs. Maybe make it generic? |
| 1205 | |
| 1206 | // we cannot use zelf.is(other) for shortcut because if we contenting a |
| 1207 | // float value NaN we always return False even they are the same object. |
| 1208 | let other = class_or_notimplemented!(Self, other); |
| 1209 | |
| 1210 | if let PyComparisonValue::Implemented(x) = |
| 1211 | op.eq_only(|| Ok(zelf.array_eq(other, vm)?.into()))? |
| 1212 | { |
| 1213 | return Ok(x.into()); |
| 1214 | } |
| 1215 | |
| 1216 | let array_a = zelf.read(); |
| 1217 | let array_b = other.read(); |
| 1218 | |
| 1219 | let res = match array_a.cmp(&array_b) { |
| 1220 | // fast path for same ArrayContentType type |
| 1221 | Ok(partial_ord) => partial_ord.is_some_and(|ord| op.eval_ord(ord)), |
| 1222 | Err(()) => { |
| 1223 | let iter = Iterator::zip(array_a.iter(vm), array_b.iter(vm)); |
| 1224 | |
| 1225 | for (a, b) in iter { |
| 1226 | let ret = match op { |
| 1227 | PyComparisonOp::Lt | PyComparisonOp::Le => { |
| 1228 | vm.bool_seq_lt(&*a?, &*b?)? |
| 1229 | } |
| 1230 | PyComparisonOp::Gt | PyComparisonOp::Ge => { |
| 1231 | vm.bool_seq_gt(&*a?, &*b?)? |
| 1232 | } |
| 1233 | _ => unreachable!(), |
| 1234 | }; |
| 1235 | if let Some(v) = ret { |
| 1236 | return Ok(PyComparisonValue::Implemented(v)); |
| 1237 | } |
| 1238 | } |
| 1239 | |
| 1240 | // fallback: |
| 1241 | op.eval_ord(array_a.len().cmp(&array_b.len())) |
| 1242 | } |
| 1243 | }; |
| 1244 | |
| 1245 | Ok(res.into()) |
| 1246 | } |
| 1247 | } |
| 1248 | |
| 1249 | impl AsBuffer for PyArray { |
no test coverage detected