1

So I found how to return numpy.array from boost::python?. However, like this I have to write this function for int, float, double separately. Is it possible to avoid this using templates? I would somehow need to convert with T to an entry to the enumeration of NPY data types. Or are there other options?

template<typename T>
boost::python::object getNumpyArray(std::vector<T>& vector)
{
    npy_intp shape[1] = { vector.size() };
    //Here I would need to replace NPY_DOUBLE with some conversion of T
    PyObject* obj = PyArray_SimpleNewFromData(1, shape, NPY_DOUBLE, vector.data());
    boost::python::handle<> handle(obj);
    boost::python::numeric::array arr(handle);

    return arr.copy();
}
Community
  • 1
  • 1
NOhs
  • 2,780
  • 3
  • 25
  • 59
  • related/dupe: http://stackoverflow.com/questions/16065183/convert-a-stdvector-to-a-numpy-array-without-copying-data – NathanOliver Jan 27 '16 at 15:23
  • @NathanOliver The question you link to (or at least the answer) is almost identical to the one I link to but does not provide any info on how to employ templates to avoid code copy-pasting using `PyArray_SimpleNewFromData`, which is basically my question. So I think my question is not a duplicate. – NOhs Jan 27 '16 at 15:33

1 Answers1

3

You can write your own trait which will select numpy type based on c++ type, for example:

template <typename T>
struct select_npy_type
{};

template <>
struct select_npy_type<double>
{
    const static NPY_TYPES type = NPY_DOUBLE;
};

template <>
struct select_npy_type<float>
{
    const static NPY_TYPES type = NPY_FLOAT;
};

template <>
struct select_npy_type<int>
{
    const static NPY_TYPES type = NPY_INT;
};

And then:

PyObject* obj = PyArray_SimpleNewFromData(1, shape, select_npy_type<T>::type, vector.data());
doqtor
  • 8,414
  • 2
  • 20
  • 36