diff --git a/src/numpy_cpp.h b/src/numpy_cpp.h index 0bc2d5c03854..1629688792bd 100644 --- a/src/numpy_cpp.h +++ b/src/numpy_cpp.h @@ -27,6 +27,13 @@ #include #include +#include + +#if defined(__GNUC__) || defined(__clang__) +#define unlikely(x) __builtin_expect(!!(x), 0) +#else +#define unlikely(x) (x) +#endif namespace numpy { @@ -235,6 +242,9 @@ class array_view_accessors T &operator()(npy_intp i) { AVC *self = static_cast(this); + if (unlikely(self->m_data == NULL)) { + throw std::out_of_range("indexing into an array_view with no data"); + } return *reinterpret_cast(self->m_data + self->m_strides[0] * i); } @@ -242,6 +252,9 @@ class array_view_accessors const T &operator()(npy_intp i) const { const AVC *self = static_cast(this); + if (unlikely(self->m_data == NULL)) { + throw std::out_of_range("indexing into an array_view with no data"); + } return *reinterpret_cast(self->m_data + self->m_strides[0] * i); } @@ -249,6 +262,9 @@ class array_view_accessors T &operator[](npy_intp i) { AVC *self = static_cast(this); + if (unlikely(self->m_data == NULL)) { + throw std::out_of_range("indexing into an array_view with no data"); + } return *reinterpret_cast(self->m_data + self->m_strides[0] * i); } @@ -256,6 +272,9 @@ class array_view_accessors const T &operator[](npy_intp i) const { const AVC *self = static_cast(this); + if (unlikely(self->m_data == NULL)) { + throw std::out_of_range("indexing into an array_view with no data"); + } return *reinterpret_cast(self->m_data + self->m_strides[0] * i); } @@ -271,6 +290,9 @@ class array_view_accessors T &operator()(npy_intp i, npy_intp j) { AVC *self = static_cast(this); + if (unlikely(self->m_data == NULL)) { + throw std::out_of_range("indexing into an array_view with no data"); + } return *reinterpret_cast(self->m_data + self->m_strides[0] * i + self->m_strides[1] * j); @@ -279,6 +301,9 @@ class array_view_accessors const T &operator()(npy_intp i, npy_intp j) const { const AVC *self = static_cast(this); + if (unlikely(self->m_data == NULL)) { + throw std::out_of_range("indexing into an array_view with no data"); + } return *reinterpret_cast(self->m_data + self->m_strides[0] * i + self->m_strides[1] * j); @@ -287,6 +312,9 @@ class array_view_accessors sub_t operator[](npy_intp i) const { const AVC *self = static_cast(this); + if (unlikely(self->m_data == NULL)) { + throw std::out_of_range("indexing into an array_view with no data"); + } return sub_t(self->m_arr, self->m_data + self->m_strides[0] * i, @@ -305,6 +333,9 @@ class array_view_accessors T &operator()(npy_intp i, npy_intp j, npy_intp k) { AVC *self = static_cast(this); + if (unlikely(self->m_data == NULL)) { + throw std::out_of_range("indexing into an array_view with no data"); + } return *reinterpret_cast(self->m_data + self->m_strides[0] * i + self->m_strides[1] * j + self->m_strides[2] * k); @@ -313,6 +344,9 @@ class array_view_accessors const T &operator()(npy_intp i, npy_intp j, npy_intp k) const { const AVC *self = static_cast(this); + if (unlikely(self->m_data == NULL)) { + throw std::out_of_range("indexing into an array_view with no data"); + } return *reinterpret_cast(self->m_data + self->m_strides[0] * i + self->m_strides[1] * j + self->m_strides[2] * k); @@ -321,6 +355,9 @@ class array_view_accessors sub_t operator[](npy_intp i) const { const AVC *self = static_cast(this); + if (unlikely(self->m_data == NULL)) { + throw std::out_of_range("indexing into an array_view with no data"); + } return sub_t(self->m_arr, self->m_data + self->m_strides[0] * i, @@ -381,9 +418,20 @@ class array_view : public detail::array_view_accessors array_view(PyArrayObject *arr, char *data, npy_intp *shape, npy_intp *strides) { + bool empty = (ND == 0); + for (size_t i = 0; i < ND; i++) { + if (shape[i] == 0) { + empty = true; + } + } + m_arr = arr; Py_XINCREF(arr); - m_data = data; + if (empty) { + m_data = NULL; + } else { + m_data = data; + } m_shape = shape; m_strides = strides; } @@ -446,10 +494,10 @@ class array_view : public detail::array_view_accessors m_data = NULL; m_shape = zeros; m_strides = zeros; - if (PyArray_NDIM(tmp) == 0 && ND == 0) { - m_arr = tmp; - return 1; - } + if (PyArray_NDIM(tmp) == 0 && ND == 0) { + m_arr = tmp; + return 1; + } } if (PyArray_NDIM(tmp) != ND) { PyErr_Format(PyExc_ValueError, @@ -465,7 +513,17 @@ class array_view : public detail::array_view_accessors m_arr = tmp; m_shape = PyArray_DIMS(m_arr); m_strides = PyArray_STRIDES(m_arr); - m_data = (char *)PyArray_BYTES(tmp); + bool empty = (ND == 0); + for (size_t i = 0; i < ND; i++) { + if (m_shape[i] == 0) { + empty = true; + } + } + if (empty) { + m_data = NULL; + } else { + m_data = (char *)PyArray_BYTES(tmp); + } } return 1; @@ -481,7 +539,11 @@ class array_view : public detail::array_view_accessors size_t size() const { - return (size_t)dim(0); + if (m_data == NULL) { + return 0; + } else { + return (size_t)dim(0); + } } bool empty() const diff --git a/src/py_exceptions.h b/src/py_exceptions.h index 82dd94dedcab..765017bf3c0b 100644 --- a/src/py_exceptions.h +++ b/src/py_exceptions.h @@ -32,7 +32,7 @@ class exception : public std::exception } \ catch (const std::bad_alloc) \ { \ - PyErr_Format(PyExc_MemoryError, "In %s: Out of memory", (name)); \ + PyErr_Format(PyExc_MemoryError, "In %s: Out of memory", (name)); \ { \ cleanup; \ } \ @@ -40,7 +40,15 @@ class exception : public std::exception } \ catch (const std::overflow_error &e) \ { \ - PyErr_Format(PyExc_OverflowError, "In %s: %s", (name), e.what()); \ + PyErr_Format(PyExc_OverflowError, "In %s: %s", (name), e.what()); \ + { \ + cleanup; \ + } \ + return (errorcode); \ + } \ + catch (const std::out_of_range &e) \ + { \ + PyErr_Format(PyExc_IndexError, "In %s: %s", (name), e.what()); \ { \ cleanup; \ } \ @@ -48,7 +56,7 @@ class exception : public std::exception } \ catch (char const *e) \ { \ - PyErr_Format(PyExc_RuntimeError, "In %s: %s", (name), e); \ + PyErr_Format(PyExc_RuntimeError, "In %s: %s", (name), e); \ { \ cleanup; \ } \ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy