mirror of
https://github.com/pybind/pybind11.git
synced 2025-02-19 15:10:38 +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;
|
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>
|
template <typename C, typename D, typename... Extra>
|
||||||
class_ &def_readwrite(const char *name, D C::*pm, const Extra&... 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)),
|
cpp_function fget([pm](const C &c) -> const D &{ return c.*pm; }, is_method(*this)),
|
||||||
|
@ -74,6 +74,32 @@ private:
|
|||||||
float *m_data;
|
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) {
|
test_initializer buffers([](py::module &m) {
|
||||||
py::class_<Matrix> mtx(m, "Matrix", py::buffer_protocol());
|
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
|
import pytest
|
||||||
from pybind11_tests import Matrix, ConstructorStats
|
from pybind11_tests import Matrix, ConstructorStats, PTMFBuffer, ConstPTMFBuffer, DerivedPTMFBuffer
|
||||||
|
|
||||||
pytestmark = pytest.requires_numpy
|
pytestmark = pytest.requires_numpy
|
||||||
|
|
||||||
@ -60,3 +61,12 @@ def test_to_python():
|
|||||||
# assert cstats.move_constructions >= 0 # Don't invoke any
|
# assert cstats.move_constructions >= 0 # Don't invoke any
|
||||||
assert cstats.copy_assignments == 0
|
assert cstats.copy_assignments == 0
|
||||||
assert cstats.move_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