SmallChange  1.0.0
A collection of extensions to Coin3D
Loading...
Searching...
No Matches
misc/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 <cstddef> // NULL definition
38
39// We usually implement inline functions below the class definition,
40// since we think that makes the file more readable. However, this is
41// not done for this class, since Microsoft Visual C++ is not too
42// happy about having functions declared as inline for a template
43// class.
44
45// FIXME: the #pragmas below is just a quick hack to avoid heaps of
46// irritating warning messages from the compiler for client code
47// compiled under MSVC++. Should try to find the real reason for the
48// warnings and fix the cause of the problem instead. 20020730 mortene.
49//
50// UPDATE 20030617 mortene: there is a Microsoft Knowledge Base
51// article at <URL:http://support.microsoft.com> which is related to
52// this problem. It's article number KB168958.
53//
54// In short, the general solution is that classes that exposes usage
55// of SbList<type> needs to declare the specific template instance
56// with "extern" and __declspec(dllimport/export).
57//
58// That is a lot of work to change, tho'. Another possibility which
59// might be better is to simply avoid using (exposing) SbList from any
60// of the other public classes. Judging from a quick look, this seems
61// feasible, and just a couple of hours or so of work.
62//
63#ifdef _MSC_VER // Microsoft Visual C++
64#pragma warning(disable:4251)
65#pragma warning(disable:4275)
66#endif // _MSC_VER
67
68template <class Type>
69class SbList {
70 // Older compilers aren't too happy about const declarations in the
71 // class definitions, so use the enum trick described by Scott
72 // Meyers in "Effective C++".
73 enum { DEFAULTSIZE = 4 };
74
75public:
76
77 SbList(const int sizehint = DEFAULTSIZE)
78 : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) {
79 if (sizehint > DEFAULTSIZE) this->grow(sizehint);
80 }
81
82 SbList(const SbList<Type> & l)
83 : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) {
84 this->copy(l);
85 }
86
87 ~SbList() {
88 if (this->itembuffer != builtinbuffer) delete[] this->itembuffer;
89 }
90
91 void copy(const SbList<Type> & l) {
92 if (this == &l) return;
93 const int n = l.numitems;
94 this->expand(n);
95 for (int i = 0; i < n; i++) this->itembuffer[i] = l.itembuffer[i];
96 }
97
98 SbList <Type> & operator=(const SbList<Type> & l) {
99 this->copy(l);
100 return *this;
101 }
102
103 void fit(void) {
104 const int items = this->numitems;
105
106 if (items < this->itembuffersize) {
107 Type * newitembuffer = this->builtinbuffer;
108 if (items > DEFAULTSIZE) newitembuffer = new Type[items];
109
110 if (newitembuffer != this->itembuffer) {
111 for (int i = 0; i < items; i++) newitembuffer[i] = this->itembuffer[i];
112 }
113
114 if (this->itembuffer != this->builtinbuffer) delete[] this->itembuffer;
115 this->itembuffer = newitembuffer;
116 this->itembuffersize = items > DEFAULTSIZE ? items : DEFAULTSIZE;
117 }
118 }
119
120 void append(const Type item) {
121 if (this->numitems == this->itembuffersize) this->grow();
122 this->itembuffer[this->numitems++] = item;
123 }
124
125 int find(const Type item) const {
126 for (int i = 0; i < this->numitems; i++)
127 if (this->itembuffer[i] == item) return i;
128 return -1;
129 }
130
131 void insert(const Type item, const int insertbefore) {
132#ifdef COIN_EXTRA_DEBUG
134#endif // COIN_EXTRA_DEBUG
135 if (this->numitems == this->itembuffersize) this->grow();
136
137 for (int i = this->numitems; i > insertbefore; i--)
138 this->itembuffer[i] = this->itembuffer[i-1];
139 this->itembuffer[insertbefore] = item;
140 this->numitems++;
141 }
142
143 void removeItem(const Type item) {
144 int idx = this->find(item);
145#ifdef COIN_EXTRA_DEBUG
146 assert(idx != -1);
147#endif // COIN_EXTRA_DEBUG
148 this->remove(idx);
149 }
150
151 void remove(const int index) {
152#ifdef COIN_EXTRA_DEBUG
153 assert(index >= 0 && index < this->numitems);
154#endif // COIN_EXTRA_DEBUG
155 this->numitems--;
156 for (int i = index; i < this->numitems; i++)
157 this->itembuffer[i] = this->itembuffer[i + 1];
158 }
159
160 void removeFast(const int index) {
161#ifdef COIN_EXTRA_DEBUG
162 assert(index >= 0 && index < this->numitems);
163#endif // COIN_EXTRA_DEBUG
164 this->itembuffer[index] = this->itembuffer[--this->numitems];
165 }
166
167 int getLength(void) const {
168 return this->numitems;
169 }
170
171 void truncate(const int length, const int fit = 0) {
172#ifdef COIN_EXTRA_DEBUG
173 assert(length <= this->numitems);
174#endif // COIN_EXTRA_DEBUG
175 this->numitems = length;
176 if (fit) this->fit();
177 }
178
179 void push(const Type item) {
180 this->append(item);
181 }
182
183 Type pop(void) {
184#ifdef COIN_EXTRA_DEBUG
185 assert(this->numitems > 0);
186#endif // COIN_EXTRA_DEBUG
187 return this->itembuffer[--this->numitems];
188 }
189
190 Type getLast(void) {
191 assert(this->numitems > 0);
192 return this->itembuffer[this->numitems - 1];
193 }
194
195 const Type * getArrayPtr(const int start = 0) const {
196 return &this->itembuffer[start];
197 }
198
199 Type operator[](const int index) const {
200#ifdef COIN_EXTRA_DEBUG
201 assert(index >= 0 && index < this->numitems);
202#endif // COIN_EXTRA_DEBUG
203 return this->itembuffer[index];
204 }
205
206 Type & operator[](const int index) {
207#ifdef COIN_EXTRA_DEBUG
208 assert(index >= 0 && index < this->numitems);
209#endif // COIN_EXTRA_DEBUG
210 return this->itembuffer[index];
211 }
212
213 int operator==(const SbList<Type> & l) const {
214 if (this == &l) return TRUE;
215 if (this->numitems != l.numitems) return FALSE;
216 for (int i = 0; i < this->numitems; i++)
217 if (this->itembuffer[i] != l.itembuffer[i]) return FALSE;
218 return TRUE;
219 }
220
221 int operator!=(const SbList<Type> & l) const {
222 return !(*this == l);
223 }
224
225protected:
226
227 void expand(const int size) {
228 this->grow(size);
229 this->numitems = size;
230 }
231
232 int getArraySize(void) const {
233 return this->itembuffersize;
234 }
235
236private:
237 void grow(const int size = -1) {
238 // Default behavior is to double array size.
239 if (size == -1) this->itembuffersize <<= 1;
240 else if (size <= this->itembuffersize) return;
241 else { this->itembuffersize = size; }
242
243 Type * newbuffer = new Type[this->itembuffersize];
244 const int n = this->numitems;
245 for (int i = 0; i < n; i++) newbuffer[i] = this->itembuffer[i];
246 if (this->itembuffer != this->builtinbuffer) delete[] this->itembuffer;
247 this->itembuffer = newbuffer;
248 }
249
250 int itembuffersize;
251 int numitems;
252 Type * itembuffer;
253 Type builtinbuffer[DEFAULTSIZE];
254};
255
256#endif // !COIN_SBLIST_H
Definition misc/SbList.h:69