Question

Is it possible to use the tools only needing Iterators and a function-pointer from the module <algorithm> on PyObjects ?

The concrete problem I want to solve (it is constructed to learn from it):

  • I have a huge list of IDs stored in a python-list
  • Now I want to perform a std::binary_search on this list, using a module written in C++

One way could be to access the python-list as c-array, constructing a vector from it (which uses the pointers/ does not copy), doing the binary_search and export the array as PyObject.

Would that be possible?

Was it helpful?

Solution

Well, a binary search isn't that complicated, so why don't you simply code one based on a range of indices instead of iterators? I believe that a list conforms to the sequence protocol of Python, so that should be pretty easy.

If you really want to use the binary_search() algorithm for a learning experience, there is also the possibility to create STL-style iterators on top of the Python sequence. All you need is a pointer to the sequence and an index to create a random-access iterator. If you want to, you can also transparently convert the Python objects in the list into an according ID type (some integer type, I guess).

struct iterator
{
    // typedefs required for fully compliant STL-style iterators
    typedef PyObject* value_type;

    iterator(PyObject* seqeunce, Py_ssize_t position):
        m_sequence(sequence), m_position(position)
    {
        assert(PySequence_Check(m_sequence));
        assert(m_position >= 0);
        assert(m_position <= PySequence_GetSize(m_sequence));
    }
    value_type operator*() const
    {
        assert(m_position < PySequence_GetSize(m_sequence));
        return PySequence_GetItem(m_sequence, m_position);
    }
    iterator& operator++()
    {
        assert(m_position <= PySequence_GetSize(m_sequence));
        ++m_position;
        return *this;
    }
    iterator& operator+=(size_t l)
    {
        m_position += l;
        return *this;
    }
};

I haven't compiled this and probably forgot a few parts, but I guess you get the idea. Just init two iterators, one with an offset of zero and one with an offset of the size of the container and give those to binary_search().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top