From ad1cadf3512f3dd789151983e5c93af411f929db Mon Sep 17 00:00:00 2001 From: Tuowen Zhao Date: Sat, 17 Sep 2016 19:27:15 +0000 Subject: restructure --- omegalib/omega_lib/include/basic/Iterator.h | 131 ++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 omegalib/omega_lib/include/basic/Iterator.h (limited to 'omegalib/omega_lib/include/basic/Iterator.h') diff --git a/omegalib/omega_lib/include/basic/Iterator.h b/omegalib/omega_lib/include/basic/Iterator.h new file mode 100644 index 0000000..8975d9e --- /dev/null +++ b/omegalib/omega_lib/include/basic/Iterator.h @@ -0,0 +1,131 @@ +/* + * 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) + +/* + * 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, +// which 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: + Any_Iterator(Iterator *p) // take over *p, *p MUST BE ON THE HEAP + { me = p; } + friend class Collection; +#if 0 + // Couldn't make this work with g++258 + friend Any_Iterator Collection::any_iterator(); +#endif + 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 -- cgit v1.2.3-70-g09d2