diff --git a/include/pybind11/common.h b/include/pybind11/common.h index 8b794f750..b644a11da 100644 --- a/include/pybind11/common.h +++ b/include/pybind11/common.h @@ -203,15 +203,15 @@ enum class return_value_policy : uint8_t { /// Information record describing a Python buffer object struct buffer_info { - void *ptr; // Pointer to the underlying storage - size_t itemsize; // Size of individual items in bytes - size_t size; // Total number of entries + void *ptr = nullptr; // Pointer to the underlying storage + size_t itemsize = 0; // Size of individual items in bytes + size_t size = 0; // Total number of entries std::string format; // For homogeneous buffers, this should be set to format_descriptor::format() - size_t ndim; // Number of dimensions + size_t ndim = 0; // Number of dimensions std::vector shape; // Shape of the tensor (1 entry per dimension) std::vector strides; // Number of entries between adjacent entries (for each per dimension) - buffer_info() : ptr(nullptr), view(nullptr) {} + buffer_info(){} buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t ndim, const std::vector &shape, const std::vector &strides) @@ -225,9 +225,9 @@ struct buffer_info { : buffer_info(ptr, itemsize, format, 1, std::vector { size }, std::vector { itemsize }) { } - buffer_info(Py_buffer *view) + buffer_info(Py_buffer *view, bool ownview = true) : ptr(view->buf), itemsize((size_t) view->itemsize), size(1), format(view->format), - ndim((size_t) view->ndim), shape((size_t) view->ndim), strides((size_t) view->ndim), view(view) { + ndim((size_t) view->ndim), shape((size_t) view->ndim), strides((size_t) view->ndim), view(view), ownview(ownview) { for (size_t i = 0; i < (size_t) view->ndim; ++i) { shape[i] = (size_t) view->shape[i]; strides[i] = (size_t) view->strides[i]; @@ -235,12 +235,33 @@ struct buffer_info { } } + buffer_info(const buffer_info &) = delete; + buffer_info& operator=(const buffer_info &) = delete; + + buffer_info(buffer_info &&other){ + (*this) = std::move(other); + } + + buffer_info& operator=(buffer_info &&rhs){ + ptr = rhs.ptr; + itemsize = rhs.itemsize; + size = rhs.size; + format = std::move(rhs.format); + ndim = rhs.ndim; + shape = std::move(rhs.shape); + strides = std::move(rhs.strides); + std::swap(view, rhs.view); + std::swap(ownview, rhs.ownview); + return *this; + } + ~buffer_info() { - if (view) { PyBuffer_Release(view); delete view; } + if (view && ownview) { PyBuffer_Release(view); delete view; } } private: Py_buffer *view = nullptr; + bool ownview = false; }; NAMESPACE_BEGIN(detail)