00001 #ifndef COLLECTION_HPP__
00002 #define COLLECTION_HPP__
00003
00004 #include "TObjArray.h"
00005 #include <iterator>
00006
00007 namespace cafe {
00008
00022 template<class T>
00023 class Collection {
00024 public:
00025 typedef T value_type;
00026 typedef size_t size_type;
00027 typedef T* pointer_type;
00028 typedef T& reference_type;
00029 typedef const T* const_pointer_type;
00030 typedef const T& const_reference_type;
00031 public:
00034 Collection(TObjArray *data)
00035 : _data(0)
00036 {
00037 if (data)
00038 _data = (new array_holder(data, false));
00039 else
00040 _data = (new array_holder(new TObjArray(), true));
00041 }
00042
00045 Collection(const Collection<T>& other)
00046 : _data(other._data)
00047 {
00048 _data->inc();
00049 }
00052 Collection(void)
00053 : _data (new array_holder(new TObjArray(), true))
00054 {}
00055
00057 virtual ~Collection() {
00058 _data->decAndDeleteIf();
00059 }
00060
00062 Collection<T>& operator=(const Collection<T>& other)
00063 {
00064 if(&other != this) {
00065 _data->decAndDeleteIf();
00066 _data = other._data;
00067 _data->inc();
00068 }
00069 return *this;
00070 }
00071
00075 void push_back (const T& item)
00076 {
00077 assert(item.IsOnHeap());
00078 make_us_owner_of_data();
00079 (*_data)->Add(const_cast<T*>(&item));
00080 }
00081
00084 void push_back(T *item)
00085 {
00086 make_us_owner_of_data();
00087 (*_data)->Add(item);
00088 }
00089
00091 const T& operator[](size_t index) const { return *static_cast<T*>((*_data)->At(index)); }
00092
00094
00095 class iterator;
00096 class const_iterator;
00097
00099 iterator begin() { return iterator(*_data, 0); }
00100 const_iterator begin() const { return const_iterator(*_data, 0); }
00101
00103 iterator end() { return iterator(*_data, *_data ? (*_data)->GetLast() + 1 : 0); }
00104 const_iterator end() const { return const_iterator(*_data, (*_data) ? (*_data)->GetLast() + 1 : 0); }
00105
00107 iterator erase(iterator it)
00108 {
00109 int i = it._index;
00110 make_us_owner_of_data();
00111 (*_data)->RemoveAt(i);
00112 (*_data)->Compress();
00113 return iterator((*_data), i);
00114 }
00115
00117 iterator erase(iterator first, iterator last)
00118 {
00119 int i = first._index;
00120 make_us_owner_of_data();
00121 while(i != last._index) {
00122 (*_data)->RemoveAt(i);
00123 ++i;
00124 }
00125 (*_data)->Compress();
00126 return iterator((*_data),first._index);
00127 }
00128
00130
00132 size_t size() const { return _data ? (*_data)->GetLast() + 1 : 0; }
00133
00144 template <typename compare>
00145 void sort(iterator from, iterator to, compare CompFun)
00146 {
00147 make_us_owner_of_data();
00148 full_sort(*(*_data),from._index,to._index,CompFun);
00149 return;
00150 }
00151
00152
00154 class iterator : public std::iterator<std::random_access_iterator_tag, T> {
00155 public:
00156 iterator() : _data(0), _index(0) {}
00157 iterator(const iterator& other) : _data(other._data), _index(other._index) {}
00158 iterator& operator=(const iterator& other)
00159 {
00160 if(this != &other) {
00161 _data = other._data;
00162 _index = other._index;
00163 }
00164 return *this;
00165 }
00166
00167 reference_type operator*() const { return *static_cast<T*>(_data->At(_index)); }
00168 pointer_type operator->() const { return static_cast<T*>(_data->At(_index)); }
00169
00170 iterator& operator++() { _index++; return *this; }
00171 iterator operator++(int) { iterator result(*this); _index++; return result; }
00172
00173 iterator& operator--() { _index--; return *this; }
00174 iterator operator--(int) { iterator result(*this); _index--; return result; }
00175
00176 iterator operator+(size_t offset) const { return iterator(_data, _index + offset); }
00177 iterator operator-(size_t offset) const { return iterator(_data, _index - offset); }
00178
00179
00180 typename std::iterator<std::random_access_iterator_tag, T>::difference_type
00181 operator-(const iterator& other) const { return _index - other._index; }
00182
00183 typename std::iterator<std::random_access_iterator_tag, T>::difference_type
00184 operator+(const iterator& other) const { return _index + other._index; }
00185
00186 iterator& operator+=(size_t offset) { _index += offset; return *this; }
00187 iterator& operator-=(size_t offset) { _index -= offset; return *this; }
00188
00189 bool operator<(const iterator& other) const{ return _index < other._index; }
00190 bool operator!=(const iterator& other) const { return _index != other._index; }
00191
00192 private:
00193 friend class Collection;
00194 friend class const_iterator;
00195 iterator(TObjArray* data, int index = 0) : _data(data), _index(index) {}
00196
00197 const TObjArray *_data;
00198 int _index;
00199 };
00200
00202 class const_iterator : public std::iterator<std::random_access_iterator_tag, T> {
00203 public:
00204 const_iterator() : _data(0), _index(0) {}
00205 const_iterator(const const_iterator& other) : _data(other._data), _index(other._index) {}
00206 const_iterator(const iterator& other) : _data(other._data), _index(other._index) {}
00207 const_iterator& operator=(const const_iterator& other)
00208 {
00209 if(this != &other) {
00210 _data = other._data;
00211 _index = other._index;
00212 }
00213 return *this;
00214 }
00215
00216 const_reference_type operator*() const { return *static_cast<const T*>(_data->At(_index)); }
00217 const_pointer_type operator->() const { return static_cast<const T*>(_data->At(_index)); }
00218
00219 const_iterator& operator++() { _index++; return *this; }
00220 const_iterator operator++(int) { const_iterator result(*this); _index++; return result; }
00221
00222 const_iterator& operator--() { _index--; return *this; }
00223 const_iterator operator--(int) { const_iterator result(*this); _index--; return result; }
00224
00225 const_iterator operator+(size_t offset) const { return const_iterator(_data, _index + offset); }
00226 const_iterator operator-(size_t offset) const { return const_iterator(_data, _index - offset); }
00227
00228
00229 typename std::iterator<std::random_access_iterator_tag, T>::difference_type
00230 operator-(const const_iterator& other) const { return _index - other._index; }
00231
00232 typename std::iterator<std::random_access_iterator_tag, T>::difference_type
00233 operator+(const const_iterator& other) const { return _index + other._index; }
00234
00235 const_iterator& operator+=(size_t offset) { _index += offset; return *this; }
00236 const_iterator& operator-=(size_t offset) { _index -= offset; return *this; }
00237
00238 bool operator<(const const_iterator& other) const{ return _index < other._index; }
00239 bool operator!=(const const_iterator& other) const { return _index != other._index; }
00240
00241 private:
00242 friend class Collection;
00243 const_iterator(const TObjArray* data, int index = 0) : _data(data), _index(index) {}
00244
00245 const TObjArray *_data;
00246 int _index;
00247 };
00248
00251 class array_holder {
00252 public:
00253 inline array_holder (TObjArray *obj, bool owned)
00254 : _array (obj), _count(1), _owned(owned)
00255 {}
00256 inline ~array_holder (void) {
00257 if (_owned) {
00258 delete _array;
00259 }
00260 }
00261
00262 TObjArray * operator->() {return _array;}
00263 operator TObjArray*() {return _array;}
00264 operator bool () {return _array != 0;}
00265
00266 inline void inc (void) {
00267 _count++;
00268 }
00269 inline void dec (void) {
00270 _count--;
00271 }
00272 inline void decAndDeleteIf (void) {
00273 dec();
00274 if (!ownersLeft()) {
00275 delete this;
00276 }
00277 }
00278 inline bool ownersLeft (void) {
00279 return _count != 0;
00280 }
00281 inline bool isOwned (void) {
00282 return _owned;
00283 }
00284 private:
00285 TObjArray *_array;
00286 int _count;
00287 bool _owned;
00288 };
00289 private:
00292 array_holder *_data;
00293
00296 void make_us_owner_of_data (void)
00297 {
00298 if (_data->isOwned()) {
00299 return;
00300 }
00301 TObjArray *t = new TObjArray (*(*_data));
00302 _data->decAndDeleteIf();
00303 _data = new array_holder (t, true);
00304 }
00305
00306
00307
00308
00309 template <typename compare>
00310 void insert_sort(TObjArray& array, int const from, int const to, compare CompFun)
00311 {
00312 int j = 0;
00313 TObject* tmp;
00314
00315 for (int i = from; i != to; ++i) {
00316 j = i;
00317 tmp = array.At(j);
00318 while ((j>0) &&
00319 !CompFun(*static_cast<T const*>(array.At(j-1)),*static_cast<T const*>(tmp))) {
00320 array[j] = array.At(j-1);
00321 --j;
00322 }
00323 array[j] = tmp;
00324 }
00325 return;
00326 }
00327
00328
00329
00330 template <typename compare>
00331 void partial_quicksort(TObjArray& array, int indLow, int indHigh, compare CompFun)
00332 {
00333
00334 const int insertSortMax = 8;
00335 int i = 0;
00336 int j = 0;
00337 int indTurn = 0;
00338 TObject const* turn = NULL;
00339
00340 if ((indHigh - indLow) > insertSortMax) {
00341 indTurn = (indLow+indHigh)/2;
00342 turn = array.At(indTurn);
00343 i = indLow;
00344 j = indHigh-1;
00345
00346 swap(array,indTurn,indHigh);
00347
00348
00349
00350 while (true) {
00351 while (!CompFun(*static_cast<T const*>(array.At(i)),*static_cast<T const*>(turn)) &&
00352 (i<=j)) {
00353 ++i;
00354 }
00355 while (CompFun(*static_cast<T const*>(array.At(j)),*static_cast<T const*>(turn)) &&
00356 (i<j)) {
00357 --j;
00358 }
00359 if (j<=i) {
00360 break;
00361 }
00362 swap(array,i,j);
00363
00364 }
00365 swap(array,indHigh,j);
00366
00367 partial_quicksort(array,indLow,j-1,CompFun);
00368 partial_quicksort(array,j+1,indHigh,CompFun);
00369 }
00370
00371 return;
00372 }
00373
00374
00375
00376 template <typename compare>
00377 void full_sort(TObjArray& array, int const from, int const to, compare CompFun)
00378 {
00379
00380
00381
00382 partial_quicksort(array,from,to-1,CompFun);
00383 insert_sort(array,from,to,CompFun);
00384 return;
00385 }
00386
00387
00388 void swap(TObjArray& array, int i, int j)
00389 {
00390 TObject* tmp = array.At(i);
00391 array[i] = array.At(j);
00392 array[j] = tmp;
00393 return;
00394 }
00395
00396 public:
00397 ClassDef(Collection, 0);
00398 };
00399
00400 }
00401
00402 #endif // COLLECTION_HPP__