Skip to content

Commit c670872

Browse files
committed
wip: Try to add arithmetic type support
1 parent 339d70f commit c670872

File tree

3 files changed

+56
-5
lines changed

3 files changed

+56
-5
lines changed

include/eigenpy/variant.hpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <boost/mpl/for_each.hpp>
1313
#include <boost/mpl/vector.hpp>
1414

15+
#include <type_traits>
16+
1517
#ifdef EIGENPY_WITH_CXX17_SUPPORT
1618
#include <variant>
1719
#endif
@@ -96,6 +98,7 @@ struct VariantValueToObject : VariantVisitorType<PyObject*, Variant> {
9698
using Base::operator();
9799
};
98100

101+
99102
/// Convert {boost,std}::variant<class...> alternative reference to a Python
100103
/// object. This converter return the alternative reference. The code that
101104
/// create the reference holder is taken from \see
@@ -110,7 +113,20 @@ struct VariantRefToObject : VariantVisitorType<PyObject*, Variant> {
110113
return Base::visit(VariantRefToObject(), v);
111114
}
112115

113-
template <typename T>
116+
template <typename T,
117+
typename std::enable_if<
118+
std::is_arithmetic<typename std::remove_cv<
119+
typename std::remove_reference<T>::type>::type>::value,
120+
bool>::type = true>
121+
result_type operator()(T t) const {
122+
return boost::python::incref(boost::python::object(t).ptr());
123+
}
124+
125+
template <typename T,
126+
typename std::enable_if<
127+
!std::is_arithmetic<typename std::remove_cv<
128+
typename std::remove_reference<T>::type>::type>::value,
129+
bool>::type = true>
114130
result_type operator()(T& t) const {
115131
return boost::python::detail::make_reference_holder::execute(&t);
116132
}
@@ -198,6 +214,7 @@ struct VariantConverter {
198214
static void registration() {
199215
typedef details::VariantValueToObject<variant_type> variant_to_value;
200216
typedef typename details::VariantAlternatives<variant_type>::types types;
217+
201218
boost::python::to_python_converter<variant_type, variant_to_value>();
202219
boost::mpl::for_each<types>(
203220
details::VariantImplicitlyConvertible<variant_type>());

unittest/python/test_variant.py.in

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ V1 = variant_module.V1
55
V2 = variant_module.V2
66
VariantHolder = variant_module.VariantHolder
77
VariantNoneHolder = variant_module.VariantNoneHolder
8+
VariantArithmeticHolder = variant_module.VariantArithmeticHolder
89
make_variant = variant_module.make_variant
910
make_variant_none = variant_module.make_variant_none
11+
make_variant_arithmetic = variant_module.make_variant_arithmetic
1012

1113
variant = make_variant()
1214
assert isinstance(variant, V1)
@@ -46,10 +48,6 @@ assert variant_holder.variant.v == v2.v
4648
# Test variant that hold a None value
4749
v_none = make_variant_none()
4850
assert v_none is None
49-
v_none = 1
50-
assert v_none == 1
51-
v_none = None
52-
assert v_none is None
5351

5452
variant_none_holder = VariantNoneHolder()
5553
v_none = variant_none_holder.variant
@@ -62,3 +60,19 @@ assert variant_none_holder.variant.v == 1
6260
v1 = variant_none_holder.variant
6361
v1.v = 10
6462
assert variant_none_holder.variant.v == 10
63+
# variant_none_holder.variant = None
64+
65+
66+
# Test variant that hold base type
67+
v_arithmetic = make_variant_arithmetic()
68+
assert isinstance(v_arithmetic, int)
69+
70+
variant_arithemtic_holder = VariantArithmeticHolder()
71+
assert isinstance(variant_arithemtic_holder.variant, int)
72+
variant_arithemtic_holder.variant = 2.0
73+
assert variant_arithemtic_holder.variant == 2
74+
assert isinstance(variant_arithemtic_holder.variant, float)
75+
# Arithmetic type doesn't support reference
76+
v1 = variant_arithemtic_holder.variant
77+
v1 = 3
78+
assert variant_arithemtic_holder.variant != v1

unittest/variant.cpp.in

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,14 @@ struct MyVariantNoneHelper<std::variant<Alternatives...> > {
3434

3535
typedef typename MyVariantNoneHelper<VARIANT<V1> >::type MyVariantNone;
3636

37+
typedef VARIANT<int, double> MyVariantArithmetic;
38+
3739
MyVariant make_variant() { return V1(); }
3840

3941
MyVariantNone make_variant_none() { return MyVariantNone(); }
4042

43+
MyVariantArithmetic make_variant_arithmetic() { return MyVariantArithmetic(); }
44+
4145
struct VariantHolder {
4246
MyVariant variant;
4347
};
@@ -46,6 +50,10 @@ struct VariantNoneHolder {
4650
MyVariantNone variant;
4751
};
4852

53+
struct VariantArithmeticHolder {
54+
MyVariantArithmetic variant;
55+
};
56+
4957
BOOST_PYTHON_MODULE(@MODNAME@) {
5058
using namespace eigenpy;
5159

@@ -74,4 +82,16 @@ BOOST_PYTHON_MODULE(@MODNAME@) {
7482
bp::make_getter(&VariantNoneHolder::variant,
7583
ConverterNone::return_internal_reference()),
7684
bp::make_setter(&VariantNoneHolder::variant));
85+
86+
typedef eigenpy::VariantConverter<MyVariantArithmetic> ConverterArithmetic;
87+
ConverterArithmetic::registration();
88+
bp::def("make_variant_arithmetic", make_variant_arithmetic);
89+
90+
boost::python::class_<VariantArithmeticHolder>("VariantArithmeticHolder",
91+
bp::init<>())
92+
.add_property(
93+
"variant",
94+
bp::make_getter(&VariantArithmeticHolder::variant,
95+
ConverterArithmetic::return_internal_reference()),
96+
bp::make_setter(&VariantArithmeticHolder::variant));
7797
}

0 commit comments

Comments
 (0)