| Store | Cart

[C++-sig] [Boost::Python] vector_indexing_suite fails to recognize type as registered

From: Eugenio Bargiacchi <sval...@gmail.com>
Sun, 12 Feb 2017 03:33:45 +0100
In the below C++ code, even though the type std::tuple<int> is registered,
boost::python fails to find that out when the tuple is within an
std::vector exposed through the vector_indexing suite. At the same time, it
is possible to reference and use the type normally as long as it's not in
the vector.

For example, this happens:

>>> print makeMyTuple()
(0,)
>>> print makeTuples()[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: No Python class registered for C++ class std::tuple<int>
>>>

Is there any way to make this work?

Best,
Eugenio

MVE:

#include <tuple>
#include <vector>

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

template <typename T>
struct TupleToPython {
    TupleToPython() {
        boost::python::to_python_converter<T, TupleToPython<T>>();
    }

    template<int...>
    struct sequence {};

    template<int N, int... S>
    struct generator : generator<N-1, N-1, S...> { };

    template<int... S>
    struct generator<0, S...> {
        using type = sequence<S...>;
    };

    template <int... I>
    static boost::python::tuple boostConvertImpl(const T& t,
sequence<I...>) {
        return boost::python::make_tuple(std::get<I>(t)...);
    }

    template <typename... Args>
    static boost::python::tuple boostConvert(const std::tuple<Args...> & t)
{
        return boostConvertImpl(t, typename
generator<sizeof...(Args)>::type());
    }

    static PyObject* convert(const T& t) {
        return boost::python::incref(boostConvert(t).ptr());
    }
};

using MyTuple = std::tuple<int>;
using Tuples = std::vector<MyTuple>;

MyTuple makeMyTuple() {
    return MyTuple();
}

Tuples makeTuples() {
    return Tuples{MyTuple()};
}

BOOST_PYTHON_MODULE(h)
{
    using namespace boost::python;

    TupleToPython<MyTuple>();
    def("makeMyTuple", makeMyTuple);

    class_<std::vector<MyTuple>>{"Tuples"}
        .def(vector_indexing_suite<std::vector<MyTuple>>());
    def("makeTuples", makeTuples);
}

_______________________________________________
Cplusplus-sig mailing list
Cplu...@python.org
https://mail.python.org/mailman/listinfo/cplusplus-sig
Recent Messages in this Thread
Eugenio Bargiacchi Feb 12, 2017 02:33 am