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 dev.meetei 1.38 memcpy(
174 (void*)rep->data(),
175 (void*)Array_data,
176 Array_size*sizeof(PEGASUS_ARRAY_T));
|
177 kumpf 1.34 Array_size = 0;
178 }
179 else
180 CopyToRaw(rep->data(), Array_data, Array_size);
|
181 mike 1.27
|
182 kumpf 1.34 ArrayRep<PEGASUS_ARRAY_T>::unref(Array_rep);
183 _rep = rep;
|
184 mike 1.5 }
185 }
186
187 #ifndef PEGASUS_ARRAY_T
188 template<class PEGASUS_ARRAY_T>
189 #endif
190 void Array<PEGASUS_ARRAY_T>::grow(Uint32 size, const PEGASUS_ARRAY_T& x)
191 {
|
192 mike 1.27 reserveCapacity(Array_size + size);
193 PEGASUS_ARRAY_T* p = Array_data + Array_size;
|
194 mike 1.5 Uint32 n = size;
195
196 while (n--)
|
197 kumpf 1.13 new(p++) PEGASUS_ARRAY_T(x);
|
198 mike 1.5
|
199 mike 1.27 Array_size += size;
|
200 mike 1.5 }
201
202 #ifndef PEGASUS_ARRAY_T
203 template<class PEGASUS_ARRAY_T>
204 #endif
205 void Array<PEGASUS_ARRAY_T>::swap(Array<PEGASUS_ARRAY_T>& x)
206 {
|
207 mike 1.27 ArrayRep<PEGASUS_ARRAY_T>* tmp = Array_rep;
|
208 mike 1.28 _rep = x._rep;
|
209 mike 1.5 x._rep = tmp;
210 }
211
212 #ifndef PEGASUS_ARRAY_T
213 template<class PEGASUS_ARRAY_T>
214 #endif
|
215 mike 1.27 void Array<PEGASUS_ARRAY_T>::append(const PEGASUS_ARRAY_T& x)
|
216 kumpf 1.10 {
|
217 mike 1.27 Uint32 n = Array_size + 1;
218
219 if (n > Array_capacity || Array_refs.get() != 1)
220 reserveCapacity(n);
221
222 new (Array_data + Array_size) PEGASUS_ARRAY_T(x);
223 Array_size++;
|
224 kumpf 1.10 }
225
226 #ifndef PEGASUS_ARRAY_T
227 template<class PEGASUS_ARRAY_T>
228 #endif
|
229 mike 1.27 void Array<PEGASUS_ARRAY_T>::append(const PEGASUS_ARRAY_T* x, Uint32 size)
|
230 kumpf 1.10 {
|
231 mike 1.27 Uint32 n = Array_size + size;
232 reserveCapacity(n);
233 CopyToRaw(Array_data + Array_size, x, size);
234 Array_size = n;
|
235 kumpf 1.10 }
236
237 #ifndef PEGASUS_ARRAY_T
238 template<class PEGASUS_ARRAY_T>
239 #endif
|
240 mike 1.27 void Array<PEGASUS_ARRAY_T>::appendArray(const Array<PEGASUS_ARRAY_T>& x)
|
241 kumpf 1.10 {
|
242 mike 1.27 append(x.getData(), x.size());
|
243 kumpf 1.13 }
244
245 #ifndef PEGASUS_ARRAY_T
246 template<class PEGASUS_ARRAY_T>
247 #endif
|
248 mike 1.27 void Array<PEGASUS_ARRAY_T>::prepend(const PEGASUS_ARRAY_T& x)
|
249 kumpf 1.13 {
|
250 mike 1.27 prepend(&x, 1);
|
251 kumpf 1.13 }
252
253 #ifndef PEGASUS_ARRAY_T
254 template<class PEGASUS_ARRAY_T>
255 #endif
|
256 mike 1.27 void Array<PEGASUS_ARRAY_T>::prepend(const PEGASUS_ARRAY_T* x, Uint32 size)
|
257 kumpf 1.13 {
|
258 mike 1.27 reserveCapacity(Array_size + size);
259 memmove(
|
260 dev.meetei 1.38 (void*)(Array_data + size),
261 (void*)Array_data,
|
262 kumpf 1.34 sizeof(PEGASUS_ARRAY_T) * Array_size);
|
263 mike 1.27 CopyToRaw(Array_data, x, size);
264 Array_size += size;
|
265 kumpf 1.10 }
266
267 #ifndef PEGASUS_ARRAY_T
268 template<class PEGASUS_ARRAY_T>
269 #endif
|
270 mike 1.27 void Array<PEGASUS_ARRAY_T>::insert(Uint32 index, const PEGASUS_ARRAY_T& x)
|
271 mike 1.5 {
|
272 mike 1.27 insert(index, &x, 1);
|
273 mike 1.5 }
274
275 #ifndef PEGASUS_ARRAY_T
276 template<class PEGASUS_ARRAY_T>
277 #endif
|
278 mike 1.27 void Array<PEGASUS_ARRAY_T>::insert(
279 Uint32 index, const PEGASUS_ARRAY_T* x, Uint32 size)
|
280 mike 1.5 {
|
281 mike 1.27 if (index > Array_size)
|
282 mike 1.29 {
|
283 mike 1.27 throw IndexOutOfBoundsException();
|
284 mike 1.29 }
|
285 mike 1.27
286 reserveCapacity(Array_size + size);
287
288 Uint32 n = Array_size - index;
289
290 if (n)
291 {
292 memmove(
|
293 kumpf 1.34 Array_data + index + size,
|
294 mike 1.27 Array_data + index,
295 sizeof(PEGASUS_ARRAY_T) * n);
296 }
297
298 CopyToRaw(Array_data + index, x, size);
299 Array_size += size;
|
300 mike 1.5 }
301
302 #ifndef PEGASUS_ARRAY_T
303 template<class PEGASUS_ARRAY_T>
304 #endif
|
305 mike 1.27 void Array<PEGASUS_ARRAY_T>::remove(Uint32 index)
|
306 kumpf 1.10 {
|
307 mike 1.27 remove(index, 1);
|
308 kumpf 1.10 }
309
310 #ifndef PEGASUS_ARRAY_T
311 template<class PEGASUS_ARRAY_T>
312 #endif
|
313 mike 1.27 void Array<PEGASUS_ARRAY_T>::remove(Uint32 index, Uint32 size)
|
314 mike 1.5 {
|
315 kumpf 1.37 if (size == 0)
316 {
317 return;
318 }
319
|
320 mike 1.27 if (Array_refs.get() != 1)
|
321 kumpf 1.34 _rep = ArrayRep<PEGASUS_ARRAY_T>::copy_on_write(Array_rep);
|
322 mike 1.27
323 // Case 1: attempting to remove last element (this is an optimization
324 // for when the array is used as a stack; see Stack class).
325
326 if (index + 1 == Array_size)
327 {
|
328 kumpf 1.34 Destroy(Array_data + index, 1);
329 Array_size--;
330 return;
|
331 mike 1.27 }
332
333 // Case 2: not attempting to remove last element:
334
335 if (index + size - 1 > Array_size)
|
336 mike 1.29 {
|
337 mike 1.27 throw IndexOutOfBoundsException();
|
338 mike 1.29 }
|
339 mike 1.27
340 Destroy(Array_data + index, size);
341 Uint32 rem = Array_size - (index + size);
342
343 if (rem)
344 {
345 memmove(
|
346 kumpf 1.34 Array_data + index,
347 Array_data + index + size,
348 sizeof(PEGASUS_ARRAY_T) * rem);
|
349 mike 1.27 }
350
351 Array_size -= size;
|
352 mike 1.5 }
353
354 #ifndef PEGASUS_ARRAY_T
355 template<class PEGASUS_ARRAY_T>
356 #endif
|
357 mike 1.27 Uint32 Array<PEGASUS_ARRAY_T>::size() const
|
358 mike 1.5 {
|
359 mike 1.27 return Array_size;
|
360 mike 1.5 }
361
362 #ifndef PEGASUS_ARRAY_T
363 template<class PEGASUS_ARRAY_T>
364 #endif
|
365 mike 1.27 PEGASUS_ARRAY_T& Array<PEGASUS_ARRAY_T>::operator[](
366 Uint32 index)
|
367 mike 1.5 {
|
368 mike 1.27 if (index >= Array_size)
369 ArrayThrowIndexOutOfBoundsException();
370
371 if (Array_refs.get() != 1)
|
372 kumpf 1.34 _rep = ArrayRep<PEGASUS_ARRAY_T>::copy_on_write(Array_rep);
|
373 mike 1.27
374 return Array_data[index];
|
375 mike 1.5 }
376
377 #ifndef PEGASUS_ARRAY_T
378 template<class PEGASUS_ARRAY_T>
379 #endif
|
380 mike 1.27 const PEGASUS_ARRAY_T& Array<PEGASUS_ARRAY_T>::operator[](
381 Uint32 index) const
|
382 mike 1.5 {
|
383 mike 1.27 if (index >= Array_size)
384 ArrayThrowIndexOutOfBoundsException();
|
385 mike 1.5
|
386 mike 1.27 return Array_data[index];
|
387 mike 1.5 }
388
389 #ifndef PEGASUS_ARRAY_T
390 template<class PEGASUS_ARRAY_T>
391 #endif
|
392 mike 1.27 Uint32 Array<PEGASUS_ARRAY_T>::getCapacity() const
|
393 mike 1.5 {
|
394 mike 1.27 return Array_capacity;
|
395 mike 1.5 }
396
397 #ifndef PEGASUS_ARRAY_T
398 template<class PEGASUS_ARRAY_T>
399 #endif
|
400 mike 1.27 const PEGASUS_ARRAY_T* Array<PEGASUS_ARRAY_T>::getData() const
|
401 mike 1.5 {
|
402 mike 1.27 return Array_data;
|
403 mike 1.5 }
|
404 kumpf 1.10
405 #ifndef PEGASUS_ARRAY_T
406 template<class PEGASUS_ARRAY_T>
407 #endif
408 PEGASUS_ARRAY_T* Array<PEGASUS_ARRAY_T>::_data() const
409 {
|
410 mike 1.27 return Array_data;
|
411 kumpf 1.10 }
|
412 mike 1.6
|
413 kumpf 1.13 #endif //!defined(Pegasus_ArrayImpl_h) || !defined(PEGASUS_ARRAY_T)
|