complex number support
diff --git a/include/pybind/pybind.h b/include/pybind/pybind.h
index e8c4ff5..570d193 100644
--- a/include/pybind/pybind.h
+++ b/include/pybind/pybind.h
@@ -393,22 +393,27 @@
Py_TYPE(self)->tp_free((PyObject*) self);
}
- void install_buffer_funcs(const std::function<buffer_info *(PyObject *)> &func) {
+ void install_buffer_funcs(
+ buffer_info *(*get_buffer)(PyObject *, void *),
+ void *get_buffer_data) {
PyHeapTypeObject *type = (PyHeapTypeObject*) m_ptr;
type->ht_type.tp_as_buffer = &type->as_buffer;
type->as_buffer.bf_getbuffer = getbuffer;
type->as_buffer.bf_releasebuffer = releasebuffer;
- ((detail::type_info *) capsule(attr("__pybind__")))->get_buffer = func;
+ auto info = ((detail::type_info *) capsule(attr("__pybind__")));
+ info->get_buffer = get_buffer;
+ info->get_buffer_data = get_buffer_data;
}
static int getbuffer(PyObject *obj, Py_buffer *view, int flags) {
- auto const &info_func = ((detail::type_info *) capsule(handle(obj).attr("__pybind__")))->get_buffer;
- if (view == nullptr || obj == nullptr || !info_func) {
+ auto const &typeinfo = ((detail::type_info *) capsule(handle(obj).attr("__pybind__")));
+
+ if (view == nullptr || obj == nullptr || !typeinfo || !typeinfo->get_buffer) {
PyErr_SetString(PyExc_BufferError, "Internal error");
return -1;
}
memset(view, 0, sizeof(Py_buffer));
- buffer_info *info = info_func(obj);
+ buffer_info *info = typeinfo->get_buffer(obj, typeinfo->get_buffer_data);
view->obj = obj;
view->ndim = 1;
view->internal = info;
@@ -483,13 +488,16 @@
return *this;
}
- class_& def_buffer(const std::function<buffer_info(type&)> &func) {
- install_buffer_funcs([func](PyObject *obj) -> buffer_info* {
+ template <typename Func>
+ class_& def_buffer(Func &&func) {
+ struct capture { Func func; };
+ capture *ptr = new capture { std::forward<Func>(func) };
+ install_buffer_funcs([](PyObject *obj, void *ptr) -> buffer_info* {
detail::type_caster<type> caster;
if (!caster.load(obj, false))
return nullptr;
- return new buffer_info(func(caster));
- });
+ return new buffer_info(((capture *) ptr)->func(caster));
+ }, ptr);
return *this;
}