00001 #ifndef EP_CVEC_H_
00002 #define EP_CVEC_H_
00003
00004 #include <utility/malloc.h>
00005 #include "algorithm.h"
00006
00007
00008 __BEGIN_SYS
00009
00010 const unsigned int CVEC_ADAPTION_RATE = 16;
00011
00017 template<class Contained>
00018 class CircularVector {
00019 public:
00024 template<class ItTp>
00025 struct Incrementor {
00031 inline Incrementor(int current, CircularVector& vec) :
00032 current(current), vec(vec) {}
00033
00039 inline Incrementor operator+(int i) {
00040 vec.inc(current, i);
00041 return Incrementor(*this);
00042 }
00043
00049 inline Incrementor operator++(int) {
00050 Incrementor result(*this);
00051 vec.inc(current, 1);
00052 return result;
00053 }
00054
00058 inline void operator++() {
00059 vec.inc(current, 1);
00060 }
00061
00065 inline void operator--() {
00066 vec.inc(current, -1);
00067 }
00068
00073 inline Incrementor operator--(int) {
00074 Incrementor result(*this);
00075 vec.inc(current, -1);
00076 return result;
00077 }
00078
00083 inline ItTp& operator*() const {
00084 return (vec._elements[current]);
00085 }
00086
00092 inline bool operator==(const Incrementor& comparable) const {
00093 return ((comparable.current == current));
00094 }
00095
00101 inline bool operator!=(const Incrementor& comparable) const {
00102 return !operator==(comparable);
00103 }
00104
00105 int current;
00106 CircularVector& vec;
00107 };
00108
00109 typedef Incrementor<Contained> Iterator;
00110 typedef Incrementor<const Contained> ConstIterator;
00111
00112 friend struct Incrementor<Contained>;
00113 friend struct Incrementor<const Contained>;
00114
00118 inline void print(Iterator begin, Iterator end) {
00119
00120
00121
00122
00123
00124 }
00125
00129 CircularVector() : _size(0), _capacity(1), _begin(0), _end(0) {
00130 _elements = (Contained*) malloc(sizeof(Contained) * capacity());
00131 }
00132
00133 virtual ~CircularVector() {
00134 free(_elements);
00135 }
00136
00141 Iterator begin() {
00142 return Iterator(_begin, *this);
00143 }
00144
00149 ConstIterator begin() const {
00150 return ConstIterator(_begin, *this);
00151 }
00152
00157 Iterator end() {
00158 return Iterator(_end, *this);
00159 }
00160
00165 ConstIterator end() const {
00166 return ConstIterator(_end, *this);
00167 }
00168
00173 inline void pushFront(const Contained& contained) {
00174
00175 if (size() >= (capacity() - 1)) enlarge();
00176 ++_size;
00177
00178 inc(_begin, -1);
00179 _elements[_begin] = contained;
00180 }
00181
00186 inline void pushBack(const Contained& contained) {
00187
00188 if (size() >= (capacity() - 1)) enlarge();
00189 ++_size;
00190 _elements[_end] = contained;
00191 inc(_end, +1);
00192
00193 }
00194
00195 inline Contained& operator[](unsigned int i) {
00196 return *(begin() + i);
00197 }
00198
00202 inline void popBack() {
00203 --_size;
00204 inc(_end, -1);
00205
00206
00207 }
00208
00212 inline void popFront() {
00213 --_size;
00214 inc(_begin, +1);
00215
00216
00217 }
00218
00223 inline Contained& front() const {
00224 return _elements[_begin];
00225 }
00226
00231 inline Contained& back() const {
00232 return _elements[_end - 1];
00233 }
00234
00239 inline unsigned int size() const {
00240 return _size;
00241 }
00242
00247 inline unsigned int capacity() const {
00248 return _capacity;
00249 }
00250
00255 inline bool isEmpty() const {
00256 return (size() == 0);
00257 }
00258
00264 void remove(const Contained& contained) {
00265 for (Iterator it = begin(); it != end(); ++it) {
00266 if (*it == contained) {
00267 ++it;
00268 shift(it, end(), -1);
00269 break;
00270 }
00271 }
00272 }
00273
00274 protected:
00278 Contained* _elements;
00279 unsigned int _size, _capacity;
00283 int _begin, _end;
00284
00290 inline void inc(int& toIncrement, int n) {
00291 toIncrement += n + _capacity;
00292 toIncrement %= _capacity;
00293 }
00294
00298 void enlarge() {
00299 Contained* newElements = (Contained*) malloc(sizeof(Contained)
00300 * capacity() * CVEC_ADAPTION_RATE);
00301
00302 copy(begin(), end(), newElements);
00303
00304 free(_elements);
00305
00306 _begin = 0;
00307 _end = size();
00308 _elements = newElements;
00309 _capacity *= CVEC_ADAPTION_RATE;
00310 }
00311
00316 void minimize() {
00317 Contained* newElements = (Contained*) malloc(sizeof(Contained)
00318 * (capacity() / CVEC_ADAPTION_RATE));
00319
00320 copy(begin(), end(), newElements);
00321
00322 free(_elements);
00323
00324 _begin = 0;
00325 _end = size();
00326 _elements = newElements;
00327 _capacity /= CVEC_ADAPTION_RATE;
00328 }
00329
00330 };
00331
00335 template<class Contained>
00336 class OrderedCVector : public CircularVector<Contained> {
00337 public:
00341 OrderedCVector() : CircularVector<Contained>() {}
00342
00343 typedef typename CircularVector<Contained>::Iterator Iterator;
00344
00350 template<typename Comparator>
00351 inline void pushBack(const Contained& contained, const Comparator& comparator) {
00352
00353
00354
00355 if (CircularVector<Contained>::size() >=
00356 (CircularVector<Contained>::capacity() - 1)) {
00357
00358 CircularVector<Contained>::enlarge();
00359 }
00360
00361 int i = 0, j = CircularVector<Contained>::size() - 1;
00362
00363 int index = (i + j)/2;
00364
00365 if (j == -1) {
00366 CircularVector<Contained>::pushBack(contained);
00367 return;
00368 }
00369
00370 int comparison = comparator(contained, (*this)[index]);
00371 int pi = -1, pj = -1;
00372 while ((i < j)) {
00373 pi = i;
00374 pj = j;
00375 if (comparison == 1) i = index + 1;
00376 else j = index + 1;
00377 if (pi == i && pj == j) {
00378 ++index;
00379 break;
00380 }
00381 comparison = comparator(contained, (*this)[index]);
00382
00383 }
00384
00385 for (unsigned int i = CircularVector<Contained>::size(); i > (unsigned int)index; --i)
00386 (*this)[i] = (*this)[i - 1];
00387
00388
00389
00390
00391
00392 ++CircularVector<Contained>::_size;
00393 (*this)[index] = contained;
00394 CircularVector<Contained>::inc(
00395 CircularVector<Contained>::_end, +1);
00396
00397
00398
00399
00400
00401
00402
00403 }
00404
00405 };
00406
00407 __END_SYS
00408
00409 #endif