00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00019
00020 #ifndef TESSERACT_CCUTIL_GENERICVECTOR_H_
00021 #define TESSERACT_CCUTIL_GENERICVECTOR_H_
00022
00023 #include <stdio.h>
00024
00025 #include "callback.h"
00026 #include "errcode.h"
00027 #include "helpers.h"
00028
00029 template <typename T>
00030 class GenericVector {
00031 public:
00032 GenericVector() { this->init(kDefaultVectorSize); }
00033 GenericVector(int size) { this->init(size); }
00034
00035
00036 GenericVector(const GenericVector& other) {
00037 this->init(other.size());
00038 this->operator+=(other);
00039 }
00040 GenericVector<T> &operator+=(const GenericVector& other);
00041 GenericVector<T> &operator=(const GenericVector& other);
00042
00043 virtual ~GenericVector();
00044
00045
00046 void reserve(int size);
00047
00048 void double_the_size();
00049
00050
00051 int size() const {
00052 return size_used_;
00053 }
00054
00055 int length() const {
00056 return size_used_;
00057 }
00058
00059
00060 bool empty() const {
00061 return size_used_ == 0;
00062 }
00063
00064
00065 T &get(int index) const;
00066 T &operator[](int index) const;
00067
00068
00069
00070
00071 int get_index(T object) const;
00072
00073
00074 bool contains(T object) const;
00075
00076
00077 T contains_index(int index) const;
00078
00079
00080 int push_back(T object);
00081 void operator+=(T t);
00082
00083
00084 void set(T t, int index);
00085
00086
00087 void insert(T t, int index);
00088
00089
00090
00091 void remove(int index);
00092
00093
00094
00095 void set_clear_callback(Callback1<T>* cb);
00096
00097
00098
00099 void set_compare_callback(ResultCallback2<bool, T const &, T const &>* cb);
00100
00101
00102
00103
00104
00105 virtual void clear();
00106
00107
00108 void delete_data_pointers();
00109
00110
00111
00112
00113 void move(GenericVector<T>* from);
00114
00115
00116
00117
00118
00119
00120
00121 bool write(FILE* f, ResultCallback2<bool, FILE*, T const &>* cb) const;
00122 bool read(FILE* f, ResultCallback3<bool, FILE*, T*, bool>* cb, bool swap);
00123
00124
00125
00126
00127
00128
00129 static T *double_the_size_memcpy(int current_size, T *data) {
00130 T *data_new = new T[current_size * 2];
00131 memcpy(data_new, data, sizeof(T) * current_size);
00132 delete[] data;
00133 return data_new;
00134 }
00135
00136 protected:
00137
00138
00139 void init(int size);
00140
00141
00142
00143
00144 static const int kDefaultVectorSize = 4;
00145 inT32 size_used_;
00146 inT32 size_reserved_;
00147 T* data_;
00148 Callback1<T>* clear_cb_;
00149
00150 mutable ResultCallback2<bool, T const &, T const &>* compare_cb_;
00151 };
00152
00153 namespace tesseract {
00154
00155 template <typename T>
00156 bool cmp_eq(T const & t1, T const & t2) {
00157 return t1 == t2;
00158 }
00159
00160 }
00161
00162
00163 template <typename T>
00164 class GenericVectorEqEq : public GenericVector<T> {
00165 public:
00166 GenericVectorEqEq() {
00167 GenericVector<T>::set_compare_callback(
00168 NewPermanentCallback(tesseract::cmp_eq<T>));
00169 }
00170 GenericVectorEqEq(int size) : GenericVector<T>(size) {
00171 GenericVector<T>::set_compare_callback(
00172 NewPermanentCallback(tesseract::cmp_eq<T>));
00173 }
00174 };
00175
00176 template <typename T>
00177 void GenericVector<T>::init(int size) {
00178 size_used_ = 0;
00179 size_reserved_ = 0;
00180 data_ = 0;
00181 clear_cb_ = 0;
00182 compare_cb_ = 0;
00183 reserve(size);
00184 }
00185
00186 template <typename T>
00187 GenericVector<T>::~GenericVector() {
00188 clear();
00189 }
00190
00191
00192
00193 template <typename T>
00194 void GenericVector<T>::reserve(int size) {
00195 if (size_reserved_ > size || size <= 0)
00196 return;
00197 T* new_array = new T[size];
00198 for (int i = 0; i < size_used_; ++i)
00199 new_array[i] = data_[i];
00200 if (data_ != NULL) delete[] data_;
00201 data_ = new_array;
00202 size_reserved_ = size;
00203 }
00204
00205 template <typename T>
00206 void GenericVector<T>::double_the_size() {
00207 if (size_reserved_ == 0) {
00208 reserve(kDefaultVectorSize);
00209 }
00210 else {
00211 reserve(2 * size_reserved_);
00212 }
00213 }
00214
00215
00216
00217
00218 template <typename T>
00219 T &GenericVector<T>::get(int index) const {
00220 ASSERT_HOST(index >= 0 && index < size_used_);
00221 return data_[index];
00222 }
00223
00224 template <typename T>
00225 T &GenericVector<T>::operator[](int index) const {
00226 return data_[index];
00227 }
00228
00229
00230 template <typename T>
00231 void GenericVector<T>::set(T t, int index) {
00232 ASSERT_HOST(index >= 0 && index < size_used_);
00233 data_[index] = t;
00234 }
00235
00236
00237
00238
00239 template <typename T>
00240 void GenericVector<T>::insert(T t, int index) {
00241 ASSERT_HOST(index >= 0 && index < size_used_);
00242 if (size_reserved_ == size_used_)
00243 double_the_size();
00244 for (int i = size_used_; i > index; --i) {
00245 data_[i] = data_[i-1];
00246 }
00247 data_[index] = t;
00248 size_used_++;
00249 }
00250
00251
00252
00253 template <typename T>
00254 void GenericVector<T>::remove(int index) {
00255 ASSERT_HOST(index >= 0 && index < size_used_);
00256 for (int i = index; i < size_used_ - 1; ++i) {
00257 data_[i] = data_[i+1];
00258 }
00259 size_used_--;
00260 }
00261
00262
00263 template <typename T>
00264 T GenericVector<T>::contains_index(int index) const {
00265 return index >= 0 && index < size_used_;
00266 }
00267
00268
00269 template <typename T>
00270 int GenericVector<T>::get_index(T object) const {
00271 for (int i = 0; i < size_used_; ++i) {
00272 ASSERT_HOST(compare_cb_ != NULL);
00273 if (compare_cb_->Run(object, data_[i]))
00274 return i;
00275 }
00276 return -1;
00277 }
00278
00279
00280 template <typename T>
00281 bool GenericVector<T>::contains(T object) const {
00282 return get_index(object) != -1;
00283 }
00284
00285
00286 template <typename T>
00287 int GenericVector<T>::push_back(T object) {
00288 int index = 0;
00289 if (size_used_ == size_reserved_)
00290 double_the_size();
00291 index = size_used_++;
00292 data_[index] = object;
00293 return index;
00294 }
00295
00296 template <typename T>
00297 void GenericVector<T>::operator+=(T t) {
00298 push_back(t);
00299 }
00300
00301 template <typename T>
00302 GenericVector<T> &GenericVector<T>::operator+=(const GenericVector& other) {
00303 for (int i = 0; i < other.size(); ++i) {
00304 this->operator+=(other.data_[i]);
00305 }
00306 return *this;
00307 }
00308
00309 template <typename T>
00310 GenericVector<T> &GenericVector<T>::operator=(const GenericVector& other) {
00311 this->clear();
00312 this->operator+=(other);
00313 return *this;
00314 }
00315
00316
00317
00318 template <typename T>
00319 void GenericVector<T>::set_clear_callback(Callback1<T>* cb) {
00320 clear_cb_ = cb;
00321 }
00322
00323
00324
00325 template <typename T>
00326 void GenericVector<T>::set_compare_callback(ResultCallback2<bool, T const &, T const &>* cb) {
00327 compare_cb_ = cb;
00328 }
00329
00330
00331 template <typename T>
00332 void GenericVector<T>::clear() {
00333 if (size_reserved_ > 0) {
00334 if (clear_cb_ != NULL)
00335 for (int i = 0; i < size_used_; ++i)
00336 clear_cb_->Run(data_[i]);
00337 delete[] data_;
00338 data_ = NULL;
00339 size_used_ = 0;
00340 size_reserved_ = 0;
00341 }
00342 if (clear_cb_ != NULL) {
00343 delete clear_cb_;
00344 clear_cb_ = NULL;
00345 }
00346 if (compare_cb_ != NULL) {
00347 delete compare_cb_;
00348 compare_cb_ = NULL;
00349 }
00350 }
00351
00352 template <typename T>
00353 void GenericVector<T>::delete_data_pointers() {
00354 for (int i = 0; i < size_used_; ++i)
00355 if (data_[i]) {
00356 delete data_[i];
00357 }
00358 }
00359
00360
00361 template <typename T>
00362 bool GenericVector<T>::write(
00363 FILE* f, ResultCallback2<bool, FILE*, T const &>* cb) const {
00364 if (fwrite(&size_reserved_, sizeof(size_reserved_), 1, f) != 1) return false;
00365 if (fwrite(&size_used_, sizeof(size_used_), 1, f) != 1) return false;
00366 if (cb != NULL) {
00367 for (int i = 0; i < size_used_; ++i) {
00368 if (!cb->Run(f, data_[i])) {
00369 delete cb;
00370 return false;
00371 }
00372 }
00373 delete cb;
00374 } else {
00375 if (fwrite(data_, sizeof(T), size_used_, f) != size_used_) return false;
00376 }
00377 return true;
00378 }
00379
00380 template <typename T>
00381 bool GenericVector<T>::read(FILE* f,
00382 ResultCallback3<bool, FILE*, T*, bool>* cb,
00383 bool swap) {
00384 uinT32 reserved;
00385 if (fread(&reserved, sizeof(reserved), 1, f) != 1) return false;
00386 if (swap) Reverse32(&reserved);
00387 reserve(reserved);
00388 if (fread(&size_used_, sizeof(size_used_), 1, f) != 1) return false;
00389 if (swap) Reverse32(&size_used_);
00390 if (cb != NULL) {
00391 for (int i = 0; i < size_used_; ++i) {
00392 if (!cb->Run(f, data_ + i, swap)) {
00393 delete cb;
00394 return false;
00395 }
00396 }
00397 delete cb;
00398 } else {
00399 if (fread(data_, sizeof(T), size_used_, f) != size_used_) return false;
00400 if (swap) {
00401 for (int i = 0; i < size_used_; ++i)
00402 ReverseN(&data_[i], sizeof(T));
00403 }
00404 }
00405 return true;
00406 }
00407
00408
00409
00410 template <typename T>
00411 void GenericVector<T>::move(GenericVector<T>* from) {
00412 this->clear();
00413 this->data_ = from->data_;
00414 this->size_reserved_ = from->size_reserved_;
00415 this->size_used_ = from->size_used_;
00416 this->compare_cb_ = from->compare_cb_;
00417 this->clear_cb_ = from->clear_cb_;
00418 from->data_ = NULL;
00419 from->clear_cb_ = NULL;
00420 from->compare_cb_ = NULL;
00421 from->size_used_ = 0;
00422 from->size_reserved_ = 0;
00423 }
00424
00425 #endif // TESSERACT_CCUTIL_GENERICVECTOR_H_