[C++-sig] doing iterators another way...

Leonard "paniq" Ritter paniq at paniq.org
Tue Apr 5 05:39:09 CEST 2005


the example that is given in the tutorial for iterators is giving a 
standard way of solving the problem for c++ iterators, but i'm also 
using enumerators which provide a set of current/next/reset commands. 
for those interested, this is how i turned my class into an iterator:

        template<typename T>
        struct Enumerator : Mu::Interface::Unknown
        {           
            typedef typename Ptrfy<T>::Type ElementReturnType;

            virtual Mu::Result Mu_InterfaceCall MoveNext(Bool& 
succeeded) = 0;
            virtual Mu::Result Mu_InterfaceCall Current(T& current) = 0;
            virtual Mu::Result Mu_InterfaceCall Reset() = 0;

            Mu_WrapGetMethod(MoveNext,Bool);
            Mu_WrapGetMethod(Current,ElementReturnType);
        };

        template<typename T>
        typename T::ElementReturnType iterator_next(T* enumerator)
        {
            if (!enumerator->MoveNext())
            {
                PyErr_SetString(PyExc_StopIteration,"");
                boost::python::throw_error_already_set();
            }
            return enumerator->Current();
        }

        template<typename T>
        T* MakePythonIteratorFromEnumerator(T* enumerator)
        {           
            enumerator->Reset();
            return enumerator;
        }

    and here's some pseudo-boost.python code:

    class_<EnumeratorClass, bases<Mu::Interface::Unknown> 
 >("EnumeratorClass")
        .def("__iter__", 
&MakePythonIteratorFromEnumerator<EnumeratorClass>, 
return_internal_reference<>())
        .def("next", &iterator_next<EnumeratorClass>)
   ;




More information about the Cplusplus-sig mailing list