1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
/*
* 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 <basic/Collection.h>
namespace omega {
#define foreach(x,T,S,A) do {for (omega::Any_Iterator<T> __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<T> __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<type>
*
* 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 T> 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<T> *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 T> 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 T> class Any_Iterator : public Iterator<T> {
public:
Any_Iterator(Collection<T> &c);
Any_Iterator(const Iterator<T> &i); // copy of i
virtual ~Any_Iterator() { delete me; }
Any_Iterator<T> &operator=(const Any_Iterator<T> &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<T> *new_copy() const { return new Any_Iterator<T>((*me).new_copy()); }
private:
//! take over *p, *p MUST BE ON THE HEAP
Any_Iterator(Iterator<T> *p) { me = p; }
friend class Collection<T>;
/*
* // Couldn't make this work with g++258
* friend Any_Iterator<T> Collection<T>::any_iterator();
*/
Iterator<T> *me;
};
template <class T> inline Any_Iterator<T>::Any_Iterator(Collection<T> &c)
{
me = c.new_iterator();
}
template <class T> inline Any_Iterator<T>::Any_Iterator(const Iterator<T> &i)
{
me = i.new_copy();
}
} // namespace
#define instantiate_Iterator(T) template class Iterator<T>;
#define instantiate_Generator(T) template class Generator<T>;
#define instantiate_Any_Iterator(T) template class Any_Iterator<T>; \
instantiate_Iterator(T)
#endif
|