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
|