Merge pull request #384 from jagerman/unique-ptr-non-default-deleters

Make unique_ptr's with non-default deleters work
This commit is contained in:
Wenzel Jakob 2016-09-05 08:26:34 +09:00 committed by GitHub
commit 614988c875
3 changed files with 28 additions and 2 deletions

View File

@ -498,9 +498,9 @@ protected:
bool success = false;
};
template <typename type> class type_caster<std::unique_ptr<type>> {
template <typename type, typename deleter> class type_caster<std::unique_ptr<type, deleter>> {
public:
static handle cast(std::unique_ptr<type> &&src, return_value_policy policy, handle parent) {
static handle cast(std::unique_ptr<type, deleter> &&src, return_value_policy policy, handle parent) {
handle result = type_caster_base<type>::cast(src.get(), policy, parent);
if (result)
src.release();

View File

@ -69,6 +69,18 @@ private:
int value;
};
class MyObject4 {
public:
MyObject4(int value) : value{value} {
print_created(this);
}
int value;
private:
~MyObject4() {
print_destroyed(this);
}
};
/// Make pybind aware of the ref-counted wrapper type (s)
PYBIND11_DECLARE_HOLDER_TYPE(T, ref<T>);
PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>);
@ -143,6 +155,10 @@ test_initializer smart_ptr([](py::module &m) {
m.def("print_myobject3_3", &print_myobject3_3);
m.def("print_myobject3_4", &print_myobject3_4);
py::class_<MyObject4, std::unique_ptr<MyObject4, py::nodelete>>(m, "MyObject4")
.def(py::init<int>())
.def_readwrite("value", &MyObject4::value);
py::implicitly_convertible<py::int_, MyObject1>();
// Expose constructor stats for the ref type

View File

@ -113,3 +113,13 @@ def test_smart_ptr(capture):
# assert cstats.move_constructions >= 0 # Doesn't invoke any
assert cstats.copy_assignments == 30
assert cstats.move_assignments == 0
def test_unique_nodelete(capture):
from pybind11_tests import MyObject4
o = MyObject4(23)
assert o.value == 23
cstats = ConstructorStats.get(MyObject4)
assert cstats.alive() == 1
del o
cstats = ConstructorStats.get(MyObject4)
assert cstats.alive() == 1 # Leak, but that's intentional