[C++-sig] howto convert a python list to a C++ matrix
Ralf W. Grosse-Kunstleve
rwgk at yahoo.com
Thu Oct 10 01:09:17 CEST 2002
--- Stefan Seefeld <stefan.seefeld at orthosoft.ca> wrote:
> But how am I to extract the elements of the list(s) in
> boost.python style ? And how should I raise a TypeError
> if I don't find what I'm looking for ?
This is how I raise Python exceptions:
void raise_index_error()
{
PyErr_SetString(PyExc_IndexError, "Index out of range.");
boost::python::throw_error_already_set();
}
BUT, you can do a lot better: you can tell Boost.Python how to convert
lists of lists automatically to your matrix type. Then you can simply
.def functions taking a matrix argument instead of providing wrappers
that do the conversion and then dispatch to the C++ library function.
For example:
void foo(matrix const& m);
def("foo", foo);
Versus with the factory approach:
void foo(matrix const& m);
void foo_wrapper(python::list &l)
{
matrix m = matrix_factory(l);
foo(m);
}
def("foo", foo_wrapper);
You will have to write a wrapper for each function that uses matrix.
Attached is a stripped down version of
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cctbx/scitbx/include/scitbx/boost_python/container_conversions.h?rev=1.5&content-type=text/vnd.viewcvs-markup
If you move and customize the code from your factory function to
the code shown below you will have a general solution that avoids
the thin-wrapper clutter.
> But 'length()' doesn't appear to exist,
David preferred to deny my repeated requests to resurrect list::size()
and tuple::size() (was there in V1). Maybe if someone helps me begging
we can change his mind for the better. Here is how it works right now:
#include <boost/python/detail/api_placeholder.hpp>
l = boost::python::len(your_list);
Ralf
struct matrix_to_list_of_lists // to_tuple in the original file
{
static PyObject* convert(matrix const& a)
{
using namespace boost::python;
list result;
// your code here to generate the list of lists
return incref(result.ptr());
}
};
// This is a "custom lvalue converter". See also: Boost.Python FAQ
struct matrix_from_list_of_lists // from_python in the original file
{
matrix_from_list_of_lists()
{
boost::python::converter::registry::push_back(
&convertible,
&construct,
boost::python::type_id<matrix>());
}
static void* convertible(PyObject* obj_ptr)
{
using namespace boost::python;
// your "factory" code here
// return 0; // if the input object is not convertible
return obj_ptr; // if the input object is convertible
}
static void construct(
PyObject* obj_ptr,
boost::python::converter::rvalue_from_python_stage1_data* data)
{
using namespace boost::python;
void* storage = (
(rvalue_from_python_storage<matrix>*)
data)->storage.bytes;
new (storage) matrix();
data->convertible = storage;
matrix& result = *((matrix*)storage);
// now set the elements of the matrix using *obj_ptr
// again similar to your "factory" code
// for error detection use
// if (PyErr_Occurred()) throw_error_already_set();
}
};
Usage:
boost::python::to_python_converter<matrix, matrix_to_list_of_lists>();
matrix_from_list_of_lists();
__________________________________________________
Do you Yahoo!?
Faith Hill - Exclusive Performances, Videos & More
http://faith.yahoo.com
More information about the Cplusplus-sig
mailing list