| 2229 | } |
| 2230 | |
| 2231 | static PyObject *Strs_richcompare(PyObject *self, PyObject *other, int op) { |
| 2232 | |
| 2233 | Strs *a = (Strs *)self; |
| 2234 | Py_ssize_t a_length = Strs_len(a); |
| 2235 | get_string_at_offset_t a_getter = str_at_offset_getter(a); |
| 2236 | if (!a_getter) { |
| 2237 | PyErr_SetString(PyExc_TypeError, "Unknown Strs kind"); |
| 2238 | return NULL; |
| 2239 | } |
| 2240 | |
| 2241 | // If the other object is also a Strs, we can compare them much faster, |
| 2242 | // avoiding the CPython API entirely |
| 2243 | if (PyObject_TypeCheck(other, &StrsType)) { |
| 2244 | Strs *b = (Strs *)other; |
| 2245 | |
| 2246 | // Check if lengths are equal |
| 2247 | Py_ssize_t b_length = Strs_len(b); |
| 2248 | if (a_length != b_length) { |
| 2249 | if (op == Py_EQ) { Py_RETURN_FALSE; } |
| 2250 | if (op == Py_NE) { Py_RETURN_TRUE; } |
| 2251 | } |
| 2252 | |
| 2253 | // The second array may have a different layout |
| 2254 | get_string_at_offset_t b_getter = str_at_offset_getter(b); |
| 2255 | if (!b_getter) { |
| 2256 | PyErr_SetString(PyExc_TypeError, "Unknown Strs kind"); |
| 2257 | return NULL; |
| 2258 | } |
| 2259 | |
| 2260 | // Check each item for equality |
| 2261 | Py_ssize_t min_length = sz_min_of_two(a_length, b_length); |
| 2262 | for (Py_ssize_t i = 0; i < min_length; i++) { |
| 2263 | PyObject *ai_parent = NULL, *bi_parent = NULL; |
| 2264 | sz_cptr_t ai_start = NULL, *bi_start = NULL; |
| 2265 | sz_size_t ai_length = 0, bi_length = 0; |
| 2266 | a_getter(a, i, a_length, &ai_parent, &ai_start, &ai_length); |
| 2267 | b_getter(b, i, b_length, &bi_parent, &bi_start, &bi_length); |
| 2268 | |
| 2269 | // When dealing with arrays, early exists make sense only in some cases |
| 2270 | int order = (int)sz_order(ai_start, ai_length, bi_start, bi_length); |
| 2271 | switch (op) { |
| 2272 | case Py_LT: |
| 2273 | case Py_LE: |
| 2274 | if (order > 0) { Py_RETURN_FALSE; } |
| 2275 | break; |
| 2276 | case Py_EQ: |
| 2277 | if (order != 0) { Py_RETURN_FALSE; } |
| 2278 | break; |
| 2279 | case Py_NE: |
| 2280 | if (order == 0) { Py_RETURN_TRUE; } |
| 2281 | break; |
| 2282 | case Py_GT: |
| 2283 | case Py_GE: |
| 2284 | if (order < 0) { Py_RETURN_FALSE; } |
| 2285 | break; |
| 2286 | default: break; |
| 2287 | } |
| 2288 | } |
nothing calls this directly
no test coverage detected
searching dependent graphs…