00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00029
#ifndef __ID__
00030
#define __ID__
00031
00032
00033
#include <list>
00034
#include <cassert>
00035
#include <iostream>
00036
00037
00038
00039
00040 typedef unsigned int uInt;
00041 #define Assert(a, b) assert( a && b)
00042
00043
00044
class noRecycling;
00045
template<
class>
00046
class wrapAround;
00047
00049
00055
template<uInt bitsIndex, uInt bitsMagic>
00056 class id
00057 {
00058
public:
00059
id<bitsIndex,bitsMagic>() :
m_id(0) {}
00060
id<bitsIndex,bitsMagic>(
const uInt& v) {
m_id = v; }
00061 ~
id<bitsIndex,bitsMagic>() {}
00062
00064 id<bitsIndex,bitsMagic> &
operator=(
const id<bitsIndex,bitsMagic>& id_) {
m_id = id_;
return *
this; }
00066 id<bitsIndex,bitsMagic> &
operator=(
const uInt& v) {
m_id = v;
return *
this; }
00068 operator uInt ()
const {
return m_id; }
00070 bool operator==(
const id<bitsIndex,bitsMagic>& id_)
const {
return m_id == id_; }
00072 bool operator!=(
const id<bitsIndex,bitsMagic>& id_)
const {
return m_id != id_; }
00074 bool isNull()
const {
return m_id == 0; }
00076
template<uInt bitsIndex_, uInt bitsMagic_>
00077 id<bitsIndex,bitsMagic> &
operator=(
const id<bitsIndex_,bitsMagic_>& id_)
00078 {
00079
Assert(id_.
m_index<=
MAX_INDEX && id_.
m_magic<=
MAX_MAGIC,
"invalid assignment to an id from an id of a different type");
00080
m_index = id_.
m_index;
00081
m_magic = id_.
m_magic;
00082
return *
this;
00083 }
00084
00086
enum
00087 {
00088 BITS_INDEX = bitsIndex,
00089 BITS_MAGIC = bitsMagic,
00090 MAX_INDEX = 1<<(bitsIndex - 1),
00091 MAX_MAGIC = 1<<(bitsMagic - 1)
00092 };
00093
00095
union
00096
{
00097
struct
00098
{
00099 uInt m_index : bitsIndex;
00100 uInt m_magic : bitsMagic;
00101 };
00102
00103 uInt m_id : (bitsIndex+bitsMagic);
00104 };
00105
protected:
00106
private:
00107 };
00108
00109
00110
00112
00115
template< uInt numBits >
00116 class newIdGen
00117 {
00118
protected:
00119 newIdGen() :
m_idGen(0) {}
00120
00123
enum
00124 {
00125 NUM_BITS = numBits,
00126 MAX_ID = 1 << (numBits - 1)
00127 };
00128
00130 uInt m_idGen : numBits;
00131 };
00132
00133
00135
00142
template<
00143
class recyclingPolicy =
noRecycling,
00144
template <
class>
class wrapAroundPolicy =
wrapAround,
00145
uInt numBits = 32
00146 >
00147 class idGen
00148 :
public recyclingPolicy
00149 ,
public wrapAroundPolicy< newIdGen<numBits> >
00150 {
00151
public:
00153 uInt getId()
00154 {
00155
00156
uInt id = getRecycledId();
00157
00158
00159
if(!
id)
id = getNewId();
00160
00161
00162
return id;
00163 }
00164
00165
00166
protected:
00167
private:
00168 };
00169
00170
00171
00172
00174 class noRecycling
00175 {
00176
public:
00178 void releaseId(uInt
id) {}
00179
00180
protected:
00182 uInt getRecycledId() {
return 0; }
00183
00184
private:
00185 };
00186
00187
00189 class recycleReleasedIds
00190 {
00191
public:
00193 void releaseId(uInt
id)
00194 {
00195 m_releasedIds.push_back(
id);
00196 }
00197
00198
protected:
00201 uInt getRecycledId()
00202 {
00203
if(m_releasedIds.size())
00204 {
00205
uInt id = *(m_releasedIds.begin());
00206 m_releasedIds.pop_front();
00207
return id;
00208 }
else
00209 {
00210
return 0;
00211 }
00212 }
00213
00214
private:
00216 std::list<uInt> m_releasedIds;
00217 };
00218
00219
00221
template<
class _newIdGen>
00222 class wrapAround :
public _newIdGen
00223 {
00224
public:
00226 uInt getNewId()
00227 {
00228
if(++m_idGen==0)
00229 {
00230 m_idGen = 1;
00231 }
00232
return m_idGen;
00233 }
00234
protected:
00235
private:
00237
00238 };
00239
00240
00244
template<
class _newIdGen>
00245 class assertOnWrapAround :
public _newIdGen
00246 {
00247
public:
00250 uInt getNewId()
00251 {
00252 ++m_idGen;
00253
Assert(m_idGen,
"exceeded maximum id");
00254
return m_idGen;
00255 }
00256
protected:
00257
private:
00258 };
00259
00260
00261
00262
00265
template<
class _newIdGen>
00266 class noWrapAround :
public _newIdGen
00267 {
00268
public:
00271 uInt getNewId()
00272 {
00273
00274
if(m_idGen==MAX_ID)
00275 {
00276
00277
return 0;
00278 }
00279
return ++m_idGen;
00280 }
00281
protected:
00282
private:
00283 };
00284
00285
#endif