diff --git a/python/dune/xt/common/fvector.hh b/python/dune/xt/common/fvector.hh index 8d52a2a14bb49035e01b542118cdb71ca31a69aa..6138b0470fe2ec6c84b51304594cc065f8db9003 100644 --- a/python/dune/xt/common/fvector.hh +++ b/python/dune/xt/common/fvector.hh @@ -20,7 +20,9 @@ NAMESPACE_BEGIN(pybind11) NAMESPACE_BEGIN(detail) -template <class FieldVectorImp> +template <class FieldVectorImp, + bool is_number = (Dune::XT::Common::is_arithmetic<typename FieldVectorImp::value_type>::value + || Dune::XT::Common::is_complex<typename FieldVectorImp::value_type>::value)> struct FieldVector_type_caster { using type = FieldVectorImp; @@ -63,6 +65,48 @@ struct FieldVector_type_caster PYBIND11_TYPE_CASTER(type, _("List[") + value_conv::name() + _("[") + _<SZ>() + _("]]")); }; // struct FieldVector_type_caster +template <class FieldVectorImp> +struct FieldVector_type_caster<FieldVectorImp, false> +{ + using type = FieldVectorImp; + typedef typename type::value_type K; + static const int SZ = type::dimension; + using value_conv = make_caster<K>; + + bool load(handle src, bool convert) + { + if (!isinstance<sequence>(src)) + return false; + auto s = reinterpret_borrow<sequence>(src); + if (s.size() != SZ) + return false; + value_conv conv; + size_t ii = 0; + for (auto it : s) { + if (ii >= SZ) + return false; + if (!conv.load(it, convert)) + return false; + value[ii++] = cast_op<K>(conv); + } + return true; + } // ... load(...) + + static handle cast(const type& src, return_value_policy policy, handle parent) + { + list l(SZ); + for (size_t ii = 0; ii < src.size(); ++ii) { + object val = reinterpret_steal<object>(value_conv::cast(src[ii], policy, parent)); + if (!val) + return handle(); + PyList_SET_ITEM(l.ptr(), ii, val.release().ptr()); // steals a reference + } + return l.release(); + } // ... cast(...) + + PYBIND11_TYPE_CASTER(type, _("List[") + value_conv::name() + _("[") + _<SZ>() + _("]]")); +}; // struct FieldVector_type_caster + template <class K, int SIZE> struct type_caster<Dune::FieldVector<K, SIZE>> : public FieldVector_type_caster<Dune::FieldVector<K, SIZE>>