mirror of
https://github.com/pybind/pybind11.git
synced 2025-02-16 13:47:53 +00:00
Support pointers to member functions in def_buffer.
Closes #857, by adding overloads to def_buffer that match pointers to member functions and wrap them in lambdas.
This commit is contained in:
parent
37b2383a64
commit
fe0cf8b73b
@ -1020,6 +1020,16 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Return, typename Class, typename... Args>
|
||||
class_ &def_buffer(Return (Class::*func)(Args...)) {
|
||||
return def_buffer([func] (type &obj) { return (obj.*func)(); });
|
||||
}
|
||||
|
||||
template <typename Return, typename Class, typename... Args>
|
||||
class_ &def_buffer(Return (Class::*func)(Args...) const) {
|
||||
return def_buffer([func] (const type &obj) { return (obj.*func)(); });
|
||||
}
|
||||
|
||||
template <typename C, typename D, typename... Extra>
|
||||
class_ &def_readwrite(const char *name, D C::*pm, const Extra&... extra) {
|
||||
cpp_function fget([pm](const C &c) -> const D &{ return c.*pm; }, is_method(*this)),
|
||||
|
@ -74,6 +74,32 @@ private:
|
||||
float *m_data;
|
||||
};
|
||||
|
||||
struct PTMFBuffer {
|
||||
int32_t value = 0;
|
||||
|
||||
py::buffer_info get_buffer_info() {
|
||||
return py::buffer_info(&value, sizeof(value),
|
||||
py::format_descriptor<int32_t>::format(), 1);
|
||||
}
|
||||
};
|
||||
|
||||
class ConstPTMFBuffer {
|
||||
std::unique_ptr<int32_t> value;
|
||||
|
||||
public:
|
||||
int32_t get_value() const { return *value; }
|
||||
void set_value(int32_t v) { *value = v; }
|
||||
|
||||
py::buffer_info get_buffer_info() const {
|
||||
return py::buffer_info(value.get(), sizeof(*value),
|
||||
py::format_descriptor<int32_t>::format(), 1);
|
||||
}
|
||||
|
||||
ConstPTMFBuffer() : value(new int32_t{0}) { };
|
||||
};
|
||||
|
||||
struct DerivedPTMFBuffer : public PTMFBuffer { };
|
||||
|
||||
test_initializer buffers([](py::module &m) {
|
||||
py::class_<Matrix> mtx(m, "Matrix", py::buffer_protocol());
|
||||
|
||||
@ -114,4 +140,21 @@ test_initializer buffers([](py::module &m) {
|
||||
);
|
||||
})
|
||||
;
|
||||
|
||||
py::class_<PTMFBuffer>(m, "PTMFBuffer", py::buffer_protocol())
|
||||
.def(py::init<>())
|
||||
.def_readwrite("value", &PTMFBuffer::value)
|
||||
.def_buffer(&PTMFBuffer::get_buffer_info);
|
||||
|
||||
py::class_<ConstPTMFBuffer>(m, "ConstPTMFBuffer", py::buffer_protocol())
|
||||
.def(py::init<>())
|
||||
.def_property("value", &ConstPTMFBuffer::get_value, &ConstPTMFBuffer::set_value)
|
||||
.def_buffer(&ConstPTMFBuffer::get_buffer_info);
|
||||
|
||||
// Tests that passing a pointer to member to the base class works in
|
||||
// the derived class.
|
||||
py::class_<DerivedPTMFBuffer>(m, "DerivedPTMFBuffer", py::buffer_protocol())
|
||||
.def(py::init<>())
|
||||
.def_readwrite("value", (int32_t DerivedPTMFBuffer::*) &DerivedPTMFBuffer::value)
|
||||
.def_buffer(&DerivedPTMFBuffer::get_buffer_info);
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
import struct
|
||||
import pytest
|
||||
from pybind11_tests import Matrix, ConstructorStats
|
||||
from pybind11_tests import Matrix, ConstructorStats, PTMFBuffer, ConstPTMFBuffer, DerivedPTMFBuffer
|
||||
|
||||
pytestmark = pytest.requires_numpy
|
||||
|
||||
@ -60,3 +61,12 @@ def test_to_python():
|
||||
# assert cstats.move_constructions >= 0 # Don't invoke any
|
||||
assert cstats.copy_assignments == 0
|
||||
assert cstats.move_assignments == 0
|
||||
|
||||
|
||||
@pytest.unsupported_on_pypy
|
||||
def test_ptmf():
|
||||
for cls in [PTMFBuffer, ConstPTMFBuffer, DerivedPTMFBuffer]:
|
||||
buf = cls()
|
||||
buf.value = 0x12345678
|
||||
value = struct.unpack('i', bytearray(buf))[0]
|
||||
assert value == 0x12345678
|
||||
|
Loading…
Reference in New Issue
Block a user