SmallChange  1.0.0
A collection of extensions to Coin3D
Loading...
Searching...
No Matches
nodekits/SbList.h
1/**************************************************************************\
2 * Copyright (c) Kongsberg Oil & Gas Technologies AS
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of the copyright holder nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31\**************************************************************************/
32
33#ifndef SMALLCHANGE_SBLIST_H
34#define SMALLCHANGE_SBLIST_H
35
36#include <Inventor/SbBasic.h>
37#include <cassert>
38#include <cstddef> // NULL definition
39
40template <class Type>
41class SbList {
42 // Older compilers aren't too happy about const declarations in the
43 // class definitions, so use the enum trick described by Scott
44 // Meyers in "Effective C++".
45 enum { DEFAULTSIZE = 4 };
46
47public:
48 SbList(const int sizehint = DEFAULTSIZE);
49 SbList(const SbList<Type> & l);
50
51 // No need to define the destructor virtual, as Coin code should
52 // always know the class type of the list objects it is handling.
53 ~SbList();
54
55 void copy(const SbList<Type> & l);
56
57 void append(const Type item);
58 int find(const Type item) const;
59 void insert(const Type item, const int insertbefore);
60 void remove(const int index);
61 void removeFast(const int index);
62 // Need to name this something else than remove(), to avoid
63 // ambiguity when Type is "int".
64 void removeItem(const Type item);
65
66 int getLength(void) const;
67 void truncate(const int length, const int fit = 0);
68
69 void push(const Type item);
70 Type pop(void);
71
72 SbList<Type> & operator=(const SbList<Type> & l);
73
74 const Type * getArrayPtr(const int start = 0) const;
75
76 Type operator[](const int index) const;
77 Type & operator[](const int index);
78
79 int operator==(const SbList<Type> & l) const;
80 int operator!=(const SbList<Type> & l) const;
81
82 void fit(void);
83
84protected:
85 void expand(const int size);
86 int getArraySize(void) const;
87
88private:
89 void grow(const int size = -1);
90
91 int itembuffersize;
92 int numitems;
93 Type * itembuffer;
94 Type builtinbuffer[DEFAULTSIZE];
95};
96
97
98/*** Inlined functions **********************************************/
99
100template <class Type> inline
102 : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer)
103{
104 if (sizehint > DEFAULTSIZE) this->grow(sizehint);
105}
106
107template <class Type> inline
109 : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer)
110{
111 this->copy(l);
112}
113
114template <class Type> inline
116{
117 if (this->itembuffer != builtinbuffer) delete [] this->itembuffer;
118}
119
120// Increase array size without modifying the number of items in the
121// array.
122template <class Type> inline void
123SbList<Type>::grow(const int size)
124{
125 // Default behavior is to double array size.
126 if (size == -1) this->itembuffersize <<= 1;
127 else if (size <= this->itembuffersize) return;
128 else { this->itembuffersize = size; }
129
130 Type * newbuffer = new Type[this->itembuffersize];
131 const int n = this->numitems;
132 for (int i = 0; i < n; i++) newbuffer[i] = this->itembuffer[i];
133 if (this->itembuffer != this->builtinbuffer) delete [] this->itembuffer;
134 this->itembuffer = newbuffer;
135}
136
137template <class Type> inline void
138SbList<Type>::expand(const int size)
139{
140 this->grow(size);
141 this->numitems = size;
142}
143
144template <class Type> inline int
146{
147 return this->itembuffersize;
148}
149
150template <class Type> inline void
152{
153 if (this == &l) return;
154
155 const int n = l.numitems;
156 this->expand(n);
157 for (int i = 0; i < n; i++) this->itembuffer[i] = l.itembuffer[i];
158}
159
160template <class Type> inline SbList<Type> &
162{
163 this->copy(l);
164 return *this;
165}
166
167template <class Type> inline void
169{
170 const int items = this->numitems;
171
172 if (items < this->itembuffersize) {
173 Type * newitembuffer = this->builtinbuffer;
174 if (items > DEFAULTSIZE) newitembuffer = new Type[items];
175
176 if (newitembuffer != this->itembuffer) {
177 for (int i = 0; i < items; i++) newitembuffer[i] = this->itembuffer[i];
178 }
179
180 if (this->itembuffer != this->builtinbuffer) delete [] this->itembuffer;
181 this->itembuffer = newitembuffer;
182 this->itembuffersize = items > DEFAULTSIZE ? items : DEFAULTSIZE;
183 }
184}
185
186template <class Type> inline void
187SbList<Type>::append(const Type item)
188{
189 if (this->numitems == this->itembuffersize) this->grow();
190 this->itembuffer[this->numitems++] = item;
191}
192
193template <class Type> inline int
194SbList<Type>::find(const Type item) const
195{
196 for (int i = 0; i < this->numitems; i++)
197 if (this->itembuffer[i] == item) return i;
198 return -1;
199}
200
201template <class Type> inline void
202SbList<Type>::insert(const Type item, const int insertbefore)
203{
204#ifdef COIN_EXTRA_DEBUG
206#endif // COIN_EXTRA_DEBUG
207 if (this->numitems == this->itembuffersize) this->grow();
208
209 for (int i = this->numitems; i > insertbefore; i--)
210 this->itembuffer[i] = this->itembuffer[i-1];
211 this->itembuffer[insertbefore] = item;
212 this->numitems++;
213}
214
215template <class Type> inline void
217{
218 int idx = this->find(item);
219#ifdef COIN_EXTRA_DEBUG
220 assert(idx != -1);
221#endif // COIN_EXTRA_DEBUG
222 this->remove(idx);
223}
224
225template <class Type> inline void
226SbList<Type>::remove(const int index)
227{
228#ifdef COIN_EXTRA_DEBUG
229 assert(index >= 0 && index < this->numitems);
230#endif // COIN_EXTRA_DEBUG
231 this->numitems--;
232 for (int i = index; i < this->numitems; i++)
233 this->itembuffer[i] = this->itembuffer[i + 1];
234}
235
236template <class Type> inline void
237SbList<Type>::removeFast(const int index)
238{
239#ifdef COIN_EXTRA_DEBUG
240 assert(index >= 0 && index < this->numitems);
241#endif // COIN_EXTRA_DEBUG
242 this->itembuffer[index] = this->itembuffer[--this->numitems];
243}
244
245template <class Type> inline int
246SbList<Type>::getLength(void) const
247{
248 return this->numitems;
249}
250
251template <class Type> inline void
252SbList<Type>::truncate(const int length, const int fit)
253{
254#ifdef COIN_EXTRA_DEBUG
255 assert(length <= this->numitems);
256#endif // COIN_EXTRA_DEBUG
257 this->numitems = length;
258 if (fit) this->fit();
259}
260
261template <class Type> inline void
262SbList<Type>::push(const Type item)
263{
264 this->append(item);
265}
266
267template <class Type> inline Type
269{
270#ifdef COIN_EXTRA_DEBUG
271 assert(this->numitems > 0);
272#endif // COIN_EXTRA_DEBUG
273 return this->itembuffer[--this->numitems];
274}
275
276template <class Type> inline const Type *
277SbList<Type>::getArrayPtr(const int start) const
278{
279 return &this->itembuffer[start];
280}
281
282template <class Type> inline Type
283SbList<Type>::operator[](const int index) const
284{
285#ifdef COIN_EXTRA_DEBUG
286 assert(index >= 0 && index < this->numitems);
287#endif // COIN_EXTRA_DEBUG
288 return this->itembuffer[index];
289}
290
291template <class Type> inline Type &
292SbList<Type>::operator[](const int index)
293{
294#ifdef COIN_EXTRA_DEBUG
295 assert(index >= 0 && index < this->numitems);
296#endif // COIN_EXTRA_DEBUG
297 return this->itembuffer[index];
298}
299
300template <class Type> inline int
302{
303 if (this == &l) return TRUE;
304 if (this->numitems != l.numitems) return FALSE;
305 for (int i = 0; i < this->numitems; i++)
306 if (this->itembuffer[i] != l.itembuffer[i]) return FALSE;
307 return TRUE;
308}
309
310template <class Type> inline int
312{
313 return !(*this == l);
314}
315
316#endif // !SMALLCHANGE_SBLIST_H
Definition misc/SbList.h:69