00001
00002
00003
00004
00005 #ifndef __COMMON_VECTOR_H
00006 #define __COMMON_VECTOR_H
00007
00008 #include "Defs.h"
00009
00010 class CBaseRecordVector
00011 {
00012 void MoveItems(int destIndex, int srcIndex);
00013 protected:
00014 int _capacity;
00015 int _size;
00016 void *_items;
00017 size_t _itemSize;
00018
00019 void ReserveOnePosition();
00020 void InsertOneItem(int index);
00021 void TestIndexAndCorrectNum(int index, int &num) const
00022 { if (index + num > _size) num = _size - index; }
00023 public:
00024 CBaseRecordVector(size_t itemSize):
00025 _capacity(0), _size(0), _items(0), _itemSize(itemSize) {}
00026 virtual ~CBaseRecordVector();
00027 int Size() const { return _size; }
00028 bool IsEmpty() const { return (_size == 0); }
00029 void Reserve(int newCapacity);
00030 virtual void Delete(int index, int num = 1);
00031 void Clear();
00032 void DeleteFrom(int index);
00033 void DeleteBack();
00034 };
00035
00036 template <class T>
00037 class CRecordVector: public CBaseRecordVector
00038 {
00039 public:
00040 CRecordVector():CBaseRecordVector(sizeof(T)){};
00041 CRecordVector(const CRecordVector &v):
00042 CBaseRecordVector(sizeof(T)) { *this = v;}
00043 CRecordVector& operator=(const CRecordVector &v)
00044 {
00045 Clear();
00046 return (*this += v);
00047 }
00048 CRecordVector& operator+=(const CRecordVector &v)
00049 {
00050 int size = v.Size();
00051 Reserve(Size() + size);
00052 for(int i = 0; i < size; i++)
00053 Add(v[i]);
00054 return *this;
00055 }
00056 int Add(T item)
00057 {
00058 ReserveOnePosition();
00059 ((T *)_items)[_size] = item;
00060 return _size++;
00061 }
00062 void Insert(int index, T item)
00063 {
00064 InsertOneItem(index);
00065 ((T *)_items)[index] = item;
00066 }
00067
00068
00069 const T& operator[](int index) const { return ((T *)_items)[index]; }
00070 T& operator[](int index) { return ((T *)_items)[index]; }
00071 const T& Front() const { return operator[](0); }
00072 T& Front() { return operator[](0); }
00073 const T& Back() const { return operator[](_size - 1); }
00074 T& Back() { return operator[](_size - 1); }
00075
00076 void Swap(int i, int j)
00077 {
00078 T temp = operator[](i);
00079 operator[](i) = operator[](j);
00080 operator[](j) = temp;
00081 }
00082
00083 void Sort(int left, int right)
00084 {
00085 if (right - left < 2)
00086 return;
00087 Swap(left, (left + right) / 2);
00088 int last = left;
00089 for (int i = left; i < right; i++)
00090 if (operator[](i) < operator[](left))
00091 Swap(++last, i);
00092 Swap(left, last);
00093 Sort(left, last);
00094 Sort(last + 1, right);
00095 }
00096 void Sort() { Sort(0, Size()); }
00097 void Sort(int left, int right, int (*compare)(const T*, const T*, void *), void *param)
00098 {
00099 if (right - left < 2)
00100 return;
00101 Swap(left, (left + right) / 2);
00102 int last = left;
00103 for (int i = left; i < right; i++)
00104 if (compare(&operator[](i), &operator[](left), param) < 0)
00105 Swap(++last, i);
00106 Swap(left, last);
00107 Sort(left, last, compare, param);
00108 Sort(last + 1, right, compare, param);
00109 }
00110
00111 void Sort(int (*compare)(const T*, const T*, void *), void *param)
00112 {
00113 Sort(0, Size(), compare, param);
00114 }
00115 };
00116
00117 typedef CRecordVector<int> CIntVector;
00118 typedef CRecordVector<unsigned int> CUIntVector;
00119 typedef CRecordVector<bool> CBoolVector;
00120 typedef CRecordVector<unsigned char> CByteVector;
00121 typedef CRecordVector<void *> CPointerVector;
00122
00123 template <class T>
00124 class CObjectVector: public CPointerVector
00125 {
00126 public:
00127 CObjectVector(){};
00128 ~CObjectVector() { Clear(); }
00129 CObjectVector(const CObjectVector &objectVector)
00130 { *this = objectVector; }
00131 CObjectVector& operator=(const CObjectVector &objectVector)
00132 {
00133 Clear();
00134 return (*this += objectVector);
00135 }
00136 CObjectVector& operator+=(const CObjectVector &objectVector)
00137 {
00138 int size = objectVector.Size();
00139 Reserve(Size() + size);
00140 for(int i = 0; i < size; i++)
00141 Add(objectVector[i]);
00142 return *this;
00143 }
00144 const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); }
00145 T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); }
00146 T& Front() { return operator[](0); }
00147 const T& Front() const { return operator[](0); }
00148 T& Back() { return operator[](_size - 1); }
00149 const T& Back() const { return operator[](_size - 1); }
00150 int Add(const T& item)
00151 { return CPointerVector::Add(new T(item)); }
00152 void Insert(int index, const T& item)
00153 { CPointerVector::Insert(index, new T(item)); }
00154 virtual void Delete(int index, int num = 1)
00155 {
00156 TestIndexAndCorrectNum(index, num);
00157 for(int i = 0; i < num; i++)
00158 delete (T *)(((void **)_items)[index + i]);
00159 CPointerVector::Delete(index, num);
00160 }
00161 int Find(const T& item) const
00162 {
00163 for(int i = 0; i < Size(); i++)
00164 if (item == (*this)[i])
00165 return i;
00166 return -1;
00167 }
00168 int FindInSorted(const T& item) const
00169 {
00170 int left = 0, right = Size();
00171 while (left != right)
00172 {
00173 int mid = (left + right) / 2;
00174 const T& midValue = (*this)[mid];
00175 if (item == midValue)
00176 return mid;
00177 if (item < midValue)
00178 right = mid;
00179 else
00180 left = mid + 1;
00181 }
00182 return -1;
00183 }
00184 int AddToSorted(const T& item)
00185 {
00186 int left = 0, right = Size();
00187 while (left != right)
00188 {
00189 int mid = (left + right) / 2;
00190 const T& midValue = (*this)[mid];
00191 if (item == midValue)
00192 {
00193 right = mid + 1;
00194 break;
00195 }
00196 if (item < midValue)
00197 right = mid;
00198 else
00199 left = mid + 1;
00200 }
00201 Insert(right, item);
00202 return right;
00203 }
00204
00205 void Sort(int (*compare)(void *const *, void *const *, void *), void *param)
00206 { CPointerVector::Sort(compare, param); }
00207
00208 static int CompareObjectItems(void *const *a1, void *const *a2, void *param)
00209 { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); }
00210 void Sort() { CPointerVector::Sort(CompareObjectItems, 0); }
00211 };
00212
00213 #endif