eigenpy 3.12.0
Bindings between Numpy and Eigen using Boost.Python
Loading...
Searching...
No Matches
std-unique-ptr.hpp
1//
2// Copyright (c) 2024 INRIA
3//
4
5#ifndef __eigenpy_utils_std_unique_ptr_hpp__
6#define __eigenpy_utils_std_unique_ptr_hpp__
7
8#include "eigenpy/fwd.hpp"
9#include "eigenpy/utils/traits.hpp"
10#include "eigenpy/utils/python-compat.hpp"
11
12#include <boost/python.hpp>
13
14#include <memory>
15#include <type_traits>
16
17namespace eigenpy {
18
19namespace details {
20
22template <typename T>
23typename std::enable_if<!is_python_primitive_type<T>::value, PyObject*>::type
24unique_ptr_to_python(std::unique_ptr<T>&& x) {
25 typedef bp::objects::pointer_holder<std::unique_ptr<T>, T> holder_t;
26 if (!x) {
27 return bp::detail::none();
28 } else {
29 return bp::objects::make_ptr_instance<T, holder_t>::execute(x);
30 }
31}
32
34template <typename T>
35typename std::enable_if<is_python_primitive_type<T>::value, PyObject*>::type
36unique_ptr_to_python(std::unique_ptr<T>&& x) {
37 if (!x) {
38 return bp::detail::none();
39 } else {
40 return bp::to_python_value<const T&>()(*x);
41 }
42}
43
46template <typename T>
47typename std::enable_if<!is_python_primitive_type<T>::value, PyObject*>::type
48internal_unique_ptr_to_python(std::unique_ptr<T>& x) {
49 if (!x) {
50 return bp::detail::none();
51 } else {
52 return bp::detail::make_reference_holder::execute(x.get());
53 }
54}
55
57template <typename T>
58typename std::enable_if<is_python_primitive_type<T>::value, PyObject*>::type
59internal_unique_ptr_to_python(std::unique_ptr<T>& x) {
60 if (!x) {
61 return bp::detail::none();
62 } else {
63 return bp::to_python_value<const T&>()(*x);
64 }
65}
66
69 template <typename T>
70 struct apply {
71 struct type {
72 typedef typename T::element_type element_type;
73
74 PyObject* operator()(T&& x) const {
75 return unique_ptr_to_python(std::forward<T>(x));
76 }
77#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
78 PyTypeObject const* get_pytype() const {
79 return bp::to_python_value<const element_type&>().get_pytype();
80 }
81#endif
82 };
83 };
84};
85
88 template <typename T>
89 struct apply {
90 struct type {
91 typedef typename remove_cvref<T>::type::element_type element_type;
92
93 PyObject* operator()(T x) const {
94 return internal_unique_ptr_to_python(x);
95 }
96#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
97 PyTypeObject const* get_pytype() const {
98 return bp::to_python_value<const element_type&>().get_pytype();
99 }
100#endif
101 };
102 };
103};
104
105} // namespace details
106
111struct StdUniquePtrCallPolicies : bp::default_call_policies {
112 typedef details::StdUniquePtrResultConverter result_converter;
113};
114
117struct ReturnInternalStdUniquePtr : bp::return_internal_reference<> {
118 typedef details::InternalStdUniquePtrConverter result_converter;
119
120 template <class ArgumentPackage>
121 static PyObject* postcall(ArgumentPackage const& args_, PyObject* result) {
122 // Don't run return_internal_reference postcall on primitive type
123 if (PyInt_Check(result) || PyBool_Check(result) || PyFloat_Check(result) ||
124 PyStr_Check(result) || PyComplex_Check(result)) {
125 return result;
126 }
127 return bp::return_internal_reference<>::postcall(args_, result);
128 }
129};
130
131} // namespace eigenpy
132
133namespace boost {
134namespace python {
135
137template <typename T>
138struct to_python_value<const std::unique_ptr<T>&>
140 std::unique_ptr<T>>::type {};
141
142} // namespace python
143} // namespace boost
144
145#endif // ifndef __eigenpy_utils_std_unique_ptr_hpp__
result_converter of ReturnInternalStdUniquePtr
result_converter of StdUniquePtrCallPolicies
Trait to remove const&.
Definition traits.hpp:19