00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __rdArray_h__
00010 #define __rdArray_h__
00011
00012
00013 #include "rdTools.h"
00014 #include "rdException.h"
00015
00016 static const int rdArray_CAPMIN = 1;
00017
00018
00019
00030 template<class T> class rdArray
00031 {
00032
00033
00034
00035
00036 protected:
00038 int _size;
00040 int _capacity;
00043 int _capacityIncrement;
00045 T _defaultValue;
00047 T *_array;
00048
00049
00050
00051
00052
00053
00054
00055 public:
00056
00063 virtual ~rdArray()
00064 {
00065 if(_array!=NULL) { delete[] _array; _array = NULL; }
00066 }
00067
00079 rdArray(const T &aDefaultValue,int aSize=0,int aCapacity=rdArray_CAPMIN)
00080 {
00081 setNull();
00082
00083
00084 _defaultValue = aDefaultValue;
00085
00086
00087 int newCapacity;
00088 int min = aSize + 1;
00089 if(min < aCapacity) min = aCapacity;
00090 computeNewCapacity(min,newCapacity);
00091 ensureCapacity(newCapacity);
00092
00093
00094 _size = aSize;
00095 if(_size<0) _size=0;
00096 }
00097
00103 rdArray(const rdArray<T> &aArray)
00104 {
00105 setNull();
00106 *this = aArray;
00107 }
00108
00109 private:
00110
00114 void setNull()
00115 {
00116 _size = 0;
00117 _capacityIncrement = -1;
00118 _capacity = 0;
00119 _array = NULL;
00120 }
00121
00122
00123
00124
00125
00126 public:
00127
00128
00129
00130
00147 T& operator[](int aIndex) const
00148 {
00149 return(_array[aIndex]);
00150 }
00151
00152
00153
00154
00155
00164 rdArray<T>& operator=(const rdArray<T> &aArray)
00165 {
00166 _size = aArray._size;
00167 _capacity = aArray._capacity;
00168 _capacityIncrement = aArray._capacityIncrement;
00169 _defaultValue = aArray._defaultValue;
00170
00171
00172 if(_array!=NULL) delete[] _array;
00173 _array = new T[_capacity];
00174 for(int i=0;i<_capacity;i++) _array[i] = aArray._array[i];
00175
00176 return(*this);
00177 }
00178
00179
00180
00181
00182
00183
00205 bool computeNewCapacity(int aMinCapacity,int &rNewCapacity)
00206 {
00207 rNewCapacity = _capacity;
00208 if(rNewCapacity < rdArray_CAPMIN) rNewCapacity = rdArray_CAPMIN;
00209
00210
00211 if(_capacityIncrement == 0) {
00212 printf("rdArray.computeNewCapacity: WARN- capacity is set");
00213 printf(" not to increase (i.e., _capacityIncrement==0).\n");
00214 return(false);
00215 }
00216
00217
00218 while(rNewCapacity < aMinCapacity) {
00219 if(_capacityIncrement < 0) {
00220 rNewCapacity = 2 * rNewCapacity;
00221 } else {
00222 rNewCapacity = rNewCapacity + _capacityIncrement;
00223 }
00224 }
00225
00226 return(true);
00227 }
00228
00236 bool ensureCapacity(int aCapacity)
00237 {
00238
00239 if(aCapacity < rdArray_CAPMIN) aCapacity = rdArray_CAPMIN;
00240 if(_capacity>=aCapacity) return(true);
00241
00242
00243 int i;
00244 T *newArray = new T[aCapacity];
00245 if(newArray==NULL) {
00246 printf("rdArray.ensureCapacity: ERR- failed to increase capacity.\n");
00247 return(false);
00248 }
00249
00250
00251 if(_array!=NULL) {
00252 for(i=0;i<_size;i++) newArray[i] = _array[i];
00253 for(i=_size;i<aCapacity;i++) newArray[i] = _defaultValue;
00254 delete []_array; _array=NULL;
00255 } else {
00256 for(i=0;i<aCapacity;i++) newArray[i] = _defaultValue;
00257 }
00258
00259
00260 _capacity = aCapacity;
00261 _array = newArray;
00262
00263 return(true);
00264 }
00265
00273 void trim()
00274 {
00275
00276 int newCapacity = _size + 1;
00277 if(newCapacity>=_capacity) return;
00278 if(newCapacity<rdArray_CAPMIN) newCapacity = rdArray_CAPMIN;
00279
00280
00281 int i;
00282 T *array = new T[newCapacity];
00283 if(array==NULL) {
00284 printf("rdArray.trim: ERR- unable to allocate temporary array.\n");
00285 return;
00286 }
00287
00288
00289 for(i=0;i<_size;i++) array[i] = _array[i];
00290
00291
00292 delete[] _array;
00293
00294
00295 _array = new T[newCapacity];
00296 if(_array==NULL) {
00297 printf("rdArray.trim: ERR- unable to allocate array.\n");
00298 return;
00299 }
00300
00301
00302 for(i=0;i<_size;i++) _array[i] = array[i];
00303 _array[_size] = _defaultValue;
00304
00305
00306 _capacity = newCapacity;
00307 }
00308
00312 int getCapacity() const
00313 {
00314 return(_capacity);
00315 }
00316
00317
00318
00319
00320
00330 void setCapacityIncrement(int aIncrement)
00331 {
00332 _capacityIncrement = aIncrement;
00333 }
00334
00338 int getCapacityIncrement() const
00339 {
00340 return(_capacityIncrement);
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00364 bool setSize(int aSize)
00365 {
00366 if(aSize==_size) return(true);
00367 if(aSize<0) aSize = 0;
00368 bool success = true;
00369 if(aSize<_size) {
00370 int i;
00371 for(i=(_size-1);i>=aSize;i--) _array[i] = _defaultValue;
00372 _size = aSize;
00373 } else if(aSize<=_capacity) {
00374 _size = aSize;
00375 } else {
00376 int newCapacity;
00377 success = computeNewCapacity(aSize+1,newCapacity);
00378 if(!success) return(false);
00379 success = ensureCapacity(newCapacity);
00380 if(success) _size = aSize;
00381 }
00382
00383 return(success);
00384 }
00385
00391 int getSize() const
00392 {
00393 return(_size);
00394 }
00395
00396
00397
00398
00399
00406 int append(const T &aValue)
00407 {
00408
00409 if((_size+1)>=_capacity) {
00410 int newCapacity;
00411 bool success;
00412 success = computeNewCapacity(_size+1,newCapacity);
00413 if(!success) return(_size);
00414 success = ensureCapacity(newCapacity);
00415 if(!success) return(_size);
00416 }
00417
00418
00419 _array[_size] = aValue;
00420 _size++;
00421
00422 return(_size);
00423 }
00424
00428 int append(const rdArray<T> &aArray)
00429 {
00430
00431 int i,n=aArray.getSize();
00432 for(i=0;i<n;i++) {
00433 append(aArray[i]);
00434 }
00435
00436 return(_size);
00437 }
00438
00439
00440
00441
00442
00458 int insert(int aIndex,const T &aValue)
00459 {
00460
00461 if(aIndex<0) {
00462 printf("rdArray.insert: ERR- aIndex was less than 0.\n");
00463 return(_size);
00464 }
00465
00466
00467 if(aIndex>=_size) {
00468 setSize(aIndex+1);
00469 _array[aIndex] = aValue;
00470 return(_size);
00471 }
00472
00473
00474 if((_size+1)>=_capacity) {
00475 int newCapacity;
00476 bool success;
00477 success = computeNewCapacity(_size+1,newCapacity);
00478 if(!success) return(_size);
00479 success = ensureCapacity(newCapacity);
00480 if(!success) return(_size);
00481 }
00482
00483
00484 int i;
00485 for(i=_size;i>aIndex;i--) {
00486 _array[i] = _array[i-1];
00487 }
00488
00489
00490 _array[aIndex] = aValue;
00491 _size++;
00492
00493 return(_size);
00494 }
00495
00496
00497
00498
00499
00512 int remove(int aIndex)
00513 {
00514 if(aIndex<0) {
00515 printf("rdArray.remove: ERR- aIndex was less than 0.\n");
00516 return(_size);
00517 }
00518 if(aIndex>=_size) {
00519 printf("rdArray.remove: ERR- aIndex was greater than or equal the ");
00520 printf("size of the array.\n");
00521 return(_size);
00522 }
00523
00524
00525 int i;
00526 _size--;
00527 for(i=aIndex;i<_size;i++) {
00528 _array[i] = _array[i+1];
00529 }
00530 _array[_size] = _defaultValue;
00531
00532
00533 return(_size);
00534 }
00535
00536
00537
00538
00539
00549 void set(int aIndex,const T &aValue)
00550 {
00551 if(aIndex<0) return;
00552
00553
00554 bool success = false;
00555 if((aIndex+2)>=_capacity) {
00556 int newCapacity;
00557 success = computeNewCapacity(aIndex+2,newCapacity);
00558 if(!success) return;
00559 success = ensureCapacity(newCapacity);
00560 if(!success) return;
00561 }
00562
00563
00564 _array[aIndex] = aValue;
00565
00566
00567 if(aIndex>=_size) _size = aIndex+1;
00568 }
00569
00584 T& get(int aIndex) const
00585 {
00586 if((aIndex<0)||(aIndex>=_size)) {
00587 throw(rdException("Array index out of bounds."));
00588 }
00589 return(_array[aIndex]);
00590 }
00591
00598 T& getLast() const
00599 {
00600 if(_size<=0) {
00601 throw(rdException("Array is empty."));
00602 }
00603 return(_array[_size-1]);
00604 }
00605
00606
00607
00608
00609
00610
00611
00612
00613
00644 int searchBinary(const T &aValue,bool aFindFirst=false,
00645 int aLo=-1,int aHi=-1) const
00646 {
00647 if(_size<=0) return(-1);
00648 int lo = aLo; if(lo<0) lo = 0;
00649 int hi = aHi; if((hi<0)||(hi>=_size)) hi = _size - 1;
00650 int mid;
00651
00652
00653 if(lo>hi) return(-1);
00654
00655
00656 while(lo <= hi) {
00657 mid = (lo + hi) / 2;
00658 if(aValue < _array[mid]) {
00659 hi = mid - 1;
00660 } else if(_array[mid] < aValue) {
00661 lo = mid + 1;
00662 } else {
00663 break;
00664 }
00665 }
00666
00667
00668 if(aValue < _array[mid]) mid--;
00669 if(mid<=0) {
00670 return(mid);
00671 }
00672
00673
00674 if(aFindFirst) {
00675 if(_array[mid-1]<_array[mid]) {
00676 return(mid);
00677 }
00678 lo = aLo; if(lo<0) lo = 0;
00679 hi = mid;
00680 int mid2 = mid;
00681 T value2 = _array[mid];
00682 while(lo <= hi) {
00683 mid2 = (lo + hi) / 2;
00684 if(_array[mid2] == value2) {
00685 hi = mid2 - 1;
00686 } else if(_array[mid2] < value2) {
00687 lo = mid2 + 1;
00688 }
00689 }
00690 if(_array[mid2]<value2) mid2++;
00691 if(mid2<mid) mid = mid2;
00692 }
00693
00694 return(mid);
00695 }
00696
00697
00698 };
00699
00700
00701
00702
00703 #endif //__rdArray_h__