00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#ifndef COIN_SBLIST_H
00021
#define COIN_SBLIST_H
00022
00023
#include <Inventor/SbBasic.h>
00024
#include <assert.h>
00025
#include <stddef.h>
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
#ifdef _MSC_VER // Microsoft Visual C++
00038
#pragma warning(disable:4251)
00039
#pragma warning(disable:4275)
00040
#endif // _MSC_VER
00041
00042
template <
class Type>
00043 class COIN_DLL_API SbList {
00044
00045
00046
00047
enum { DEFAULTSIZE = 4 };
00048
00049
public:
00050
00051 SbList(
const int sizehint = DEFAULTSIZE)
00052 : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) {
00053
if (sizehint > DEFAULTSIZE) this->grow(sizehint);
00054 }
00055
00056 SbList(
const SbList<Type> & l)
00057 : itembuffersize(DEFAULTSIZE), numitems(0), itembuffer(builtinbuffer) {
00058 this->copy(l);
00059 }
00060
00061 ~SbList() {
00062
if (this->itembuffer != builtinbuffer)
delete[] this->itembuffer;
00063 }
00064
00065 void copy(
const SbList<Type> & l) {
00066
if (
this == &l)
return;
00067
const int n = l.
numitems;
00068 this->expand(n);
00069
for (
int i = 0; i < n; i++) this->itembuffer[i] = l.
itembuffer[i];
00070 }
00071
00072 SbList <Type> & operator=(
const SbList<Type> & l) {
00073 this->copy(l);
00074
return *
this;
00075 }
00076
00077 void fit(
void) {
00078
const int items = this->numitems;
00079
00080
if (items < this->itembuffersize) {
00081 Type * newitembuffer = this->builtinbuffer;
00082
if (items > DEFAULTSIZE) newitembuffer =
new Type[items];
00083
00084
if (newitembuffer != this->itembuffer) {
00085
for (
int i = 0; i < items; i++) newitembuffer[i] = this->itembuffer[i];
00086 }
00087
00088
if (this->itembuffer != this->builtinbuffer)
delete[] this->itembuffer;
00089 this->itembuffer = newitembuffer;
00090 this->itembuffersize = items > DEFAULTSIZE ? items : DEFAULTSIZE;
00091 }
00092 }
00093
00094 void append(
const Type item) {
00095
if (this->numitems == this->itembuffersize) this->grow();
00096 this->itembuffer[this->numitems++] = item;
00097 }
00098
00099 int find(
const Type item)
const {
00100
for (
int i = 0; i < this->numitems; i++)
00101
if (this->itembuffer[i] == item)
return i;
00102
return -1;
00103 }
00104
00105 void insert(
const Type item,
const int insertbefore) {
00106
#ifdef COIN_EXTRA_DEBUG
00107
assert(insertbefore >= 0 && insertbefore <= this->numitems);
00108
#endif // COIN_EXTRA_DEBUG
00109
if (this->numitems == this->itembuffersize) this->grow();
00110
00111
for (
int i = this->numitems; i > insertbefore; i--)
00112 this->itembuffer[i] = this->itembuffer[i-1];
00113 this->itembuffer[insertbefore] = item;
00114 this->numitems++;
00115 }
00116
00117 void removeItem(
const Type item) {
00118
int idx = this->find(item);
00119
#ifdef COIN_EXTRA_DEBUG
00120
assert(idx != -1);
00121
#endif // COIN_EXTRA_DEBUG
00122
this->remove(idx);
00123 }
00124
00125 void remove(
const int index) {
00126
#ifdef COIN_EXTRA_DEBUG
00127
assert(index >= 0 && index < this->numitems);
00128
#endif // COIN_EXTRA_DEBUG
00129
this->numitems--;
00130
for (
int i = index; i < this->numitems; i++)
00131 this->itembuffer[i] = this->itembuffer[i + 1];
00132 }
00133
00134 void removeFast(
const int index) {
00135
#ifdef COIN_EXTRA_DEBUG
00136
assert(index >= 0 && index < this->numitems);
00137
#endif // COIN_EXTRA_DEBUG
00138
this->itembuffer[index] = this->itembuffer[--this->numitems];
00139 }
00140
00141 int getLength(
void)
const {
00142
return this->numitems;
00143 }
00144
00145 void truncate(
const int length,
const int fit = 0) {
00146
#ifdef COIN_EXTRA_DEBUG
00147
assert(length <= this->numitems);
00148
#endif // COIN_EXTRA_DEBUG
00149
this->numitems = length;
00150
if (fit) this->fit();
00151 }
00152
00153 void push(
const Type item) {
00154 this->append(item);
00155 }
00156
00157 Type pop(
void) {
00158
#ifdef COIN_EXTRA_DEBUG
00159
assert(this->numitems > 0);
00160
#endif // COIN_EXTRA_DEBUG
00161
return this->itembuffer[--this->numitems];
00162 }
00163
00164 const Type * getArrayPtr(
const int start = 0)
const {
00165
return &this->itembuffer[start];
00166 }
00167
00168 Type operator[](
const int index)
const {
00169
#ifdef COIN_EXTRA_DEBUG
00170
assert(index >= 0 && index < this->numitems);
00171
#endif // COIN_EXTRA_DEBUG
00172
return this->itembuffer[index];
00173 }
00174
00175 Type & operator[](
const int index) {
00176
#ifdef COIN_EXTRA_DEBUG
00177
assert(index >= 0 && index < this->numitems);
00178
#endif // COIN_EXTRA_DEBUG
00179
return this->itembuffer[index];
00180 }
00181
00182 int operator==(
const SbList<Type> & l)
const {
00183
if (
this == &l)
return TRUE;
00184
if (this->numitems != l.
numitems)
return FALSE;
00185
for (
int i = 0; i < this->numitems; i++)
00186
if (this->itembuffer[i] != l.
itembuffer[i])
return FALSE;
00187
return TRUE;
00188 }
00189
00190 int operator!=(
const SbList<Type> & l)
const {
00191
return !(*
this == l);
00192 }
00193
00194
protected:
00195
00196 void expand(
const int size) {
00197 this->grow(size);
00198 this->numitems = size;
00199 }
00200
00201 int getArraySize(
void)
const {
00202
return this->itembuffersize;
00203 }
00204
00205
private:
00206
void grow(
const int size = -1) {
00207
00208
if (size == -1) this->itembuffersize <<= 1;
00209
else if (size <= this->itembuffersize)
return;
00210
else { this->itembuffersize = size; }
00211
00212 Type * newbuffer =
new Type[this->itembuffersize];
00213
const int n = this->numitems;
00214
for (
int i = 0; i < n; i++) newbuffer[i] = this->itembuffer[i];
00215
if (this->itembuffer != this->builtinbuffer)
delete[] this->itembuffer;
00216 this->itembuffer = newbuffer;
00217 }
00218
00219
int itembuffersize;
00220
int numitems;
00221 Type * itembuffer;
00222 Type builtinbuffer[DEFAULTSIZE];
00223 };
00224
00225
#endif // !COIN_SBLIST_H