[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