File: rtiterator.h

package info (click to toggle)
robotour 3.1.1-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 2,596 kB
  • ctags: 2,972
  • sloc: cpp: 17,705; sh: 3,060; ansic: 2,778; makefile: 144
file content (185 lines) | stat: -rwxr-xr-x 8,661 bytes parent folder | download
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
 * rtiterator.h
 * 
 * Copyright (c) 2000-2004 by Florian Fischer (florianfischer@gmx.de)
 * and Martin Trautmann (martintrautmann@gmx.de) 
 * 
 * This file may be distributed and/or modified under the terms of the 
 * GNU General Public License version 2 as published by the Free Software 
 * Foundation. 
 * 
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 * 
 */

/** \file
  * Contains classes and methods which are needed to traverse collections (like 
  * <tt>List</tt>s and <tt>Map</tt>s) using iterators.
  * @see Iterator
  * @see deleteCurrent()
  * @see deleteAll()
  */

#ifndef __LRT_ITERATOR__
#define __LRT_ITERATOR__

#include "rtsystem.h"
#include "rtdefs.h"

namespace lrt {

/** An iterator implementation. This interface must be implemented by whatever class
  * serving as a concrete iterator for a collection in libRT.
  */
template<class T> class IIteratorImpl 
{
public:
	/** Destroys the iterator implementation. */
	virtual ~IIteratorImpl() {}
	/** Move the iterator to the next element. If there is no next element, 
	  * the iterator should move to an invalid position. */
	virtual void goToNext() = 0;
	/** Move the iterator to the previous element. If there is no previous element, 
	  * the iterator should move to an invalid position. */
	virtual void goToPrev() = 0;
	/** Check if this iterator implementation is at the same position of the same
	  * collection as the given one. 
	  * Note: You should first check that the other implementation is of your same
	  * class, by using a <tt>dynamic_cast</tt> to your concrete implementation. */
	virtual bool equals(const IIteratorImpl<T> *) const = 0;

	/** Return true if the current iterator position denotes a valid element. */
	virtual bool hasElement() const = 0;
	/** Return true iff <tt>goToNext(); hasElement();</tt> would return true. */
	virtual bool hasNext() const = 0;
	/** Return true iff <tt>goToPrev(); hasElement();</tt> would return true. */
	virtual bool hasPrev() const = 0;

	/** Return a modifyable reference to the element at the current iterator position,
	  * or any nonsense element if the current position is invalid. */
	virtual T& get() = 0;
	/** Return a constant reference to the element at the current iterator position,
	  * or any nonsense element if the current position is invalid. */
	virtual const T& get() const = 0;

	/** Return <tt>true</tt> if the iterator can modify its collection.
	  * (e.g. remove elements from it, modify its elements,...) */
	virtual bool canModify() = 0;
	/** Remove the element at the current iterator position, and advance
	  * to the next element. */
	virtual void remove() = 0;

	/** Return a copy of your concrete iterator implementation, pointing to the same
	  * collection element. */
	virtual IIteratorImpl<T> *clone() const = 0;
};

/** A bi-directional iterator for collections in libRT. 
  * This class is just a wrapper class for higher comfort for any iterator implementations.
  * Collections which provide access using iterators, should implement the IIteratorImpl 
  * interface in a <tt>YourCollection::Iterator</tt> class and then return 
  * <tt>Iterator<T>(new YourCollection::Iterator())</tt> in any access methods (where 
  * <tt>T</tt> is the element type of <tt>YourCollection</tt>).
  */
template<class T> class Iterator
{
public:
	/** Creates a duplicate of the given iterator. */
	Iterator(const Iterator<T>& iter) : impl(iter.impl->clone()) {}
	/** Creates an iterator, using the iterator implementation impl. */
	Iterator(IIteratorImpl<T> *impl) : impl(impl) { if(!impl) System::exit(-2, "Iterator implementations must not be 0!"); }
	/** Returns the iterator implementation this iterator is using. */
	inline IIteratorImpl<T>* getImpl() { return impl; }
	/** Deletes the iterator implementation this iterator is using. */
	~Iterator() { delete impl; }
	
	// C++-Iterator members
	/** Proceeds to the next element of the collection. */
	inline Iterator<T> operator++(int) { Iterator<T> ret = clone(); impl->goToNext(); return ret; }
	/** Moves to the previous element of the collection. */
	inline Iterator<T> operator--(int) { Iterator<T> ret = clone(); impl->goToPrev(); return ret; }
	/** Checks if this iterator and <tt>it</tt> are at the same position of the same collection object. */
	inline bool operator==( const Iterator<T> &it ) const { return impl->equals(it->impl); }
	/** Moves to the position at which <tt>it</tt> stands. */
	inline Iterator<T>& operator=(const Iterator<T>& it) { delete impl; impl = it.impl->clone(); return *this; }

	/** Returns the element at the current position, or an invalid reference if there isn't any. 
	  * You should use hasElement() to check the current position before dereferencing the iterator. */
	inline T& operator*()					{ return get(); }
	/** Returns the element at the current position, or an invalid reference if there isn't any. 
	  * You should use hasElement() to check the current position before dereferencing the iterator. */
	inline const T &operator*() const		{ return get(); }
	/** Proceeds to the next element of the collection. */
	inline Iterator<T>& operator++() { impl->goToNext(); return *this; }
	/** Moves to the previous element of the collection. */
	inline Iterator<T>& operator--() { impl->goToPrev(); return *this; }

	// Java Interface
	/** Checks if there is an element at the current position of this iterator. */
	inline bool hasElement() const { return impl->hasElement(); }
	/** Checks if there is an element at the next position of this iterator. */
	inline bool hasNext() const    { return impl->hasNext(); }
	/** Checks if there is an element at the previous position of this iterator. */
	inline bool hasPrev() const    { return impl->hasPrev(); }
	
	/** Returns the element at the current position, and moves forward thereafter.
	  * You should use hasElement() to check the current position before using next().
	  */
	inline T& next()	{ T& ret = get(); impl->goToNext(); return ret; }
	/** Returns the element at the current position, and moves to the previous element thereafter.
	  * You should use hasElement() to check the current position before using prev().
	  */
	inline T& prev()	{ T& ret = get(); impl->goToPrev(); return ret; }
	

	// our own, better methods
	/** Returns the element at the current position, or an invalid reference if there isn't any. 
	  * You should use hasElement() to check the current position before using get(). */
	inline T& get()				{ return impl->get(); }
	/** Returns the element at the current position, or an invalid reference if there isn't any. 
	  * You should use hasElement() to check the current position before using get(). */
	inline const T& get() const { return impl->get(); }
	/** Returns <tt>true</tt> if the iterator can modify its collection. 
	  * (e.g. remove elements from it.) */
	inline bool canModify() const { return impl->canModify(); }
	/** Removes the element at the current position, and advances
	  * to the next element. If the iterator cannot be modified, does nothing. 
	  * @see canModify() */
	inline void remove() { if(canModify()) impl->remove(); }

	/** Returns a new iterator pointing to the next element of the collection. */
	inline Iterator<T> getNext() const		{ return ++clone(); }
	/** Returns a new iterator pointing to the previous element of the collection. */
	inline Iterator<T> getPrev() const		{ return --clone(); }

protected:
	/** Clones this iterator by cloning its implementation. */
	Iterator<T> clone() const { return Iterator(impl->clone()); }
private:
	IIteratorImpl<T>* impl;
};

// MSVC++ Bug Workaround
#ifndef __LRT_TPTR_DEFINED
#define __LRT_TPTR_DEFINED
LRT_DEFINE_PTR(T)
#endif

/** Removes the element at the current position from the collection, 
  * deletes it and advances the iterator to the next position.
  * @param pos Iterator to a collection. The iterator must be modifyable. 
  * @see Iterator<T>::canModify() */
template<class LRT_NPTR(T)> void deleteCurrent(Iterator<LRT_PTR(T)>& pos);

/** Removes all elements from the collection and deletes them. 
  * @param begin An Iterator to the begin of a collection. The iterator must be modifyable. 
  *              It should no longer be used after the function returns.
  * @see Iterator<T>::canModify() */
template<class LRT_NPTR(T)> void deleteAll(Iterator<LRT_PTR(T)> begin);

} // namespace

#include "rtiterator.templ.cpp"

#endif