Boost Python Tuple Iterator

Я пытаюсь экспортировать итератор над кортежами из C++ в Python, используя следующий код:

class PyContainer
{
public:
    PyContainer(int maxSize) : maxSize(maxSize) { cout << "Constructor called with maxSize = " << maxSize << endl; }

    boost::python::tuple AllocateTuple(int idx)
    {
        cout << "Allocating pyRecord " << idx << endl;
        return boost::python::make_tuple(idx);
    }

    class iterator : public std::iterator<std::input_iterator_tag, boost::python::tuple>
    {
    public:
        iterator(const iterator& rhs) : idx(rhs.idx), currTuple(rhs.currTuple), self(rhs.self) { cout << "copy iterator(rhs.idx=" << rhs.idx << ", currTuple=" << currTuple.ptr()<< ")" << endl; }
        iterator(PyContainer *self, int idx) : idx(idx), currTuple(), self(self) { cout << "iterator(idx=" << idx << ")" << endl; }
        ~iterator() { cout << "~iterator " << currTuple.ptr()<< endl; }

        boost::python::tuple& operator*() 
        { 
            cout << "operator* " << currTuple.ptr()<< endl;
            return currTuple;
        }

        // Pre-increment
        iterator& operator++() 
        { 
            cout << "preinc " << currTuple.ptr()<< endl;
            ++idx;
            return *this; 
        }

        // Post-increment.     
        iterator operator++(int)
        {
            currTuple = self->AllocateTuple(idx);

            cout << "postinc " << currTuple.ptr()<< endl;
            iterator tmp(*this);
            operator++();
            return tmp;
        }

        // Comparison.
        bool operator==(const iterator& rhs) { return this->idx == rhs.idx; }
        bool operator!=(const iterator& rhs) { return !this->operator==(rhs); }

    private:
        int idx;
        boost::python::tuple currTuple;
        PyContainer* self;
    };
    iterator begin() { return iterator(this, 0); }
    iterator end() { return iterator(this, maxSize); }
private:
    int maxSize;
};

BOOST_PYTHON_MODULE(hello_ext)
{
    using namespace boost::python;
    class_<PyContainer, boost::noncopyable>("PyContainer", init<int>())
        .def("__iter__", boost::python::iterator<PyContainer, return_internal_reference<>>())
        ;
}

В Python я использую итератор, как это:

import hello_ext as a
r = a.PyContainer(2)
for i in r:
    print i

Вывод из C++ выглядит следующим образом:

Конструктор называется 
итератора (IDX =2) 
копировать итератор (rhs.idx=2, currentRecord=005D1030) 
итератор 005D1030
итератора (IDX = 0)
копировать итератор (rhs.idx=0, currentRecord=005D1030)
итератор 005D1030
копировать итератор (rhs.idx=0, currentRecord=005D1030)
копировать итератор (rhs.idx=2, currentRecord=005D1030)
итератор 005D1030
итератор 005D1030
копировать итератор (rhs.idx=0, currentRecord=005D1030)
копировать итератор (rhs.idx=2, currentRecord=005D1030)
итератор 005D1030
итератор 005D1030
0==2
Выделение pyRecord 0
Postinc 008F7970
копировать итератор (rhs.idx=0, currentRecord=008F7970)
preinc ​​008F7970
копировать итератор (rhs.idx = 0, currentRecord = 008F7970)
итератор 008F7970
оператор * 008F7970
итератор 008F7970

И, наконец, получена ошибка: Ошибка подтверждения

Нужно ли управлять временем жизни объекта из Python?

0 ответов

Другие вопросы по тегам