diff --git a/libsrc/core/python_ngcore.hpp b/libsrc/core/python_ngcore.hpp index 44ba8033..b26b8481 100644 --- a/libsrc/core/python_ngcore.hpp +++ b/libsrc/core/python_ngcore.hpp @@ -14,6 +14,56 @@ #include "profiler.hpp" namespace py = pybind11; +//////////////////////////////////////////////////////////////////////////////// +// automatic conversion of python list to Array<> +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) + +template struct ngcore_list_caster { + using value_conv = make_caster; + + bool load(handle src, bool convert) { + if (!isinstance(src) || isinstance(src)) + return false; + auto s = reinterpret_borrow(src); + value.SetSize(s.size()); + value.SetSize0(); + for (auto it : s) { + value_conv conv; + if (!conv.load(it, convert)) + return false; + value.Append(cast_op(std::move(conv))); + } + return true; + } + +public: + template + static handle cast(T &&src, return_value_policy policy, handle parent) { + if (!std::is_lvalue_reference::value) + policy = return_value_policy_override::policy(policy); + list l(src.Size()); + size_t index = 0; + for (auto &&value : src) { + auto value_ = reinterpret_steal(value_conv::cast(forward_like(value), policy, parent)); + if (!value_) + return handle(); + PyList_SET_ITEM(l.ptr(), (ssize_t) index++, value_.release().ptr()); // steals a reference + } + return l.release(); + } + + PYBIND11_TYPE_CASTER(Type, _("Array[") + value_conv::name + _("]")); +}; + +template struct type_caster> + : ngcore_list_caster, Type> { }; + + +NAMESPACE_END(detail) +NAMESPACE_END(PYBIND11_NAMESPACE) +//////////////////////////////////////////////////////////////////////////////// + namespace ngcore { NGCORE_API extern bool ngcore_have_numpy;