Coin  4.0.10
Coin3D core library
Loading...
Searching...
No Matches
SbList.h
1#ifndef COIN_SBLIST_H
2#define COIN_SBLIST_H
3
4/**************************************************************************\
5 * Copyright (c) Kongsberg Oil & Gas Technologies AS
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * Neither the name of the copyright holder nor the names of its
20 * contributors may be used to endorse or promote products derived from
21 * this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34\**************************************************************************/
35
36#include <cassert>
37#include <climits>
38#include <cstddef> // NULL definition
39#include <new>
40#include <Inventor/SbBasic.h> // TRUE/FALSE
41
42// We usually implement inline functions below the class definition,
43// since we think that makes the file more readable. However, this is
44// not done for this class, since Microsoft Visual C++ is not too
45// happy about having functions declared as inline for a template
46// class.
47
48// FIXME: the #pragmas below is just a quick hack to avoid heaps of
49// irritating warning messages from the compiler for client code
50// compiled under MSVC++. Should try to find the real reason for the
51// warnings and fix the cause of the problem instead. 20020730 mortene.
52//
53// UPDATE 20030617 mortene: there is a Microsoft Knowledge Base
54// article at <URL:http://support.microsoft.com> which is related to
55// this problem. It's article number KB168958.
56//
57// In short, the general solution is that classes that exposes usage
58// of SbList<type> needs to declare the specific template instance
59// with "extern" and __declspec(dllimport/export).
60//
61// That is a lot of work to change, tho'. Another possibility which
62// might be better is to simply avoid using (exposing) SbList from any
63// of the other public classes. Judging from a quick look, this seems
64// feasible, and just a couple of hours or so of work.
65//
66#ifdef _MSC_VER // Microsoft Visual C++
67#pragma warning(disable:4251)
68#pragma warning(disable:4275)
69#endif // _MSC_VER
70
71template <typename Type>
72class SbList {
73 // Older compilers aren't too happy about const declarations in the
74 // class definitions, so use the enum trick described by Scott
75 // Meyers in "Effective C++".
76 enum { DEFAULTSIZE = 4 };
77
78public:
79
80 SbList(const int sizehint = DEFAULTSIZE)
81 : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) {
82 if (sizehint > DEFAULTSIZE) this->grow(sizehint);
83 }
84
86 : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) {
87 this->copy(l);
88 }
89
91 if (this->itembuffer != builtinbuffer) delete[] this->itembuffer;
92 }
93
94 void copy(const SbList<Type> & l) {
95 if (this == &l) return;
96 const int n = l.numitems;
97 this->expand(n);
98 for (int i = 0; i < n; i++) this->itembuffer[i] = l.itembuffer[i];
99 }
100
102 this->copy(l);
103 return *this;
104 }
105
106 void fit(void) {
107 const int items = this->numitems;
108
109 if (items < this->itembuffersize) {
110 Type * newitembuffer = this->builtinbuffer;
111 if (items > DEFAULTSIZE) newitembuffer = new Type[items];
112
113 if (newitembuffer != this->itembuffer) {
114 try {
115 for (int i = 0; i < items; i++) newitembuffer[i] = this->itembuffer[i];
116 }
117 catch (...) {
118 if (newitembuffer != this->builtinbuffer) delete[] newitembuffer;
119 throw;
120 }
121 }
122
123 if (this->itembuffer != this->builtinbuffer) delete[] this->itembuffer;
124 this->itembuffer = newitembuffer;
125 this->itembuffersize = items > DEFAULTSIZE ? items : DEFAULTSIZE;
126 }
127 }
128
129 void append(const Type item) {
130 if (this->numitems == this->itembuffersize) this->grow();
131 this->itembuffer[this->numitems++] = item;
132 }
133
134 int find(const Type item) const {
135 for (int i = 0; i < this->numitems; i++)
136 if (this->itembuffer[i] == item) return i;
137 return -1;
138 }
139
140 void insert(const Type item, const int insertbefore) {
141#ifdef COIN_EXTRA_DEBUG
143#endif // COIN_EXTRA_DEBUG
144 if (this->numitems == this->itembuffersize) this->grow();
145
146 for (int i = this->numitems; i > insertbefore; i--)
147 this->itembuffer[i] = this->itembuffer[i-1];
148 this->itembuffer[insertbefore] = item;
149 this->numitems++;
150 }
151
152 void removeItem(const Type item) {
153 int idx = this->find(item);
154#ifdef COIN_EXTRA_DEBUG
155 assert(idx != -1);
156#endif // COIN_EXTRA_DEBUG
157 if (idx >= 0) this->remove(idx);
158 }
159
160 void remove(const int index) {
161#ifdef COIN_EXTRA_DEBUG
162 assert(index >= 0 && index < this->numitems);
163#endif // COIN_EXTRA_DEBUG
164 this->numitems--;
165 for (int i = index; i < this->numitems; i++)
166 this->itembuffer[i] = this->itembuffer[i + 1];
167 }
168
169 void removeFast(const int index) {
170#ifdef COIN_EXTRA_DEBUG
171 assert(index >= 0 && index < this->numitems);
172#endif // COIN_EXTRA_DEBUG
173 this->itembuffer[index] = this->itembuffer[--this->numitems];
174 }
175
176 int getLength(void) const {
177 return this->numitems;
178 }
179
180 void truncate(const int length, const int dofit = 0) {
181#ifdef COIN_EXTRA_DEBUG
182 assert(length <= this->numitems);
183#endif // COIN_EXTRA_DEBUG
184 this->numitems = length;
185 if (dofit) this->fit();
186 }
187
188 void push(const Type item) {
189 this->append(item);
190 }
191
192 Type pop(void) {
193#ifdef COIN_EXTRA_DEBUG
194 assert(this->numitems > 0);
195#endif // COIN_EXTRA_DEBUG
196 return this->itembuffer[--this->numitems];
197 }
198
199 const Type * getArrayPtr(const int start = 0) const {
200 return &this->itembuffer[start];
201 }
202
203 Type operator[](const int index) const {
204#ifdef COIN_EXTRA_DEBUG
205 assert(index >= 0 && index < this->numitems);
206#endif // COIN_EXTRA_DEBUG
207 return this->itembuffer[index];
208 }
209
210 Type & operator[](const int index) {
211#ifdef COIN_EXTRA_DEBUG
212 assert(index >= 0 && index < this->numitems);
213#endif // COIN_EXTRA_DEBUG
214 return this->itembuffer[index];
215 }
216
217 int operator==(const SbList<Type> & l) const {
218 if (this == &l) return TRUE;
219 if (this->numitems != l.numitems) return FALSE;
220 for (int i = 0; i < this->numitems; i++)
221 if (this->itembuffer[i] != l.itembuffer[i]) return FALSE;
222 return TRUE;
223 }
224
225 int operator!=(const SbList<Type> & l) const {
226 return !(*this == l);
227 }
228
229 void ensureCapacity(const int size) {
230 if ((size > itembuffersize) &&
231 (size > DEFAULTSIZE)) {
232 this->grow(size);
233 }
234 }
235
236protected:
237
238 void expand(const int size) {
239 this->grow(size);
240 this->numitems = size;
241 }
242
243 int getArraySize(void) const {
244 return this->itembuffersize;
245 }
246
247private:
248 void grow(const int size = -1) {
249 // Default growth doubles the current capacity. Check before the
250 // multiplication to avoid signed overflow.
251 int newsize;
252 if (size == -1) {
253 if (this->itembuffersize > INT_MAX / 2) throw std::bad_alloc();
254 newsize = this->itembuffersize * 2;
255 }
256 else if (size <= this->itembuffersize) return;
257 else { newsize = size; }
258
259 Type * newbuffer = new Type[newsize];
260 const int n = this->numitems;
261 try {
262 for (int i = 0; i < n; i++) newbuffer[i] = this->itembuffer[i];
263 }
264 catch (...) {
265 delete[] newbuffer;
266 throw;
267 }
268 if (this->itembuffer != this->builtinbuffer) delete[] this->itembuffer;
269 this->itembuffer = newbuffer;
270 this->itembuffersize = newsize;
271 }
272
273 int itembuffersize;
274 int numitems;
275 Type * itembuffer;
276 Type builtinbuffer[DEFAULTSIZE];
277};
278
279#endif // !COIN_SBLIST_H
The SbList class is a template container class for lists.
Definition SbList.h:72
void truncate(const int length, const int dofit=0)
Definition SbList.h:180
int getLength(void) const
Definition SbList.h:176
SbList(const SbList< Type > &l)
Definition SbList.h:85
Type pop(void)
Definition SbList.h:192
int find(const Type item) const
Definition SbList.h:134
SbList< Type > & operator=(const SbList< Type > &l)
Definition SbList.h:101
void removeFast(const int index)
Definition SbList.h:169
Type & operator[](const int index)
Definition SbList.h:210
int operator!=(const SbList< Type > &l) const
Definition SbList.h:225
int getArraySize(void) const
Definition SbList.h:243
const Type * getArrayPtr(const int start=0) const
Definition SbList.h:199
void remove(const int index)
Definition SbList.h:160
SbList(const int sizehint=DEFAULTSIZE)
Definition SbList.h:80
void removeItem(const Type item)
Definition SbList.h:152
int operator==(const SbList< Type > &l) const
Definition SbList.h:217
void copy(const SbList< Type > &l)
Definition SbList.h:94
void fit(void)
Definition SbList.h:106
void insert(const Type item, const int insertbefore)
Definition SbList.h:140
~SbList()
Definition SbList.h:90
void append(const Type item)
Definition SbList.h:129
void expand(const int size)
Definition SbList.h:238
void ensureCapacity(const int size)
Definition SbList.h:229
Type operator[](const int index) const
Definition SbList.h:203
void push(const Type item)
Definition SbList.h:188