Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   Related Pages  

rdArray.h

00001 // rdArray.h
00002 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00003 // Copyright 2003 Realistic Dynamics, Inc.
00004 // All rights reserved.
00005 //
00006 // Please do not read, copy, distribute, or use without permission.
00007 // Contact: Frank C. Anderson, fca@RealisticDynamics.com
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 // DATA
00035 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00036 protected:
00038    int _size;
00040    int _capacity;
00043    int _capacityIncrement;
00045    T _defaultValue;
00047    T *_array;
00048 
00049 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00050 // METHODS
00051 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00052 //=============================================================================
00053 // CONTRUCTION
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    // DEFAULT VALUE
00084    _defaultValue = aDefaultValue;
00085 
00086    // CAPACITY
00087    int newCapacity;
00088    int min = aSize + 1;
00089    if(min < aCapacity) min = aCapacity;
00090    computeNewCapacity(min,newCapacity);
00091    ensureCapacity(newCapacity);
00092 
00093    // SIZE
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 // OPERATORS
00125 //=============================================================================
00126 public:
00127 //-----------------------------------------------------------------------------
00128 // BRACKETS ([])
00129 //-----------------------------------------------------------------------------
00130 //_____________________________________________________________________________
00147 T& operator[](int aIndex) const
00148 {
00149    return(_array[aIndex]);
00150 }
00151 
00152 //-----------------------------------------------------------------------------
00153 // ASSIGNMENT (=)
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    // ARRAY
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 // CAPACITY
00182 //=============================================================================
00183 //_____________________________________________________________________________
00205 bool computeNewCapacity(int aMinCapacity,int &rNewCapacity)
00206 {
00207    rNewCapacity = _capacity;
00208    if(rNewCapacity < rdArray_CAPMIN) rNewCapacity = rdArray_CAPMIN;
00209 
00210    // CHECK FOR ZERO INCREMENT
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    // INCREMENT UNTIL LARGER THAN THE MINIMUM SIZE
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    // CHECK REQUESTED CAPACITY
00239    if(aCapacity < rdArray_CAPMIN) aCapacity = rdArray_CAPMIN;
00240    if(_capacity>=aCapacity) return(true);
00241 
00242    // ALLOCATE THE NEW ARRAY
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    // COPY CURRENT ARRAY
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    // REASSIGN
00260    _capacity = aCapacity;
00261    _array = newArray;
00262 
00263    return(true);
00264 }
00265 //_____________________________________________________________________________
00273 void trim()
00274 {
00275    // COMPUTE NEW CAPACITY
00276    int newCapacity = _size + 1;
00277    if(newCapacity>=_capacity) return;
00278    if(newCapacity<rdArray_CAPMIN) newCapacity = rdArray_CAPMIN;
00279 
00280    // ALLOCATE TEMPORARY ARRAY
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    // COPY CURRENT ARRAY
00289    for(i=0;i<_size;i++) array[i] = _array[i];
00290 
00291    // DELETE OLD ARRAY
00292    delete[] _array;
00293 
00294    // ALLOCATE NEW ARRAY
00295    _array = new T[newCapacity];
00296    if(_array==NULL) {
00297       printf("rdArray.trim: ERR- unable to allocate array.\n");
00298       return;
00299    }
00300 
00301    // RESET PREVIOUS VALUES
00302    for(i=0;i<_size;i++) _array[i] = array[i];
00303    _array[_size] = _defaultValue;
00304 
00305    // SET CORRECT CAPACITY
00306    _capacity = newCapacity;
00307 }
00308 //_____________________________________________________________________________
00312 int getCapacity() const
00313 {
00314    return(_capacity);
00315 }
00316 
00317 //-----------------------------------------------------------------------------
00318 // CAPACITY INCREMENT
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 // STORAGE OPERATIONS
00345 //=============================================================================
00346 //-----------------------------------------------------------------------------
00347 // SIZE
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 // APPEND
00398 //-----------------------------------------------------------------------------
00399 //_____________________________________________________________________________
00406 int append(const T &aValue)
00407 {
00408    // ENSURE CAPACITY
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    // SET
00419    _array[_size] = aValue;
00420    _size++;
00421 
00422    return(_size);
00423 }
00424 //_____________________________________________________________________________
00428 int append(const rdArray<T> &aArray)
00429 {
00430    // LOOP THROUGH THE ELEMENTS
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 // INSERT
00441 //-----------------------------------------------------------------------------
00442 //_____________________________________________________________________________
00458 int insert(int aIndex,const T &aValue)
00459 {
00460    // NEGATIVE INDEX
00461    if(aIndex<0) {
00462       printf("rdArray.insert: ERR- aIndex was less than 0.\n");
00463       return(_size);
00464    }
00465 
00466    // INDEX PAST END OF ARRAY
00467    if(aIndex>=_size) {
00468       setSize(aIndex+1);
00469       _array[aIndex] = aValue;
00470       return(_size);
00471    }
00472 
00473    // ENSURE CAPACITY
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    // SHIFT ARRAY
00484    int i;
00485    for(i=_size;i>aIndex;i--) {
00486       _array[i] = _array[i-1];
00487    }
00488 
00489    // SET
00490    _array[aIndex] = aValue;
00491    _size++;
00492 
00493    return(_size);
00494 }
00495 
00496 //-----------------------------------------------------------------------------
00497 // REMOVE
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    // SHIFT ARRAY
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 // SET AND GET
00538 //-----------------------------------------------------------------------------
00539 //_____________________________________________________________________________
00549 void set(int aIndex,const T &aValue)
00550 {
00551    if(aIndex<0) return;
00552 
00553    // ENSURE CAPACITY
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    // SET
00564    _array[aIndex] = aValue;
00565 
00566    // FIRST EMPTY
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    //void insert(int aIndex,const T &aValue);
00606    //void remove(int aIndex);
00607    //void remove(const T &aValue);
00608 
00609 
00610 //=============================================================================
00611 // SEARCH
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    // CHECK lo AND hi
00653    if(lo>hi) return(-1);
00654 
00655    // SEARCH
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    // MAKE SURE LESS THAN
00668    if(aValue < _array[mid]) mid--;
00669    if(mid<=0) {
00670       return(mid);
00671    }
00672 
00673    // FIND FIRST
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 }; // END of class rdArray
00699 //=============================================================================
00700 //=============================================================================
00701 
00702 
00703 #endif //__rdArray_h__

Generated on Wed Aug 20 02:17:05 2003 for Simulation Software by doxygen1.3