[C++-sig] Re: Adding __len__ to range objects

David Abrahams dave at boost-consulting.com
Mon Aug 11 00:27:54 CEST 2003


Raoul Gough <RaoulGough at yahoo.co.uk> writes:

> I recently wanted to know how many items were in a C++ vector, which I
> had only exposed to Python via iterator pairs (boost::python::range).
> Currently, len(range_object) doesn't work because range doesn't
> provide a __len__ method, but it isn't hard to add this. I did the
> following in d:/CVS/boost/boost/boost/python/object/iterator.hpp:
>
> in template <...> struct iterator_range, add
>
>   typename std::iterator_traits<Iterator>::difference_type
>   distance () const {
>     return std::distance (m_start, m_finish);
>   }
>
> in template <...> object demand_iterator_class (...)
>
>       return class_<range_>(name, no_init)
>           .def("__iter__", identity_function())
>           .setattr("next", next_function)
> 	  .def("__len__", &range_::distance)
>           ;
>
> and everything worked OK. This seems to me like a useful addition -
> any comments? If it seems sensible, maybe David Abrahams could add
> something similar to the CVS?

It only works for random-access iterators.  You could fix it so that
it would only create the __len__ function for random-access
iterators; that would be better.

Then, also, range() creates an iterator-returning function, not an
iteratable-returning function.  There are subtle differences.

    for x in some_list:
       print x

    for x in some_list:
       print x  # prints the same elements

but:

    for x in some_iterator:
       print x

    for x in some_iterator:
       print x  # prints nothing

None of the Python iterators support __len__ and I wonder if it's a
good idea to add it to an iterator we create.  Your thoughts?

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





More information about the Cplusplus-sig mailing list