File: rtlist.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 6,643 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
/*
 * rtlist.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 the class template <tt>List</tt>, a double-linked list collection.
  * @see List
  */

#ifndef __LRT_LIST__
#define __LRT_LIST__

#include "rtiterator.h"
#include "rtdefs.h"

namespace lrt{

/** A double-linked list collection. 
  * As opposed to <tt>Vector</tt>s, elements can be inserted and removed very quickly
  * into lists, and sequential access to elements (forwards and backwards) is quick, too.
  * (The class Iterator is used for this.)
  * However, random access to elements is quite slow.
  */	
template<class T> class List
{
public:
	class Node
	{
	public:
		inline Node* getNext() const	{ return next; }
		inline Node* getPrev() const	{ return prev; }
		inline T& accessElement()		{ return element; }
		inline const T& accessElement() const { return element; }
	private:
		Node( const T &element ) : 	element(element), next(0), prev(0) {}
		~Node() {}

		inline void setNext( Node* nn)	{ next = nn; }
		inline void setPrev( Node* nn)	{ prev = nn; }

		friend class List<T>;
		T element;
		Node *next;
		Node *prev;
	};

	/** Concrete implementation of an iterator on lists. 
	  * This class is for use by List itself only. Use Iterator instead. */
	class IteratorImpl : public lrt::IIteratorImpl<T>
	{
	public:
		virtual ~IteratorImpl() {}
		
		// reimplementing just the virtual functions...
		virtual void goToNext() { if(element != 0) element = element->getNext(); }
		virtual void goToPrev() { if(element != 0) element = element->getPrev(); }
		virtual bool equals(const IIteratorImpl<T> *it) const 
		{ 
			const IteratorImpl* i = LRT_DYNAMIC_CAST(const IteratorImpl*)(it); 
			if(!i) return false; 
			return (element == i->element); 
		}

		virtual bool hasNext() const	{ if(!element) return false; return (element->getNext() != 0); }
		virtual bool hasPrev() const	{ if(!element) return false; return (element->getPrev() != 0); }
		virtual bool hasElement() const	{ return (element != 0); }

		virtual T& get()				{ return element->accessElement(); }
		virtual const T& get() const	{ return element->accessElement(); }

		virtual bool canModify()		{ return canMod; }
		virtual void remove()			{ if(!element) return; Node* el = element; element = list->remove(el); }

	private:
		friend class List<T>;
		virtual IIteratorImpl<T>* clone() const	{ return new IteratorImpl(list, element, canMod); }
		// el=0 means no element
		IteratorImpl(List<T>* const l, Node* el, bool cm) : list(l), element(el), canMod(cm) {} 
		List<T>* const list;
		Node *element;
		bool canMod;
	};

	/** Creates an empty list. */
	List();
	/** Creates a new list which contains a copy of all entries of the given list. */
	List(const List<T> &);
	/** Clears the list, then copies all the entries from the given list over to this one. */
	List<T> &operator=(const List<T> &);
	/** Destroys the list and all of its elements. */
	~List();

	/** Append an element to the list. 
	  * @param elem The element to append (it will be copied). 
	  * @return A reference to the appended element. */
	T& append( const T& elem );
	/** Prepend an element to the list. 
	  * @param elem The element to prepend (it will be copied). 
	  * @return A reference to the prepended element. */
	T& prepend( const T& elem );
	/** Insert an element before the given position. 
	  * @param pos The position after the new element. If the iterator points to nothing, 
	  *	           the new element is simply appended to the list. 
	  * @param elem The element to insert (it will be copied). 
	  * @return A reference to the inserted element. */
	T& insertBefore( Iterator<T> &pos, const T& elem ); // inserts before
	/** Insert an element after the given position. 
	  * @param pos The position before the new element. If the iterator points to nothing, 
	  *	           the new element is simply appended to the list. 
	  * @param elem The element to insert (it will be copied). 
	  * @return A reference to the inserted element. */
	T& insertAfter ( Iterator<T> &pos, const T& elem ); // inserts after
	/** Remove an element from the list. 
	  * Moves the iterator to the next element of the list. */
	inline void remove( Iterator<T> &pos );
	/** Remove an element from the list. 
	  * Returns a pointer to the next element of the list. */
	Node* remove(Node* element);

	/** Remove all elements from the list, and destroy them. */
	void clear();

	/** Returns the current element count of the list. */
	inline int length() const;
	/** Returns the current element count of the list. */
	inline int getSize() const;

	inline Node* first();
	inline const Node* first() const;
	inline Node* last();
	inline const Node* last() const;

	/** Returns an unmodifyable iterator to the first element of the list. 
	  * If the list is empty, the iterator points to nothing; you can use 
	  * Iterator::hasElement() to check this. */
	inline Iterator<T> begin() const;
	/** Returns an unmodifyable iterator to the last element of the list. 
	  * If the list is empty, the iterator points to nothing; you can use 
	  * Iterator::hasElement() to check this. */
	inline Iterator<T> end() const;
	/** Returns an modifyable iterator to the first element of the list. 
	  * If the list is empty, the iterator points to nothing; you can use 
	  * Iterator::hasElement() to check this. */
	inline Iterator<T> begin();
	/** Returns an modifyable iterator to the last element of the list. 
	  * If the list is empty, the iterator points to nothing; you can use 
	  * Iterator::hasElement() to check this. */
	inline Iterator<T> end();
private:
	friend class IteratorImpl; // my iterator
	int len;
	Node *_begin, *_end;	
};


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

/** Removes the given node from the list, 
  * deletes it and advances the pointer to the next node.
  * @param list The list to remove the node from.
  * @param n A list node. 
  */
template<class T> void deleteNode(List<T>& list, typename List<T>::Node*& n);

} // namespace

#include "rtlist.templ.cpp"

#endif