@@ -22,33 +22,38 @@ struct buffer_info {
2222 ssize_t ndim = 0 ; // Number of dimensions
2323 std::vector<ssize_t > shape; // Shape of the tensor (1 entry per dimension)
2424 std::vector<ssize_t > strides; // Number of entries between adjacent entries (for each per dimension)
25+ bool readonly = false ; // flag to indicate if the underlying storage may be written to
2526
2627 buffer_info () { }
2728
2829 buffer_info (void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim,
29- detail::any_container<ssize_t > shape_in, detail::any_container<ssize_t > strides_in)
30+ detail::any_container<ssize_t > shape_in, detail::any_container<ssize_t > strides_in, bool readonly= false )
3031 : ptr (ptr), itemsize (itemsize), size (1 ), format (format), ndim (ndim),
31- shape (std::move (shape_in)), strides (std::move (strides_in)) {
32+ shape (std::move (shape_in)), strides (std::move (strides_in)), readonly (readonly) {
3233 if (ndim != (ssize_t ) shape.size () || ndim != (ssize_t ) strides.size ())
3334 pybind11_fail (" buffer_info: ndim doesn't match shape and/or strides length" );
3435 for (size_t i = 0 ; i < (size_t ) ndim; ++i)
3536 size *= shape[i];
3637 }
3738
3839 template <typename T>
39- buffer_info (T *ptr, detail::any_container<ssize_t > shape_in, detail::any_container<ssize_t > strides_in)
40- : buffer_info (private_ctr_tag (), ptr, sizeof (T), format_descriptor<T>::format (), static_cast <ssize_t >(shape_in->size ()), std::move (shape_in), std::move (strides_in)) { }
40+ buffer_info (T *ptr, detail::any_container<ssize_t > shape_in, detail::any_container<ssize_t > strides_in, bool readonly= false )
41+ : buffer_info (private_ctr_tag (), ptr, sizeof (T), format_descriptor<T>::format (), static_cast <ssize_t >(shape_in->size ()), std::move (shape_in), std::move (strides_in), readonly ) { }
4142
42- buffer_info (void *ptr, ssize_t itemsize, const std::string &format, ssize_t size)
43- : buffer_info (ptr, itemsize, format, 1 , {size}, {itemsize}) { }
43+ buffer_info (void *ptr, ssize_t itemsize, const std::string &format, ssize_t size, bool readonly= false )
44+ : buffer_info (ptr, itemsize, format, 1 , {size}, {itemsize}, readonly ) { }
4445
4546 template <typename T>
46- buffer_info (T *ptr, ssize_t size)
47- : buffer_info (ptr, sizeof (T), format_descriptor<T>::format (), size) { }
47+ buffer_info (T *ptr, ssize_t size, bool readonly=false )
48+ : buffer_info (ptr, sizeof (T), format_descriptor<T>::format (), size, readonly) { }
49+
50+ template <typename T>
51+ buffer_info (const T *ptr, ssize_t size, bool readonly=true )
52+ : buffer_info (const_cast <T*>(ptr), sizeof (T), format_descriptor<T>::format (), size, readonly) { }
4853
4954 explicit buffer_info (Py_buffer *view, bool ownview = true )
5055 : buffer_info (view->buf , view->itemsize , view->format , view->ndim ,
51- {view->shape , view->shape + view->ndim }, {view->strides , view->strides + view->ndim }) {
56+ {view->shape , view->shape + view->ndim }, {view->strides , view->strides + view->ndim }, view-> readonly ) {
5257 this ->view = view;
5358 this ->ownview = ownview;
5459 }
@@ -70,6 +75,7 @@ struct buffer_info {
7075 strides = std::move (rhs.strides );
7176 std::swap (view, rhs.view );
7277 std::swap (ownview, rhs.ownview );
78+ readonly = rhs.readonly ;
7379 return *this ;
7480 }
7581
@@ -81,8 +87,8 @@ struct buffer_info {
8187 struct private_ctr_tag { };
8288
8389 buffer_info (private_ctr_tag, void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim,
84- detail::any_container<ssize_t > &&shape_in, detail::any_container<ssize_t > &&strides_in)
85- : buffer_info (ptr, itemsize, format, ndim, std::move (shape_in), std::move (strides_in)) { }
90+ detail::any_container<ssize_t > &&shape_in, detail::any_container<ssize_t > &&strides_in, bool readonly )
91+ : buffer_info (ptr, itemsize, format, ndim, std::move (shape_in), std::move (strides_in), readonly ) { }
8692
8793 Py_buffer *view = nullptr ;
8894 bool ownview = false ;
0 commit comments