Coin Logo Coin3D is Free Software,
published under the BSD 3-clause license.
https://bitbucket.org/Coin3D/
http://www.kongsberg.com/kogt/
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
SbList.h
Go to the documentation of this file.
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 
40 template <class Type>
41 class 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 
47 public:
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 
84 protected:
85  void expand(const int size);
86  int getArraySize(void) const;
87 
88 private:
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 
100 template <class Type> inline
101 SbList<Type>::SbList(const int sizehint)
102  : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer)
103 {
104  if (sizehint > DEFAULTSIZE) this->grow(sizehint);
105 }
106 
107 template <class Type> inline
109  : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer)
110 {
111  this->copy(l);
112 }
113 
114 template <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.
122 template <class Type> inline void
123 SbList<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 
137 template <class Type> inline void
138 SbList<Type>::expand(const int size)
139 {
140  this->grow(size);
141  this->numitems = size;
142 }
143 
144 template <class Type> inline int
145 SbList<Type>::getArraySize(void) const
146 {
147  return this->itembuffersize;
148 }
149 
150 template <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 
160 template <class Type> inline SbList<Type> &
162 {
163  this->copy(l);
164  return *this;
165 }
166 
167 template <class Type> inline void
168 SbList<Type>::fit(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 
186 template <class Type> inline void
187 SbList<Type>::append(const Type item)
188 {
189  if (this->numitems == this->itembuffersize) this->grow();
190  this->itembuffer[this->numitems++] = item;
191 }
192 
193 template <class Type> inline int
194 SbList<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 
201 template <class Type> inline void
202 SbList<Type>::insert(const Type item, const int insertbefore)
203 {
204 #ifdef COIN_EXTRA_DEBUG
205  assert(insertbefore >= 0 && insertbefore <= this->numitems);
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 
215 template <class Type> inline void
216 SbList<Type>::removeItem(const Type item)
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 
225 template <class Type> inline void
226 SbList<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 
236 template <class Type> inline void
237 SbList<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 
245 template <class Type> inline int
246 SbList<Type>::getLength(void) const
247 {
248  return this->numitems;
249 }
250 
251 template <class Type> inline void
252 SbList<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 
261 template <class Type> inline void
262 SbList<Type>::push(const Type item)
263 {
264  this->append(item);
265 }
266 
267 template <class Type> inline Type
268 SbList<Type>::pop(void)
269 {
270 #ifdef COIN_EXTRA_DEBUG
271  assert(this->numitems > 0);
272 #endif // COIN_EXTRA_DEBUG
273  return this->itembuffer[--this->numitems];
274 }
275 
276 template <class Type> inline const Type *
277 SbList<Type>::getArrayPtr(const int start) const
278 {
279  return &this->itembuffer[start];
280 }
281 
282 template <class Type> inline Type
283 SbList<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 
291 template <class Type> inline Type &
292 SbList<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 
300 template <class Type> inline int
301 SbList<Type>::operator==(const SbList<Type> & l) const
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 
310 template <class Type> inline int
311 SbList<Type>::operator!=(const SbList<Type> & l) const
312 {
313  return !(*this == l);
314 }
315 
316 #endif // !SMALLCHANGE_SBLIST_H
SbList(const int sizehint=DEFAULTSIZE)
Definition: SbList.h:101
Type pop(void)
Definition: SbList.h:268
void push(const Type item)
Definition: SbList.h:262
int operator==(const SbList< Type > &l) const
Definition: SbList.h:301
void append(const Type item)
Definition: SbList.h:187
void remove(const int index)
Definition: SbList.h:226
Definition: SbList.h:69
int find(const Type item) const
Definition: SbList.h:194
void truncate(const int length, const int dofit=0)
Definition: SbList.h:252
int operator!=(const SbList< Type > &l) const
Definition: SbList.h:311
const Type * getArrayPtr(const int start=0) const
Definition: SbList.h:277
int getArraySize(void) const
Definition: SbList.h:145
Type operator[](const int index) const
Definition: SbList.h:283
void insert(const Type item, const int insertbefore)
Definition: SbList.h:202
void copy(const SbList< Type > &l)
Definition: SbList.h:151
void removeItem(const Type item)
Definition: SbList.h:216
void fit(void)
Definition: SbList.h:168
void removeFast(const int index)
Definition: SbList.h:237
~SbList()
Definition: SbList.h:115
SbList< Type > & operator=(const SbList< Type > &l)
Definition: SbList.h:161
void expand(const int size)
Definition: SbList.h:138
int getLength(void) const
Definition: SbList.h:246