From 8bd31c71e432323ecc6cee6d33daabb0aec8ceed Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Thu, 14 Apr 2016 14:26:13 +0200 Subject: [PATCH] New automatic return value policy for cat() and make_tuple(), fixed an ambiguity issue --- docs/advanced.rst | 3 +++ include/pybind11/cast.h | 15 ++++++++++----- include/pybind11/common.h | 3 +++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/docs/advanced.rst b/docs/advanced.rst index d2a66bc11..9df5cb3fe 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -418,6 +418,9 @@ functions. The default policy is :enum:`return_value_policy::automatic`. | :enum:`return_value_policy::automatic` | Automatic: copy objects returned as values and take ownership of | | | objects returned as pointers | +--------------------------------------------------+---------------------------------------------------------------------------+ +| :enum:`return_value_policy::automatic_reference` | Automatic variant 2 : copy objects returned as values and reference | +| | objects returned as pointers | ++--------------------------------------------------+---------------------------------------------------------------------------+ | :enum:`return_value_policy::copy` | Create a new copy of the returned object, which will be owned by Python | +--------------------------------------------------+---------------------------------------------------------------------------+ | :enum:`return_value_policy::take_ownership` | Reference the existing object and take ownership. Python will call | diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 670c3afa0..0fe35274d 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -178,6 +178,8 @@ public: if (policy == return_value_policy::automatic) policy = return_value_policy::take_ownership; + else if (policy == return_value_policy::automatic_reference) + policy = return_value_policy::reference; if (policy == return_value_policy::copy) { wrapper->value = copy_constructor(wrapper->value); @@ -217,7 +219,7 @@ public: type_caster() : type_caster_generic(typeid(type)) { } static handle cast(const type &src, return_value_policy policy, handle parent) { - if (policy == return_value_policy::automatic) + if (policy == return_value_policy::automatic || policy == return_value_policy::automatic_reference) policy = return_value_policy::copy; return cast(&src, policy, parent); } @@ -706,20 +708,23 @@ template inline T cast(handle handle) { return (T) conv; } -template inline object cast(const T &value, return_value_policy policy = return_value_policy::automatic, handle parent = handle()) { +template inline object cast(const T &value, return_value_policy policy = return_value_policy::automatic_reference, handle parent = handle()) { if (policy == return_value_policy::automatic) policy = std::is_pointer::value ? return_value_policy::take_ownership : return_value_policy::copy; + else if (policy == return_value_policy::automatic_reference) + policy = std::is_pointer::value ? return_value_policy::reference : return_value_policy::copy; return object(detail::type_caster::type>::cast(value, policy, parent), false); } template inline T handle::cast() const { return pybind11::cast(*this); } template <> inline void handle::cast() const { return; } -template inline tuple make_tuple(Args&&... args_) { +template inline tuple make_tuple(Args&&... args_) { const size_t size = sizeof...(Args); std::array args { { object(detail::type_caster::type>::cast( - std::forward(args_), return_value_policy::automatic, nullptr), false)... } + std::forward(args_), policy, nullptr), false)... } }; for (auto &arg_value : args) if (!arg_value) @@ -732,7 +737,7 @@ template inline tuple make_tuple(Args&&... args_) { } template inline object handle::call(Args&&... args) const { - tuple args_tuple = make_tuple(std::forward(args)...); + tuple args_tuple = pybind11::make_tuple(std::forward(args)...); object result(PyObject_CallObject(m_ptr, args_tuple.ptr()), false); if (!result) throw error_already_set(); diff --git a/include/pybind11/common.h b/include/pybind11/common.h index bd3e4241a..15047b859 100644 --- a/include/pybind11/common.h +++ b/include/pybind11/common.h @@ -137,6 +137,9 @@ enum class return_value_policy : int { /** Automatic: copy objects returned as values and take ownership of objects returned as pointers */ automatic = 0, + /** Automatic variant 2: copy objects returned as values and reference objects + returned as pointers */ + automatic_reference, /** Reference the object and take ownership. Python will call the destructor and delete operator when the reference count reaches zero */ take_ownership,