![]() |
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) 1998-2007 by Systems in Motion. All rights reserved. 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 Systems in Motion about acquiring 00018 * a Coin Professional Edition License. 00019 * 00020 * See http://www.coin3d.org/ for more information. 00021 * 00022 * Systems in Motion, Postboks 1283, Pirsenteret, 7462 Trondheim, 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 Visual C++ is not too happy about 00034 // having functions declared as inline for a template class. 00035 // pederb, 2001-10-12 00036 00037 // FIXME: this is just a quick hack to avoid heaps of irritating 00038 // warning messages from the compiler for client code compiled under 00039 // MSVC++. Should try to find the real reason for the warnings and fix 00040 // the cause of the problem instead. 20020730 mortene. 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 // Older compilers aren't too happy about const declarations in the 00049 // class definitions, so use the enum trick described by Scott 00050 // Meyers in "Effective C++". 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 dofit = 0) { 00150 #ifdef COIN_EXTRA_DEBUG 00151 assert(length <= this->numitems); 00152 #endif // COIN_EXTRA_DEBUG 00153 this->numitems = length; 00154 if (dofit) 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 // Default behavior is to double array size. 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
Copyright © 1998-2007 by Systems in Motion AS. All rights reserved.
Generated on Mon Feb 23 16:33:09 2009 for Coin by Doxygen. 1.5.8