mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-29 16:37:13 +00:00
Fix type alias initialization
Type alias for alias classes with members didn't work properly: space was only allocated for sizeof(type), but if we want to be able to put a type_alias instance there, we need sizeof(type_alias), but sizeof(type_alias) > sizeof(type) whenever type_alias has members.
This commit is contained in:
parent
5812d64ba2
commit
9c6859ee6e
@ -851,7 +851,7 @@ public:
|
|||||||
record.scope = scope;
|
record.scope = scope;
|
||||||
record.name = name;
|
record.name = name;
|
||||||
record.type = &typeid(type);
|
record.type = &typeid(type);
|
||||||
record.type_size = sizeof(type);
|
record.type_size = sizeof(detail::conditional_t<has_alias, type_alias, type>);
|
||||||
record.instance_size = sizeof(instance_type);
|
record.instance_size = sizeof(instance_type);
|
||||||
record.init_holder = init_holder;
|
record.init_holder = init_holder;
|
||||||
record.dealloc = dealloc;
|
record.dealloc = dealloc;
|
||||||
|
@ -192,34 +192,41 @@ void init_issues(py::module &m) {
|
|||||||
m2.def("get_moveissue1", [](int i) -> MoveIssue1 * { return new MoveIssue1(i); }, py::return_value_policy::move);
|
m2.def("get_moveissue1", [](int i) -> MoveIssue1 * { return new MoveIssue1(i); }, py::return_value_policy::move);
|
||||||
m2.def("get_moveissue2", [](int i) { return MoveIssue2(i); }, py::return_value_policy::move);
|
m2.def("get_moveissue2", [](int i) { return MoveIssue2(i); }, py::return_value_policy::move);
|
||||||
|
|
||||||
// Issue 392: overridding reference-returning functions
|
// Issues 392/397: overridding reference-returning functions
|
||||||
class OverrideTest {
|
class OverrideTest {
|
||||||
public:
|
public:
|
||||||
struct A { int value = 99; };
|
struct A { std::string value = "hi"; };
|
||||||
int v;
|
std::string v;
|
||||||
A a;
|
A a;
|
||||||
explicit OverrideTest(int v) : v{v} {}
|
explicit OverrideTest(const std::string &v) : v{v} {}
|
||||||
virtual int int_value() { return v; }
|
virtual std::string str_value() { return v; }
|
||||||
virtual int &int_ref() { return v; }
|
virtual std::string &str_ref() { return v; }
|
||||||
virtual A A_value() { return a; }
|
virtual A A_value() { return a; }
|
||||||
virtual A &A_ref() { return a; }
|
virtual A &A_ref() { return a; }
|
||||||
};
|
};
|
||||||
class PyOverrideTest : public OverrideTest {
|
class PyOverrideTest : public OverrideTest {
|
||||||
public:
|
public:
|
||||||
using OverrideTest::OverrideTest;
|
using OverrideTest::OverrideTest;
|
||||||
int int_value() override { PYBIND11_OVERLOAD(int, OverrideTest, int_value); }
|
std::string str_value() override { PYBIND11_OVERLOAD(std::string, OverrideTest, str_value); }
|
||||||
// Not allowed (uncommenting should hit a static_assert failure): we can't get a reference
|
// Not allowed (uncommenting should hit a static_assert failure): we can't get a reference
|
||||||
// to a python numeric value, since we only copy values in the numeric type caster:
|
// to a python numeric value, since we only copy values in the numeric type caster:
|
||||||
// int &int_ref() override { PYBIND11_OVERLOAD(int &, OverrideTest, int_ref); }
|
// std::string &str_ref() override { PYBIND11_OVERLOAD(std::string &, OverrideTest, str_ref); }
|
||||||
|
// But we can work around it like this:
|
||||||
|
private:
|
||||||
|
std::string _tmp;
|
||||||
|
std::string str_ref_helper() { PYBIND11_OVERLOAD(std::string, OverrideTest, str_ref); }
|
||||||
|
public:
|
||||||
|
std::string &str_ref() override { return _tmp = str_ref_helper(); }
|
||||||
|
|
||||||
A A_value() override { PYBIND11_OVERLOAD(A, OverrideTest, A_value); }
|
A A_value() override { PYBIND11_OVERLOAD(A, OverrideTest, A_value); }
|
||||||
A &A_ref() override { PYBIND11_OVERLOAD(A &, OverrideTest, A_ref); }
|
A &A_ref() override { PYBIND11_OVERLOAD(A &, OverrideTest, A_ref); }
|
||||||
};
|
};
|
||||||
py::class_<OverrideTest::A>(m2, "OverrideTest_A")
|
py::class_<OverrideTest::A>(m2, "OverrideTest_A")
|
||||||
.def_readwrite("value", &OverrideTest::A::value);
|
.def_readwrite("value", &OverrideTest::A::value);
|
||||||
py::class_<OverrideTest, PyOverrideTest>(m2, "OverrideTest")
|
py::class_<OverrideTest, PyOverrideTest>(m2, "OverrideTest")
|
||||||
.def(py::init<int>())
|
.def(py::init<const std::string &>())
|
||||||
.def("int_value", &OverrideTest::int_value)
|
.def("str_value", &OverrideTest::str_value)
|
||||||
// .def("int_ref", &OverrideTest::int_ref)
|
// .def("str_ref", &OverrideTest::str_ref)
|
||||||
.def("A_value", &OverrideTest::A_value)
|
.def("A_value", &OverrideTest::A_value)
|
||||||
.def("A_ref", &OverrideTest::A_ref);
|
.def("A_ref", &OverrideTest::A_ref);
|
||||||
|
|
||||||
|
@ -169,15 +169,15 @@ def test_move_fallback():
|
|||||||
|
|
||||||
def test_override_ref():
|
def test_override_ref():
|
||||||
from pybind11_tests.issues import OverrideTest
|
from pybind11_tests.issues import OverrideTest
|
||||||
o = OverrideTest(42)
|
o = OverrideTest("asdf")
|
||||||
|
|
||||||
# Not allowed (see associated .cpp comment)
|
# Not allowed (see associated .cpp comment)
|
||||||
#i = o.int_ref()
|
#i = o.str_ref()
|
||||||
#assert o.int_ref() == 42
|
#assert o.str_ref() == "asdf"
|
||||||
assert o.int_value() == 42
|
assert o.str_value() == "asdf"
|
||||||
|
|
||||||
assert o.A_value().value == 99
|
assert o.A_value().value == "hi"
|
||||||
a = o.A_ref()
|
a = o.A_ref()
|
||||||
assert a.value == 99
|
assert a.value == "hi"
|
||||||
a.value = 7
|
a.value = "bye"
|
||||||
assert a.value == 7
|
assert a.value == "bye"
|
||||||
|
Loading…
Reference in New Issue
Block a user