Commit 9f0dfce8 by Wenzel Jakob

returning unique pointers is now allowed

parent a3ee1a45
......@@ -527,9 +527,40 @@ Python side:
py::implicitly_convertible<A, B>();
Unique pointers
===============
Given a class ``Example`` with Python bindings, it's possible to return
instances wrapped in C++11 unique pointers, like so
.. code-block:: cpp
std::unique_ptr<Example> create_example() { return std::unique_ptr<Example>(new Example()); }
.. code-block:: cpp
m.def("create_example", &create_example);
In other words, there is nothing special that needs to be done. While returning
unique pointers in this way is allowed, it is *illegal* to use them as function
arguments. For instance, the following function signature cannot be processed
by pybind11.
.. code-block:: cpp
void do_something_with_example(std::unique_ptr<Example> ex) { ... }
The above signature would imply that Python needs to give up ownership of an
object that is passed to this function, which is generally not possible (for
instance, the object might be referenced elsewhere).
Smart pointers
==============
This section explains how to pass values that are wrapped in "smart" pointer
types with internal reference counting. For simpler C++11 unique pointers,
please refer to the previous section.
The binding generator for classes (:class:`class_`) takes an optional second
template type, which denotes a special *holder* type that is used to manage
references to the object. When wrapping a type named ``Type``, the default
......
......@@ -31,4 +31,10 @@ void init_ex14(py::module &m) {
m.def("print_void_ptr", [](void *ptr) { std::cout << "Got void ptr : " << (uint64_t) ptr << std::endl; });
m.def("return_null_str", []() { return (char *) nullptr; });
m.def("print_null_str", [](char *ptr) { std::cout << "Got null str : " << (uint64_t) ptr << std::endl; });
m.def("return_unique_ptr", []() -> std::unique_ptr<StringList> {
StringList *result = new StringList();
result->push_back("some value");
return std::unique_ptr<StringList>(result);
});
}
......@@ -6,6 +6,7 @@ sys.path.append('.')
from example import StringList, print_opaque_list
from example import return_void_ptr, print_void_ptr
from example import return_null_str, print_null_str
from example import return_unique_ptr
l = StringList()
l.push_back("Element 1")
......@@ -19,3 +20,5 @@ print_void_ptr(return_void_ptr())
print(return_null_str())
print_null_str(return_null_str())
print(return_unique_ptr())
......@@ -7,3 +7,4 @@ Opaque list:
Got void ptr : 1234
None
Got null str : 0
[u'some value']
......@@ -405,6 +405,17 @@ protected:
bool success = false;
};
template <typename type> class type_caster<std::unique_ptr<type>> {
public:
static handle cast(std::unique_ptr<type> &&src, return_value_policy policy, handle parent) {
handle result = type_caster<type>::cast(src.get(), policy, parent);
if (result)
src.release();
return result;
}
static PYBIND11_DESCR name() { return type_caster<type>::name(); }
};
template <> class type_caster<std::wstring> {
public:
bool load(handle src, bool) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment