00001
00002 #ifndef INCLUDED_ListMemBuf_h
00003 #define INCLUDED_ListMemBuf_h
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 template < class T_t, unsigned int MAX, class idx_t=unsigned short >
00020 class ListMemBuf {
00021 public:
00022
00023 ListMemBuf();
00024 ~ListMemBuf();
00025
00026
00027 typedef T_t T;
00028
00029 static const unsigned int MAX_ENTRIES = MAX;
00030
00031 typedef idx_t index_t;
00032
00033 static index_t getMaxCapacity() { return MAX_ENTRIES; }
00034 index_t size() const { return cursize; }
00035 index_t countf() const;
00036 index_t countb() const;
00037 bool empty() const { return cursize==0; }
00038
00039
00040
00041
00042 inline T& operator[](unsigned int x) { return *(T*)(void*)(entries[x].data); }
00043 inline const T& operator[](unsigned int x) const { return *(const T*)(const void*)(entries[x].data); }
00044
00045 inline index_t begin() const { return activeBegin; }
00046 T& front() { return *(T*)(void*)(entries[activeBegin].data); }
00047 const T& front() const { return *(const T*)(const void*)(entries[activeBegin].data); }
00048
00049 inline index_t end() const { return (index_t)-1; }
00050 T& back() { return *(T*)(void*)(entries[activeBack].data); }
00051 const T& back() const { return *(const T*)(const void*)(entries[activeBack].data); }
00052
00053 index_t new_front();
00054 index_t push_front(const T& data) { index_t tmp=new_front(); if(tmp!=end()) operator[](tmp)=data; return tmp; }
00055 void pop_front();
00056 void pop_front(T& ret) { ret=front(); pop_front(); }
00057
00058 index_t new_back();
00059 index_t push_back(const T& data) { index_t tmp=new_back(); if(tmp!=end()) operator[](tmp)=data; return tmp; }
00060 void pop_back();
00061 void pop_back(T& ret) { ret=back(); pop_back(); }
00062
00063 index_t new_before(index_t x);
00064 index_t push_before(index_t x, const T& data) { index_t tmp=new_before(x); if(tmp!=end()) operator[](tmp)=data; return tmp; }
00065
00066 index_t new_after(index_t x) { return new_before(next(x)); }
00067 index_t push_after(index_t x, const T& data) { index_t tmp=new_after(x); if(tmp!=end()) operator[](tmp)=data; return tmp; }
00068
00069 void erase(index_t x);
00070 void clear();
00071
00072 void swap(index_t a, index_t b);
00073
00074 index_t next(index_t x) const { return x==end()?activeBegin:entries[x].next; }
00075 index_t prev(index_t x) const { return x==end()?activeBack:entries[x].prev; }
00076
00077 protected:
00078 index_t pop_free();
00079 void push_free(index_t x);
00080
00081
00082 struct entry_t {
00083
00084 entry_t() : next(static_cast<index_t>(-1)), prev(static_cast<index_t>(-1)) {}
00085 double data[(sizeof(T)-1)/sizeof(double)+1];
00086 index_t next;
00087 index_t prev;
00088 };
00089 entry_t entries[MAX_ENTRIES==0?1:MAX_ENTRIES];
00090 index_t activeBegin;
00091 index_t activeBack;
00092 index_t freeBegin;
00093 index_t freeBack;
00094 index_t cursize;
00095 };
00096
00097 template < class T, unsigned int MAX, class index_t >
00098 ListMemBuf<T,MAX,index_t>::ListMemBuf()
00099 : activeBegin(end()), activeBack(end()), freeBegin(end()), freeBack(end()), cursize(0)
00100 {
00101 for(unsigned int x=0; x+1<MAX_ENTRIES; x++)
00102 entries[x].next=x+1;
00103 entries[MAX_ENTRIES-1].next=end();
00104 freeBegin=0;
00105 freeBack=MAX_ENTRIES-1;
00106 }
00107
00108 template < class T, unsigned int MAX, class index_t >
00109 ListMemBuf<T,MAX,index_t>::~ListMemBuf() {
00110 clear();
00111 }
00112
00113 template < class T, unsigned int MAX, class index_t>
00114 index_t
00115 ListMemBuf<T,MAX,index_t>::countf() const {
00116 int x=0;
00117 for(index_t c=begin(); c!=end(); c=next(c))
00118 x++;
00119 return x;
00120 }
00121
00122 template < class T, unsigned int MAX, class index_t>
00123 index_t
00124 ListMemBuf<T,MAX,index_t>::countb() const {
00125 int x=0;
00126 for(index_t c=end(); c!=begin(); c=prev(c))
00127 x++;
00128 return x;
00129 }
00130
00131 template < class T, unsigned int MAX, class index_t >
00132 index_t
00133 ListMemBuf<T,MAX,index_t>::new_front() {
00134 index_t tmp = pop_free();
00135 if(tmp==end())
00136 return end();
00137 entries[tmp].prev=end();
00138 entries[tmp].next=activeBegin;
00139 if(activeBegin!=end())
00140 entries[activeBegin].prev=tmp;
00141 else
00142 activeBack=tmp;
00143 activeBegin=tmp;
00144 return tmp;
00145 }
00146
00147 template < class T, unsigned int MAX, class index_t >
00148 index_t
00149 ListMemBuf<T,MAX,index_t>::new_back() {
00150 index_t tmp = pop_free();
00151 if(tmp==end())
00152 return end();
00153 entries[tmp].prev=activeBack;
00154 entries[tmp].next=end();
00155 if(activeBack!=end())
00156 entries[activeBack].next=tmp;
00157 else
00158 activeBegin=tmp;
00159 activeBack=tmp;
00160 return tmp;
00161 }
00162
00163 template < class T, unsigned int MAX, class index_t >
00164 index_t
00165 ListMemBuf<T,MAX,index_t>::new_before(index_t x) {
00166 if(x==end())
00167 return new_back();
00168 if(entries[x].prev==end())
00169 return new_front();
00170 index_t tmp = pop_free();
00171 if(tmp==end())
00172 return end();
00173 entries[tmp].next=x;
00174 entries[tmp].prev=entries[x].prev;
00175 entries[x].prev=tmp;
00176 entries[ entries[tmp].prev ].next = tmp;
00177 return tmp;
00178 }
00179
00180 template < class T, unsigned int MAX, class index_t >
00181 void
00182 ListMemBuf<T,MAX,index_t>::pop_front() {
00183 index_t tmp = activeBegin;
00184 activeBegin = entries[activeBegin].next;
00185 if(activeBegin==end())
00186 activeBack=end();
00187 else
00188 entries[activeBegin].prev = end();
00189 push_free(tmp);
00190 }
00191
00192 template < class T, unsigned int MAX, class index_t >
00193 void
00194 ListMemBuf<T,MAX,index_t>::pop_back() {
00195 index_t tmp = activeBack;
00196 activeBack = entries[activeBack].prev;
00197 if(activeBack==end())
00198 activeBegin=end();
00199 else
00200 entries[activeBack].next = end();
00201 push_free(tmp);
00202 }
00203
00204 template < class T, unsigned int MAX, class index_t >
00205 void
00206 ListMemBuf<T,MAX,index_t>::erase(index_t x) {
00207 if(x==activeBegin) {
00208 pop_front();
00209 return;
00210 }
00211 if(x==activeBack) {
00212 pop_back();
00213 return;
00214 }
00215 entries[ entries[x].next ].prev = entries[x].prev;
00216 entries[ entries[x].prev ].next = entries[x].next;
00217 push_free(x);
00218 }
00219
00220 template < class T, unsigned int MAX, class index_t >
00221 void
00222 ListMemBuf<T,MAX,index_t>::clear() {
00223 if(cursize!=0) {
00224 for(index_t it=activeBegin; it!=end(); it=entries[it].next)
00225 operator[](it).~T();
00226 if(freeBack==end())
00227 freeBegin=activeBegin;
00228 else
00229 entries[freeBack].next=activeBegin;
00230 freeBack=activeBack;
00231 activeBegin=activeBack=end();
00232 }
00233 cursize=0;
00234 }
00235
00236 template < class T, unsigned int MAX, class index_t >
00237 void
00238 ListMemBuf<T,MAX,index_t>::swap(index_t a, index_t b) {
00239 if(a==b || a==end() || b==end())
00240 return;
00241 if(entries[a].prev==b) {
00242 entries[a].prev=entries[b].prev;
00243 entries[b].next=entries[a].next;
00244 entries[a].next=b;
00245 entries[b].prev=a;
00246 if(entries[a].prev!=end())
00247 entries[entries[a].prev].next=a;
00248 else
00249 activeBegin=a;
00250 if(entries[b].next!=end())
00251 entries[entries[b].next].prev=b;
00252 else
00253 activeBack=b;
00254 } else if(entries[a].next==b) {
00255 entries[a].next=entries[b].next;
00256 entries[b].prev=entries[a].prev;
00257 entries[a].prev=b;
00258 entries[b].next=a;
00259 if(entries[a].next!=end())
00260 entries[entries[a].next].prev=a;
00261 else
00262 activeBack=a;
00263 if(entries[b].prev!=end())
00264 entries[entries[b].prev].next=b;
00265 else
00266 activeBegin=b;
00267 } else {
00268 index_t tmpp=entries[a].prev, tmpn=entries[a].next;
00269 entries[a].prev=entries[b].prev;
00270 entries[a].next=entries[b].next;
00271 entries[b].prev=tmpp;
00272 entries[b].next=tmpn;
00273 if(entries[a].prev!=end())
00274 entries[entries[a].prev].next=a;
00275 else
00276 activeBegin=a;
00277 if(entries[a].next!=end())
00278 entries[entries[a].next].prev=a;
00279 else
00280 activeBack=a;
00281 if(entries[b].prev!=end())
00282 entries[entries[b].prev].next=b;
00283 else
00284 activeBegin=b;
00285 if(entries[b].next!=end())
00286 entries[entries[b].next].prev=b;
00287 else
00288 activeBack=b;
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 }
00314
00315
00316
00317 template < class T, unsigned int MAX, class index_t >
00318 index_t
00319 ListMemBuf<T,MAX,index_t>::pop_free() {
00320 if(freeBegin==end())
00321 return end();
00322 index_t tmp=freeBegin;
00323 if(freeBegin==freeBack)
00324 freeBegin=freeBack=end();
00325 else
00326 freeBegin=entries[freeBegin].next;
00327 cursize++;
00328 new (entries[tmp].data) T;
00329 return tmp;
00330 }
00331
00332
00333 template < class T, unsigned int MAX, class index_t >
00334 void
00335 ListMemBuf<T,MAX,index_t>::push_free(index_t x) {
00336 if(freeBack==end())
00337 freeBegin=x;
00338 else
00339 entries[freeBack].next=x;
00340 freeBack=x;
00341 cursize--;
00342 operator[](x).~T();
00343 }
00344
00345
00346
00347
00348
00349
00350 #endif