@@ -63,6 +63,7 @@ struct is_comparable<T, enable_if_t<container_traits<T>::is_pair>> {
6363template <typename , typename , typename ... Args> void vector_if_copy_constructible (const Args&...) { }
6464template <typename , typename , typename ... Args> void vector_if_equal_operator (const Args&...) { }
6565template <typename , typename , typename ... Args> void vector_if_insertion_operator (const Args&...) { }
66+ template <typename , typename , typename , typename ... Args> void vector_buffer (const Args&...) { }
6667
6768template <typename Vector, typename Class_, enable_if_t <std::is_copy_constructible<typename Vector::value_type>::value, int > = 0 >
6869void vector_if_copy_constructible (Class_ &cl) {
@@ -126,6 +127,23 @@ template <typename Vector, typename Class_> auto vector_if_insertion_operator(Cl
126127 );
127128}
128129
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+
129147NAMESPACE_END (detail)
130148
131149//
@@ -152,6 +170,9 @@ pybind11::class_<Vector, holder_type> bind_vector(pybind11::module &m, std::stri
152170 // Register stream insertion operator (if possible)
153171 detail::vector_if_insertion_operator<Vector, Class_>(cl, name);
154172
173+ // Register the buffer interface (if possible)
174+ detail::vector_buffer<Class_, Vector, T>(cl);
175+
155176 cl.def (" __init__" , [](Vector &v, iterable it) {
156177 new (&v) Vector ();
157178 try {
0 commit comments