1 martin 1.35 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.36 //
|
3 martin 1.35 // 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.36 //
|
10 martin 1.35 // 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.36 //
|
17 martin 1.35 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.36 //
|
20 martin 1.35 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.36 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.35 // 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.36 //
|
28 martin 1.35 //////////////////////////////////////////////////////////////////////////
|
29 mike 1.5 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
|
32 kumpf 1.13 // Only include if not included as general template or if explicit instantiation
33 #if !defined(Pegasus_ArrayImpl_h) || defined(PEGASUS_ARRAY_T)
34 #if !defined(PEGASUS_ARRAY_T)
35 #define Pegasus_ArrayImpl_h
36 #endif
37
38 PEGASUS_NAMESPACE_END
39
40 #include <Pegasus/Common/Memory.h>
41 #include <Pegasus/Common/ArrayRep.h>
|
42 kumpf 1.23 #include <Pegasus/Common/InternalException.h>
|
43 mike 1.27 #include <Pegasus/Common/Linkage.h>
|
44 kumpf 1.13
45 PEGASUS_NAMESPACE_BEGIN
|
46 mike 1.5
|
47 mike 1.27 PEGASUS_COMMON_LINKAGE void ArrayThrowIndexOutOfBoundsException();
48
|
49 mike 1.5 #ifndef PEGASUS_ARRAY_T
50 template<class PEGASUS_ARRAY_T>
51 #endif
52 Array<PEGASUS_ARRAY_T>::Array()
53 {
|
54 mike 1.27 _rep = &ArrayRepBase::_empty_rep;
|
55 mike 1.5 }
56
57 #ifndef PEGASUS_ARRAY_T
58 template<class PEGASUS_ARRAY_T>
59 #endif
60 Array<PEGASUS_ARRAY_T>::Array(const Array<PEGASUS_ARRAY_T>& x)
61 {
|
62 mike 1.27 _rep = x._rep;
63 ArrayRep<PEGASUS_ARRAY_T>::ref(Array_rep);
|
64 mike 1.5 }
65
66 #ifndef PEGASUS_ARRAY_T
67 template<class PEGASUS_ARRAY_T>
68 #endif
69 Array<PEGASUS_ARRAY_T>::Array(Uint32 size)
70 {
|
71 mike 1.28 _rep = ArrayRep<PEGASUS_ARRAY_T>::alloc(size);
|
72 kumpf 1.23
|
73 dave.sudlik 1.32 // ArrayRep<PEGASUS_ARRAY_T>::alloc() throws a bad_alloc exception if
74 // storage could not be obtained.
|
75 kumpf 1.23
|
76 mike 1.27 InitializeRaw(Array_data, size);
|
77 mike 1.5 }
78
79 #ifndef PEGASUS_ARRAY_T
80 template<class PEGASUS_ARRAY_T>
81 #endif
82 Array<PEGASUS_ARRAY_T>::Array(Uint32 size, const PEGASUS_ARRAY_T& x)
83 {
|
84 mike 1.27 _rep = ArrayRep<PEGASUS_ARRAY_T>::alloc(size);
|
85 mike 1.5
|
86 dave.sudlik 1.32 // ArrayRep<PEGASUS_ARRAY_T>::alloc() throws a bad_alloc exception if
87 // storage could not be obtained.
|
88 kumpf 1.23
|
89 mike 1.27 PEGASUS_ARRAY_T* data = Array_data;
90
91 // Note: we could use template specialization (by adding functions to
92 // Memory.h) so that this loop becomes a memset() for single byte raw
93 // types, but this function is rarely called.
|
94 mike 1.5
95 while (size--)
|
96 kumpf 1.13 new(data++) PEGASUS_ARRAY_T(x);
|
97 mike 1.5 }
98
99 #ifndef PEGASUS_ARRAY_T
100 template<class PEGASUS_ARRAY_T>
101 #endif
102 Array<PEGASUS_ARRAY_T>::Array(const PEGASUS_ARRAY_T* items, Uint32 size)
103 {
|
104 mike 1.27 _rep = ArrayRep<PEGASUS_ARRAY_T>::alloc(size);
|
105 kumpf 1.23
|
106 dave.sudlik 1.32 // ArrayRep<PEGASUS_ARRAY_T>::alloc() throws a bad_alloc exception if
107 // storage could not be obtained.
|
108 kumpf 1.23
|
109 mike 1.27 CopyToRaw(Array_data, items, size);
|
110 mike 1.5 }
111
112 #ifndef PEGASUS_ARRAY_T
113 template<class PEGASUS_ARRAY_T>
114 #endif
115 Array<PEGASUS_ARRAY_T>::~Array()
116 {
|
117 mike 1.27 ArrayRep<PEGASUS_ARRAY_T>::unref(Array_rep);
|
118 mike 1.5 }
119
120 #ifndef PEGASUS_ARRAY_T
121 template<class PEGASUS_ARRAY_T>
122 #endif
123 Array<PEGASUS_ARRAY_T>& Array<PEGASUS_ARRAY_T>::operator=(
124 const Array<PEGASUS_ARRAY_T>& x)
125 {
|
126 mike 1.27 if (x._rep != Array_rep)
|
127 mike 1.5 {
|
128 kumpf 1.34 ArrayRep<PEGASUS_ARRAY_T>::unref(Array_rep);
129 _rep = x._rep;
130 ArrayRep<PEGASUS_ARRAY_T>::ref(Array_rep);
|
131 mike 1.5 }
|
132 mike 1.27
|
133 mike 1.5 return *this;
134 }
135
136 #ifndef PEGASUS_ARRAY_T
137 template<class PEGASUS_ARRAY_T>
138 #endif
139 void Array<PEGASUS_ARRAY_T>::clear()
140 {
|
141 mike 1.27 if (Array_size)
142 {
|
143 kumpf 1.34 if (Array_refs.get() == 1)
144 {
145 Destroy(Array_data, Array_size);
146 Array_size = 0;
147 }
148 else
149 {
150 ArrayRep<PEGASUS_ARRAY_T>::unref(Array_rep);
151 _rep = &ArrayRepBase::_empty_rep;
152 }
|
153 mike 1.27 }
|
154 mike 1.5 }
155
156 #ifndef PEGASUS_ARRAY_T
157 template<class PEGASUS_ARRAY_T>
158 #endif
|
159 kumpf 1.18 void Array<PEGASUS_ARRAY_T>::reserveCapacity(Uint32 capacity)
|
160 mike 1.5 {
|
161 mike 1.27 if (capacity > Array_capacity || Array_refs.get() != 1)
|
162 kumpf 1.10 {
|
163 kumpf 1.34 ArrayRep<PEGASUS_ARRAY_T>* rep =
164 ArrayRep<PEGASUS_ARRAY_T>::alloc(capacity);
|
165 mike 1.27
|
166 dave.sudlik 1.32 // ArrayRep<PEGASUS_ARRAY_T>::alloc() throws a bad_alloc exception if
167 // storage could not be obtained.
|
168 mike 1.27
|
169 kumpf 1.34 rep->size = Array_size;
|
170 mike 1.27
|
171 kumpf 1.34 if (Array_refs.get() == 1)
172 {
173 memcpy(rep->data(), Array_data, Array_size*sizeof(PEGASUS_ARRAY_T));
174 Array_size = 0;
175 }
176 else
177 CopyToRaw(rep->data(), Array_data, Array_size);
|
178 mike 1.27
|
179 kumpf 1.34 ArrayRep<PEGASUS_ARRAY_T>::unref(Array_rep);
180 _rep = rep;
|
181 mike 1.5 }
182 }
183
184 #ifndef PEGASUS_ARRAY_T
185 template<class PEGASUS_ARRAY_T>
186 #endif
187 void Array<PEGASUS_ARRAY_T>::grow(Uint32 size, const PEGASUS_ARRAY_T& x)
188 {
|
189 mike 1.27 reserveCapacity(Array_size + size);
190 PEGASUS_ARRAY_T* p = Array_data + Array_size;
|
191 mike 1.5 Uint32 n = size;
192
193 while (n--)
|
194 kumpf 1.13 new(p++) PEGASUS_ARRAY_T(x);
|
195 mike 1.5
|
196 mike 1.27 Array_size += size;
|
197 mike 1.5 }
198
199 #ifndef PEGASUS_ARRAY_T
200 template<class PEGASUS_ARRAY_T>
201 #endif
202 void Array<PEGASUS_ARRAY_T>::swap(Array<PEGASUS_ARRAY_T>& x)
203 {
|
204 mike 1.27 ArrayRep<PEGASUS_ARRAY_T>* tmp = Array_rep;
|
205 mike 1.28 _rep = x._rep;
|
206 mike 1.5 x._rep = tmp;
207 }
208
209 #ifndef PEGASUS_ARRAY_T
210 template<class PEGASUS_ARRAY_T>
211 #endif
|
212 mike 1.27 void Array<PEGASUS_ARRAY_T>::append(const PEGASUS_ARRAY_T& x)
|
213 kumpf 1.10 {
|
214 mike 1.27 Uint32 n = Array_size + 1;
215
216 if (n > Array_capacity || Array_refs.get() != 1)
217 reserveCapacity(n);
218
219 new (Array_data + Array_size) PEGASUS_ARRAY_T(x);
220 Array_size++;
|
221 kumpf 1.10 }
222
223 #ifndef PEGASUS_ARRAY_T
224 template<class PEGASUS_ARRAY_T>
225 #endif
|
226 mike 1.27 void Array<PEGASUS_ARRAY_T>::append(const PEGASUS_ARRAY_T* x, Uint32 size)
|
227 kumpf 1.10 {
|
228 mike 1.27 Uint32 n = Array_size + size;
229 reserveCapacity(n);
230 CopyToRaw(Array_data + Array_size, x, size);
231 Array_size = n;
|
232 kumpf 1.10 }
233
234 #ifndef PEGASUS_ARRAY_T
235 template<class PEGASUS_ARRAY_T>
236 #endif
|
237 mike 1.27 void Array<PEGASUS_ARRAY_T>::appendArray(const Array<PEGASUS_ARRAY_T>& x)
|
238 kumpf 1.10 {
|
239 mike 1.27 append(x.getData(), x.size());
|
240 kumpf 1.13 }
241
242 #ifndef PEGASUS_ARRAY_T
243 template<class PEGASUS_ARRAY_T>
244 #endif
|
245 mike 1.27 void Array<PEGASUS_ARRAY_T>::prepend(const PEGASUS_ARRAY_T& x)
|
246 kumpf 1.13 {
|
247 mike 1.27 prepend(&x, 1);
|
248 kumpf 1.13 }
249
250 #ifndef PEGASUS_ARRAY_T
251 template<class PEGASUS_ARRAY_T>
252 #endif
|
253 mike 1.27 void Array<PEGASUS_ARRAY_T>::prepend(const PEGASUS_ARRAY_T* x, Uint32 size)
|
254 kumpf 1.13 {
|
255 mike 1.27 reserveCapacity(Array_size + size);
256 memmove(
|
257 kumpf 1.34 Array_data + size,
258 Array_data,
259 sizeof(PEGASUS_ARRAY_T) * Array_size);
|
260 mike 1.27 CopyToRaw(Array_data, x, size);
261 Array_size += size;
|
262 kumpf 1.10 }
263
264 #ifndef PEGASUS_ARRAY_T
265 template<class PEGASUS_ARRAY_T>
266 #endif
|
267 mike 1.27 void Array<PEGASUS_ARRAY_T>::insert(Uint32 index, const PEGASUS_ARRAY_T& x)
|
268 mike 1.5 {
|
269 mike 1.27 insert(index, &x, 1);
|
270 mike 1.5 }
271
272 #ifndef PEGASUS_ARRAY_T
273 template<class PEGASUS_ARRAY_T>
274 #endif
|
275 mike 1.27 void Array<PEGASUS_ARRAY_T>::insert(
276 Uint32 index, const PEGASUS_ARRAY_T* x, Uint32 size)
|
277 mike 1.5 {
|
278 mike 1.27 if (index > Array_size)
|
279 mike 1.29 {
|
280 mike 1.27 throw IndexOutOfBoundsException();
|
281 mike 1.29 }
|
282 mike 1.27
283 reserveCapacity(Array_size + size);
284
285 Uint32 n = Array_size - index;
286
287 if (n)
288 {
289 memmove(
|
290 kumpf 1.34 Array_data + index + size,
|
291 mike 1.27 Array_data + index,
292 sizeof(PEGASUS_ARRAY_T) * n);
293 }
294
295 CopyToRaw(Array_data + index, x, size);
296 Array_size += size;
|
297 mike 1.5 }
298
299 #ifndef PEGASUS_ARRAY_T
300 template<class PEGASUS_ARRAY_T>
301 #endif
|
302 mike 1.27 void Array<PEGASUS_ARRAY_T>::remove(Uint32 index)
|
303 kumpf 1.10 {
|
304 mike 1.27 remove(index, 1);
|
305 kumpf 1.10 }
306
307 #ifndef PEGASUS_ARRAY_T
308 template<class PEGASUS_ARRAY_T>
309 #endif
|
310 mike 1.27 void Array<PEGASUS_ARRAY_T>::remove(Uint32 index, Uint32 size)
|
311 mike 1.5 {
|
312 kumpf 1.36.2.1 if (size == 0)
313 {
314 return;
315 }
316
|
317 mike 1.27 if (Array_refs.get() != 1)
|
318 kumpf 1.34 _rep = ArrayRep<PEGASUS_ARRAY_T>::copy_on_write(Array_rep);
|
319 mike 1.27
320 // Case 1: attempting to remove last element (this is an optimization
321 // for when the array is used as a stack; see Stack class).
322
323 if (index + 1 == Array_size)
324 {
|
325 kumpf 1.34 Destroy(Array_data + index, 1);
326 Array_size--;
327 return;
|
328 mike 1.27 }
329
330 // Case 2: not attempting to remove last element:
331
332 if (index + size - 1 > Array_size)
|
333 mike 1.29 {
|
334 mike 1.27 throw IndexOutOfBoundsException();
|
335 mike 1.29 }
|
336 mike 1.27
337 Destroy(Array_data + index, size);
338 Uint32 rem = Array_size - (index + size);
339
340 if (rem)
341 {
342 memmove(
|
343 kumpf 1.34 Array_data + index,
344 Array_data + index + size,
345 sizeof(PEGASUS_ARRAY_T) * rem);
|
346 mike 1.27 }
347
348 Array_size -= size;
|
349 mike 1.5 }
350
351 #ifndef PEGASUS_ARRAY_T
352 template<class PEGASUS_ARRAY_T>
353 #endif
|
354 mike 1.27 Uint32 Array<PEGASUS_ARRAY_T>::size() const
|
355 mike 1.5 {
|
356 mike 1.27 return Array_size;
|
357 mike 1.5 }
358
359 #ifndef PEGASUS_ARRAY_T
360 template<class PEGASUS_ARRAY_T>
361 #endif
|
362 mike 1.27 PEGASUS_ARRAY_T& Array<PEGASUS_ARRAY_T>::operator[](
363 Uint32 index)
|
364 mike 1.5 {
|
365 mike 1.27 if (index >= Array_size)
366 ArrayThrowIndexOutOfBoundsException();
367
368 if (Array_refs.get() != 1)
|
369 kumpf 1.34 _rep = ArrayRep<PEGASUS_ARRAY_T>::copy_on_write(Array_rep);
|
370 mike 1.27
371 return Array_data[index];
|
372 mike 1.5 }
373
374 #ifndef PEGASUS_ARRAY_T
375 template<class PEGASUS_ARRAY_T>
376 #endif
|
377 mike 1.27 const PEGASUS_ARRAY_T& Array<PEGASUS_ARRAY_T>::operator[](
378 Uint32 index) const
|
379 mike 1.5 {
|
380 mike 1.27 if (index >= Array_size)
381 ArrayThrowIndexOutOfBoundsException();
|
382 mike 1.5
|
383 mike 1.27 return Array_data[index];
|
384 mike 1.5 }
385
386 #ifndef PEGASUS_ARRAY_T
387 template<class PEGASUS_ARRAY_T>
388 #endif
|
389 mike 1.27 Uint32 Array<PEGASUS_ARRAY_T>::getCapacity() const
|
390 mike 1.5 {
|
391 mike 1.27 return Array_capacity;
|
392 mike 1.5 }
393
394 #ifndef PEGASUS_ARRAY_T
395 template<class PEGASUS_ARRAY_T>
396 #endif
|
397 mike 1.27 const PEGASUS_ARRAY_T* Array<PEGASUS_ARRAY_T>::getData() const
|
398 mike 1.5 {
|
399 mike 1.27 return Array_data;
|
400 mike 1.5 }
|
401 kumpf 1.10
402 #ifndef PEGASUS_ARRAY_T
403 template<class PEGASUS_ARRAY_T>
404 #endif
405 PEGASUS_ARRAY_T* Array<PEGASUS_ARRAY_T>::_data() const
406 {
|
407 mike 1.27 return Array_data;
|
408 kumpf 1.10 }
|
409 mike 1.6
|
410 kumpf 1.13 #endif //!defined(Pegasus_ArrayImpl_h) || !defined(PEGASUS_ARRAY_T)
|