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