Edinburgh Speech Tools  2.4-release
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends Pages
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>
75 template <class Container, class IPointer, class Entry>
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>
196 class EST_TStructIterator
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>
219 class EST_TRwIterator
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