Commit 3b2f9768 authored by Jan Möbius's avatar Jan Möbius

Mapping for IdList to python

parent d59dbe68
......@@ -21,5 +21,8 @@
The Vector type used in the C++ code is mapped from python. Details can be found here:
\subpage python_scripting_vector_type
\subsection python_scripting_idlisttype IDList data type
The IdList type used in the C++ code is mapped from python. Details can be found here:
\subpage python_scripting_IDList_type
*/
......@@ -358,3 +358,112 @@ namespace pybind11 { namespace detail {
}
};
}} // namespace pybind11::detail
/** \page python_scripting_IDList_type IDList data type used for python scripting
*
* The list type IdList is mapped to python.
*
* The integrated conversion can map the C++ IdList type to and from a tuple, a list or a numpy array.
* The preferred choice is the numpy array.
*
* Creating a list in python is the done like in the following example:
* \code
* import numpy as np
*
* list = np.array( [3,16,18])
* \endcode
*
* The conversion from C++ to python will always create a numpy array on the python side.
*/
namespace pybind11 { namespace detail {
template <> struct type_caster<IdList> {
public:
/**
* This macro establishes the name 'IdList' in
* function signatures and declares a local variable
* 'value' of type IdList
*/
PYBIND11_TYPE_CASTER(IdList, _("IdList"));
/**
* Conversion part 1 (Python->C++): convert a PyObject into a IdList
* instance or return false upon failure. The second argument
* indicates whether implicit conversions should be applied.
*/
bool load(handle src, bool convert ) {
/* Extract PyObject from handle */
PyObject* source = src.ptr();
if ( PyList_Check(source) ) {
const auto size = PyList_Size(source);
value.resize(size);
for ( auto i = 0 ; i < size ; ++i ) {
value[i] = static_cast<int>(PyLong_AsLong(PyList_GET_ITEM(source,i)));
}
} else if ( PyTuple_Check(source) ) {
const auto size = PyTuple_Size(source);
value.resize(size);
for ( auto i = 0 ; i < size ; ++i ) {
value[i] = static_cast<int>(PyLong_AsLong(PyTuple_GET_ITEM(source,i)));
}
} else if ( py::cast<py::array>(source) ) {
py::array array = py::cast<py::array>(source);
if ( array.ndim() != 1) {
PyErr_SetString(PyExc_RuntimeError, "IdList Conversion: Numpy Array dimension should be one!");
throw py::error_already_set();
return false;
}
auto buf = py::array_t<int, py::array::c_style | py::array::forcecast>::ensure(src);
if (!buf) {
PyErr_SetString(PyExc_RuntimeError, "IdList Conversion: Numpy Array, conversion failed.");
return false;
}
std::cerr << "Buffer size : " << buf.size() << std::endl;
value.resize(buf.size());
for ( auto i = 0 ; i < buf.size() ; ++i ) {
value[i] = *buf.data(i) ;
}
return true;
} else {
PyErr_SetString(PyExc_RuntimeError, "Vector Conversion: Not a list or a tuple or a numpy array.");
throw py::error_already_set();
return false;
}
/* Ensure return code was OK (to avoid out-of-range errors etc) */
return ( !PyErr_Occurred() );
}
/**
* Conversion part 2 (C++ -> Python): convert an IdList instance into
* a Python object. The second and third arguments are used to
* indicate the return value policy and parent object (for
* ``return_value_policy::reference_internal``) and are generally
* ignored by implicit casters.
*/
static handle cast(IdList src, return_value_policy /* policy */, handle parent ) {
// Create numpy array
py::array a(1, src.data());
return a.release();
}
};
}} // namespace pybind11::detail
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment