Coin Logo http://www.sim.no/
http://www.coin3d.org/

SbList.h
00001 #ifndef COIN_SBLIST_H
00002 #define COIN_SBLIST_H
00003 
00004 /**************************************************************************\
00005  *
00006  *  This file is part of the Coin 3D visualization library.
00007  *  Copyright (C) by Kongsberg Oil & Gas Technologies.
00008  *
00009  *  This library is free software; you can redistribute it and/or
00010  *  modify it under the terms of the GNU General Public License
00011  *  ("GPL") version 2 as published by the Free Software Foundation.
00012  *  See the file LICENSE.GPL at the root directory of this source
00013  *  distribution for additional information about the GNU GPL.
00014  *
00015  *  For using Coin with software that can not be combined with the GNU
00016  *  GPL, and for taking advantage of the additional benefits of our
00017  *  support services, please contact Kongsberg Oil & Gas Technologies
00018  *  about acquiring a Coin Professional Edition License.
00019  *
00020  *  See http://www.coin3d.org/ for more information.
00021  *
00022  *  Kongsberg Oil & Gas Technologies, Bygdoy Alle 5, 0257 Oslo, NORWAY.
00023  *  http://www.sim.no/  sales@sim.no  coin-support@coin3d.org
00024  *
00025 \**************************************************************************/
00026 
00027 #include <assert.h>
00028 #include <stddef.h> // NULL definition
00029 #include <Inventor/SbBasic.h> // TRUE/FALSE
00030 
00031 // We usually implement inline functions below the class definition,
00032 // since we think that makes the file more readable. However, this is
00033 // not done for this class, since Microsoft Visual C++ is not too
00034 // happy about having functions declared as inline for a template
00035 // class.
00036 
00037 // FIXME: the #pragmas below is just a quick hack to avoid heaps of
00038 // irritating warning messages from the compiler for client code
00039 // compiled under MSVC++. Should try to find the real reason for the
00040 // warnings and fix the cause of the problem instead. 20020730 mortene.
00041 //
00042 // UPDATE 20030617 mortene: there is a Microsoft Knowledge Base
00043 // article at <URL:http://support.microsoft.com> which is related to
00044 // this problem. It's article number KB168958.
00045 //
00046 // In short, the general solution is that classes that exposes usage
00047 // of SbList<type> needs to declare the specific template instance
00048 // with "extern" and __declspec(dllimport/export).
00049 //
00050 // That is a lot of work to change, tho'. Another possibility which
00051 // might be better is to simply avoid using (exposing) SbList from any
00052 // of the other public classes. Judging from a quick look, this seems
00053 // feasible, and just a couple of hours or so of work.
00054 //
00055 #ifdef _MSC_VER // Microsoft Visual C++
00056 #pragma warning(disable:4251)
00057 #pragma warning(disable:4275)
00058 #endif // _MSC_VER
00059 
00060 template <class Type>
00061 class SbList {
00062   // Older compilers aren't too happy about const declarations in the
00063   // class definitions, so use the enum trick described by Scott
00064   // Meyers in "Effective C++".
00065   enum { DEFAULTSIZE = 4 };
00066 
00067 public:
00068 
00069   SbList(const int sizehint = DEFAULTSIZE)
00070     : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) {
00071     if (sizehint > DEFAULTSIZE) this->grow(sizehint);
00072   }
00073 
00074   SbList(const SbList<Type> & l)
00075     : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) {
00076     this->copy(l);
00077   }
00078 
00079   ~SbList() {
00080     if (this->itembuffer != builtinbuffer) delete[] this->itembuffer;
00081   }
00082 
00083   void copy(const SbList<Type> & l) {
00084     if (this == &l) return;
00085     const int n = l.numitems;
00086     this->expand(n);
00087     for (int i = 0; i < n; i++) this->itembuffer[i] = l.itembuffer[i];
00088   }
00089 
00090   SbList <Type> & operator=(const SbList<Type> & l) {
00091     this->copy(l);
00092     return *this;
00093   }
00094 
00095   void fit(void) {
00096     const int items = this->numitems;
00097 
00098     if (items < this->itembuffersize) {
00099       Type * newitembuffer = this->builtinbuffer;
00100       if (items > DEFAULTSIZE) newitembuffer = new Type[items];
00101 
00102       if (newitembuffer != this->itembuffer) {
00103         for (int i = 0; i < items; i++) newitembuffer[i] = this->itembuffer[i];
00104       }
00105 
00106       if (this->itembuffer != this->builtinbuffer) delete[] this->itembuffer;
00107       this->itembuffer = newitembuffer;
00108       this->itembuffersize = items > DEFAULTSIZE ? items : DEFAULTSIZE;
00109     }
00110   }
00111 
00112   void append(const Type item) {
00113     if (this->numitems == this->itembuffersize) this->grow();
00114     this->itembuffer[this->numitems++] = item;
00115   }
00116 
00117   int find(const Type item) const {
00118     for (int i = 0; i < this->numitems; i++)
00119       if (this->itembuffer[i] == item) return i;
00120     return -1;
00121   }
00122 
00123   void insert(const Type item, const int insertbefore) {
00124 #ifdef COIN_EXTRA_DEBUG
00125     assert(insertbefore >= 0 && insertbefore <= this->numitems);
00126 #endif // COIN_EXTRA_DEBUG
00127     if (this->numitems == this->itembuffersize) this->grow();
00128 
00129     for (int i = this->numitems; i > insertbefore; i--)
00130       this->itembuffer[i] = this->itembuffer[i-1];
00131     this->itembuffer[insertbefore] = item;
00132     this->numitems++;
00133   }
00134 
00135   void removeItem(const Type item) {
00136     int idx = this->find(item);
00137 #ifdef COIN_EXTRA_DEBUG
00138     assert(idx != -1);
00139 #endif // COIN_EXTRA_DEBUG
00140     this->remove(idx);
00141   }
00142 
00143   void remove(const int index) {
00144 #ifdef COIN_EXTRA_DEBUG
00145     assert(index >= 0 && index < this->numitems);
00146 #endif // COIN_EXTRA_DEBUG
00147     this->numitems--;
00148     for (int i = index; i < this->numitems; i++)
00149       this->itembuffer[i] = this->itembuffer[i + 1];
00150   }
00151 
00152   void removeFast(const int index) {
00153 #ifdef COIN_EXTRA_DEBUG
00154     assert(index >= 0 && index < this->numitems);
00155 #endif // COIN_EXTRA_DEBUG
00156     this->itembuffer[index] = this->itembuffer[--this->numitems];
00157   }
00158 
00159   int getLength(void) const {
00160     return this->numitems;
00161   }
00162 
00163   void truncate(const int length, const int dofit = 0) {
00164 #ifdef COIN_EXTRA_DEBUG
00165     assert(length <= this->numitems);
00166 #endif // COIN_EXTRA_DEBUG
00167     this->numitems = length;
00168     if (dofit) this->fit();
00169   }
00170 
00171   void push(const Type item) {
00172     this->append(item);
00173   }
00174 
00175   Type pop(void) {
00176 #ifdef COIN_EXTRA_DEBUG
00177     assert(this->numitems > 0);
00178 #endif // COIN_EXTRA_DEBUG
00179     return this->itembuffer[--this->numitems];
00180   }
00181 
00182   const Type * getArrayPtr(const int start = 0) const {
00183     return &this->itembuffer[start];
00184   }
00185 
00186   Type operator[](const int index) const {
00187 #ifdef COIN_EXTRA_DEBUG
00188     assert(index >= 0 && index < this->numitems);
00189 #endif // COIN_EXTRA_DEBUG
00190     return this->itembuffer[index];
00191   }
00192 
00193   Type & operator[](const int index) {
00194 #ifdef COIN_EXTRA_DEBUG
00195     assert(index >= 0 && index < this->numitems);
00196 #endif // COIN_EXTRA_DEBUG
00197     return this->itembuffer[index];
00198   }
00199 
00200   int operator==(const SbList<Type> & l) const {
00201     if (this == &l) return TRUE;
00202     if (this->numitems != l.numitems) return FALSE;
00203     for (int i = 0; i < this->numitems; i++)
00204       if (this->itembuffer[i] != l.itembuffer[i]) return FALSE;
00205     return TRUE;
00206   }
00207 
00208   int operator!=(const SbList<Type> & l) const {
00209     return !(*this == l);
00210   }
00211 
00212   void ensureCapacity(const int size) {
00213     if ((size > itembuffersize) &&
00214         (size > DEFAULTSIZE)) {
00215       this->grow(size);
00216     }
00217   }
00218 
00219 protected:
00220 
00221   void expand(const int size) {
00222     this->grow(size);
00223     this->numitems = size;
00224   }
00225 
00226   int getArraySize(void) const {
00227     return this->itembuffersize;
00228   }
00229 
00230 private:
00231   void grow(const int size = -1) {
00232     // Default behavior is to double array size.
00233     if (size == -1) this->itembuffersize <<= 1;
00234     else if (size <= this->itembuffersize) return;
00235     else { this->itembuffersize = size; }
00236 
00237     Type * newbuffer = new Type[this->itembuffersize];
00238     const int n = this->numitems;
00239     for (int i = 0; i < n; i++) newbuffer[i] = this->itembuffer[i];
00240     if (this->itembuffer != this->builtinbuffer) delete[] this->itembuffer;
00241     this->itembuffer = newbuffer;
00242   }
00243 
00244   int itembuffersize;
00245   int numitems;
00246   Type * itembuffer;
00247   Type builtinbuffer[DEFAULTSIZE];
00248 };
00249 
00250 #endif // !COIN_SBLIST_H

Copyright © 1998-2010 by Kongsberg Oil & Gas Technologies. All rights reserved.

Generated for Coin by Doxygen 1.7.5.1.