Edinburgh Speech Tools  2.4-release
EST_TIterator.h
1  /************************************************************************/
2  /* */
3  /* Centre for Speech Technology Research */
4  /* University of Edinburgh, UK */
5  /* Copyright (c) 1996,1997 */
6  /* All Rights Reserved. */
7  /* */
8  /* Permission is hereby granted, free of charge, to use and distribute */
9  /* this software and its documentation without restriction, including */
10  /* without limitation the rights to use, copy, modify, merge, publish, */
11  /* distribute, sublicense, and/or sell copies of this work, and to */
12  /* permit persons to whom this work is furnished to do so, subject to */
13  /* the following conditions: */
14  /* 1. The code must retain the above copyright notice, this list of */
15  /* conditions and the following disclaimer. */
16  /* 2. Any modifications must be clearly marked as such. */
17  /* 3. Original authors' names are not deleted. */
18  /* 4. The authors' names are not used to endorse or promote products */
19  /* derived from this software without specific prior written */
20  /* permission. */
21  /* */
22  /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23  /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24  /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25  /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26  /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27  /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28  /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29  /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30  /* THIS SOFTWARE. */
31  /* */
32  /************************************************************************/
33 
34 #ifndef __EST_TITERATOR_H__
35 #define __EST_TITERATOR_H__
36 
37 /** Template class defining interface to an iterator, i.e an object
38  * which returns elements from a structure one at a time.
39  *
40  * This is template is usually hidden in the declaration of the
41  * container classes with a typedef for Entries providing a more
42  * convenient name for the iterator. However the interface is that
43  * defined here.
44  *
45  * We support two interfaces, a pointer like interface similar to
46  * specialised iteration code elsewhere in the speech tools library
47  * and to the iterators in the C++ standard template library and an
48  * interface similar to that of Enumerations in Java.
49  *
50  * <programlisting arch='c++'>
51  * MyContainer::Entries them;
52  *
53  * for(them.begin(container); them; them++)
54  * {
55  * MyContainer::Entry &it = *them;
56  * // Do Something With it
57  * }</programlisting>
58  *
59  * <programlisting arch='c++'>
60  * MyContainer::Entries them;
61  *
62  * them.begin(container);
63  * while (them.has_more_entries())
64  * {
65  * MyContainer::Entry &it = them.next_entry();
66  * // Do Something With it
67  * }</programlisting>
68  *
69  * @author Richard Caley <rjc@cstr.ed.ac.uk>
70  * @version $Id: EST_TIterator.h,v 1.7 2013/04/13 14:17:11 awb Exp $
71  */
72 
73 template <class Container, class IPointer, class Entry>
74  class EST_TStructIterator;
75 template <class Container, class IPointer, class Entry>
76  class EST_TRwIterator;
77 template <class Container, class IPointer, class Entry>
79 
80 template <class Container, class IPointer, class Entry>
82 {
83 protected:
84  /// The container we are looking at.
85  Container *cont;
86 
87  /// Position in the structure. May or may not be useful.
88  unsigned int pos;
89 
90  /** Structure defined by the container class which contains the
91  * current state of the iteration.
92  */
93  IPointer pointer;
94 
95 public:
96  /// Name for an iterator like this
98 
99  /// Create an iterator not associated with any specific container.
100  EST_TIterator() {cont=NULL;}
101 
102  /// Create an iterator ready to run over the given container.
103  EST_TIterator(const Container &over)
104  { begin(over); }
105 
106  /// Copy an iterator by assignment
107  Iter &operator = (const Iter &orig)
108  { cont=orig.cont; pos=orig.pos; pointer=orig.pointer; return *this;}
109 
110  /// Assigning a container to an iterator sets it ready to start.
111  Iter &operator = (const Container &over)
112  { begin(over); return *this;}
113 
114  /// Set the iterator ready to run over this container.
115  void begin(const Container &over)
116  {cont=((Container *)(void *)&over); beginning();}
117 
118  /// Reset to the start of the container.
119  void beginning()
120  {if (cont) cont->point_to_first(pointer); pos=0;}
121 
122  /**@name End Tests
123  */
124  //@{
125  /// True if there are more elements to look at.
126  bool has_more_elements() const
127  {return cont && cont->points_to_something(pointer);}
128 
129  /// True when there are no more.
130  bool at_end() const
131  {return !has_more_elements();}
132 
133  /** Viewing the iterator as an integer (for instance in a test)
134  * sees a non-zero value iff there are elements still to look at.
135  */
136  operator int() const
137  {return has_more_elements();}
138  //@}
139 
140  /**@name Moving Forward
141  */
142  //@{
143  /// Next moves to the next entry.
144  void next()
145  {cont->move_pointer_forwards(pointer); pos++;}
146 
147  /// The increment operator does the same as next.
149  {next(); return *this;}
150  Iter operator ++(int dummy)
151  {
152  (void)dummy;
153  Iter old =*this;
154  next();
155  return old;
156  }
157  //@}
158 
159  /**@name Access
160  */
161  //@{
162  /// Return the element currently pointed to.
163  const Entry& current() const
164  {return cont->points_at(pointer);}
165 
166  /// The * operator returns the current element.
167  const Entry &operator *() const
168  {return current();}
169 
170 #if 0
171  // This only works for some Entry types.
172  const Entry *operator ->() const
173  {return &current();}
174 #endif
175 
176  /// Return the current element and move the pointer forwards.
177  const Entry& next_element()
178  {
179  const Entry &it = cont->points_at(pointer);
180  cont->move_pointer_forwards(pointer);
181  return it;
182  }
183 
184  /// Return the current position
185 
186  unsigned int n() const { return pos; }
187  //@}
188 
189  friend class EST_TStructIterator <Container, IPointer, Entry>;
190  friend class EST_TRwIterator <Container, IPointer, Entry>;
191  friend class EST_TRwStructIterator <Container, IPointer, Entry>;
192 
193 };
194 
195 template <class Container, class IPointer, class Entry>
197  : public EST_TIterator<Container, IPointer, Entry>
198 {
199 public:
200 
202 
203  /// Create an iterator not associated with any specific container.
204  EST_TStructIterator() {this->cont=NULL;}
205 
206  /// Copy an iterator by assignment
207  Iter &operator = (const Iter &orig)
208  { this->cont=orig.cont; this->pos=orig.pos; this->pointer=orig.pointer; return *this;}
209 
210  /// Create an iterator ready to run over the given container.
211  EST_TStructIterator(const Container &over)
212  { this->begin(over); }
213 
214  const Entry *operator ->() const
215  {return &this->current();}
216 };
217 
218 template <class Container, class IPointer, class Entry>
220  : public EST_TIterator<Container, IPointer, Entry>
221 {
222 private:
223  /// Can't access constant containers this way.
224  // EST_TRwIterator(const Container &over) { (void) over; }
225 
226  /// Can't access constant containers this way.
227  // void begin(const Container &over) { (void) over; }
228 
229 public:
230 
232 
233  /// Create an iterator not associated with any specific container.
234  EST_TRwIterator() {this->cont=NULL;}
235 
236  /// Copy an iterator by assignment
237  Iter &operator = (const Iter &orig)
238  { this->cont=orig.cont; this->pos=orig.pos; this->pointer=orig.pointer; return *this;}
239 
240  /// Create an iterator ready to run over the given container.
241  EST_TRwIterator(Container &over)
242  { begin(over); }
243 
244  /// Set the iterator ready to run over this container.
245  void begin(Container &over)
246  {this->cont=&over; this->beginning();}
247 
248  /**@name Access
249  */
250  //@{
251  /// Return the element currently pointed to.
252  Entry& current() const
253  {return this->cont->points_at(this->pointer);}
254 
255  /// The * operator returns the current element.
256  Entry &operator *() const
257  {return current();}
258 
259 #if 0
260  Entry *operator ->() const
261  {return &current();}
262 #endif
263 
264  /// Return the current element and move the pointer forwards.
265  Entry& next_element()
266  {
267  Entry &it = this->cont->points_at(this->pointer);
268  this->cont->move_pointer_forwards(this->pointer);
269  return it;
270  }
271 
272  //@}
273 };
274 
275 template <class Container, class IPointer, class Entry>
277  : public EST_TRwIterator<Container, IPointer, Entry>
278 {
279 public:
280 
282 
283  /// Create an iterator not associated with any specific container.
284  EST_TRwStructIterator() {this->cont=NULL;}
285 
286  /// Copy an iterator by assignment
287  Iter &operator = (const Iter &orig)
288  { this->cont=orig.cont; this->pos=orig.pos; this->pointer=orig.pointer; return *this;}
289 
290  /// Create an iterator ready to run over the given container.
291  EST_TRwStructIterator(Container &over)
292  { this->begin(over); }
293 
294  Entry *operator ->() const
295  {return &this->current();}
296 };
297 
298 #endif
EST_TIterator< Container, IPointer, Entry > Iter
Name for an iterator like this.
Definition: EST_TIterator.h:97
Iter & operator++()
The increment operator does the same as next.
unsigned int n() const
Return the current position.
const Entry & current() const
Return the element currently pointed to.
void begin(const Container &over)
Set the iterator ready to run over this container.
bool has_more_elements() const
True if there are more elements to look at.
bool at_end() const
True when there are no more.
EST_TIterator(const Container &over)
Create an iterator ready to run over the given container.
Iter & operator=(const Iter &orig)
Copy an iterator by assignment.
IPointer pointer
Definition: EST_TIterator.h:93
EST_TIterator()
Create an iterator not associated with any specific container.
const Entry & operator*() const
The * operator returns the current element.
void next()
Next moves to the next entry.
Container * cont
The container we are looking at.
Definition: EST_TIterator.h:85
const Entry & next_element()
Return the current element and move the pointer forwards.
void beginning()
Reset to the start of the container.
unsigned int pos
Position in the structure. May or may not be useful.
Definition: EST_TIterator.h:88
EST_TRwIterator< Container, IPointer, Entry > Iter
Can't access constant containers this way.
Entry & next_element()
Return the current element and move the pointer forwards.
EST_TRwIterator(Container &over)
Create an iterator ready to run over the given container.
EST_TRwIterator()
Create an iterator not associated with any specific container.
Iter & operator=(const Iter &orig)
Copy an iterator by assignment.
void begin(Container &over)
Set the iterator ready to run over this container.
Entry & operator*() const
The * operator returns the current element.
Entry & current() const
Return the element currently pointed to.
EST_TRwStructIterator()
Create an iterator not associated with any specific container.
EST_TRwStructIterator(Container &over)
Create an iterator ready to run over the given container.
Iter & operator=(const Iter &orig)
Copy an iterator by assignment.
EST_TStructIterator()
Create an iterator not associated with any specific container.
EST_TStructIterator(const Container &over)
Create an iterator ready to run over the given container.
Iter & operator=(const Iter &orig)
Copy an iterator by assignment.