diff --git a/src/_path.h b/src/_path.h index ccc1cb81107c..0c115e3d2735 100644 --- a/src/_path.h +++ b/src/_path.h @@ -1244,68 +1244,24 @@ bool convert_to_string(PathIterator &path, } template -struct _is_sorted +bool is_sorted(PyArrayObject *array) { - bool operator()(PyArrayObject *array) - { - npy_intp size; - npy_intp i; - T last_value = -INFINITY; - T current_value; - - size = PyArray_DIM(array, 0); - - for (i = 0; i < size; ++i) { - last_value = *((T *)PyArray_GETPTR1(array, i)); - if (!std::isnan(last_value)) { - break; - } - } - - if (i == size) { - // The whole array is non-finite - return false; - } - - for (; i < size; ++i) { - current_value = *((T *)PyArray_GETPTR1(array, i)); - if (!std::isnan(current_value)) { - if (current_value < last_value) { - return false; - } - last_value = current_value; - } - } - - return true; - } -}; - - -template -struct _is_sorted_int -{ - bool operator()(PyArrayObject *array) - { - npy_intp size; - npy_intp i; - T last_value; - T current_value; - - size = PyArray_DIM(array, 0); - - last_value = *((T *)PyArray_GETPTR1(array, 0)); - - for (i = 1; i < size; ++i) { - current_value = *((T *)PyArray_GETPTR1(array, i)); - if (current_value < last_value) { + npy_intp size = PyArray_DIM(array, 0); + using limits = std::numeric_limits; + T last = limits::has_infinity ? -limits::infinity() : limits::min(); + + for (npy_intp i = 0; i < size; ++i) { + T current = *(T *)PyArray_GETPTR1(array, i); + // The following tests !isnan(current), but also works for integral + // types. (The isnan(IntegralType) overload is absent on MSVC.) + if (current == current) { + if (current < last) { return false; } - last_value = current_value; + last = current; } - - return true; } + return true; }; diff --git a/src/_path_wrapper.cpp b/src/_path_wrapper.cpp index b4081560411d..8c297907ab98 100644 --- a/src/_path_wrapper.cpp +++ b/src/_path_wrapper.cpp @@ -807,54 +807,29 @@ static PyObject *Py_is_sorted(PyObject *self, PyObject *obj) /* Handle just the most common types here, otherwise coerce to double */ - switch(PyArray_TYPE(array)) { + switch (PyArray_TYPE(array)) { case NPY_INT: - { - _is_sorted_int is_sorted; - result = is_sorted(array); - } + result = is_sorted(array); break; - case NPY_LONG: - { - _is_sorted_int is_sorted; - result = is_sorted(array); - } + result = is_sorted(array); break; - case NPY_LONGLONG: - { - _is_sorted_int is_sorted; - result = is_sorted(array); - } + result = is_sorted(array); break; - case NPY_FLOAT: - { - _is_sorted is_sorted; - result = is_sorted(array); - } + result = is_sorted(array); break; - case NPY_DOUBLE: - { - _is_sorted is_sorted; - result = is_sorted(array); - } + result = is_sorted(array); break; - default: - { - Py_DECREF(array); - array = (PyArrayObject *)PyArray_FromObject(obj, NPY_DOUBLE, 1, 1); - - if (array == NULL) { - return NULL; - } - - _is_sorted is_sorted; - result = is_sorted(array); + Py_DECREF(array); + array = (PyArrayObject *)PyArray_FromObject(obj, NPY_DOUBLE, 1, 1); + if (array == NULL) { + return NULL; } + result = is_sorted(array); } Py_DECREF(array);