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