0

I am trying to have an array using boost python

#include <boost/python.hpp>
#include <memory>
#include <vector>

class MyObject
{
public:
    MyObject(int value)
        : value_(value)
    {
    }

    int value() const { return value_; }
    void set_value(int value) { value_ = value; }

private:
    int value_;
};

class MyArray
{
public:
    MyArray(int size)
        : array_(size)
    {
        for (auto& obj : array_)
        {
            obj = std::make_shared<MyObject>(0);
        }
    }

    std::shared_ptr<MyObject>& operator[](int index) { return array_[index]; }
    int size() const { return static_cast<int>(array_.size()); }

private:
    std::vector<std::shared_ptr<MyObject>> array_;
};

BOOST_PYTHON_MODULE(example)
{
    namespace python = boost::python;

    python::class_<MyObject, std::shared_ptr<MyObject>>("MyObject", python::init<int>())
        .add_property("value", &MyObject::value, &MyObject::set_value);

    python::class_<MyArray, std::shared_ptr<MyArray>>("MyArray", python::init<int>())
        .def("__getitem__", &MyArray::operator[], boost::python::return_value_policy<boost::python::copy_non_const_reference>())
        .def("__len__", &MyArray::size);
}

It works reasonably well in Python: the len function works, and the accessor [] works as well but the for loop does not stop at the right iterator and I get a C++ run time error, trying to access myArray[3], the fourth (inexistant) item

my_array = analyse_script.MyArray(3)

my_array[0].value = 1
my_array[1].value = 2
my_array[2].value = 3

print(len(my_array))  # prints "3"

for obj in my_array:
  print(obj.value)  # prints "1", "2", "3"

What should I change to make it work? Thanks in advance!

1 Answer 1

0

In the end rather than working with an unnecessary class MyArray, I was advised by a colleague to use vector_indexing_suite

So my code looks like this and works

    boost::python::class_<std::vector<std::shared_ptr<MyObject>>>("MyArray")
        .def(boost::python::vector_indexing_suite<std::vector<std::shared_ptr<MyObject>>>())
        .def("__iter__", boost::python::iterator<std::vector<std::shared_ptr<MyObject>>>())
        ;

I am still interested to understand why my first attempt did not work but this is less urgent!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.