(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                              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)

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2