[C++-sig] Retrieving lvalues using custom converters (numpy 1-D converters attached)
Ravi
lists_ravi at lavabit.com
Fri Oct 3 23:08:28 CEST 2008
On Thursday 02 October 2008 20:03:58 Neal Becker wrote:
> Sorry, I'm still confused. Suppose I have this:
>
> ublas::vector<double> create (int size, double init) {
> return ublas::vector<double> (size, init);
> }
>
> With default return value policy, this fails. We used:
> register_vector_to_python_converters< false, contiguous_vector_to_py,
> default_ublas_array_traits>();
>
> Which does _not_ copy the data and uses PyArray_SimpleNewFromData. The
> data is immediately destroyed and the array returned to python is garbage.
Ok, here is an extremely hackish solution for the return_by_value return value
policy. This solution is not guaranteed to work if call policies chaining is
used. At the end of numpy.h, please append the following code:
------- start here --------
namespace boost { namespace python { namespace detail {
template <typename T, typename A>
struct registry_to_python_value< boost::numeric::ublas::vector<T, A> const &>
{
typedef typename boost::numeric::ublas::vector<T, A> vector_t;
typedef typename value_arg< vector_t const&>::type argument_type;
PyObject* operator()(argument_type in) const
{
// Do we need the extra incref in contiguous_vector_to_py or should we go
directly
// to the implementation in pyarray_from_vector_impl to avoid the incref?
return numpy::contiguous_vector_to_py<true, vector_t>::convert( in );
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
PyTypeObject const* get_pytype() const {
return converter::registered<vector_t
const&>::converters.to_python_target_type();
}
#endif
BOOST_STATIC_CONSTANT(bool, uses_registry = false);
};
}}} // namespace boost::python::detail
------- ends here ---------
You will also need to include boost/python/to_python_value.hpp. If you can
think of a better solution, I would be grateful. I am aware that a copy is
made here, but I could not think of a solution that avoids copies.
If Dave Abrahams is reading this: Am I hijacking the conversion mechanism at
the right point or is there a better point, such as make_instance? I could not
get make_instance to work with custom converters.
Regards,
Ravi
More information about the Cplusplus-sig
mailing list