mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 13:15:12 +00:00
Enable unique_ptr holder with mixed Deleters between base and derived types (#1353)
* Check default holder -Recognize "std::unique_ptr<T, D>" as a default holder even if "D" doesn't match between base and derived holders * Add test for unique_ptr<T, D> change
This commit is contained in:
parent
cea42467b0
commit
63c2a972fe
@ -1069,7 +1069,7 @@ public:
|
|||||||
record.holder_size = sizeof(holder_type);
|
record.holder_size = sizeof(holder_type);
|
||||||
record.init_instance = init_instance;
|
record.init_instance = init_instance;
|
||||||
record.dealloc = dealloc;
|
record.dealloc = dealloc;
|
||||||
record.default_holder = std::is_same<holder_type, std::unique_ptr<type>>::value;
|
record.default_holder = detail::is_instantiation<std::unique_ptr, holder_type>::value;
|
||||||
|
|
||||||
set_operator_new<type>(&record);
|
set_operator_new<type>(&record);
|
||||||
|
|
||||||
|
@ -186,6 +186,32 @@ TEST_SUBMODULE(smart_ptr, m) {
|
|||||||
.def(py::init<int>())
|
.def(py::init<int>())
|
||||||
.def_readwrite("value", &MyObject4::value);
|
.def_readwrite("value", &MyObject4::value);
|
||||||
|
|
||||||
|
// test_unique_deleter
|
||||||
|
// Object with std::unique_ptr<T, D> where D is not matching the base class
|
||||||
|
// Object with a protected destructor
|
||||||
|
class MyObject4a {
|
||||||
|
public:
|
||||||
|
MyObject4a(int i) {
|
||||||
|
value = i;
|
||||||
|
print_created(this);
|
||||||
|
};
|
||||||
|
int value;
|
||||||
|
protected:
|
||||||
|
virtual ~MyObject4a() { print_destroyed(this); }
|
||||||
|
};
|
||||||
|
py::class_<MyObject4a, std::unique_ptr<MyObject4a, py::nodelete>>(m, "MyObject4a")
|
||||||
|
.def(py::init<int>())
|
||||||
|
.def_readwrite("value", &MyObject4a::value);
|
||||||
|
|
||||||
|
// Object derived but with public destructor and no Deleter in default holder
|
||||||
|
class MyObject4b : public MyObject4a {
|
||||||
|
public:
|
||||||
|
MyObject4b(int i) : MyObject4a(i) { print_created(this); }
|
||||||
|
~MyObject4b() { print_destroyed(this); }
|
||||||
|
};
|
||||||
|
py::class_<MyObject4b, MyObject4a>(m, "MyObject4b")
|
||||||
|
.def(py::init<int>());
|
||||||
|
|
||||||
// test_large_holder
|
// test_large_holder
|
||||||
class MyObject5 { // managed by huge_unique_ptr
|
class MyObject5 { // managed by huge_unique_ptr
|
||||||
public:
|
public:
|
||||||
|
@ -115,6 +115,27 @@ def test_unique_nodelete():
|
|||||||
assert cstats.alive() == 1 # Leak, but that's intentional
|
assert cstats.alive() == 1 # Leak, but that's intentional
|
||||||
|
|
||||||
|
|
||||||
|
def test_unique_nodelete4a():
|
||||||
|
o = m.MyObject4a(23)
|
||||||
|
assert o.value == 23
|
||||||
|
cstats = ConstructorStats.get(m.MyObject4a)
|
||||||
|
assert cstats.alive() == 1
|
||||||
|
del o
|
||||||
|
assert cstats.alive() == 1 # Leak, but that's intentional
|
||||||
|
|
||||||
|
|
||||||
|
def test_unique_deleter():
|
||||||
|
o = m.MyObject4b(23)
|
||||||
|
assert o.value == 23
|
||||||
|
cstats4a = ConstructorStats.get(m.MyObject4a)
|
||||||
|
assert cstats4a.alive() == 2 # Two becaue of previous test
|
||||||
|
cstats4b = ConstructorStats.get(m.MyObject4b)
|
||||||
|
assert cstats4b.alive() == 1
|
||||||
|
del o
|
||||||
|
assert cstats4a.alive() == 1 # Should now only be one leftover from previous test
|
||||||
|
assert cstats4b.alive() == 0 # Should be deleted
|
||||||
|
|
||||||
|
|
||||||
def test_large_holder():
|
def test_large_holder():
|
||||||
o = m.MyObject5(5)
|
o = m.MyObject5(5)
|
||||||
assert o.value == 5
|
assert o.value == 5
|
||||||
|
Loading…
Reference in New Issue
Block a user