| 44 | |
| 45 | /// Information record describing a Python buffer object |
| 46 | struct buffer_info { |
| 47 | void *ptr = nullptr; // Pointer to the underlying storage |
| 48 | ssize_t itemsize = 0; // Size of individual items in bytes |
| 49 | ssize_t size = 0; // Total number of entries |
| 50 | std::string format; // For homogeneous buffers, this should be set to |
| 51 | // format_descriptor<T>::format() |
| 52 | ssize_t ndim = 0; // Number of dimensions |
| 53 | std::vector<ssize_t> shape; // Shape of the tensor (1 entry per dimension) |
| 54 | std::vector<ssize_t> strides; // Number of bytes between adjacent entries |
| 55 | // (for each per dimension) |
| 56 | bool readonly = false; // flag to indicate if the underlying storage may be written to |
| 57 | |
| 58 | buffer_info() = default; |
| 59 | |
| 60 | buffer_info(void *ptr, |
| 61 | ssize_t itemsize, |
| 62 | const std::string &format, |
| 63 | ssize_t ndim, |
| 64 | detail::any_container<ssize_t> shape_in, |
| 65 | detail::any_container<ssize_t> strides_in, |
| 66 | bool readonly = false) |
| 67 | : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim), |
| 68 | shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) { |
| 69 | if (ndim != static_cast<ssize_t>(shape.size()) |
| 70 | || ndim != static_cast<ssize_t>(strides.size())) { |
| 71 | pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length"); |
| 72 | } |
| 73 | for (size_t i = 0; i < static_cast<size_t>(ndim); ++i) { |
| 74 | size *= shape[i]; |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | template <typename T> |
| 79 | buffer_info(T *ptr, |
| 80 | detail::any_container<ssize_t> shape_in, |
| 81 | detail::any_container<ssize_t> strides_in, |
| 82 | bool readonly = false) |
| 83 | : buffer_info(private_ctr_tag(), |
| 84 | ptr, |
| 85 | sizeof(T), |
| 86 | format_descriptor<T>::format(), |
| 87 | static_cast<ssize_t>(shape_in->size()), |
| 88 | std::move(shape_in), |
| 89 | std::move(strides_in), |
| 90 | readonly) {} |
| 91 | |
| 92 | buffer_info(void *ptr, |
| 93 | ssize_t itemsize, |
| 94 | const std::string &format, |
| 95 | ssize_t size, |
| 96 | bool readonly = false) |
| 97 | : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}, readonly) {} |
| 98 | |
| 99 | template <typename T> |
| 100 | buffer_info(T *ptr, ssize_t size, bool readonly = false) |
| 101 | : buffer_info(ptr, sizeof(T), format_descriptor<T>::format(), size, readonly) {} |
| 102 | |
| 103 | template <typename T> |