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

  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)

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2