From d2b628bba41dc4964f3332b81678c48259f0cecd Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Sat, 30 Apr 2016 23:02:39 +0200 Subject: [PATCH] added testcase for issue #187 --- example/issues.cpp | 37 +++++++++++++++++++++++++++++++++++-- example/issues.py | 12 +++++++++++- example/issues.ref | 1 + 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/example/issues.cpp b/example/issues.cpp index 8fc90f45..5c8c369f 100644 --- a/example/issues.cpp +++ b/example/issues.cpp @@ -10,6 +10,8 @@ #include "example.h" #include +PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr); + void init_issues(py::module &m) { py::module m2 = m.def_submodule("issues"); @@ -20,7 +22,9 @@ void init_issues(py::module &m) { m2.def("print_char", [](char c) { std::cout << c << std::endl; }); // #159: virtual function dispatch has problems with similar-named functions - struct Base { virtual void dispatch(void) const = 0; }; + struct Base { virtual void dispatch(void) const { + /* for some reason MSVC2015 can't compile this if the function is pure virtual */ + }; }; struct DispatchIssue : Base { virtual void dispatch(void) const { @@ -58,4 +62,33 @@ void init_issues(py::module &m) { m2.def("iterator_passthrough", [](py::iterator s) -> py::iterator { return py::make_iterator(std::begin(s), std::end(s)); }); -} + + // #187: issue involving std::shared_ptr<> return value policy & garbage collection + struct ElementBase { virtual void foo() { } /* Force creation of virtual table */ }; + struct ElementA : ElementBase { + ElementA(int v) : v(v) { } + int value() { return v; } + int v; + }; + + struct ElementList { + void add(std::shared_ptr e) { l.push_back(e); } + std::vector> l; + }; + + py::class_> (m2, "ElementBase"); + + py::class_>(m2, "ElementA", py::base()) + .def(py::init()) + .def("value", &ElementA::value); + + py::class_>(m2, "ElementList") + .def(py::init<>()) + .def("add", &ElementList::add) + .def("get", [](ElementList &el){ + py::list list; + for (auto &e : el.l) + list.append(py::cast(e)); + return list; + }); +}; diff --git a/example/issues.py b/example/issues.py index be241e18..2dfd0591 100644 --- a/example/issues.py +++ b/example/issues.py @@ -5,8 +5,10 @@ sys.path.append('.') from example.issues import print_cchar, print_char from example.issues import DispatchIssue, dispatch_issue_go -from example.issues import Placeholder ,return_vec_of_reference_wrapper +from example.issues import Placeholder, return_vec_of_reference_wrapper from example.issues import iterator_passthrough +from example.issues import ElementList, ElementA +import gc print_cchar("const char *") print_char('c') @@ -32,3 +34,11 @@ dispatch_issue_go(b) print(return_vec_of_reference_wrapper(Placeholder(4))) print(list(iterator_passthrough(iter([3, 5, 7, 9, 11, 13, 15])))) + +el = ElementList() +for i in range(10): + el.add(ElementA(i)) +gc.collect() +for i, v in enumerate(el.get()): + print("%i==%i, " % (i, v.value()), end='') +print() diff --git a/example/issues.ref b/example/issues.ref index 6d9a893c..13bafc22 100644 --- a/example/issues.ref +++ b/example/issues.ref @@ -4,3 +4,4 @@ Failed as expected: Tried to call pure virtual function "dispatch" Yay.. [Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]] [3, 5, 7, 9, 11, 13, 15] +0==0, 1==1, 2==2, 3==3, 4==4, 5==5, 6==6, 7==7, 8==8, 9==9,