1 martin 1.7 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.8 //
|
3 martin 1.7 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.8 //
|
10 martin 1.7 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.8 //
|
17 martin 1.7 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.8 //
|
20 martin 1.7 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.8 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.7 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.8 //
|
28 martin 1.7 //////////////////////////////////////////////////////////////////////////
|
29 mike 1.2 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include "List.h"
33 #include "PegasusAssert.h"
34
35 PEGASUS_NAMESPACE_BEGIN
36
|
37 kumpf 1.3 ListRep::ListRep(void (*destructor)(Linkable*))
38 : _front(0), _back(0), _size(0)
|
39 mike 1.2 {
40 if (destructor)
|
41 kumpf 1.3 _destructor = destructor;
|
42 mike 1.2 else
|
43 kumpf 1.3 _destructor = 0;
|
44 mike 1.2 }
45
46 ListRep::~ListRep()
47 {
48 PEGASUS_DEBUG_ASSERT(_magic);
49
50 clear();
51 #ifdef PEGASUS_DEBUG
52 memset(this, 0xDD, sizeof(ListRep));
53 #endif
54 }
55
56 void ListRep::clear()
57 {
58 PEGASUS_DEBUG_ASSERT(_magic);
59
60 if (_destructor)
61 {
|
62 kumpf 1.3 // Reset _front, _back, and _size in case the destructor calls
63 // a method of List.
|
64 mike 1.2
|
65 kumpf 1.3 Linkable* front = _front;
66
67 _front = 0;
68 _back = 0;
69 _size = 0;
70
71 for (Linkable* p = front; p; )
72 {
73 PEGASUS_DEBUG_ASSERT(p->magic);
74 Linkable* next = p->next;
75 p->list = 0;
76 _destructor(p);
77 p = next;
78 }
|
79 mike 1.2 }
80 }
81
82 void ListRep::insert_front(Linkable* elem)
83 {
84 PEGASUS_DEBUG_ASSERT(_magic);
85 PEGASUS_DEBUG_ASSERT(elem != 0);
86 PEGASUS_DEBUG_ASSERT(elem->magic);
87 PEGASUS_DEBUG_ASSERT(elem->list == 0);
88
89 elem->list = this;
90 elem->next = _front;
91 elem->prev = 0;
92
93 if (_front)
|
94 kumpf 1.3 _front->prev = elem;
|
95 mike 1.2 else
|
96 kumpf 1.3 _back = elem;
|
97 mike 1.2
98 _front = elem;
99 _size++;
100 }
101
102 void ListRep::insert_back(Linkable* elem)
103 {
104 PEGASUS_DEBUG_ASSERT(_magic);
105 PEGASUS_DEBUG_ASSERT(elem != 0);
106 PEGASUS_DEBUG_ASSERT(elem->magic);
107 PEGASUS_DEBUG_ASSERT(elem->list == 0);
108
109 elem->list = this;
110 elem->prev = _back;
111 elem->next = 0;
112
113 if (_back)
|
114 kumpf 1.3 _back->next = elem;
|
115 mike 1.2 else
|
116 kumpf 1.3 _front = elem;
|
117 mike 1.2
118 _back = elem;
119 _size++;
120 }
121
122 void ListRep::insert_after(
|
123 kumpf 1.3 Linkable* pos,
|
124 mike 1.2 Linkable* elem)
125 {
126 PEGASUS_DEBUG_ASSERT(_magic);
127 PEGASUS_DEBUG_ASSERT(pos != 0);
128 PEGASUS_DEBUG_ASSERT(elem != 0);
129 PEGASUS_DEBUG_ASSERT(elem->magic);
130 PEGASUS_DEBUG_ASSERT(pos->magic);
131 PEGASUS_DEBUG_ASSERT(elem->list == 0);
132
133 elem->list = this;
134 elem->prev = pos;
135 elem->next = pos->next;
136
137 if (pos->next)
|
138 kumpf 1.3 pos->next->prev = elem;
|
139 mike 1.2
140 pos->next = elem;
141
142 if (pos == _back)
|
143 kumpf 1.3 _back = elem;
|
144 mike 1.2
145 _size++;
146 }
147
148 void ListRep::insert_before(
|
149 kumpf 1.3 Linkable* pos,
|
150 mike 1.2 Linkable* elem)
151 {
152 PEGASUS_DEBUG_ASSERT(_magic);
153 PEGASUS_DEBUG_ASSERT(pos != 0);
154 PEGASUS_DEBUG_ASSERT(elem != 0);
155 PEGASUS_DEBUG_ASSERT(pos->magic);
156 PEGASUS_DEBUG_ASSERT(elem->magic);
157 PEGASUS_DEBUG_ASSERT(elem->list == 0);
158
159 elem->list = this;
160 elem->next = pos;
161 elem->prev = pos->prev;
162
163 if (pos->prev)
|
164 kumpf 1.3 pos->prev->next = elem;
|
165 mike 1.2
166 pos->prev = elem;
167
168 if (pos == _front)
|
169 kumpf 1.3 _front = elem;
|
170 mike 1.2
171 _size++;
172 }
173
174 void ListRep::remove(Linkable* pos)
175 {
176 PEGASUS_DEBUG_ASSERT(_magic);
177 PEGASUS_DEBUG_ASSERT(pos != 0);
178 PEGASUS_DEBUG_ASSERT(pos->magic);
179 PEGASUS_DEBUG_ASSERT(pos->list == this);
180 PEGASUS_DEBUG_ASSERT(_size != 0);
181
182 if (_size == 0)
|
183 kumpf 1.3 return;
|
184 mike 1.2
185 if (pos->prev)
|
186 kumpf 1.3 pos->prev->next = pos->next;
|
187 mike 1.2
188 if (pos->next)
|
189 kumpf 1.3 pos->next->prev = pos->prev;
|
190 mike 1.2
191 if (pos == _front)
|
192 kumpf 1.3 _front = pos->next;
|
193 mike 1.2
194 if (pos == _back)
|
195 kumpf 1.3 _back = pos->prev;
|
196 mike 1.2
197 pos->list = 0;
198
199 _size--;
200 }
201
202 bool ListRep::contains(const Linkable* elem)
203 {
204 PEGASUS_DEBUG_ASSERT(_magic);
205 PEGASUS_DEBUG_ASSERT(elem != 0);
206 PEGASUS_DEBUG_ASSERT(elem->magic);
207
208 for (const Linkable* p = _front; p; p = p->next)
209 {
|
210 kumpf 1.3 if (p == elem)
211 return true;
|
212 mike 1.2 }
213
214 // Not found!
215 return false;
216 }
217
218 Linkable* ListRep::remove_front()
219 {
220 PEGASUS_DEBUG_ASSERT(_magic);
221
222 if (_size == 0)
|
223 kumpf 1.3 return 0;
|
224 mike 1.2
225 Linkable* elem = _front;
226 remove(elem);
227
228 return elem;
229 }
230
231 Linkable* ListRep::remove_back()
232 {
233 PEGASUS_DEBUG_ASSERT(_magic);
|
234 dmitry.mikulin 1.6
235 if (_size == 0)
236 return 0;
|
237 mike 1.2
238 Linkable* elem = _back;
239 remove(elem);
240
241 return elem;
242 }
243
244 Linkable* ListRep::find(ListRep::Equal equal, const void* client_data)
245 {
246 PEGASUS_DEBUG_ASSERT(_magic);
247 PEGASUS_DEBUG_ASSERT(equal != 0);
248
249 for (Linkable* p = _front; p; p = p->next)
250 {
|
251 kumpf 1.3 if ((*equal)(p, client_data))
252 {
253 PEGASUS_DEBUG_ASSERT(p->magic);
254 return p;
255 }
|
256 mike 1.2 }
257
258 // Not found!
259 return 0;
260 }
261
262 Linkable* ListRep::remove(ListRep::Equal equal, const void* client_data)
263 {
264 PEGASUS_DEBUG_ASSERT(_magic);
265 PEGASUS_DEBUG_ASSERT(equal != 0);
266
267 Linkable* p = find(equal, client_data);
268
269 if (p)
270 {
|
271 kumpf 1.3 PEGASUS_DEBUG_ASSERT(p->magic);
272 remove(p);
|
273 mike 1.2 }
274
275 return p;
276 }
277
278 void ListRep::apply(ListRep::Apply apply, const void* client_data)
279 {
280 PEGASUS_DEBUG_ASSERT(_magic);
281 PEGASUS_DEBUG_ASSERT(apply != 0);
282
283 for (Linkable* p = _front; p; p = p->next)
|
284 kumpf 1.3 (*apply)(p, client_data);
|
285 mike 1.2 }
286
287 PEGASUS_NAMESPACE_END
|