(file) Return to List.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 mike  1.1.2.2 //%2006////////////////////////////////////////////////////////////////////////
  2               //
  3               // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4               // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5               // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6               // IBM Corp.; EMC Corporation, The Open Group.
  7               // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8               // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9               // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10               // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11               // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12               // EMC Corporation; Symantec Corporation; The Open Group.
 13               //
 14               // Permission is hereby granted, free of charge, to any person obtaining a copy
 15               // of this software and associated documentation files (the "Software"), to
 16               // deal in the Software without restriction, including without limitation the
 17               // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18               // sell copies of the Software, and to permit persons to whom the Software is
 19               // furnished to do so, subject to the following conditions:
 20               // 
 21               // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22 mike  1.1.2.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23               // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24               // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25               // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26               // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27               // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28               // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29               //
 30               //==============================================================================
 31               //
 32               // Author: Mike Brasher (m.brasher@inovadevelopment.com)
 33               //
 34               //%/////////////////////////////////////////////////////////////////////////////
 35               
 36 mike  1.1.2.1 #include "List.h"
 37 mike  1.1.2.2 #include "PegasusAssert.h"
 38 mike  1.1.2.1 
 39               #ifdef PEGASUS_LINKABLE_SANITY
 40 mike  1.1.2.2 # define PEGASUS_LIST_ASSERT(COND) PEGASUS_ASSERT(COND)
 41 mike  1.1.2.1 #else
 42 mike  1.1.2.2 # define PEGASUS_LIST_ASSERT(COND) /* empty */
 43 mike  1.1.2.1 #endif
 44               
 45 mike  1.1.2.2 #define PEGASUS_LIST_MAGIC 0x6456FD0A
 46 mike  1.1.2.1 
 47               PEGASUS_NAMESPACE_BEGIN
 48               
 49               ListRep::ListRep(void (*destructor)(Linkable*)) : 
 50                   _magic(PEGASUS_LIST_MAGIC), _front(0), _back(0), _size(0)
 51               {
 52                   if (destructor)
 53               	_destructor = destructor;
 54                   else
 55               	_destructor = 0;
 56               }
 57               
 58               ListRep::~ListRep()
 59               {
 60 mike  1.1.2.2     PEGASUS_LIST_ASSERT(_magic == PEGASUS_LIST_MAGIC);
 61 mike  1.1.2.1 
 62                   clear();
 63               #ifdef PEGASUS_LINKABLE_SANITY
 64                   memset(this, 0xDD, sizeof(ListRep));
 65               #endif
 66               }
 67               
 68               void ListRep::clear()
 69               {
 70 mike  1.1.2.2     PEGASUS_LIST_ASSERT(_magic == PEGASUS_LIST_MAGIC);
 71 mike  1.1.2.1 
 72                   if (_destructor)
 73                   {
 74 mike  1.1.2.3 	// Reset _front, _back, and _size so that if this is called back,
 75               	// there will be nothing to delete.
 76               
 77               	Linkable* front = _front;
 78               	Linkable* back = _back;
 79               	size_t size= _size;
 80               
 81               	_front = 0;
 82               	_back = 0;
 83               	_size = 0;
 84               
 85               	for (Linkable* p = front; p; )
 86 mike  1.1.2.1 	{
 87 mike  1.1.2.2 	    PEGASUS_LIST_ASSERT(p->magic == PEGASUS_LINKABLE_MAGIC);
 88 mike  1.1.2.1 	    Linkable* next = p->next;
 89               	    _destructor(p);
 90               	    p = next;
 91               	}
 92                   }
 93               }
 94               
 95               void ListRep::insert_front(Linkable* elem)
 96               {
 97 mike  1.1.2.2     PEGASUS_LIST_ASSERT(_magic == PEGASUS_LIST_MAGIC);
 98                   PEGASUS_LIST_ASSERT(elem != 0);
 99                   PEGASUS_LIST_ASSERT(elem->magic == PEGASUS_LINKABLE_MAGIC);
100                   PEGASUS_LIST_ASSERT(elem->list == 0);
101 mike  1.1.2.1 
102                   elem->list = this;
103                   elem->next = _front;
104                   elem->prev = 0;
105               
106                   if (_front)
107               	_front->prev = elem;
108                   else
109               	_back = elem;
110               
111                   _front = elem;
112                   _size++;
113               }
114               
115               void ListRep::insert_back(Linkable* elem)
116               {
117 mike  1.1.2.2     PEGASUS_LIST_ASSERT(_magic == PEGASUS_LIST_MAGIC);
118                   PEGASUS_LIST_ASSERT(elem != 0);
119                   PEGASUS_LIST_ASSERT(elem->magic == PEGASUS_LINKABLE_MAGIC);
120                   PEGASUS_LIST_ASSERT(elem->list == 0);
121 mike  1.1.2.1 
122                   elem->list = this;
123                   elem->prev = _back;
124                   elem->next = 0;
125               
126                   if (_back)
127               	_back->next = elem;
128                   else
129               	_front = elem;
130               
131                   _back = elem;
132                   _size++;
133               }
134               
135               void ListRep::insert_after(
136                   Linkable* pos, 
137                   Linkable* elem)
138               {
139 mike  1.1.2.2     PEGASUS_LIST_ASSERT(_magic == PEGASUS_LIST_MAGIC);
140                   PEGASUS_LIST_ASSERT(pos != 0);
141                   PEGASUS_LIST_ASSERT(elem != 0);
142                   PEGASUS_LIST_ASSERT(elem->magic == PEGASUS_LINKABLE_MAGIC);
143                   PEGASUS_LIST_ASSERT(pos->magic == PEGASUS_LINKABLE_MAGIC);
144                   PEGASUS_LIST_ASSERT(elem->list == 0);
145 mike  1.1.2.1 
146                   elem->list = this;
147                   elem->prev = pos;
148                   elem->next = pos->next;
149               
150                   if (pos->next)
151               	pos->next->prev = elem;
152               
153                   pos->next = elem;
154               
155                   if (pos == _back)
156               	_back = elem;
157               
158                   _size++;
159               }
160               
161               void ListRep::insert_before(
162                   Linkable* pos, 
163                   Linkable* elem)
164               {
165 mike  1.1.2.2     PEGASUS_LIST_ASSERT(_magic == PEGASUS_LIST_MAGIC);
166                   PEGASUS_LIST_ASSERT(pos != 0);
167                   PEGASUS_LIST_ASSERT(elem != 0);
168                   PEGASUS_LIST_ASSERT(pos->magic == PEGASUS_LINKABLE_MAGIC);
169                   PEGASUS_LIST_ASSERT(elem->magic == PEGASUS_LINKABLE_MAGIC);
170                   PEGASUS_LIST_ASSERT(elem->list == 0);
171 mike  1.1.2.1 
172                   elem->list = this;
173                   elem->next = pos;
174                   elem->prev = pos->prev;
175               
176                   if (pos->prev)
177               	pos->prev->next = elem;
178               
179                   pos->prev = elem;
180               
181                   if (pos == _front)
182               	_front = elem;
183               
184                   _size++;
185               }
186               
187               void ListRep::remove(Linkable* pos)
188               {
189 mike  1.1.2.2     PEGASUS_LIST_ASSERT(_magic == PEGASUS_LIST_MAGIC);
190                   PEGASUS_LIST_ASSERT(pos != 0);
191                   PEGASUS_LIST_ASSERT(pos->magic == PEGASUS_LINKABLE_MAGIC);
192                   PEGASUS_LIST_ASSERT(pos->list == this);
193                   PEGASUS_LIST_ASSERT(_size != 0);
194 mike  1.1.2.1 
195                   if (_size == 0)
196               	return;
197               
198                   if (pos->prev)
199               	pos->prev->next = pos->next;
200               
201                   if (pos->next)
202               	pos->next->prev = pos->prev;
203               
204                   if (pos == _front)
205               	_front = pos->next;
206               
207                   if (pos == _back)
208               	_back = pos->prev;
209               
210                   pos->list = 0;
211               
212                   _size--;
213               }
214               
215 mike  1.1.2.1 bool ListRep::contains(const Linkable* elem)
216               {
217 mike  1.1.2.2     PEGASUS_LIST_ASSERT(_magic == PEGASUS_LIST_MAGIC);
218                   PEGASUS_LIST_ASSERT(elem != 0);
219                   PEGASUS_LIST_ASSERT(elem->magic == PEGASUS_LINKABLE_MAGIC);
220 mike  1.1.2.1 
221                   return elem && elem->list == this;
222               
223               #if 0
224                   for (const Linkable* p = _front; p; p = p->next)
225                   {
226               	if (p == elem)
227               	    return true;
228                   }
229               
230                   // Not found!
231                   return false;
232               #endif
233               }
234               
235               Linkable* ListRep::remove_front()
236               {
237 mike  1.1.2.2     PEGASUS_LIST_ASSERT(_magic == PEGASUS_LIST_MAGIC);
238 mike  1.1.2.1 
239                   if (_size == 0)
240               	return 0;
241               
242                   Linkable* elem = _front;
243                   remove(elem);
244               
245                   return elem;
246               }
247               
248               Linkable* ListRep::remove_back()
249               {
250 mike  1.1.2.2     PEGASUS_LIST_ASSERT(_magic == PEGASUS_LIST_MAGIC);
251                   PEGASUS_LIST_ASSERT(_size > 0);
252 mike  1.1.2.1 
253                   Linkable* elem = _back;
254                   remove(elem);
255               
256                   return elem;
257               }
258               
259               Linkable* ListRep::find(ListRep::Equal equal, const void* client_data)
260               {
261 mike  1.1.2.2     PEGASUS_LIST_ASSERT(_magic == PEGASUS_LIST_MAGIC);
262                   PEGASUS_LIST_ASSERT(equal != 0);
263 mike  1.1.2.1 
264                   for (Linkable* p = _front; p; p = p->next)
265                   {
266               	if ((*equal)(p, client_data))
267               	{
268 mike  1.1.2.2 	    PEGASUS_LIST_ASSERT(p->magic == PEGASUS_LINKABLE_MAGIC);
269 mike  1.1.2.1 	    return p;
270               	}
271                   }
272               
273                   // Not found!
274                   return 0;
275               }
276               
277               Linkable* ListRep::remove(ListRep::Equal equal, const void* client_data)
278               {
279 mike  1.1.2.2     PEGASUS_LIST_ASSERT(_magic == PEGASUS_LIST_MAGIC);
280                   PEGASUS_LIST_ASSERT(equal != 0);
281 mike  1.1.2.1 
282                   Linkable* p = find(equal, client_data);
283               
284                   if (p)
285                   {
286 mike  1.1.2.2 	PEGASUS_LIST_ASSERT(p->magic == PEGASUS_LINKABLE_MAGIC);
287 mike  1.1.2.1 	remove(p);
288                   }
289               
290                   return p;
291               }
292               
293               void ListRep::apply(ListRep::Apply apply, const void* client_data)
294               {
295 mike  1.1.2.2     PEGASUS_LIST_ASSERT(_magic == PEGASUS_LIST_MAGIC);
296                   PEGASUS_LIST_ASSERT(apply != 0);
297 mike  1.1.2.1 
298                   for (Linkable* p = _front; p; p = p->next)
299               	(*apply)(p, client_data);
300               }
301               
302               PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2