1 /**************************************************************************\ 2 * 3 * This file is part of the Coin 3D visualization library. 4 * Copyright (C) by Kongsberg Oil & Gas Technologies. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * ("GPL") version 2 as published by the Free Software Foundation. 9 * See the file LICENSE.GPL at the root directory of this source 10 * distribution for additional information about the GNU GPL. 11 * 12 * For using Coin with software that can not be combined with the GNU 13 * GPL, and for taking advantage of the additional benefits of our 14 * support services, please contact Kongsberg Oil & Gas Technologies 15 * about acquiring a Coin Professional Edition License. 16 * 17 * See http://www.coin3d.org/ for more information. 18 * 19 * Kongsberg Oil & Gas Technologies, Bygdoy Alle 5, 0257 Oslo, NORWAY. 20 * http://www.sim.no/ sales@sim.no coin-support@coin3d.org 21 * 22 \**************************************************************************/ 23 24 #ifndef SOGUI_SBGUILIST_H 25 #define SOGUI_SBGUILIST_H 26 27 /**************************************************************************/ 28 29 // IMPORTANT NOTES: 30 // 31 // * This file is a duplicate of Coin's lists/SbList.h file, and any 32 // important fixes/improvements here should be migrated. 33 // 34 // * This file contains definitions which should only be used during 35 // library build for now. It is not yet installed for use by the 36 // application programmer. 37 38 /**************************************************************************/ 39 40 #include <Inventor/SbBasic.h> 41 #include <assert.h> 42 #include <stddef.h> // NULL definition 43 44 // We usually implement inline functions below the class definition, 45 // since we think that makes the file more readable. However, this is 46 // not done for this class, since Visual C++ is not too happy about 47 // having functions declared as inline for a template class. 48 // pederb, 2001-10-12 49 50 template <class Type> 51 class SbGuiList { 52 // Older compilers aren't too happy about const declarations in the 53 // class definitions, so use the enum trick described by Scott 54 // Meyers in "Effective C++". 55 enum { DEFAULTSIZE = 4 }; 56 57 public: 58 59 SbGuiList(const int sizehint = DEFAULTSIZE) itembuffersize(DEFAULTSIZE)60 : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) { 61 if (sizehint > DEFAULTSIZE) this->grow(sizehint); 62 } 63 SbGuiList(const SbGuiList<Type> & l)64 SbGuiList(const SbGuiList<Type> & l) 65 : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) { 66 this->copy(l); 67 } 68 ~SbGuiList()69 ~SbGuiList() { 70 if (this->itembuffer != builtinbuffer) delete[] this->itembuffer; 71 } 72 copy(const SbGuiList<Type> & l)73 void copy(const SbGuiList<Type> & l) { 74 if (this == &l) return; 75 const int n = l.numitems; 76 this->expand(n); 77 for (int i = 0; i < n; i++) this->itembuffer[i] = l.itembuffer[i]; 78 } 79 80 SbGuiList <Type> & operator=(const SbGuiList<Type> & l) { 81 this->copy(l); 82 return *this; 83 } 84 fit(void)85 void fit(void) { 86 const int items = this->numitems; 87 88 if (items < this->itembuffersize) { 89 Type * newitembuffer = this->builtinbuffer; 90 if (items > DEFAULTSIZE) newitembuffer = new Type[items]; 91 92 if (newitembuffer != this->itembuffer) { 93 for (int i = 0; i < items; i++) newitembuffer[i] = this->itembuffer[i]; 94 } 95 96 if (this->itembuffer != this->builtinbuffer) delete[] this->itembuffer; 97 this->itembuffer = newitembuffer; 98 this->itembuffersize = items > DEFAULTSIZE ? items : DEFAULTSIZE; 99 } 100 } 101 append(const Type item)102 void append(const Type item) { 103 if (this->numitems == this->itembuffersize) this->grow(); 104 this->itembuffer[this->numitems++] = item; 105 } 106 find(const Type item)107 int find(const Type item) const { 108 for (int i = 0; i < this->numitems; i++) 109 if (this->itembuffer[i] == item) return i; 110 return -1; 111 } 112 insert(const Type item,const int insertbefore)113 void insert(const Type item, const int insertbefore) { 114 assert(insertbefore >= 0 && insertbefore <= this->numitems); 115 if (this->numitems == this->itembuffersize) this->grow(); 116 117 for (int i = this->numitems; i > insertbefore; i--) 118 this->itembuffer[i] = this->itembuffer[i-1]; 119 this->itembuffer[insertbefore] = item; 120 this->numitems++; 121 } 122 removeItem(const Type item)123 void removeItem(const Type item) { 124 int idx = this->find(item); 125 assert(idx != -1); 126 this->remove(idx); 127 } 128 remove(const int index)129 void remove(const int index) { 130 assert(index >= 0 && index < this->numitems); 131 this->numitems--; 132 for (int i = index; i < this->numitems; i++) 133 this->itembuffer[i] = this->itembuffer[i + 1]; 134 } 135 removeFast(const int index)136 void removeFast(const int index) { 137 assert(index >= 0 && index < this->numitems); 138 this->itembuffer[index] = this->itembuffer[--this->numitems]; 139 } 140 getLength(void)141 int getLength(void) const { 142 return this->numitems; 143 } 144 145 void truncate(const int length, const int fit = 0) { 146 assert(length <= this->numitems); 147 this->numitems = length; 148 if (fit) this->fit(); 149 } 150 push(const Type item)151 void push(const Type item) { 152 this->append(item); 153 } 154 pop(void)155 Type pop(void) { 156 assert(this->numitems > 0); 157 return this->itembuffer[--this->numitems]; 158 } 159 160 const Type * getArrayPtr(const int start = 0) const { 161 return &this->itembuffer[start]; 162 } 163 164 Type operator[](const int index) const { 165 assert(index >= 0 && index < this->numitems); 166 return this->itembuffer[index]; 167 } 168 169 Type & operator[](const int index) { 170 assert(index >= 0 && index < this->numitems); 171 return this->itembuffer[index]; 172 } 173 174 int operator==(const SbGuiList<Type> & l) const { 175 if (this == &l) return TRUE; 176 if (this->numitems != l.numitems) return FALSE; 177 for (int i = 0; i < this->numitems; i++) 178 if (this->itembuffer[i] != l.itembuffer[i]) return FALSE; 179 return TRUE; 180 } 181 182 int operator!=(const SbGuiList<Type> & l) const { 183 return !(*this == l); 184 } 185 186 protected: 187 expand(const int size)188 void expand(const int size) { 189 this->grow(size); 190 this->numitems = size; 191 } 192 getArraySize(void)193 int getArraySize(void) const { 194 return this->itembuffersize; 195 } 196 197 private: 198 void grow(const int size = -1) { 199 // Default behavior is to double array size. 200 if (size == -1) this->itembuffersize <<= 1; 201 else if (size <= this->itembuffersize) return; 202 else { this->itembuffersize = size; } 203 204 Type * newbuffer = new Type[this->itembuffersize]; 205 const int n = this->numitems; 206 for (int i = 0; i < n; i++) newbuffer[i] = this->itembuffer[i]; 207 if (this->itembuffer != this->builtinbuffer) delete[] this->itembuffer; 208 this->itembuffer = newbuffer; 209 } 210 211 int itembuffersize; 212 int numitems; 213 Type * itembuffer; 214 Type builtinbuffer[DEFAULTSIZE]; 215 }; 216 217 #endif // !SOGUI_SBGUILIST_H 218