![]() |
http://www.sim.no/ http://www.coin3d.org/ |
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 on Sun May 1 2011 02:58:20 for Coin by Doxygen 1.7.3.