Tesseract  3.02
tesseract-ocr/ccutil/genericvector.h
Go to the documentation of this file.
00001 
00002 // File:        genericvector.h
00003 // Description: Generic vector class
00004 // Author:      Daria Antonova
00005 // Created:     Mon Jun 23 11:26:43 PDT 2008
00006 //
00007 // (C) Copyright 2007, Google Inc.
00008 // Licensed under the Apache License, Version 2.0 (the "License");
00009 // you may not use this file except in compliance with the License.
00010 // You may obtain a copy of the License at
00011 // http://www.apache.org/licenses/LICENSE-2.0
00012 // Unless required by applicable law or agreed to in writing, software
00013 // distributed under the License is distributed on an "AS IS" BASIS,
00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 // See the License for the specific language governing permissions and
00016 // limitations under the License.
00017 //
00019 //
00020 #ifndef TESSERACT_CCUTIL_GENERICVECTOR_H_
00021 #define TESSERACT_CCUTIL_GENERICVECTOR_H_
00022 
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 
00026 #include "tesscallback.h"
00027 #include "errcode.h"
00028 #include "helpers.h"
00029 #include "ndminx.h"
00030 
00031 // Use PointerVector<T> below in preference to GenericVector<T*>, as that
00032 // provides automatic deletion of pointers, [De]Serialize that works, and
00033 // sort that works.
00034 template <typename T>
00035 class GenericVector {
00036  public:
00037   GenericVector() { this->init(kDefaultVectorSize); }
00038   explicit GenericVector(int size) { this->init(size); }
00039 
00040   // Copy
00041   GenericVector(const GenericVector& other) {
00042     this->init(other.size());
00043     this->operator+=(other);
00044   }
00045   GenericVector<T> &operator+=(const GenericVector& other);
00046   GenericVector<T> &operator=(const GenericVector& other);
00047 
00048   virtual ~GenericVector();
00049 
00050   // Reserve some memory.
00051   void reserve(int size);
00052   // Double the size of the internal array.
00053   void double_the_size();
00054 
00055   // Resizes to size and sets all values to t.
00056   void init_to_size(int size, T t);
00057 
00058   // Return the size used.
00059   int size() const {
00060     return size_used_;
00061   }
00062 
00063   int length() const {
00064     return size_used_;
00065   }
00066 
00067   // Return true if empty.
00068   bool empty() const {
00069     return size_used_ == 0;
00070   }
00071 
00072   // Return the object from an index.
00073   T &get(int index) const;
00074   T &back() const;
00075   T &operator[](int index) const;
00076 
00077   // Return the index of the T object.
00078   // This method NEEDS a compare_callback to be passed to
00079   // set_compare_callback.
00080   int get_index(T object) const;
00081 
00082   // Return true if T is in the array
00083   bool contains(T object) const;
00084 
00085   // Return true if the index is valid
00086   T contains_index(int index) const;
00087 
00088   // Push an element in the end of the array
00089   int push_back(T object);
00090   void operator+=(T t);
00091 
00092   // Push an element in the end of the array if the same
00093   // element is not already contained in the array.
00094   int push_back_new(T object);
00095 
00096   // Push an element in the front of the array
00097   // Note: This function is O(n)
00098   int push_front(T object);
00099 
00100   // Set the value at the given index
00101   void set(T t, int index);
00102 
00103   // Insert t at the given index, push other elements to the right.
00104   void insert(T t, int index);
00105 
00106   // Removes an element at the given index and
00107   // shifts the remaining elements to the left.
00108   virtual void remove(int index);
00109 
00110   // Truncates the array to the given size by removing the end.
00111   // If the current size is less, the array is not expanded.
00112   virtual void truncate(int size) {
00113     if (size < size_used_)
00114       size_used_ = size;
00115   }
00116 
00117   // Add a callback to be called to delete the elements when the array took
00118   // their ownership.
00119   void set_clear_callback(TessCallback1<T>* cb);
00120 
00121   // Add a callback to be called to compare the elements when needed (contains,
00122   // get_id, ...)
00123   void set_compare_callback(TessResultCallback2<bool, T const &, T const &>* cb);
00124 
00125   // Clear the array, calling the clear callback function if any.
00126   // All the owned callbacks are also deleted.
00127   // If you don't want the callbacks to be deleted, before calling clear, set
00128   // the callback to NULL.
00129   virtual void clear();
00130 
00131   // Delete objects pointed to by data_[i]
00132   void delete_data_pointers();
00133 
00134   // This method clears the current object, then, does a shallow copy of
00135   // its argument, and finally invalidates its argument.
00136   // Callbacks are moved to the current object;
00137   void move(GenericVector<T>* from);
00138 
00139   // Read/Write the array to a file. This does _NOT_ read/write the callbacks.
00140   // The callback given must be permanent since they will be called more than
00141   // once. The given callback will be deleted at the end.
00142   // If the callbacks are NULL, then the data is simply read/written using
00143   // fread (and swapping)/fwrite.
00144   // Returns false on error or if the callback returns false.
00145   // DEPRECATED. Use [De]Serialize[Classes] instead.
00146   bool write(FILE* f, TessResultCallback2<bool, FILE*, T const &>* cb) const;
00147   bool read(FILE* f, TessResultCallback3<bool, FILE*, T*, bool>* cb, bool swap);
00148   // Writes a vector of simple types to the given file. Assumes that bitwise
00149   // read/write of T will work. Returns false in case of error.
00150   virtual bool Serialize(FILE* fp) const;
00151   // Reads a vector of simple types from the given file. Assumes that bitwise
00152   // read/write will work with ReverseN according to sizeof(T).
00153   // Returns false in case of error.
00154   // If swap is true, assumes a big/little-endian swap is needed.
00155   virtual bool DeSerialize(bool swap, FILE* fp);
00156   // Writes a vector of classes to the given file. Assumes the existence of
00157   // bool T::Serialize(FILE* fp) const that returns false in case of error.
00158   // Returns false in case of error.
00159   bool SerializeClasses(FILE* fp) const;
00160   // Reads a vector of classes from the given file. Assumes the existence of
00161   // bool T::Deserialize(bool swap, FILE* fp) that returns false in case of
00162   // error. Also needs T::T() and T::T(constT&), as init_to_size is used in
00163   // this function. Returns false in case of error.
00164   // If swap is true, assumes a big/little-endian swap is needed.
00165   bool DeSerializeClasses(bool swap, FILE* fp);
00166 
00167   // Allocates a new array of double the current_size, copies over the
00168   // information from data to the new location, deletes data and returns
00169   // the pointed to the new larger array.
00170   // This function uses memcpy to copy the data, instead of invoking
00171   // operator=() for each element like double_the_size() does.
00172   static T *double_the_size_memcpy(int current_size, T *data) {
00173     T *data_new = new T[current_size * 2];
00174     memcpy(data_new, data, sizeof(T) * current_size);
00175     delete[] data;
00176     return data_new;
00177   }
00178 
00179   // Sorts the members of this vector using the less than comparator (cmp_lt),
00180   // which compares the values. Useful for GenericVectors to primitive types.
00181   // Will not work so great for pointers (unless you just want to sort some
00182   // pointers). You need to provide a specialization to sort_cmp to use
00183   // your type.
00184   void sort();
00185 
00186   // Sort the array into the order defined by the qsort function comparator.
00187   // The comparator function is as defined by qsort, ie. it receives pointers
00188   // to two Ts and returns negative if the first element is to appear earlier
00189   // in the result and positive if it is to appear later, with 0 for equal.
00190   void sort(int (*comparator)(const void*, const void*)) {
00191     qsort(data_, size_used_, sizeof(*data_), comparator);
00192   }
00193 
00194   // Searches the array (assuming sorted in ascending order, using sort()) for
00195   // an element equal to target and returns true if it is present.
00196   // Use binary_search to get the index of target, or its nearest candidate.
00197   bool bool_binary_search(const T& target) const {
00198     int index = binary_search(target);
00199     if (index >= size_used_)
00200       return false;
00201     return data_[index] == target;
00202   }
00203   // Searches the array (assuming sorted in ascending order, using sort()) for
00204   // an element equal to target and returns the index of the best candidate.
00205   // The return value is conceptually the largest index i such that
00206   // data_[i] <= target or 0 if target < the whole vector.
00207   // NOTE that this function uses operator> so really the return value is
00208   // the largest index i such that data_[i] > target is false.
00209   int binary_search(const T& target) const {
00210     int bottom = 0;
00211     int top = size_used_;
00212     do {
00213       int middle = (bottom + top) / 2;
00214       if (data_[middle] > target)
00215         top = middle;
00216       else
00217         bottom = middle;
00218     }
00219     while (top - bottom > 1);
00220     return bottom;
00221   }
00222 
00223   // Compact the vector by deleting elements using operator!= on basic types.
00224   // The vector must be sorted.
00225   void compact_sorted() {
00226     if (size_used_ == 0)
00227       return;
00228 
00229     // First element is in no matter what, hence the i = 1.
00230     int last_write = 0;
00231     for (int i = 1; i < size_used_; ++i) {
00232       // Finds next unique item and writes it.
00233       if (data_[last_write] != data_[i])
00234         data_[++last_write] = data_[i];
00235     }
00236     // last_write is the index of a valid data cell, so add 1.
00237     size_used_ = last_write + 1;
00238   }
00239 
00240   // Compact the vector by deleting elements for which delete_cb returns
00241   // true. delete_cb is a permanent callback and will be deleted.
00242   void compact(TessResultCallback1<bool, int>* delete_cb) {
00243     int new_size = 0;
00244     int old_index = 0;
00245     // Until the callback returns true, the elements stay the same.
00246     while (old_index < size_used_ && !delete_cb->Run(old_index++))
00247       ++new_size;
00248     // Now just copy anything else that gets false from delete_cb.
00249     for (; old_index < size_used_; ++old_index) {
00250       if (!delete_cb->Run(old_index)) {
00251         data_[new_size++] = data_[old_index];
00252       }
00253     }
00254     size_used_ = new_size;
00255     delete delete_cb;
00256   }
00257 
00258   T dot_product(const GenericVector<T>& other) const {
00259     T result = static_cast<T>(0);
00260     for (int i = MIN(size_used_, other.size_used_) - 1; i >= 0; --i)
00261       result += data_[i] * other.data_[i];
00262     return result;
00263   }
00264 
00265  protected:
00266 
00267   // Init the object, allocating size memory.
00268   void init(int size);
00269 
00270   // We are assuming that the object generally placed in thie
00271   // vector are small enough that for efficiency it makes sence
00272   // to start with a larger initial size.
00273   static const int kDefaultVectorSize = 4;
00274   inT32   size_used_;
00275   inT32   size_reserved_;
00276   T*    data_;
00277   TessCallback1<T>* clear_cb_;
00278   // Mutable because Run method is not const
00279   mutable TessResultCallback2<bool, T const &, T const &>* compare_cb_;
00280 };
00281 
00282 namespace tesseract {
00283 
00284 template <typename T>
00285 bool cmp_eq(T const & t1, T const & t2) {
00286   return t1 == t2;
00287 }
00288 
00289 // Used by sort()
00290 // return < 0 if t1 < t2
00291 // return 0 if t1 == t2
00292 // return > 0 if t1 > t2
00293 template <typename T>
00294 int sort_cmp(const void* t1, const void* t2) {
00295   const T* a = static_cast<const T *> (t1);
00296   const T* b = static_cast<const T *> (t2);
00297   if (*a < *b) {
00298     return -1;
00299   } else if (*b < *a) {
00300     return 1;
00301   } else {
00302     return 0;
00303   }
00304 }
00305 
00306 // Used by PointerVector::sort()
00307 // return < 0 if t1 < t2
00308 // return 0 if t1 == t2
00309 // return > 0 if t1 > t2
00310 template <typename T>
00311 int sort_ptr_cmp(const void* t1, const void* t2) {
00312   const T* a = *reinterpret_cast<T * const *>(t1);
00313   const T* b = *reinterpret_cast<T * const *>(t2);
00314   if (*a < *b) {
00315     return -1;
00316   } else if (*b < *a) {
00317     return 1;
00318   } else {
00319     return 0;
00320   }
00321 }
00322 
00323 // Subclass for a vector of pointers. Use in preference to GenericVector<T*>
00324 // as it provides automatic deletion and correct serialization, with the
00325 // corollary that all copy operations are deep copies of the pointed-to objects.
00326 template<typename T>
00327 class PointerVector : public GenericVector<T*> {
00328  public:
00329   PointerVector() : GenericVector<T*>() { }
00330   explicit PointerVector(int size) : GenericVector<T*>(size) { }
00331   virtual ~PointerVector() {
00332     // Clear must be called here, even though it is called again by the base,
00333     // as the base will call the wrong clear.
00334     clear();
00335   }
00336   // Copy must be deep, as the pointers will be automatically deleted on
00337   // destruction.
00338   PointerVector(const PointerVector& other) {
00339     this->init(other.size());
00340     this->operator+=(other);
00341   }
00342   PointerVector<T>& operator+=(const PointerVector& other) {
00343     this->reserve(this->size_used_ + other.size_used_);
00344     for (int i = 0; i < other.size(); ++i) {
00345       this->push_back(new T(*other.data_[i]));
00346     }
00347     return *this;
00348   }
00349 
00350   PointerVector<T>& operator=(const PointerVector& other) {
00351     this->truncate(0);
00352     this->operator+=(other);
00353     return *this;
00354   }
00355 
00356   // Removes an element at the given index and
00357   // shifts the remaining elements to the left.
00358   virtual void remove(int index) {
00359     delete GenericVector<T*>::data_[index];
00360     GenericVector<T*>::remove(index);
00361   }
00362 
00363   // Truncates the array to the given size by removing the end.
00364   // If the current size is less, the array is not expanded.
00365   virtual void truncate(int size) {
00366     for (int i = size; i < GenericVector<T*>::size_used_; ++i)
00367       delete GenericVector<T*>::data_[i];
00368     GenericVector<T*>::truncate(size);
00369   }
00370 
00371   // Compact the vector by deleting elements for which delete_cb returns
00372   // true. delete_cb is a permanent callback and will be deleted.
00373   void compact(TessResultCallback1<bool, const T*>* delete_cb) {
00374     int new_size = 0;
00375     int old_index = 0;
00376     // Until the callback returns true, the elements stay the same.
00377     while (old_index < GenericVector<T*>::size_used_ &&
00378            !delete_cb->Run(GenericVector<T*>::data_[old_index++]))
00379       ++new_size;
00380     // Now just copy anything else that gets false from delete_cb.
00381     for (; old_index < GenericVector<T*>::size_used_; ++old_index) {
00382       if (!delete_cb->Run(GenericVector<T*>::data_[old_index])) {
00383         GenericVector<T*>::data_[new_size++] =
00384             GenericVector<T*>::data_[old_index];
00385       } else {
00386         delete GenericVector<T*>::data_[old_index];
00387       }
00388     }
00389     GenericVector<T*>::size_used_ = new_size;
00390     delete delete_cb;
00391   }
00392 
00393   // Clear the array, calling the clear callback function if any.
00394   // All the owned callbacks are also deleted.
00395   // If you don't want the callbacks to be deleted, before calling clear, set
00396   // the callback to NULL.
00397   virtual void clear() {
00398     GenericVector<T*>::delete_data_pointers();
00399     GenericVector<T*>::clear();
00400   }
00401 
00402   // Writes a vector of simple types to the given file. Assumes that bitwise
00403   // read/write of T will work. Returns false in case of error.
00404   virtual bool Serialize(FILE* fp) const {
00405     inT32 used = GenericVector<T*>::size_used_;
00406     if (fwrite(&used, sizeof(used), 1, fp) != 1) return false;
00407     for (int i = 0; i < used; ++i) {
00408       inT8 non_null = GenericVector<T*>::data_[i] != NULL;
00409       if (fwrite(&non_null, sizeof(non_null), 1, fp) != 1) return false;
00410       if (non_null && !GenericVector<T*>::data_[i]->Serialize(fp)) return false;
00411     }
00412     return true;
00413   }
00414   // Reads a vector of simple types from the given file. Assumes that bitwise
00415   // read/write will work with ReverseN according to sizeof(T).
00416   // Also needs T::T(), as new T is used in this function.
00417   // Returns false in case of error.
00418   // If swap is true, assumes a big/little-endian swap is needed.
00419   virtual bool DeSerialize(bool swap, FILE* fp) {
00420     inT32 reserved;
00421     if (fread(&reserved, sizeof(reserved), 1, fp) != 1) return false;
00422     if (swap) Reverse32(&reserved);
00423     GenericVector<T*>::reserve(reserved);
00424     for (int i = 0; i < reserved; ++i) {
00425       inT8 non_null;
00426       if (fread(&non_null, sizeof(non_null), 1, fp) != 1) return false;
00427       T* item = NULL;
00428       if (non_null) {
00429         item = new T;
00430         if (!item->DeSerialize(swap, fp)) return false;
00431       }
00432       this->push_back(item);
00433     }
00434     return true;
00435   }
00436 
00437   // Sorts the items pointed to by the members of this vector using
00438   // t::operator<().
00439   void sort() {
00440     sort(&sort_ptr_cmp<T>);
00441   }
00442 };
00443 
00444 }  // namespace tesseract
00445 
00446 // A useful vector that uses operator== to do comparisons.
00447 template <typename T>
00448 class GenericVectorEqEq : public GenericVector<T> {
00449  public:
00450   GenericVectorEqEq() {
00451     GenericVector<T>::set_compare_callback(
00452         NewPermanentTessCallback(tesseract::cmp_eq<T>));
00453   }
00454   GenericVectorEqEq(int size) : GenericVector<T>(size) {
00455     GenericVector<T>::set_compare_callback(
00456         NewPermanentTessCallback(tesseract::cmp_eq<T>));
00457   }
00458 };
00459 
00460 template <typename T>
00461 void GenericVector<T>::init(int size) {
00462   size_used_ = 0;
00463   size_reserved_ = 0;
00464   data_ = 0;
00465   clear_cb_ = 0;
00466   compare_cb_ = 0;
00467   reserve(size);
00468 }
00469 
00470 template <typename T>
00471 GenericVector<T>::~GenericVector() {
00472   clear();
00473 }
00474 
00475 // Reserve some memory. If the internal array contains elements, they are
00476 // copied.
00477 template <typename T>
00478 void GenericVector<T>::reserve(int size) {
00479   if (size_reserved_ >= size || size <= 0)
00480     return;
00481   T* new_array = new T[size];
00482   for (int i = 0; i < size_used_; ++i)
00483     new_array[i] = data_[i];
00484   if (data_ != NULL) delete[] data_;
00485   data_ = new_array;
00486   size_reserved_ = size;
00487 }
00488 
00489 template <typename T>
00490 void GenericVector<T>::double_the_size() {
00491   if (size_reserved_ == 0) {
00492     reserve(kDefaultVectorSize);
00493   }
00494   else {
00495     reserve(2 * size_reserved_);
00496   }
00497 }
00498 
00499 // Resizes to size and sets all values to t.
00500 template <typename T>
00501 void GenericVector<T>::init_to_size(int size, T t) {
00502   reserve(size);
00503   size_used_ = size;
00504   for (int i = 0; i < size; ++i)
00505     data_[i] = t;
00506 }
00507 
00508 
00509 // Return the object from an index.
00510 template <typename T>
00511 T &GenericVector<T>::get(int index) const {
00512   ASSERT_HOST(index >= 0 && index < size_used_);
00513   return data_[index];
00514 }
00515 
00516 template <typename T>
00517 T &GenericVector<T>::operator[](int index) const {
00518  return data_[index];
00519 }
00520 
00521 template <typename T>
00522 T &GenericVector<T>::back() const {
00523   ASSERT_HOST(size_used_ > 0);
00524   return data_[size_used_ - 1];
00525 }
00526 
00527 // Return the object from an index.
00528 template <typename T>
00529 void GenericVector<T>::set(T t, int index) {
00530   ASSERT_HOST(index >= 0 && index < size_used_);
00531   data_[index] = t;
00532 }
00533 
00534 // Shifts the rest of the elements to the right to make
00535 // space for the new elements and inserts the given element
00536 // at the specified index.
00537 template <typename T>
00538 void GenericVector<T>::insert(T t, int index) {
00539   ASSERT_HOST(index >= 0 && index < size_used_);
00540   if (size_reserved_ == size_used_)
00541     double_the_size();
00542   for (int i = size_used_; i > index; --i) {
00543     data_[i] = data_[i-1];
00544   }
00545   data_[index] = t;
00546   size_used_++;
00547 }
00548 
00549 // Removes an element at the given index and
00550 // shifts the remaining elements to the left.
00551 template <typename T>
00552 void GenericVector<T>::remove(int index) {
00553   ASSERT_HOST(index >= 0 && index < size_used_);
00554   for (int i = index; i < size_used_ - 1; ++i) {
00555     data_[i] = data_[i+1];
00556   }
00557   size_used_--;
00558 }
00559 
00560 // Return true if the index is valindex
00561 template <typename T>
00562 T GenericVector<T>::contains_index(int index) const {
00563   return index >= 0 && index < size_used_;
00564 }
00565 
00566 // Return the index of the T object.
00567 template <typename T>
00568 int GenericVector<T>::get_index(T object) const {
00569   for (int i = 0; i < size_used_; ++i) {
00570     ASSERT_HOST(compare_cb_ != NULL);
00571     if (compare_cb_->Run(object, data_[i]))
00572       return i;
00573   }
00574   return -1;
00575 }
00576 
00577 // Return true if T is in the array
00578 template <typename T>
00579 bool GenericVector<T>::contains(T object) const {
00580   return get_index(object) != -1;
00581 }
00582 
00583 // Add an element in the array
00584 template <typename T>
00585 int GenericVector<T>::push_back(T object) {
00586   int index = 0;
00587   if (size_used_ == size_reserved_)
00588     double_the_size();
00589   index = size_used_++;
00590   data_[index] = object;
00591   return index;
00592 }
00593 
00594 template <typename T>
00595 int GenericVector<T>::push_back_new(T object) {
00596   int index = get_index(object);
00597   if (index >= 0)
00598     return index;
00599   return push_back(object);
00600 }
00601 
00602 // Add an element in the array (front)
00603 template <typename T>
00604 int GenericVector<T>::push_front(T object) {
00605   if (size_used_ == size_reserved_)
00606     double_the_size();
00607   for (int i = size_used_; i > 0; --i)
00608     data_[i] = data_[i-1];
00609   data_[0] = object;
00610   ++size_used_;
00611   return 0;
00612 }
00613 
00614 template <typename T>
00615 void GenericVector<T>::operator+=(T t) {
00616   push_back(t);
00617 }
00618 
00619 template <typename T>
00620 GenericVector<T> &GenericVector<T>::operator+=(const GenericVector& other) {
00621   this->reserve(size_used_ + other.size_used_);
00622   for (int i = 0; i < other.size(); ++i) {
00623     this->operator+=(other.data_[i]);
00624   }
00625   return *this;
00626 }
00627 
00628 template <typename T>
00629 GenericVector<T> &GenericVector<T>::operator=(const GenericVector& other) {
00630   this->truncate(0);
00631   this->operator+=(other);
00632   return *this;
00633 }
00634 
00635 // Add a callback to be called to delete the elements when the array took
00636 // their ownership.
00637 template <typename T>
00638 void GenericVector<T>::set_clear_callback(TessCallback1<T>* cb) {
00639   clear_cb_ = cb;
00640 }
00641 
00642 // Add a callback to be called to delete the elements when the array took
00643 // their ownership.
00644 template <typename T>
00645 void GenericVector<T>::set_compare_callback(TessResultCallback2<bool, T const &, T const &>* cb) {
00646   compare_cb_ = cb;
00647 }
00648 
00649 // Clear the array, calling the callback function if any.
00650 template <typename T>
00651 void GenericVector<T>::clear() {
00652   if (size_reserved_ > 0) {
00653     if (clear_cb_ != NULL)
00654       for (int i = 0; i < size_used_; ++i)
00655         clear_cb_->Run(data_[i]);
00656     delete[] data_;
00657     data_ = NULL;
00658     size_used_ = 0;
00659     size_reserved_ = 0;
00660   }
00661   if (clear_cb_ != NULL) {
00662     delete clear_cb_;
00663     clear_cb_ = NULL;
00664   }
00665   if (compare_cb_ != NULL) {
00666     delete compare_cb_;
00667     compare_cb_ = NULL;
00668   }
00669 }
00670 
00671 template <typename T>
00672 void GenericVector<T>::delete_data_pointers() {
00673   for (int i = 0; i < size_used_; ++i)
00674     if (data_[i]) {
00675       delete data_[i];
00676     }
00677 }
00678 
00679 
00680 template <typename T>
00681 bool GenericVector<T>::write(
00682     FILE* f, TessResultCallback2<bool, FILE*, T const &>* cb) const {
00683   if (fwrite(&size_reserved_, sizeof(size_reserved_), 1, f) != 1) return false;
00684   if (fwrite(&size_used_, sizeof(size_used_), 1, f) != 1) return false;
00685   if (cb != NULL) {
00686     for (int i = 0; i < size_used_; ++i) {
00687       if (!cb->Run(f, data_[i])) {
00688         delete cb;
00689         return false;
00690       }
00691     }
00692     delete cb;
00693   } else {
00694     if (fwrite(data_, sizeof(T), size_used_, f) != size_used_) return false;
00695   }
00696   return true;
00697 }
00698 
00699 template <typename T>
00700 bool GenericVector<T>::read(FILE* f,
00701                             TessResultCallback3<bool, FILE*, T*, bool>* cb,
00702                             bool swap) {
00703   inT32 reserved;
00704   if (fread(&reserved, sizeof(reserved), 1, f) != 1) return false;
00705   if (swap) Reverse32(&reserved);
00706   reserve(reserved);
00707   if (fread(&size_used_, sizeof(size_used_), 1, f) != 1) return false;
00708   if (swap) Reverse32(&size_used_);
00709   if (cb != NULL) {
00710     for (int i = 0; i < size_used_; ++i) {
00711       if (!cb->Run(f, data_ + i, swap)) {
00712         delete cb;
00713         return false;
00714       }
00715     }
00716     delete cb;
00717   } else {
00718     if (fread(data_, sizeof(T), size_used_, f) != size_used_) return false;
00719     if (swap) {
00720       for (int i = 0; i < size_used_; ++i)
00721         ReverseN(&data_[i], sizeof(T));
00722     }
00723   }
00724   return true;
00725 }
00726 
00727 // Writes a vector of simple types to the given file. Assumes that bitwise
00728 // read/write of T will work. Returns false in case of error.
00729 template <typename T>
00730 bool GenericVector<T>::Serialize(FILE* fp) const {
00731   if (fwrite(&size_used_, sizeof(size_used_), 1, fp) != 1) return false;
00732   if (fwrite(data_, sizeof(*data_), size_used_, fp) != size_used_) return false;
00733   return true;
00734 }
00735 
00736 // Reads a vector of simple types from the given file. Assumes that bitwise
00737 // read/write will work with ReverseN according to sizeof(T).
00738 // Returns false in case of error.
00739 // If swap is true, assumes a big/little-endian swap is needed.
00740 template <typename T>
00741 bool GenericVector<T>::DeSerialize(bool swap, FILE* fp) {
00742   inT32 reserved;
00743   if (fread(&reserved, sizeof(reserved), 1, fp) != 1) return false;
00744   if (swap) Reverse32(&reserved);
00745   reserve(reserved);
00746   size_used_ = reserved;
00747   if (fread(data_, sizeof(T), size_used_, fp) != size_used_) return false;
00748   if (swap) {
00749     for (int i = 0; i < size_used_; ++i)
00750       ReverseN(&data_[i], sizeof(data_[i]));
00751   }
00752   return true;
00753 }
00754 
00755 // Writes a vector of classes to the given file. Assumes the existence of
00756 // bool T::Serialize(FILE* fp) const that returns false in case of error.
00757 // Returns false in case of error.
00758 template <typename T>
00759 bool GenericVector<T>::SerializeClasses(FILE* fp) const {
00760   if (fwrite(&size_used_, sizeof(size_used_), 1, fp) != 1) return false;
00761   for (int i = 0; i < size_used_; ++i) {
00762     if (!data_[i].Serialize(fp)) return false;
00763   }
00764   return true;
00765 }
00766 
00767 // Reads a vector of classes from the given file. Assumes the existence of
00768 // bool T::Deserialize(bool swap, FILE* fp) that returns false in case of
00769 // error. Alse needs T::T() and T::T(constT&), as init_to_size is used in
00770 // this function. Returns false in case of error.
00771 // If swap is true, assumes a big/little-endian swap is needed.
00772 template <typename T>
00773 bool GenericVector<T>::DeSerializeClasses(bool swap, FILE* fp) {
00774   uinT32 reserved;
00775   if (fread(&reserved, sizeof(reserved), 1, fp) != 1) return false;
00776   if (swap) Reverse32(&reserved);
00777   T empty;
00778   init_to_size(reserved, empty);
00779   for (int i = 0; i < reserved; ++i) {
00780     if (!data_[i].DeSerialize(swap, fp)) return false;
00781   }
00782   return true;
00783 }
00784 
00785 // This method clear the current object, then, does a shallow copy of
00786 // its argument, and finally invalidates its argument.
00787 template <typename T>
00788 void GenericVector<T>::move(GenericVector<T>* from) {
00789   this->clear();
00790   this->data_ = from->data_;
00791   this->size_reserved_ = from->size_reserved_;
00792   this->size_used_ = from->size_used_;
00793   this->compare_cb_ = from->compare_cb_;
00794   this->clear_cb_ = from->clear_cb_;
00795   from->data_ = NULL;
00796   from->clear_cb_ = NULL;
00797   from->compare_cb_ = NULL;
00798   from->size_used_ = 0;
00799   from->size_reserved_ = 0;
00800 }
00801 
00802 template <typename T>
00803 void GenericVector<T>::sort() {
00804   sort(&tesseract::sort_cmp<T>);
00805 }
00806 
00807 #endif  // TESSERACT_CCUTIL_GENERICVECTOR_H_