Skip to content
Snippets Groups Projects
Unverified Commit c670872a authored by Joris Vaillant's avatar Joris Vaillant
Browse files

wip: Try to add arithmetic type support

parent 339d70f7
No related branches found
No related tags found
No related merge requests found
Pipeline #35893 canceled
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include <boost/mpl/for_each.hpp> #include <boost/mpl/for_each.hpp>
#include <boost/mpl/vector.hpp> #include <boost/mpl/vector.hpp>
#include <type_traits>
#ifdef EIGENPY_WITH_CXX17_SUPPORT #ifdef EIGENPY_WITH_CXX17_SUPPORT
#include <variant> #include <variant>
#endif #endif
...@@ -96,6 +98,7 @@ struct VariantValueToObject : VariantVisitorType<PyObject*, Variant> { ...@@ -96,6 +98,7 @@ struct VariantValueToObject : VariantVisitorType<PyObject*, Variant> {
using Base::operator(); using Base::operator();
}; };
/// Convert {boost,std}::variant<class...> alternative reference to a Python /// Convert {boost,std}::variant<class...> alternative reference to a Python
/// object. This converter return the alternative reference. The code that /// object. This converter return the alternative reference. The code that
/// create the reference holder is taken from \see /// create the reference holder is taken from \see
...@@ -110,7 +113,20 @@ struct VariantRefToObject : VariantVisitorType<PyObject*, Variant> { ...@@ -110,7 +113,20 @@ struct VariantRefToObject : VariantVisitorType<PyObject*, Variant> {
return Base::visit(VariantRefToObject(), v); return Base::visit(VariantRefToObject(), v);
} }
template <typename T> template <typename T,
typename std::enable_if<
std::is_arithmetic<typename std::remove_cv<
typename std::remove_reference<T>::type>::type>::value,
bool>::type = true>
result_type operator()(T t) const {
return boost::python::incref(boost::python::object(t).ptr());
}
template <typename T,
typename std::enable_if<
!std::is_arithmetic<typename std::remove_cv<
typename std::remove_reference<T>::type>::type>::value,
bool>::type = true>
result_type operator()(T& t) const { result_type operator()(T& t) const {
return boost::python::detail::make_reference_holder::execute(&t); return boost::python::detail::make_reference_holder::execute(&t);
} }
...@@ -198,6 +214,7 @@ struct VariantConverter { ...@@ -198,6 +214,7 @@ struct VariantConverter {
static void registration() { static void registration() {
typedef details::VariantValueToObject<variant_type> variant_to_value; typedef details::VariantValueToObject<variant_type> variant_to_value;
typedef typename details::VariantAlternatives<variant_type>::types types; typedef typename details::VariantAlternatives<variant_type>::types types;
boost::python::to_python_converter<variant_type, variant_to_value>(); boost::python::to_python_converter<variant_type, variant_to_value>();
boost::mpl::for_each<types>( boost::mpl::for_each<types>(
details::VariantImplicitlyConvertible<variant_type>()); details::VariantImplicitlyConvertible<variant_type>());
......
...@@ -5,8 +5,10 @@ V1 = variant_module.V1 ...@@ -5,8 +5,10 @@ V1 = variant_module.V1
V2 = variant_module.V2 V2 = variant_module.V2
VariantHolder = variant_module.VariantHolder VariantHolder = variant_module.VariantHolder
VariantNoneHolder = variant_module.VariantNoneHolder VariantNoneHolder = variant_module.VariantNoneHolder
VariantArithmeticHolder = variant_module.VariantArithmeticHolder
make_variant = variant_module.make_variant make_variant = variant_module.make_variant
make_variant_none = variant_module.make_variant_none make_variant_none = variant_module.make_variant_none
make_variant_arithmetic = variant_module.make_variant_arithmetic
variant = make_variant() variant = make_variant()
assert isinstance(variant, V1) assert isinstance(variant, V1)
...@@ -46,10 +48,6 @@ assert variant_holder.variant.v == v2.v ...@@ -46,10 +48,6 @@ assert variant_holder.variant.v == v2.v
# Test variant that hold a None value # Test variant that hold a None value
v_none = make_variant_none() v_none = make_variant_none()
assert v_none is None assert v_none is None
v_none = 1
assert v_none == 1
v_none = None
assert v_none is None
variant_none_holder = VariantNoneHolder() variant_none_holder = VariantNoneHolder()
v_none = variant_none_holder.variant v_none = variant_none_holder.variant
...@@ -62,3 +60,19 @@ assert variant_none_holder.variant.v == 1 ...@@ -62,3 +60,19 @@ assert variant_none_holder.variant.v == 1
v1 = variant_none_holder.variant v1 = variant_none_holder.variant
v1.v = 10 v1.v = 10
assert variant_none_holder.variant.v == 10 assert variant_none_holder.variant.v == 10
# variant_none_holder.variant = None
# Test variant that hold base type
v_arithmetic = make_variant_arithmetic()
assert isinstance(v_arithmetic, int)
variant_arithemtic_holder = VariantArithmeticHolder()
assert isinstance(variant_arithemtic_holder.variant, int)
variant_arithemtic_holder.variant = 2.0
assert variant_arithemtic_holder.variant == 2
assert isinstance(variant_arithemtic_holder.variant, float)
# Arithmetic type doesn't support reference
v1 = variant_arithemtic_holder.variant
v1 = 3
assert variant_arithemtic_holder.variant != v1
...@@ -34,10 +34,14 @@ struct MyVariantNoneHelper<std::variant<Alternatives...> > { ...@@ -34,10 +34,14 @@ struct MyVariantNoneHelper<std::variant<Alternatives...> > {
typedef typename MyVariantNoneHelper<VARIANT<V1> >::type MyVariantNone; typedef typename MyVariantNoneHelper<VARIANT<V1> >::type MyVariantNone;
typedef VARIANT<int, double> MyVariantArithmetic;
MyVariant make_variant() { return V1(); } MyVariant make_variant() { return V1(); }
MyVariantNone make_variant_none() { return MyVariantNone(); } MyVariantNone make_variant_none() { return MyVariantNone(); }
MyVariantArithmetic make_variant_arithmetic() { return MyVariantArithmetic(); }
struct VariantHolder { struct VariantHolder {
MyVariant variant; MyVariant variant;
}; };
...@@ -46,6 +50,10 @@ struct VariantNoneHolder { ...@@ -46,6 +50,10 @@ struct VariantNoneHolder {
MyVariantNone variant; MyVariantNone variant;
}; };
struct VariantArithmeticHolder {
MyVariantArithmetic variant;
};
BOOST_PYTHON_MODULE(@MODNAME@) { BOOST_PYTHON_MODULE(@MODNAME@) {
using namespace eigenpy; using namespace eigenpy;
...@@ -74,4 +82,16 @@ BOOST_PYTHON_MODULE(@MODNAME@) { ...@@ -74,4 +82,16 @@ BOOST_PYTHON_MODULE(@MODNAME@) {
bp::make_getter(&VariantNoneHolder::variant, bp::make_getter(&VariantNoneHolder::variant,
ConverterNone::return_internal_reference()), ConverterNone::return_internal_reference()),
bp::make_setter(&VariantNoneHolder::variant)); bp::make_setter(&VariantNoneHolder::variant));
typedef eigenpy::VariantConverter<MyVariantArithmetic> ConverterArithmetic;
ConverterArithmetic::registration();
bp::def("make_variant_arithmetic", make_variant_arithmetic);
boost::python::class_<VariantArithmeticHolder>("VariantArithmeticHolder",
bp::init<>())
.add_property(
"variant",
bp::make_getter(&VariantArithmeticHolder::variant,
ConverterArithmetic::return_internal_reference()),
bp::make_setter(&VariantArithmeticHolder::variant));
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment