From dbe43ffccee87ee1f94d01d8b109f494db15ec5b Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Thu, 21 Apr 2016 12:21:14 +0200 Subject: [PATCH] completed implicit type casters for reference_wrapper --- docs/changelog.rst | 1 + example/issues.cpp | 8 +++++--- example/issues.py | 4 ++-- example/issues.ref | 2 +- include/pybind11/cast.h | 2 ++ 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index d14dad862..80d14a8d1 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -16,6 +16,7 @@ Changelog * Added a ``get_include()`` function to the Python module that returns the path of the directory containing the installed pybind11 header files * Documentation improvements: import issues, symbol visibility, pickling, limitations +* Added casting support for ``std::reference_wrapper<>`` 1.4 (April 7, 2016) -------------------------- diff --git a/example/issues.cpp b/example/issues.cpp index e2048b13a..c8af75692 100644 --- a/example/issues.cpp +++ b/example/issues.cpp @@ -20,7 +20,7 @@ struct DispatchIssue : Base { } }; -struct Placeholder { int i; }; +struct Placeholder { int i; Placeholder(int i) : i(i) { } }; void dispatch_issue_go(const Base * b) { b->dispatch(); } @@ -42,17 +42,19 @@ void init_issues(py::module &m) { m2.def("dispatch_issue_go", &dispatch_issue_go); py::class_(m2, "Placeholder") + .def(py::init()) .def("__repr__", [](const Placeholder &p) { return "Placeholder[" + std::to_string(p.i) + "]"; }); // #171: Can't return reference wrappers (or STL datastructures containing them) - m2.def("return_vec_of_reference_wrapper", [] { + m2.def("return_vec_of_reference_wrapper", [](std::reference_wrapper p4){ Placeholder *p1 = new Placeholder{1}; Placeholder *p2 = new Placeholder{2}; - Placeholder *p3 = new Placeholder{2}; + Placeholder *p3 = new Placeholder{3}; std::vector> v; v.push_back(std::ref(*p1)); v.push_back(std::ref(*p2)); v.push_back(std::ref(*p3)); + v.push_back(p4); return v; }); } diff --git a/example/issues.py b/example/issues.py index 4095daa6f..e0726f0b8 100644 --- a/example/issues.py +++ b/example/issues.py @@ -5,7 +5,7 @@ sys.path.append('.') from example.issues import print_cchar, print_char from example.issues import DispatchIssue, dispatch_issue_go -from example.issues import return_vec_of_reference_wrapper +from example.issues import Placeholder ,return_vec_of_reference_wrapper print_cchar("const char *") print_char('c') @@ -28,4 +28,4 @@ class PyClass2(DispatchIssue): b = PyClass2() dispatch_issue_go(b) -print(return_vec_of_reference_wrapper()) +print(return_vec_of_reference_wrapper(Placeholder(4))) diff --git a/example/issues.ref b/example/issues.ref index 74b34c28f..fce7b9555 100644 --- a/example/issues.ref +++ b/example/issues.ref @@ -2,4 +2,4 @@ const char * c Failed as expected: Tried to call pure virtual function "dispatch" Yay.. -[Placeholder[1], Placeholder[2], Placeholder[2]] +[Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]] diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 1002ab1e7..440d9b678 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -246,6 +246,8 @@ public: static handle cast(const std::reference_wrapper &src, return_value_policy policy, handle parent) { return type_caster::cast(&src.get(), policy, parent); } + template using cast_op_type = std::reference_wrapper; + operator std::reference_wrapper() { return std::ref(*((type *) this->value)); } }; #define PYBIND11_TYPE_CASTER(type, py_name) \