00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __DAE_ARRAY_H__
00010 #define __DAE_ARRAY_H__
00011 #include <new>
00012 #include <dae/daeMemorySystem.h>
00013
00014 class daeAtomicType;
00015
00019 class daeArray
00020 {
00021 protected:
00022 size_t _count;
00023 size_t _capacity;
00024 daeMemoryRef _data;
00025 size_t _elementSize;
00026 daeAtomicType* _type;
00027 public:
00031 DLLSPEC daeArray();
00035 virtual DLLSPEC ~daeArray();
00045 virtual DLLSPEC void clear() = 0;
00050 DLLSPEC void setElementSize(size_t elementSize);
00055 size_t getElementSize() const {return _elementSize;}
00060 virtual void setCount(size_t cnt) = 0;
00065 size_t getCount() const {return _count;}
00070 virtual void grow(size_t minCapacity) = 0;
00075 size_t getCapacity() const {return _capacity;}
00080 daeMemoryRef getRaw(size_t index) const {return _data + index*_elementSize;}
00089 virtual daeInt removeIndex(size_t index) = 0;
00090
00091
00092 void setRawCount(size_t cnt) { setCount(cnt); }
00093 daeMemoryRef getRawData() const {return _data;}
00094 };
00095
00099 template <class T>
00100 class daeTArray : public daeArray
00101 {
00102 protected:
00103 T* prototype;
00104 public:
00108 daeTArray() {
00109 _elementSize = sizeof( T );
00110 prototype = NULL;
00111 }
00115 explicit daeTArray(T* prototype) : prototype(prototype) {
00116 _elementSize = sizeof( T );
00117 }
00121 daeTArray( const daeTArray<T> &cpy ) : daeArray() {
00122 prototype = NULL;
00123 *this = cpy;
00124 }
00128 explicit daeTArray( const T &el ) {
00129 _elementSize = sizeof(T);
00130 prototype = NULL;
00131 append( el );
00132 }
00136 virtual ~daeTArray() {
00137 clear();
00138 delete prototype;
00139 }
00143 virtual void clear()
00144 {
00145 for(size_t i=0;i<_count;i++)
00146 ((T*)_data + i)->~T();
00147 free(_data);
00148 _count = 0;
00149 _capacity = 0;
00150 _data = NULL;
00151 }
00152
00157 void grow(size_t minCapacity) {
00158 if (minCapacity <= _capacity)
00159 return;
00160
00161 size_t newCapacity = _capacity == 0 ? 1 : _capacity;
00162 while(newCapacity < minCapacity)
00163 newCapacity *= 2;
00164
00165 T* newData = (T*)malloc(newCapacity*_elementSize);
00166 for (size_t i = 0; i < _count; i++) {
00167 new (&newData[i]) T(get(i));
00168 ((T*)_data + i)->~T();
00169 }
00170
00171 if (_data != NULL)
00172 free(_data);
00173
00174 _data = (daeMemoryRef)newData;
00175 _capacity = newCapacity;
00176 }
00177
00186 virtual daeInt removeIndex(size_t index)
00187 {
00188 if (index >= _count)
00189 return(DAE_ERR_INVALID_CALL);
00190
00191 for (size_t i = index; i < _count-1; i++)
00192 *((T*)_data+i) = *((T*)_data+i+1);
00193 ((T*)_data+(_count-1))->~T();
00194 _count--;
00195 return DAE_OK;
00196 }
00197
00205 void setCount(size_t nElements, const T& value)
00206 {
00207 grow(nElements);
00208
00209 for (size_t i = nElements; i < _count; i++)
00210 ((T*)_data+i)->~T();
00211
00212 for (size_t i = _count; i < nElements; i++)
00213 new ((void*)((T*)_data+i)) T(value);
00214 _count = nElements;
00215 }
00216
00223 virtual void setCount(size_t nElements) {
00224 if (prototype)
00225 setCount(nElements, *prototype);
00226 else
00227 setCount(nElements, T());
00228 }
00229
00235 void set(size_t index, const T& value) {
00236 if (index >= _count)
00237 setCount(index+1);
00238 ((T*)_data)[index] = value;
00239 }
00240
00246 T& get(size_t index) {
00247 assert(index < _count);
00248 return ((T*)_data)[index]; }
00254 const T& get(size_t index) const {
00255 assert(index < _count);
00256 return ((T*)_data)[index]; }
00257
00263 size_t append(const T& value) {
00264 set(_count, value);
00265 return _count-1;
00266 }
00267
00275 size_t appendUnique(const T& value) {
00276 size_t ret;
00277 if (find(value,ret) != DAE_OK)
00278 return append(value);
00279 else
00280 return ret;
00281 }
00282
00287 void prepend(const T& value) {
00288 insertAt(0, value);
00289 }
00290
00299 daeInt remove(const T& value, size_t *idx = NULL )
00300 {
00301 size_t index;
00302 if(find(value,index) == DAE_OK)
00303 {
00304 if ( idx != NULL ) {
00305 *idx = index;
00306 }
00307 return(removeIndex( index ));
00308 }
00309 else
00310 {
00311 return(DAE_ERR_INVALID_CALL);
00312 }
00313 }
00320 daeInt find(const T& value, size_t &index) const
00321 {
00322 size_t i;
00323 for(i=0;i<_count;i++)
00324 {
00325 if (((T*)_data)[i] == value)
00326 {
00327 index = i;
00328 return DAE_OK;
00329 }
00330 }
00331
00332 return DAE_ERR_QUERY_NO_MATCH;
00333 }
00339 T* find(const T& value) const {
00340 size_t i;
00341 if (find(value, i) == DAE_OK)
00342 return get(i);
00343 return NULL;
00344 }
00350 T& operator[](size_t index) {
00351 assert(index < _count);
00352 return ((T*)_data)[index]; }
00358 const T& operator[](size_t index) const {
00359 assert(index < _count);
00360 return ((T*)_data)[index]; }
00361
00368 void insert(size_t index, size_t n, const T& val = T()) {
00369 if (index >= _count) {
00370
00371 size_t oldCount = _count;
00372 setCount(index + n);
00373 for (size_t i = oldCount; i < _count; i++)
00374 get(i) = val;
00375 }
00376 else {
00377 setCount(_count + n);
00378 for (size_t i = _count-1; i >= index+n; i--)
00379 get(i) = get(i-n);
00380 for (size_t i = index; i < index+n; i++)
00381 get(i) = val;
00382 }
00383 }
00384
00390 void insertAt(size_t index, const T& value) {
00391 insert(index, 1);
00392 get(index) = value;
00393 }
00394
00400 daeTArray<T> &operator=( const daeTArray<T> &other ) {
00401 if (this != &other) {
00402 clear();
00403 _elementSize = other._elementSize;
00404 _type = other._type;
00405 grow(other._count);
00406 for(size_t i=0;i<other._count;i++)
00407 append(other[i]);
00408 }
00409
00410 return *this;
00411 }
00412
00418 bool operator==(const daeTArray<T>& other) {
00419 if (getCount() != other.getCount())
00420 return false;
00421 for (size_t i = 0; i < getCount(); i++)
00422 if (get(i) != other.get(i))
00423 return false;
00424 return true;
00425 }
00426
00427
00433 void set2( const T &one, const T &two )
00434 {
00435 setCount( 2 );
00436 set( 0, one );
00437 set( 1, two );
00438 }
00445 void set3( const T &one, const T &two, const T &three )
00446 {
00447 setCount( 3 );
00448 set( 0, one );
00449 set( 1, two );
00450 set( 2, three );
00451 }
00459 void set4( const T &one, const T &two, const T &three, const T &four )
00460 {
00461 setCount( 4 );
00462 set( 0, one );
00463 set( 1, two );
00464 set( 2, three );
00465 set( 3, four );
00466 }
00467
00475 void set2at( size_t index, const T &one, const T &two )
00476 {
00477 set( index, one );
00478 set( index+1, two );
00479 }
00488 void set3at( size_t index, const T &one, const T &two, const T &three )
00489 {
00490 set( index, one );
00491 set( index+1, two );
00492 set( index+2, three );
00493 }
00503 void set4at( size_t index, const T &one, const T &two, const T &three, const T &four )
00504 {
00505 set( index, one );
00506 set( index+1, two );
00507 set( index+2, three );
00508 set( index+3, four );
00509 }
00510
00516 void append2( const T &one, const T &two )
00517 {
00518 append( one );
00519 append( two );
00520 }
00527 void append3( const T &one, const T &two, const T &three )
00528 {
00529 append( one );
00530 append( two );
00531 append( three );
00532 }
00540 void append4( const T &one, const T &two, const T &three, const T &four )
00541 {
00542 append( one );
00543 append( two );
00544 append( three );
00545 append( four );
00546 }
00547
00554 void insert2at( size_t index, const T &one, const T &two )
00555 {
00556 insert(index, 2);
00557 set(index, one);
00558 set(index+1, two);
00559 }
00567 void insert3at( size_t index, const T &one, const T &two, const T &three )
00568 {
00569 insert(index, 3);
00570 set( index, one );
00571 set( index+1, two );
00572 set( index+2, three );
00573 }
00582 void insert4at( size_t index, const T &one, const T &two, const T &three, const T &four )
00583 {
00584 insert(index, 4);
00585 set( index, one );
00586 set( index+1, two );
00587 set( index+2, three );
00588 set( index+4, four );
00589 }
00590
00598 daeInt get2at( size_t index, T &one, T &two )
00599 {
00600 daeInt retVal = 0;
00601 if ( index < _count )
00602 {
00603 one = get(index);
00604 retVal++;
00605 }
00606 if ( index+1 < _count )
00607 {
00608 two = get(index+1);
00609 retVal++;
00610 }
00611 return retVal;
00612 }
00621 daeInt get3at( size_t index, T &one, T &two, T &three )
00622 {
00623 daeInt retVal = 0;
00624 if ( index < _count )
00625 {
00626 one = get(index);
00627 retVal++;
00628 }
00629 if ( index+1 < _count )
00630 {
00631 two = get(index+1);
00632 retVal++;
00633 }
00634 if ( index+2 < _count )
00635 {
00636 three = get(index+2);
00637 retVal++;
00638 }
00639 return retVal;
00640 }
00650 daeInt get4at( size_t index, T &one, T &two, T &three, T &four )
00651 {
00652 daeInt retVal = 0;
00653 if ( index < _count )
00654 {
00655 one = get(index);
00656 retVal++;
00657 }
00658 if ( index+1 < _count )
00659 {
00660 two = get(index+1);
00661 retVal++;
00662 }
00663 if ( index+2 < _count )
00664 {
00665 three = get(index+2);
00666 retVal++;
00667 }
00668 if ( index+3 < _count )
00669 {
00670 four = get(index+3);
00671 retVal++;
00672 }
00673 return retVal;
00674 }
00675
00681 void appendArray( size_t num, T *array )
00682 {
00683 if ( array == NULL )
00684 return;
00685
00686 for ( size_t i = 0; i < num; i++ )
00687 append( array[i] );
00688 }
00693 void appendArray( const daeTArray<T> &array ){
00694 size_t num = array.getCount();
00695 for ( size_t i = 0; i < num; i++ )
00696 append( array[i] );
00697 }
00698 };
00699
00700
00701 #endif //__DAE_ARRAY_H__