[C++-sig] boost.python iterators

David Abrahams dave at boost-consulting.com
Tue Aug 16 04:35:45 CEST 2005


Dirk, you're in the wrong mailing list/newsgroup.  Try the Python C++
sig (where followups are directed).

Dirk Steenpass <steenpaz at sdf-eu.org> writes:

> Dear all,
>
> I am looking for a way to create a python savvy iterator by wrapping
> a container that provides begin and end member functions taking
> arguments.

Taking arguments, hmm.

> The reference manual entry on boost::python::range left me unsure whether
> the appended code would compile (it does not).
>
> The sentence:
>
> "The first form creates a Python callable object which, when invoked, converts
> its argument to a Target object x, and creates a Python iterator which
> traverses [bind(start,_1)(x), bind(finish,_1)(x)), applying NextPolicies to the
> iterator's next() function."
>
> suggested to me that a single argument, i.e., the target reference is passed to
> the accessor functions. 

Correct.

> This would imply that the accessor takes exactly one argument. (???)

Correct.

> However, the subsequent explanations about the deduction of Target left me with
> the impression that accessor functions and accessor member function pointers
> may take several arguments.

I understand.  I think the text is misleading.  I should delete
"arguments..."

> Any help is appreciated,

Your problem is that you're forgetting the implicit "this" argument.
In Python that corresponds to the initial explicit "self."

Probably your simplest solution would be something like:

    python::object Elements(A& a, A::SizeType n)
    {
        return 
          python::range<python::default_call_policies, A>(
              boost::bind(&A::begin, _1, n)
            , boost::bind(&A::end, _1, n)
          )(boost::ref(a));
    }

Then wrap that.  We create a new Python function object on the fly
each time and invoke it.  The bind expressions just bind n into the
accessors so that they take only a single argument.

HTH,

> dirk
>
> //--- A [n] example -----------------------------------------------------------
> // Does not compile with gcc 3.3.6 and gcc 4.0.2
>
> #include <vector>
>
> #include <boost/python.hpp>
>
> using namespace std;
> using namespace boost::python;
>
> class A
> {
> public:
>     typedef std::vector<int> VecInt;
>     typedef VecInt::iterator Iter;
>     typedef VecInt::size_type SizeType;
>
> public:
>     A(): vec_(100, 23) {}
>
>     Iter Begin(SizeType ignored) { return vec_.begin(); }
>     Iter End(SizeType ignored) { return vec_.end(); }
>
> private:
>     VecInt vec_;
> };
>
> BOOST_PYTHON_MODULE(A)
> {
>     class_<A>("A")
>         .def("Elements", range(&A::Begin, &A::End))
>         ;
> }
>
> // Just allowing standalone compilation.
> int main(void)
> {
>     return 0;
> }

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com




More information about the Cplusplus-sig mailing list