[C++-sig] doing iterators another way...
Leonard "paniq" Ritter
paniq at paniq.org
Tue Apr 5 10:16:28 CEST 2005
the approach below has the flaw that recursive iterations will fail
since the enumerator is not cloned. for that purpose i added a Clone()
method to the enumerator interface which is called in
MakePythonIteratorFromEnumerator, where a Ptr<T> (a custom smart pointer
class) is returned, hence suspending the need for a return value call
policy.
Leonard "paniq" Ritter wrote:
> 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>)
> ;
>
> _______________________________________________
> C++-sig mailing list
> C++-sig at python.org
> http://mail.python.org/mailman/listinfo/c++-sig
>
>
More information about the Cplusplus-sig
mailing list