EPICS Base  7.0.8.1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tsSLList.h
1 /*************************************************************************\
2 * Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * SPDX-License-Identifier: EPICS
7 * EPICS Base is distributed subject to a Software License Agreement found
8 * in file LICENSE that is included with this distribution.
9 \*************************************************************************/
10 /*
11  * type safe singly linked list templates
12  *
13  * Author Jeffrey O. Hill
15  * 505 665 1831
16  */
17 
18 #ifndef tsSLListh
19 #define tsSLListh
20 
21 #ifndef assert // allow use of epicsAssert.h
22 #include <assert.h>
23 #endif
24 
25 //
26 // the hp compiler complains about parameterized friend
27 // class that has not been declared without this?
28 //
29 template < class T > class tsSLList;
30 template < class T > class tsSLIter;
31 template < class T > class tsSLIterConst;
32 
33 //
34 // tsSLNode<T>
35 // NOTE: class T must derive from tsSLNode<T>
36 //
37 template <class T>
38 class tsSLNode {
39 public:
40  tsSLNode ();
41  tsSLNode < T > & operator = ( const tsSLNode < T > & );
42 private:
43  void removeNextItem (); // removes the item after this node
44  T *pNext;
45  tsSLNode ( const tsSLNode < T > & );
46  friend class tsSLList < T >;
47  friend class tsSLIter < T >;
48  friend class tsSLIterConst < T >;
49 };
50 
51 
52 //
53 // tsSLList<T>
54 // NOTE: class T must derive from tsSLNode<T>
55 //
56 template < class T >
57 class tsSLList : public tsSLNode < T > {
58 public:
59  tsSLList (); // creates an empty list
60  tsSLList ( tsSLList & );
61  void insert ( T &item, tsSLNode < T > &itemBefore ); // insert after item before
62  void add ( T &item ); // add to the beginning of the list
63  T * get (); // remove from the beginning of the list
64  T * pop (); // same as get
65  void push ( T &item ); // same as add
66  T * first () const;
67  void remove ( T &itemBefore );
68  tsSLIterConst <T> firstIter () const;
69  tsSLIter <T> firstIter ();
70  static tsSLIterConst <T> invalidConstIter ();
71  static tsSLIter <T> invalidIter ();
72 private:
73  const tsSLList < T > & operator = ( const tsSLList < T > & );
74 };
75 
76 //
77 // tsSLIterConst<T>
78 //
79 template < class T >
80 class tsSLIterConst {
81 public:
82  tsSLIterConst ();
83  bool valid () const;
84  bool operator == (const tsSLIterConst<T> &rhs) const;
85  bool operator != (const tsSLIterConst<T> &rhs) const;
86  tsSLIterConst<T> & operator = (const tsSLIterConst<T> &);
87  const T & operator * () const;
88  const T * operator -> () const;
89  tsSLIterConst<T> & operator ++ ();
90  tsSLIterConst<T> operator ++ (int);
91  const T * pointer () const;
92 protected:
93  const T * pEntry;
94  tsSLIterConst ( const T *pInitialEntry );
95  friend class tsSLList < T >;
96 };
97 
98 //
99 // tsSLIter<T>
100 //
101 template < class T >
102 class tsSLIter {
103 public:
104  tsSLIter ();
105  bool valid () const;
106  bool operator == (const tsSLIter<T> &rhs) const;
107  bool operator != (const tsSLIter<T> &rhs) const;
108  tsSLIter<T> & operator = (const tsSLIter<T> &);
109  T & operator * () const;
110  T * operator -> () const;
111  tsSLIter <T> & operator ++ ();
112  tsSLIter <T> operator ++ (int);
113  T * pointer () const;
114 private:
115  T *pEntry;
116  tsSLIter ( T *pInitialEntry );
117  friend class tsSLList < T >;
118 };
119 
121 //
122 // tsSLNode<T> inline member functions
123 //
125 
126 //
127 // tsSLNode<T>::tsSLNode ()
128 //
129 template < class T >
130 inline tsSLNode < T > :: tsSLNode () : pNext ( 0 ) {}
131 
132 //
133 // tsSLNode<T>::tsSLNode ( const tsSLNode < T > & )
134 // private - not to be used - implemented to eliminate warnings
135 //
136 template < class T >
137 inline tsSLNode < T > :: tsSLNode ( const tsSLNode < T > & )
138 {
139 }
140 
141 //
142 // tsSLNode<T>::operator =
143 //
144 // when someone copies into a class deriving from this
145 // do _not_ change the node pointers
146 //
147 template < class T >
149  ( const tsSLNode < T > & )
150 {
151  return *this;
152 }
153 
154 //
155 // removeNextItem ()
156 //
157 // removes the item after this node
158 //
159 template <class T>
160 inline void tsSLNode<T>::removeNextItem ()
161 {
162  T *pItem = this->pNext;
163  if ( pItem ) {
164  tsSLNode < T > *pNode = pItem;
165  this->pNext = pNode->pNext;
166  }
167 }
168 
170 //
171 // tsSLList<T> inline member functions
172 //
174 
175 //
176 // tsSLList<T>::tsSLList()
177 // create an empty list
178 //
179 template < class T >
180 inline tsSLList < T > :: tsSLList ()
181 {
182 }
183 
184 //
185 // tsSLList<T>::tsSLList( tsSLList & )
186 //
187 template < class T >
188 inline tsSLList < T > :: tsSLList ( tsSLList &listIn )
189 {
190  this->pNext = listIn.pNext;
191  listIn.pNext = 0;
192 }
193 
194 //
195 // tsSLList<T>::insert()
196 // (itemBefore might be the list header object and therefore
197 // will not always be of type T)
198 //
199 template < class T >
200 inline void tsSLList < T > :: insert ( T &item, tsSLNode < T > &itemBefore )
201 {
202  tsSLNode < T > &node = item;
203  node.pNext = itemBefore.pNext;
204  itemBefore.pNext = &item;
205 }
206 
207 //
208 // tsSLList<T>::add ()
209 //
210 template < class T >
211 inline void tsSLList < T > :: add ( T &item )
212 {
213  this->insert ( item, *this );
214 }
215 
216 //
217 // tsSLList<T>::get ()
218 //
219 template < class T >
220 inline T * tsSLList < T > :: get ()
221 {
222  tsSLNode < T > *pThisNode = this;
223  T *pItem = pThisNode->pNext;
224  pThisNode->removeNextItem ();
225  return pItem;
226 }
227 
228 //
229 // tsSLList<T>::pop ()
230 //
231 template < class T >
232 inline T * tsSLList < T > :: pop ()
233 {
234  return this->get ();
235 }
236 
237 //
238 // tsSLList<T>::push ()
239 //
240 template <class T>
241 inline void tsSLList < T > :: push ( T &item )
242 {
243  this->add (item);
244 }
245 
246 template <class T>
247 inline T * tsSLList < T > :: first () const
248 {
249  const tsSLNode < T > *pThisNode = this;
250  return pThisNode->pNext;
251 }
252 
253 template <class T>
254 inline void tsSLList < T > :: remove ( T &itemBefore )
255 {
256  tsSLNode < T > *pBeforeNode = &itemBefore;
257  tsSLNode < T > *pAfterNode = pBeforeNode->pNext;
258  pBeforeNode->pNext = pAfterNode->pNext;
259 }
260 
261 template <class T>
262 inline tsSLIterConst <T> tsSLList < T > :: firstIter () const
263 {
264  const tsSLNode < T > *pThisNode = this;
265  return tsSLIterConst <T> ( pThisNode->pNext );
266 }
267 
268 template <class T>
269 inline tsSLIter <T> tsSLList < T > :: firstIter ()
270 {
271  tsSLNode < T > *pThisNode = this;
272  return tsSLIter <T> ( pThisNode->pNext );
273 }
274 
275 template <class T>
276 inline tsSLIterConst <T> tsSLList < T > :: invalidConstIter ()
277 {
278  return tsSLIterConst <T> ( 0 );
279 }
280 
281 template <class T>
282 inline tsSLIter <T> tsSLList < T > :: invalidIter ()
283 {
284  return tsSLIter <T> ( 0 );
285 }
286 
288 //
289 // tsSLIterConst<T> inline member functions
290 //
292 
293 template < class T >
294 inline tsSLIterConst<T>::tsSLIterConst ( const T *pInitialEntry ) :
295  pEntry ( pInitialEntry )
296 {
297 }
298 
299 template < class T >
301  pEntry ( 0 )
302 {
303 }
304 
305 template < class T >
306 inline bool tsSLIterConst<T>::valid () const
307 {
308  return this->pEntry != 0;
309 }
310 
311 template < class T >
312 inline bool tsSLIterConst<T>::operator == ( const tsSLIterConst<T> &rhs ) const
313 {
314  return this->pEntry == rhs.pConstEntry;
315 }
316 
317 template < class T >
318 inline bool tsSLIterConst<T>::operator != (const tsSLIterConst<T> &rhs) const
319 {
320  return this->pEntry != rhs.pConstEntry;
321 }
322 
323 template < class T >
325 {
326  this->pEntry = rhs.pEntry;
327  return *this;
328 }
329 
330 template < class T >
331 inline const T & tsSLIterConst<T>::operator * () const
332 {
333  return *this->pEntry;
334 }
335 
336 template < class T >
337 inline const T * tsSLIterConst<T>::operator -> () const
338 {
339  return this->pEntry;
340 }
341 
342 template < class T >
343 inline tsSLIterConst<T> & tsSLIterConst<T>::operator ++ () // prefix ++
344 {
345  const tsSLNode < T > *pCurNode = this->pEntry;
346  this->pEntry = pCurNode->pNext;
347  return *this;
348 }
349 
350 template < class T >
351 inline tsSLIterConst<T> tsSLIterConst<T>::operator ++ ( int ) // postfix ++
352 {
353  const tsSLIterConst<T> tmp = *this;
354  const tsSLNode < T > *pCurNode = this->pEntry;
355  this->pEntry = pCurNode->pNext;
356  return tmp;
357 }
358 
359 template <class T>
360 inline const T * tsSLIterConst < T > :: pointer () const
361 {
362  return this->pEntry;
363 }
364 
366 //
367 // tsSLIter<T> inline member functions
368 //
370 
371 template < class T >
372 inline tsSLIter<T>::tsSLIter ( T *pInitialEntry ) :
373  pEntry ( pInitialEntry )
374 {
375 }
376 
377 template < class T >
378 inline tsSLIter<T>::tsSLIter () :
379  pEntry ( 0 )
380 {
381 }
382 
383 template < class T >
384 inline bool tsSLIter<T>::valid () const
385 {
386  return this->pEntry != 0;
387 }
388 
389 template < class T >
390 inline bool tsSLIter<T>::operator == ( const tsSLIter<T> &rhs ) const
391 {
392  return this->pEntry == rhs.pEntry;
393 }
394 
395 template < class T >
396 inline bool tsSLIter<T>::operator != ( const tsSLIter<T> &rhs ) const
397 {
398  return this->pEntry != rhs.pEntry;
399 }
400 
401 template < class T >
402 inline tsSLIter<T> & tsSLIter<T>::operator = ( const tsSLIter<T> & rhs )
403 {
404  this->pEntry = rhs.pEntry;
405  return *this;
406 }
407 
408 template < class T >
409 inline T & tsSLIter<T>::operator * () const
410 {
411  return *this->pEntry;
412 }
413 
414 template < class T >
415 inline T * tsSLIter<T>::operator -> () const
416 {
417  return this->pEntry;
418 }
419 
420 template < class T >
421 inline tsSLIter<T> & tsSLIter<T>::operator ++ () // prefix ++
422 {
423  const tsSLNode < T > *pCurNode = this->pEntry;
424  this->pEntry = pCurNode->pNext;
425  return *this;
426 }
427 
428 template < class T >
429 inline tsSLIter<T> tsSLIter<T>::operator ++ ( int ) // postfix ++
430 {
431  const tsSLIter<T> tmp = *this;
432  const tsSLNode < T > *pCurNode = this->pEntry;
433  this->pEntry = pCurNode->pNext;
434  return tmp;
435 }
436 
437 template <class T>
438 inline T * tsSLIter < T > :: pointer () const
439 {
440  return this->pEntry;
441 }
442 
443 #endif // tsSLListh