From a56ca1a26926f940002e02488d9564fe38d49d74 Mon Sep 17 00:00:00 2001 From: Joris Vaillant <joris.vaillant@inria.fr> Date: Thu, 1 Feb 2024 15:37:48 +0100 Subject: [PATCH] unique_ptr: Move object --- include/eigenpy/std_unique_ptr.hpp | 48 ++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/include/eigenpy/std_unique_ptr.hpp b/include/eigenpy/std_unique_ptr.hpp index c45dbd08..45ac265d 100644 --- a/include/eigenpy/std_unique_ptr.hpp +++ b/include/eigenpy/std_unique_ptr.hpp @@ -6,31 +6,53 @@ #define __eigenpy_utils_std_unique_ptr_hpp__ #include "eigenpy/fwd.hpp" +#include "eigenpy/utils/traits.hpp" #include <boost/python.hpp> #include <memory> -#include <iostream> namespace eigenpy { +namespace details { + +template <typename T> +typename std::enable_if<is_class_or_union_remove_cvref<T>::value, + PyObject*>::type +unique_ptr_to_python(std::unique_ptr<T>&& x) { + if (!x) { + return bp::detail::none(); + } else { + return bp::detail::make_owning_holder::execute(x.release()); + } +} + +template <typename T> +typename std::enable_if<!is_class_or_union_remove_cvref<T>::value, + PyObject*>::type +unique_ptr_to_python(std::unique_ptr<T>&& x) { + if (!x) { + return bp::detail::none(); + } else { + return bp::to_python_value<const T&>()(*x); + } +} + +} // namespace details + /// result_converter of StdUniquePtrCallPolicies struct StdUniquePtrResultConverter { - template <class T> + template <typename T> struct apply { struct type { - typedef typename bp::detail::value_arg<T>::type argument_type; + typedef typename T::element_type element_type; - /// TODO, this work by copy - /// We maybe can transfer the ownership to Python for class type - /// and when argument_type is an lvalue ref - PyObject* operator()(argument_type x) const { - return bp::to_python_value<const typename T::element_type&>()(*x); + PyObject* operator()(T&& x) const { + return details::unique_ptr_to_python(std::forward<T>(x)); } #ifndef BOOST_PYTHON_NO_PY_SIGNATURES PyTypeObject const* get_pytype() const { - return bp::to_python_value<const typename T::element_type&>() - .get_pytype(); + return bp::to_python_value<const element_type&>().get_pytype(); } #endif BOOST_STATIC_CONSTANT(bool, uses_registry = true); @@ -38,8 +60,10 @@ struct StdUniquePtrResultConverter { }; }; -/// Access CallPolicie to get std::unique_ptr value from a functio -/// that return an std::unique_ptr +/// CallPolicies to get std::unique_ptr value from a function +/// that return an std::unique_ptr. +/// If the object inside the std::unique_ptr is a class or an union +/// it will be moved. In other case, it will be copied. struct StdUniquePtrCallPolicies : bp::default_call_policies { typedef StdUniquePtrResultConverter result_converter; }; -- GitLab