00001 #ifndef COIN_SBLIST_H
00002 #define COIN_SBLIST_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <Inventor/SbBasic.h>
00028 #include <assert.h>
00029 #include <stddef.h>
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifdef _MSC_VER // Microsoft Visual C++
00042 #pragma warning(disable:4251)
00043 #pragma warning(disable:4275)
00044 #endif // _MSC_VER
00045
00046 template <class Type>
00047 class SbList {
00048
00049
00050
00051 enum { DEFAULTSIZE = 4 };
00052
00053 public:
00054
00055 SbList(const int sizehint = DEFAULTSIZE)
00056 : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) {
00057 if (sizehint > DEFAULTSIZE) this->grow(sizehint);
00058 }
00059
00060 SbList(const SbList<Type> & l)
00061 : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) {
00062 this->copy(l);
00063 }
00064
00065 ~SbList() {
00066 if (this->itembuffer != builtinbuffer) delete[] this->itembuffer;
00067 }
00068
00069 void copy(const SbList<Type> & l) {
00070 if (this == &l) return;
00071 const int n = l.numitems;
00072 this->expand(n);
00073 for (int i = 0; i < n; i++) this->itembuffer[i] = l.itembuffer[i];
00074 }
00075
00076 SbList <Type> & operator=(const SbList<Type> & l) {
00077 this->copy(l);
00078 return *this;
00079 }
00080
00081 void fit(void) {
00082 const int items = this->numitems;
00083
00084 if (items < this->itembuffersize) {
00085 Type * newitembuffer = this->builtinbuffer;
00086 if (items > DEFAULTSIZE) newitembuffer = new Type[items];
00087
00088 if (newitembuffer != this->itembuffer) {
00089 for (int i = 0; i < items; i++) newitembuffer[i] = this->itembuffer[i];
00090 }
00091
00092 if (this->itembuffer != this->builtinbuffer) delete[] this->itembuffer;
00093 this->itembuffer = newitembuffer;
00094 this->itembuffersize = items > DEFAULTSIZE ? items : DEFAULTSIZE;
00095 }
00096 }
00097
00098 void append(const Type item) {
00099 if (this->numitems == this->itembuffersize) this->grow();
00100 this->itembuffer[this->numitems++] = item;
00101 }
00102
00103 int find(const Type item) const {
00104 for (int i = 0; i < this->numitems; i++)
00105 if (this->itembuffer[i] == item) return i;
00106 return -1;
00107 }
00108
00109 void insert(const Type item, const int insertbefore) {
00110 #ifdef COIN_EXTRA_DEBUG
00111 assert(insertbefore >= 0 && insertbefore <= this->numitems);
00112 #endif // COIN_EXTRA_DEBUG
00113 if (this->numitems == this->itembuffersize) this->grow();
00114
00115 for (int i = this->numitems; i > insertbefore; i--)
00116 this->itembuffer[i] = this->itembuffer[i-1];
00117 this->itembuffer[insertbefore] = item;
00118 this->numitems++;
00119 }
00120
00121 void removeItem(const Type item) {
00122 int idx = this->find(item);
00123 #ifdef COIN_EXTRA_DEBUG
00124 assert(idx != -1);
00125 #endif // COIN_EXTRA_DEBUG
00126 this->remove(idx);
00127 }
00128
00129 void remove(const int index) {
00130 #ifdef COIN_EXTRA_DEBUG
00131 assert(index >= 0 && index < this->numitems);
00132 #endif // COIN_EXTRA_DEBUG
00133 this->numitems--;
00134 for (int i = index; i < this->numitems; i++)
00135 this->itembuffer[i] = this->itembuffer[i + 1];
00136 }
00137
00138 void removeFast(const int index) {
00139 #ifdef COIN_EXTRA_DEBUG
00140 assert(index >= 0 && index < this->numitems);
00141 #endif // COIN_EXTRA_DEBUG
00142 this->itembuffer[index] = this->itembuffer[--this->numitems];
00143 }
00144
00145 int getLength(void) const {
00146 return this->numitems;
00147 }
00148
00149 void truncate(const int length, const int fit = 0) {
00150 #ifdef COIN_EXTRA_DEBUG
00151 assert(length <= this->numitems);
00152 #endif // COIN_EXTRA_DEBUG
00153 this->numitems = length;
00154 if (fit) this->fit();
00155 }
00156
00157 void push(const Type item) {
00158 this->append(item);
00159 }
00160
00161 Type pop(void) {
00162 #ifdef COIN_EXTRA_DEBUG
00163 assert(this->numitems > 0);
00164 #endif // COIN_EXTRA_DEBUG
00165 return this->itembuffer[--this->numitems];
00166 }
00167
00168 const Type * getArrayPtr(const int start = 0) const {
00169 return &this->itembuffer[start];
00170 }
00171
00172 Type operator[](const int index) const {
00173 #ifdef COIN_EXTRA_DEBUG
00174 assert(index >= 0 && index < this->numitems);
00175 #endif // COIN_EXTRA_DEBUG
00176 return this->itembuffer[index];
00177 }
00178
00179 Type & operator[](const int index) {
00180 #ifdef COIN_EXTRA_DEBUG
00181 assert(index >= 0 && index < this->numitems);
00182 #endif // COIN_EXTRA_DEBUG
00183 return this->itembuffer[index];
00184 }
00185
00186 int operator==(const SbList<Type> & l) const {
00187 if (this == &l) return TRUE;
00188 if (this->numitems != l.numitems) return FALSE;
00189 for (int i = 0; i < this->numitems; i++)
00190 if (this->itembuffer[i] != l.itembuffer[i]) return FALSE;
00191 return TRUE;
00192 }
00193
00194 int operator!=(const SbList<Type> & l) const {
00195 return !(*this == l);
00196 }
00197
00198 protected:
00199
00200 void expand(const int size) {
00201 this->grow(size);
00202 this->numitems = size;
00203 }
00204
00205 int getArraySize(void) const {
00206 return this->itembuffersize;
00207 }
00208
00209 private:
00210 void grow(const int size = -1) {
00211
00212 if (size == -1) this->itembuffersize <<= 1;
00213 else if (size <= this->itembuffersize) return;
00214 else { this->itembuffersize = size; }
00215
00216 Type * newbuffer = new Type[this->itembuffersize];
00217 const int n = this->numitems;
00218 for (int i = 0; i < n; i++) newbuffer[i] = this->itembuffer[i];
00219 if (this->itembuffer != this->builtinbuffer) delete[] this->itembuffer;
00220 this->itembuffer = newbuffer;
00221 }
00222
00223 int itembuffersize;
00224 int numitems;
00225 Type * itembuffer;
00226 Type builtinbuffer[DEFAULTSIZE];
00227 };
00228
00229 #endif // !COIN_SBLIST_H