7#ifndef __eigenpy_optional_hpp__ 8#define __eigenpy_optional_hpp__ 10#include "eigenpy/fwd.hpp" 11#include "eigenpy/eigen-from-python.hpp" 12#include "eigenpy/registration.hpp" 14#include <boost/optional.hpp> 15#ifdef EIGENPY_WITH_CXX17_SUPPORT 19#ifndef EIGENPY_DEFAULT_OPTIONAL 20#define EIGENPY_DEFAULT_OPTIONAL boost::optional 28struct expected_pytype_for_arg<boost::optional<T>>
29 : expected_pytype_for_arg<T> {};
31#ifdef EIGENPY_WITH_CXX17_SUPPORT 33struct expected_pytype_for_arg<std::optional<T>> : expected_pytype_for_arg<T> {
47template <
template <
typename>
class OptionalTpl>
52 typedef boost::none_t type;
53 static type value() {
return boost::none; }
56#ifdef EIGENPY_WITH_CXX17_SUPPORT 59 typedef std::nullopt_t
type;
60 static type value() {
return std::nullopt; }
64template <
typename NoneType>
66 static PyObject *convert(
const NoneType &) { Py_RETURN_NONE; }
68 static void registration() {
70 bp::to_python_converter<NoneType, NoneToPython, false>();
76 template <
typename>
class OptionalTpl = EIGENPY_DEFAULT_OPTIONAL>
78 static PyObject *convert(
const OptionalTpl<T> &obj) {
80 return bp::incref(bp::object(*obj).ptr());
82 return bp::incref(bp::object().ptr());
86 static PyTypeObject
const *get_pytype() {
87 return bp::converter::registered_pytype<T>::get_pytype();
90 static void registration() {
98 template <
typename>
class OptionalTpl = EIGENPY_DEFAULT_OPTIONAL>
100 static void *convertible(PyObject *obj_ptr);
102 static void construct(PyObject *obj_ptr,
103 bp::converter::rvalue_from_python_stage1_data *memory);
105 static void registration();
108template <
typename T,
template <
typename>
class OptionalTpl>
109void *OptionalFromPython<T, OptionalTpl>::convertible(PyObject *obj_ptr) {
110 if (obj_ptr == Py_None) {
113 bp::extract<T> bp_obj(obj_ptr);
120template <
typename T,
template <
typename>
class OptionalTpl>
121void OptionalFromPython<T, OptionalTpl>::construct(
122 PyObject *obj_ptr, bp::converter::rvalue_from_python_stage1_data *memory) {
124 using rvalue_storage_t =
125 bp::converter::rvalue_from_python_storage<OptionalTpl<T>>;
127 reinterpret_cast<rvalue_storage_t *
>(
reinterpret_cast<void *
>(memory))
130 if (obj_ptr == Py_None) {
131 new (storage) OptionalTpl<T>(nullopt_helper<OptionalTpl>::value());
133 const T value = bp::extract<T>(obj_ptr);
134 new (storage) OptionalTpl<T>(value);
137 memory->convertible = storage;
140template <
typename T,
template <
typename>
class OptionalTpl>
141void OptionalFromPython<T, OptionalTpl>::registration() {
142 bp::converter::registry::push_back(
143 &convertible, &construct, bp::type_id<OptionalTpl<T>>(),
144 bp::converter::expected_pytype_for_arg<OptionalTpl<T>>::get_pytype);
152 template <
typename>
class OptionalTpl = EIGENPY_DEFAULT_OPTIONAL>
154 static void registration() {
155 detail::OptionalToPython<T, OptionalTpl>::registration();
156 detail::OptionalFromPython<T, OptionalTpl>::registration();
bool check_registration()
Check at runtime the registration of the type T inside the boost python registry.