@@ -63,6 +63,7 @@ struct is_comparable<T, enable_if_t<container_traits<T>::is_pair>> {
63
63
template <typename , typename , typename ... Args> void vector_if_copy_constructible (const Args&...) { }
64
64
template <typename , typename , typename ... Args> void vector_if_equal_operator (const Args&...) { }
65
65
template <typename , typename , typename ... Args> void vector_if_insertion_operator (const Args&...) { }
66
+ template <typename , typename , typename , typename ... Args> void vector_buffer (const Args&...) { }
66
67
67
68
template <typename Vector, typename Class_, enable_if_t <std::is_copy_constructible<typename Vector::value_type>::value, int > = 0 >
68
69
void vector_if_copy_constructible (Class_ &cl) {
@@ -126,6 +127,23 @@ template <typename Vector, typename Class_> auto vector_if_insertion_operator(Cl
126
127
);
127
128
}
128
129
130
+ // Provide the buffer interface for vectors if we have data(), the contained type is numeric and we have a format for it
131
+ template <typename Class_, typename Vector, typename T>
132
+ enable_if_t <std::is_arithmetic<T>::value && !std::is_same<T, bool >::value, decltype(format_descriptor<T>::format(), std::declval<Vector>().data(), void ())>
133
+ vector_buffer (Class_& cl) {
134
+ cl.def_buffer ([](Vector& v) -> py::buffer_info {
135
+ return py::buffer_info (v.data (), sizeof (T), py::format_descriptor<T>::format (), 1 , {v.size ()}, {sizeof (T)});
136
+ });
137
+
138
+ cl.def (" __init__" , [](Vector& vec, py::buffer buf) {
139
+ auto info = buf.request ();
140
+ if (info.ndim != 1 || info.strides [0 ] != info.itemsize || info.itemsize != sizeof (T) || info.format != py::format_descriptor<T>::format ())
141
+ throw pybind11::type_error ();
142
+ new (&vec) Vector (info.shape [0 ]);
143
+ memcpy (vec.data (), info.ptr , info.shape [0 ] * sizeof (T));
144
+ });
145
+ }
146
+
129
147
NAMESPACE_END (detail)
130
148
131
149
//
@@ -152,6 +170,9 @@ pybind11::class_<Vector, holder_type> bind_vector(pybind11::module &m, std::stri
152
170
// Register stream insertion operator (if possible)
153
171
detail::vector_if_insertion_operator<Vector, Class_>(cl, name);
154
172
173
+ // Register the buffer interface (if possible)
174
+ detail::vector_buffer<Class_, Vector, T>(cl);
175
+
155
176
cl.def (" __init__" , [](Vector &v, iterable it) {
156
177
new (&v) Vector ();
157
178
try {
0 commit comments