Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

SbList.h

00001 /**************************************************************************\
00002  *
00003  *  This file is part of the Coin 3D visualization library.
00004  *  Copyright (C) 1998-2003 by Systems in Motion. All rights reserved.
00005  *
00006  *  This library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Lesser General Public License
00008  *  version 2.1 as published by the Free Software Foundation. See the
00009  *  file LICENSE.LGPL at the root directory of the distribution for
00010  *  more details.
00011  *
00012  *  If you want to use Coin for applications not compatible with the
00013  *  LGPL, please contact SIM to acquire a Professional Edition license.
00014  *
00015  *  Systems in Motion, Teknobyen, Abels Gate 5, 7030 Trondheim, NORWAY
00016  *  http://www.sim.no support@sim.no Voice: +47 22114160 Fax: +47 22207097
00017  *
00018 \**************************************************************************/
00019 
00020 #ifndef COIN_SBLIST_H
00021 #define COIN_SBLIST_H
00022 
00023 #include <Inventor/SbBasic.h>
00024 #include <assert.h>
00025 #include <stddef.h> // NULL definition
00026 
00027 // We usually implement inline functions below the class definition,
00028 // since we think that makes the file more readable. However, this is
00029 // not done for this class, since Visual C++ is not too happy about
00030 // having functions declared as inline for a template class.
00031 // pederb, 2001-10-12
00032 
00033 // FIXME: this is just a quick hack to avoid heaps of irritating
00034 // warning messages from the compiler for client code compiled under
00035 // MSVC++. Should try to find the real reason for the warnings and fix
00036 // the cause of the problem instead. 20020730 mortene.
00037 #ifdef _MSC_VER // Microsoft Visual C++
00038 #pragma warning(disable:4251)
00039 #pragma warning(disable:4275)
00040 #endif // _MSC_VER
00041 
00042 template <class Type>
00043 class COIN_DLL_API SbList {
00044   // Older compilers aren't too happy about const declarations in the
00045   // class definitions, so use the enum trick described by Scott
00046   // Meyers in "Effective C++".
00047   enum { DEFAULTSIZE = 4 };
00048 
00049 public:
00050 
00051   SbList(const int sizehint = DEFAULTSIZE)
00052     : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) {
00053     if (sizehint > DEFAULTSIZE) this->grow(sizehint);
00054   }
00055 
00056   SbList(const SbList<Type> & l)
00057     : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) {
00058     this->copy(l);
00059   }
00060 
00061   ~SbList() {
00062     if (this->itembuffer != builtinbuffer) delete[] this->itembuffer;
00063   }
00064 
00065   void copy(const SbList<Type> & l) {
00066     if (this == &l) return;
00067     const int n = l.numitems;
00068     this->expand(n);
00069     for (int i = 0; i < n; i++) this->itembuffer[i] = l.itembuffer[i];
00070   }
00071 
00072   SbList <Type> & operator=(const SbList<Type> & l) {
00073     this->copy(l);
00074     return *this;
00075   }
00076 
00077   void fit(void) {
00078     const int items = this->numitems;
00079 
00080     if (items < this->itembuffersize) {
00081       Type * newitembuffer = this->builtinbuffer;
00082       if (items > DEFAULTSIZE) newitembuffer = new Type[items];
00083 
00084       if (newitembuffer != this->itembuffer) {
00085         for (int i = 0; i < items; i++) newitembuffer[i] = this->itembuffer[i];
00086       }
00087 
00088       if (this->itembuffer != this->builtinbuffer) delete[] this->itembuffer;
00089       this->itembuffer = newitembuffer;
00090       this->itembuffersize = items > DEFAULTSIZE ? items : DEFAULTSIZE;
00091     }
00092   }
00093 
00094   void append(const Type item) {
00095     if (this->numitems == this->itembuffersize) this->grow();
00096     this->itembuffer[this->numitems++] = item;
00097   }
00098 
00099   int find(const Type item) const {
00100     for (int i = 0; i < this->numitems; i++)
00101       if (this->itembuffer[i] == item) return i;
00102     return -1;
00103   }
00104 
00105   void insert(const Type item, const int insertbefore) {
00106 #ifdef COIN_EXTRA_DEBUG
00107     assert(insertbefore >= 0 && insertbefore <= this->numitems);
00108 #endif // COIN_EXTRA_DEBUG
00109     if (this->numitems == this->itembuffersize) this->grow();
00110 
00111     for (int i = this->numitems; i > insertbefore; i--)
00112       this->itembuffer[i] = this->itembuffer[i-1];
00113     this->itembuffer[insertbefore] = item;
00114     this->numitems++;
00115   }
00116 
00117   void removeItem(const Type item) {
00118     int idx = this->find(item);
00119 #ifdef COIN_EXTRA_DEBUG
00120     assert(idx != -1);
00121 #endif // COIN_EXTRA_DEBUG
00122     this->remove(idx);
00123   }
00124 
00125   void remove(const int index) {
00126 #ifdef COIN_EXTRA_DEBUG
00127     assert(index >= 0 && index < this->numitems);
00128 #endif // COIN_EXTRA_DEBUG
00129     this->numitems--;
00130     for (int i = index; i < this->numitems; i++)
00131       this->itembuffer[i] = this->itembuffer[i + 1];
00132   }
00133 
00134   void removeFast(const int index) {
00135 #ifdef COIN_EXTRA_DEBUG
00136     assert(index >= 0 && index < this->numitems);
00137 #endif // COIN_EXTRA_DEBUG
00138     this->itembuffer[index] = this->itembuffer[--this->numitems];
00139   }
00140 
00141   int getLength(void) const {
00142     return this->numitems;
00143   }
00144 
00145   void truncate(const int length, const int fit = 0) {
00146 #ifdef COIN_EXTRA_DEBUG
00147     assert(length <= this->numitems);
00148 #endif // COIN_EXTRA_DEBUG
00149     this->numitems = length;
00150     if (fit) this->fit();
00151   }
00152 
00153   void push(const Type item) {
00154     this->append(item);
00155   }
00156 
00157   Type pop(void) {
00158 #ifdef COIN_EXTRA_DEBUG
00159     assert(this->numitems > 0);
00160 #endif // COIN_EXTRA_DEBUG
00161     return this->itembuffer[--this->numitems];
00162   }
00163 
00164   const Type * getArrayPtr(const int start = 0) const {
00165     return &this->itembuffer[start];
00166   }
00167 
00168   Type operator[](const int index) const {
00169 #ifdef COIN_EXTRA_DEBUG
00170     assert(index >= 0 && index < this->numitems);
00171 #endif // COIN_EXTRA_DEBUG
00172     return this->itembuffer[index];
00173   }
00174 
00175   Type & operator[](const int index) {
00176 #ifdef COIN_EXTRA_DEBUG
00177     assert(index >= 0 && index < this->numitems);
00178 #endif // COIN_EXTRA_DEBUG
00179     return this->itembuffer[index];
00180   }
00181 
00182   int operator==(const SbList<Type> & l) const {
00183     if (this == &l) return TRUE;
00184     if (this->numitems != l.numitems) return FALSE;
00185     for (int i = 0; i < this->numitems; i++)
00186       if (this->itembuffer[i] != l.itembuffer[i]) return FALSE;
00187     return TRUE;
00188   }
00189 
00190   int operator!=(const SbList<Type> & l) const {
00191     return !(*this == l);
00192   }
00193 
00194 protected:
00195 
00196   void expand(const int size) {
00197     this->grow(size);
00198     this->numitems = size;
00199   }
00200 
00201   int getArraySize(void) const {
00202     return this->itembuffersize;
00203   }
00204 
00205 private:
00206   void grow(const int size = -1) {
00207     // Default behavior is to double array size.
00208     if (size == -1) this->itembuffersize <<= 1;
00209     else if (size <= this->itembuffersize) return;
00210     else { this->itembuffersize = size; }
00211 
00212     Type * newbuffer = new Type[this->itembuffersize];
00213     const int n = this->numitems;
00214     for (int i = 0; i < n; i++) newbuffer[i] = this->itembuffer[i];
00215     if (this->itembuffer != this->builtinbuffer) delete[] this->itembuffer;
00216     this->itembuffer = newbuffer;
00217   }
00218 
00219   int itembuffersize;
00220   int numitems;
00221   Type * itembuffer;
00222   Type builtinbuffer[DEFAULTSIZE];
00223 };
00224 
00225 #endif // !COIN_SBLIST_H

Generated on Sat Oct 25 16:54:46 2003 for Coin by doxygen 1.3.4