MeVisLabToolboxReference
MeVisLab/Standard/Sources/Inventor/SoShader/Inventor/SbList.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 //-----------------------------------------------------------------------------
00003 
00004 #ifndef  _SB_LIST_
00005 #define  _SB_LIST_
00006 
00007 #include "SoShaderSystem.h"
00008 
00012 
00013 // This class is loosely derived from class SbPList.
00014 
00015 template <class Type> 
00016 class SbList
00017 {
00018    public:
00019    
00020       // Constructor
00021       SbList() {
00022          ptrs  = NULL;
00023          nPtrs = ptrsSize = 0;
00024 
00025          setSize(0);
00026       }
00027    
00028       // Constructor allocates enough room for the given number of pointers
00029       SbList(int initSize) {
00030          ptrs  = NULL;
00031          nPtrs = ptrsSize = 0;
00032 
00033          setSize(initSize);             // Makes enough room for initSize entries
00034          setSize(0);                    // Sets nPtrs back to 0
00035       }
00036    
00037       // Constructor for copying
00038       SbList(const SbList &pl) {
00039          nPtrs = pl.nPtrs;
00040          ptrsSize = pl.ptrsSize;
00041          ptrs = new Type[ptrsSize];
00042 
00043          for(int i = 0; i < nPtrs; i++)
00044             ptrs[i] = pl.ptrs[i];
00045       }
00046    
00047       // Destructor
00048       ~SbList() {
00049          delete [] ptrs;
00050       }
00051    
00052       // Adds given pointer to end of list
00053       void      append(const Type &value) {
00054          if(nPtrs + 1 > ptrsSize) expand(nPtrs + 1);
00055          ptrs[nPtrs++] = value;
00056       }
00057    
00058       // Returns index of given pointer in list, or -1 if not found
00059       int       find(const Type &value) const {
00060          for(int i = 0; i < nPtrs; i++)
00061             if(ptrs[i] == value)
00062                return(i);
00063 
00064          return -1;     // Not found
00065       }
00066    
00067       // Inserts given pointer in list before pointer with given index
00068       void      insert(const Type &value, int addBefore) {
00069          // If addBefore is off the end of the list, grow the list (and
00070          // initialize any new elements to NULL)
00071          if(addBefore > nPtrs) grow(addBefore);
00072 
00073          // Make room for one more
00074          setSize(nPtrs + 1);
00075 
00076          // Move pointers forward to make room
00077          for(int i = nPtrs - 1; i > addBefore; --i)
00078             ptrs[i] = ptrs[i - 1];
00079 
00080          // Insert the new one
00081          ptrs[addBefore] = value;
00082       }
00083    
00084       // Removes pointer with given index
00085       void      remove(int which) {
00086          // Move all pointers after the ith one backward
00087          for(int i = which; i < nPtrs - 1; i++)
00088             ptrs[i] = ptrs[i + 1];
00089 
00090          // Shrink the list
00091          setSize(nPtrs - 1);
00092       }
00093    
00094       // Returns number of pointers in list
00095       int       getLength() const {
00096          return nPtrs;
00097       }
00098    
00099       // Removes all pointers after one with given index, inclusive
00100       // ??? should really be an error check in here
00101       void      truncate(int start) {
00102          nPtrs = start;
00103       }
00104    
00105       // Copy a PList
00106       void      copy(const SbList &pl) {
00107          setSize(pl.nPtrs);
00108 
00109          for(int i = 0; i < nPtrs; i++)
00110             ptrs[i] = pl.ptrs[i];
00111       }
00112    
00113       SbList   &operator =(const SbList &pl) {
00114          copy(pl); return *this;
00115       }
00116    
00117       // Returns pointer with given index
00118       Type     &operator [](int i) const {
00119          if(i >= nPtrs) grow(i);
00120          return ptrs[i];
00121       }
00122    
00123       // equality tests
00124       int       operator ==(const SbList &pl) const {
00125          return pl.nPtrs == nPtrs ? compare(pl) : FALSE;
00126       }
00127       int       operator !=(const SbList &pl) const {
00128          return pl.nPtrs == nPtrs ? ! compare(pl) : TRUE;
00129       }
00130    
00131    // Internal versions of [] that do not check for bounds:
00132    SoINTERNAL public:
00133 
00134       void *    get(int i) const {
00135          return ptrs[i];
00136       }
00137       void      set(int i, void *j) {
00138          ptrs[i] = j;
00139       }
00140    
00141    private:
00142    
00143       // NOTE: this must be called only if the number of elements in the two
00144       // lists is the same, otherwise badness could result
00145       int       compare(const SbList &pl) const {
00146          for(int i = 0; i < nPtrs; i++)
00147          if((*this)[i] != pl[i])
00148             return FALSE;
00149 
00150          return TRUE;
00151       }
00152    
00153       Type     *ptrs;           // The collection of pointers
00154       int       nPtrs;          // Number of pointers used
00155       int       ptrsSize;       // Number of pointers allocated
00156    
00157       // There are three(!) methods to expand the list.  grow() is used
00158       // when space is dynamically created, and needs to be initialized
00159       // to NULL:
00160       void      grow(int max) const {
00161          int newSize = max+1;
00162          int oldSize = nPtrs;
00163 
00164 #ifdef DEBUG
00165          if(newSize <= oldSize)
00166             SoDebugError::post("(internal) SbList::grow", "newSize <= oldSize!");
00167 #endif // DEBUG
00168 
00169          // Get around the const thing:
00170          SbList *me = (SbList *)this;
00171 
00172          me->setSize(newSize);
00173     
00174          for(int i = oldSize; i < newSize; i++)
00175             me->ptrs[i] = NULL;
00176       }
00177    
00178       // setSize is used by grow and in other places internally where we
00179       // know that nothing needs to be initialized to NULL.
00180       void      setSize(int size) {
00181          if(size > ptrsSize) expand(size);
00182          nPtrs = size;
00183       }
00184    
00185       // expand is the lowest level routine.  It just reallocates the
00186       // array and copies over the old values.
00187       void      expand(int size) {
00188          if(ptrsSize == 0)
00189             ptrsSize = 4;
00190 
00191          while(size > ptrsSize) {
00192 #ifdef DEBUG
00193             // check for overflow
00194             int oldPtrsSize = ptrsSize;
00195             ptrsSize *= 2;
00196             if(ptrsSize < oldPtrsSize)
00197                SoDebugError::post("SbList::expand", "Attempt to expand list beyond capacity;\n A core dump is likely");
00198 #else
00199             ptrsSize *= 2;
00200 #endif
00201          }
00202 
00203          Type *newPtrs = new Type[ptrsSize];
00204 
00205          if(ptrs != NULL) {
00206             for(int i = 0; i < nPtrs; i++)
00207                newPtrs[i] = ptrs[i];
00208             delete [] ptrs;
00209          }
00210 
00211          ptrs = newPtrs;
00212       }
00213 };
00214 
00215 #endif  // _SB_LIST_