1111
1212#include " detail/common.h"
1313
14- PYBIND11_NAMESPACE_BEGIN (PYBIND11_NAMESPACE)
14+ PYBIND11_NAMESPACE_BEGIN (PYBIND11_NAMESPACE)
1515
16- PYBIND11_NAMESPACE_BEGIN(detail)
16+ PYBIND11_NAMESPACE_BEGIN (detail)
1717
1818// Default, C-style strides
19- inline std::vector<ssize_t> c_strides(const std::vector<ssize_t > &shape, ssize_t itemsize) {
19+ inline std::vector<ssize_t> c_strides (const std::vector<ssize_t >& shape, ssize_t itemsize)
20+ {
2021 auto ndim = shape.size ();
21- std::vector<ssize_t > strides (ndim, itemsize);
22- if (ndim > 0 ) {
23- for (size_t i = ndim - 1 ; i > 0 ; --i) {
22+ std::vector<ssize_t > strides (ndim, itemsize);
23+ if (ndim > 0 )
24+ {
25+ for (size_t i = ndim - 1 ; i > 0 ; --i)
26+ {
2427 strides[i - 1 ] = strides[i] * shape[i];
2528 }
2629 }
2730 return strides;
2831}
2932
3033// F-style strides; default when constructing an array_t with `ExtraFlags & f_style`
31- inline std::vector<ssize_t > f_strides (const std::vector<ssize_t > &shape, ssize_t itemsize) {
34+ inline std::vector<ssize_t > f_strides (const std::vector<ssize_t >& shape, ssize_t itemsize)
35+ {
3236 auto ndim = shape.size ();
33- std::vector<ssize_t > strides (ndim, itemsize);
34- for (size_t i = 1 ; i < ndim; ++i) {
37+ std::vector<ssize_t > strides (ndim, itemsize);
38+ for (size_t i = 1 ; i < ndim; ++i)
39+ {
3540 strides[i] = strides[i - 1 ] * shape[i - 1 ];
3641 }
3742 return strides;
@@ -40,11 +45,12 @@ inline std::vector<ssize_t> f_strides(const std::vector<ssize_t> &shape, ssize_t
4045template <typename T, typename SFINAE = void >
4146struct compare_buffer_info ;
4247
43- PYBIND11_NAMESPACE_END (detail)
48+ PYBIND11_NAMESPACE_END (detail)
4449
4550// / Information record describing a Python buffer object
46- struct buffer_info {
47- void *ptr = nullptr ; // Pointer to the underlying storage
51+ struct buffer_info
52+ {
53+ void * ptr = nullptr ; // Pointer to the underlying storage
4854 ssize_t itemsize = 0 ; // Size of individual items in bytes
4955 ssize_t size = 0 ; // Total number of entries
5056 std::string format; // For homogeneous buffers, this should be set to
@@ -57,101 +63,127 @@ struct buffer_info {
5763
5864 buffer_info () = default ;
5965
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 != (ssize_t ) shape.size () || ndim != (ssize_t ) strides.size ()) {
70- pybind11_fail (" buffer_info: ndim doesn't match shape and/or strides length" );
66+ buffer_info (void * ptr,
67+ ssize_t itemsize,
68+ const std::string& format,
69+ ssize_t ndim,
70+ detail::any_container<ssize_t > shape_in,
71+ detail::any_container<ssize_t > strides_in,
72+ bool readonly = false )
73+ : ptr (ptr)
74+ , itemsize (itemsize)
75+ , size (1 )
76+ , format (format)
77+ , ndim (ndim)
78+ , shape (std::move (shape_in))
79+ , strides (std::move (strides_in))
80+ , readonly (readonly)
81+ {
82+ if (ndim != (ssize_t ) shape.size () || ndim != (ssize_t ) strides.size ())
83+ {
84+ pybind11_fail (" buffer_info: ndim doesn't match shape and/or strides length" );
7185 }
72- for (size_t i = 0 ; i < (size_t ) ndim; ++i) {
86+ for (size_t i = 0 ; i < (size_t ) ndim; ++i)
87+ {
7388 size *= shape[i];
7489 }
7590 }
7691
7792 template <typename T>
78- buffer_info (T *ptr,
79- detail::any_container<ssize_t > shape_in,
80- detail::any_container<ssize_t > strides_in,
81- bool readonly = false )
82- : buffer_info (private_ctr_tag (),
83- ptr,
84- sizeof (T),
85- format_descriptor<T>::format (),
86- static_cast <ssize_t >(shape_in->size ()),
87- std::move (shape_in),
88- std::move (strides_in),
89- readonly) {}
90-
91- buffer_info (void *ptr,
92- ssize_t itemsize,
93- const std::string &format,
94- ssize_t size,
95- bool readonly = false )
96- : buffer_info (ptr, itemsize, format, 1 , {size}, {itemsize}, readonly) {}
93+ buffer_info (T* ptr,
94+ detail::any_container<ssize_t > shape_in,
95+ detail::any_container<ssize_t > strides_in,
96+ bool readonly = false )
97+ : buffer_info (private_ctr_tag (),
98+ ptr,
99+ sizeof (T),
100+ format_descriptor<T>::format (),
101+ static_cast <ssize_t > (shape_in->size ()),
102+ std::move (shape_in),
103+ std::move (strides_in),
104+ readonly)
105+ {
106+ }
107+
108+ buffer_info (void * ptr,
109+ ssize_t itemsize,
110+ const std::string& format,
111+ ssize_t size,
112+ bool readonly = false )
113+ : buffer_info (ptr, itemsize, format, 1 , { size }, { itemsize }, readonly)
114+ {
115+ }
97116
98117 template <typename T>
99- buffer_info (T *ptr, ssize_t size, bool readonly = false )
100- : buffer_info (ptr, sizeof (T), format_descriptor<T>::format (), size, readonly) {}
118+ buffer_info (T* ptr, ssize_t size, bool readonly = false )
119+ : buffer_info (ptr, sizeof (T), format_descriptor<T>::format (), size, readonly)
120+ {
121+ }
101122
102123 template <typename T>
103- buffer_info (const T *ptr, ssize_t size, bool readonly = true )
104- : buffer_info (
105- const_cast <T *>(ptr), sizeof (T), format_descriptor<T>::format (), size, readonly) {}
106-
107- explicit buffer_info (Py_buffer *view, bool ownview = true )
108- : buffer_info (
109- view->buf ,
110- view->itemsize ,
111- view->format ,
112- view->ndim ,
113- {view->shape , view->shape + view->ndim },
114- /* Though buffer::request() requests PyBUF_STRIDES, ctypes objects
115- * ignore this flag and return a view with NULL strides.
116- * When strides are NULL, build them manually. */
117- view->strides
118- ? std::vector<ssize_t >(view->strides , view->strides + view->ndim )
119- : detail::c_strides ({view->shape , view->shape + view->ndim }, view->itemsize ),
120- (view->readonly != 0 )) {
124+ buffer_info (const T* ptr, ssize_t size, bool readonly = true )
125+ : buffer_info (
126+ const_cast <T*> (ptr),
127+ sizeof (T),
128+ format_descriptor<T>::format (),
129+ size,
130+ readonly)
131+ {
132+ }
133+
134+ explicit buffer_info (Py_buffer* view, bool ownview = true )
135+ : buffer_info (
136+ view->buf ,
137+ view->itemsize ,
138+ view->format ,
139+ view->ndim ,
140+ { view->shape , view->shape + view->ndim },
141+ /* Though buffer::request() requests PyBUF_STRIDES, ctypes objects
142+ * ignore this flag and return a view with NULL strides.
143+ * When strides are NULL, build them manually. */
144+ view->strides
145+ ? std::vector<ssize_t > (view->strides , view->strides + view->ndim )
146+ : detail::c_strides ({ view->shape , view->shape + view->ndim }, view->itemsize ),
147+ (view->readonly != 0 ))
148+ {
121149 // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
122150 this ->m_view = view;
123151 // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
124152 this ->ownview = ownview;
125153 }
126154
127- buffer_info (const buffer_info &) = delete ;
128- buffer_info & operator =(const buffer_info &) = delete ;
155+ buffer_info (const buffer_info&) = delete ;
156+ buffer_info& operator = (const buffer_info&) = delete ;
129157
130- buffer_info (buffer_info && other) noexcept { (*this ) = std::move (other); }
158+ buffer_info (buffer_info&& other) noexcept { (*this ) = std::move (other); }
131159
132- buffer_info &operator =(buffer_info &&rhs) noexcept {
160+ buffer_info& operator = (buffer_info&& rhs) noexcept
161+ {
133162 ptr = rhs.ptr ;
134163 itemsize = rhs.itemsize ;
135164 size = rhs.size ;
136- format = std::move (rhs.format );
165+ format = std::move (rhs.format );
137166 ndim = rhs.ndim ;
138- shape = std::move (rhs.shape );
139- strides = std::move (rhs.strides );
140- std::swap (m_view, rhs.m_view );
141- std::swap (ownview, rhs.ownview );
167+ shape = std::move (rhs.shape );
168+ strides = std::move (rhs.strides );
169+ std::swap (m_view, rhs.m_view );
170+ std::swap (ownview, rhs.ownview );
142171 readonly = rhs.readonly ;
143172 return *this ;
144173 }
145174
146- ~buffer_info () {
147- if (m_view && ownview) {
148- PyBuffer_Release (m_view);
175+ ~buffer_info ()
176+ {
177+ if (m_view && ownview)
178+ {
179+ PyBuffer_Release (m_view);
149180 delete m_view;
150181 }
151182 }
152183
153- Py_buffer *view () const { return m_view; }
154- Py_buffer *&view () { return m_view; }
184+ Py_buffer* view () const { return m_view; }
185+
186+ Py_buffer*& view () { return m_view; }
155187
156188 /* True if the buffer item type is equivalent to `T`. */
157189 // To define "equivalent" by example:
@@ -160,49 +192,64 @@ struct buffer_info {
160192 // on some platforms, but `int` and `unsigned` will never be equivalent.
161193 // For the ground truth, please inspect `detail::compare_buffer_info<>`.
162194 template <typename T>
163- bool item_type_is_equivalent_to () const {
164- return detail::compare_buffer_info<T>::compare (*this );
195+ bool item_type_is_equivalent_to () const
196+ {
197+ return detail::compare_buffer_info<T>::compare (*this );
165198 }
166199
167200private:
168- struct private_ctr_tag {};
169-
170- buffer_info (private_ctr_tag,
171- void *ptr,
172- ssize_t itemsize,
173- const std::string &format,
174- ssize_t ndim,
175- detail::any_container<ssize_t > &&shape_in,
176- detail::any_container<ssize_t > &&strides_in,
177- bool readonly)
178- : buffer_info (
179- ptr, itemsize, format, ndim, std::move (shape_in), std::move (strides_in), readonly) {}
180-
181- Py_buffer *m_view = nullptr ;
201+ struct private_ctr_tag
202+ {
203+ };
204+
205+ buffer_info (private_ctr_tag,
206+ void * ptr,
207+ ssize_t itemsize,
208+ const std::string& format,
209+ ssize_t ndim,
210+ detail::any_container<ssize_t >&& shape_in,
211+ detail::any_container<ssize_t >&& strides_in,
212+ bool readonly)
213+ : buffer_info (
214+ ptr,
215+ itemsize,
216+ format,
217+ ndim,
218+ std::move (shape_in),
219+ std::move (strides_in),
220+ readonly)
221+ {
222+ }
223+
224+ Py_buffer* m_view = nullptr ;
182225 bool ownview = false ;
183226};
184227
185- PYBIND11_NAMESPACE_BEGIN (detail)
228+ PYBIND11_NAMESPACE_BEGIN (detail)
186229
187230template <typename T, typename SFINAE>
188- struct compare_buffer_info {
189- static bool compare (const buffer_info &b) {
231+ struct compare_buffer_info
232+ {
233+ static bool compare (const buffer_info& b)
234+ {
190235 // NOLINTNEXTLINE(bugprone-sizeof-expression) Needed for `PyObject *`
191- return b.format == format_descriptor<T>::format () && b.itemsize == (ssize_t ) sizeof (T);
236+ return b.format == format_descriptor<T>::format () && b.itemsize == (ssize_t ) sizeof (T);
192237 }
193238};
194239
195240template <typename T>
196- struct compare_buffer_info <T, detail::enable_if_t <std::is_integral<T>::value>> {
197- static bool compare (const buffer_info &b) {
198- return (size_t ) b.itemsize == sizeof (T)
199- && (b.format == format_descriptor<T>::value
200- || ((sizeof (T) == sizeof (long ))
201- && b.format == (std::is_unsigned<T>::value ? " L" : " l" ))
202- || ((sizeof (T) == sizeof (size_t ))
203- && b.format == (std::is_unsigned<T>::value ? " N" : " n" )));
241+ struct compare_buffer_info <T, detail::enable_if_t <std::is_integral<T>::value>>
242+ {
243+ static bool compare (const buffer_info& b)
244+ {
245+ return (size_t ) b.itemsize == sizeof (T)
246+ && (b.format == format_descriptor<T>::value
247+ || ((sizeof (T) == sizeof (long ))
248+ && b.format == (std::is_unsigned<T>::value ? " L" : " l" ))
249+ || ((sizeof (T) == sizeof (size_t ))
250+ && b.format == (std::is_unsigned<T>::value ? " N" : " n" )));
204251 }
205252};
206253
207- PYBIND11_NAMESPACE_END (detail)
208- PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
254+ PYBIND11_NAMESPACE_END (detail)
255+ PYBIND11_NAMESPACE_END (PYBIND11_NAMESPACE)
0 commit comments