/* * Base classes for iterators, generators * * These don't really work yet for constant collections. * I'm not sure how to make that happen. */ #if ! defined _Iterator_h #define _Iterator_h 1 #include namespace omega { #define foreach(x,T,S,A) do {for (omega::Any_Iterator __P_##x = (S).any_iterator();__P_##x;__P_##x++) {T & x = *__P_##x; A;}} while (0) #define foreachSeparated(x,T,S,A,B) do {for (omega::Any_Iterator __P_##x = (S).any_iterator();__P_##x;) {T & x = *__P_##x; A; __P_##x++; if (__P_##x) B;}} while (0) /*! * \brief Abstract base class Iterator * * Supports two styles of iteration: * ~~~ * for ( ... initialize i (typically i = collection) ... ; i ; i++ ) * operate_on(*i) * ~~~ * or * ~~~ * for ( ... initialize i ... ; i.live() ; i.next() ) * operate_on(i.curr()) * ~~~ * **IF THE COLLECTION IS CHANGED, THE ITERATOR IS NO LONGER VALID** * * For collections that are not "Sequence"s, the order in * which the elements are returned may not be consistent. */ template class Iterator { public: virtual const T & operator*() const = 0; virtual T & operator*() = 0; virtual void operator++(int) = 0; virtual void operator++() = 0; virtual bool live() const = 0; operator bool() const { return live(); } const T & curr() const { return *(*this); } T & curr() { return *(*this); } void next() { (*this)++; } virtual Iterator *new_copy() const = 0; virtual ~Iterator() {} }; //! A generator is like an iterator but it gives out values /*! Values may or may not exist in some writable collection */ template class Generator { public: virtual T operator*() const = 0; virtual void operator++(int) = 0; virtual void operator++() = 0; virtual int live() const = 0; operator int() const { return live(); } const T curr() const { return *(*this); } T curr() { return *(*this); } void next() { (*this)++; } }; //! Delegate to any kind of iterator (on the heap) /*! * * If created via a reference, become a copy of the iterator * * If created via a pointer, manipulate that pointer and free *p when this dies * * Mostly useful for Collection::iterator `Iterator::Iterator(Collection)` */ template class Any_Iterator : public Iterator { public: Any_Iterator(Collection &c); Any_Iterator(const Iterator &i); // copy of i virtual ~Any_Iterator() { delete me; } Any_Iterator &operator=(const Any_Iterator &rhs) { delete me; me = rhs.me->new_copy(); return *this; } const T & operator*() const { return *(*me); } T & operator*() { return *(*me); } void operator++(int) { (*me)++; } void operator++() { ++(*me); } bool live() const { return (*me).live(); } Iterator *new_copy() const { return new Any_Iterator((*me).new_copy()); } private: //! take over *p, *p MUST BE ON THE HEAP Any_Iterator(Iterator *p) { me = p; } friend class Collection; /* * // Couldn't make this work with g++258 * friend Any_Iterator Collection::any_iterator(); */ Iterator *me; }; template inline Any_Iterator::Any_Iterator(Collection &c) { me = c.new_iterator(); } template inline Any_Iterator::Any_Iterator(const Iterator &i) { me = i.new_copy(); } } // namespace #define instantiate_Iterator(T) template class Iterator; #define instantiate_Generator(T) template class Generator; #define instantiate_Any_Iterator(T) template class Any_Iterator; \ instantiate_Iterator(T) #endif