|
1 // Common/Vector.h |
|
2 |
|
3 #ifndef __COMMON_VECTOR_H |
|
4 #define __COMMON_VECTOR_H |
|
5 |
|
6 #include "Defs.h" |
|
7 |
|
8 class CBaseRecordVector |
|
9 { |
|
10 void MoveItems(int destIndex, int srcIndex); |
|
11 protected: |
|
12 int _capacity; |
|
13 int _size; |
|
14 void *_items; |
|
15 size_t _itemSize; |
|
16 |
|
17 void ReserveOnePosition(); |
|
18 void InsertOneItem(int index); |
|
19 void TestIndexAndCorrectNum(int index, int &num) const |
|
20 { if (index + num > _size) num = _size - index; } |
|
21 public: |
|
22 CBaseRecordVector(size_t itemSize): |
|
23 _capacity(0), _size(0), _items(0), _itemSize(itemSize) {} |
|
24 virtual ~CBaseRecordVector(); |
|
25 int Size() const { return _size; } |
|
26 bool IsEmpty() const { return (_size == 0); } |
|
27 void Reserve(int newCapacity); |
|
28 virtual void Delete(int index, int num = 1); |
|
29 void Clear(); |
|
30 void DeleteFrom(int index); |
|
31 void DeleteBack(); |
|
32 }; |
|
33 |
|
34 template <class T> |
|
35 class CRecordVector: public CBaseRecordVector |
|
36 { |
|
37 public: |
|
38 CRecordVector():CBaseRecordVector(sizeof(T)){}; |
|
39 CRecordVector(const CRecordVector &v): |
|
40 CBaseRecordVector(sizeof(T)) { *this = v;} |
|
41 CRecordVector& operator=(const CRecordVector &v) |
|
42 { |
|
43 Clear(); |
|
44 return (*this += v); |
|
45 } |
|
46 CRecordVector& operator+=(const CRecordVector &v) |
|
47 { |
|
48 int size = v.Size(); |
|
49 Reserve(Size() + size); |
|
50 for(int i = 0; i < size; i++) |
|
51 Add(v[i]); |
|
52 return *this; |
|
53 } |
|
54 int Add(T item) |
|
55 { |
|
56 ReserveOnePosition(); |
|
57 ((T *)_items)[_size] = item; |
|
58 return _size++; |
|
59 } |
|
60 void Insert(int index, T item) |
|
61 { |
|
62 InsertOneItem(index); |
|
63 ((T *)_items)[index] = item; |
|
64 } |
|
65 // T* GetPointer() const { return (T*)_items; } |
|
66 // operator const T *() const { return _items; }; |
|
67 const T& operator[](int index) const { return ((T *)_items)[index]; } |
|
68 T& operator[](int index) { return ((T *)_items)[index]; } |
|
69 const T& Front() const { return operator[](0); } |
|
70 T& Front() { return operator[](0); } |
|
71 const T& Back() const { return operator[](_size - 1); } |
|
72 T& Back() { return operator[](_size - 1); } |
|
73 |
|
74 void Swap(int i, int j) |
|
75 { |
|
76 T temp = operator[](i); |
|
77 operator[](i) = operator[](j); |
|
78 operator[](j) = temp; |
|
79 } |
|
80 |
|
81 int FindInSorted(const T& item) const |
|
82 { |
|
83 int left = 0, right = Size(); |
|
84 while (left != right) |
|
85 { |
|
86 int mid = (left + right) / 2; |
|
87 const T& midValue = (*this)[mid]; |
|
88 if (item == midValue) |
|
89 return mid; |
|
90 if (item < midValue) |
|
91 right = mid; |
|
92 else |
|
93 left = mid + 1; |
|
94 } |
|
95 return -1; |
|
96 } |
|
97 |
|
98 void Sort(int left, int right) |
|
99 { |
|
100 if (right - left < 2) |
|
101 return; |
|
102 Swap(left, (left + right) / 2); |
|
103 int last = left; |
|
104 for (int i = left; i < right; i++) |
|
105 if (operator[](i) < operator[](left)) |
|
106 Swap(++last, i); |
|
107 Swap(left, last); |
|
108 Sort(left, last); |
|
109 Sort(last + 1, right); |
|
110 } |
|
111 void Sort() { Sort(0, Size()); } |
|
112 void Sort(int left, int right, int (*compare)(const T*, const T*, void *), void *param) |
|
113 { |
|
114 if (right - left < 2) |
|
115 return; |
|
116 Swap(left, (left + right) / 2); |
|
117 int last = left; |
|
118 for (int i = left; i < right; i++) |
|
119 if (compare(&operator[](i), &operator[](left), param) < 0) |
|
120 Swap(++last, i); |
|
121 Swap(left, last); |
|
122 Sort(left, last, compare, param); |
|
123 Sort(last + 1, right, compare, param); |
|
124 } |
|
125 |
|
126 void Sort(int (*compare)(const T*, const T*, void *), void *param) |
|
127 { |
|
128 Sort(0, Size(), compare, param); |
|
129 } |
|
130 }; |
|
131 |
|
132 typedef CRecordVector<int> CIntVector; |
|
133 typedef CRecordVector<unsigned int> CUIntVector; |
|
134 typedef CRecordVector<bool> CBoolVector; |
|
135 typedef CRecordVector<unsigned char> CByteVector; |
|
136 typedef CRecordVector<void *> CPointerVector; |
|
137 |
|
138 template <class T> |
|
139 class CObjectVector: public CPointerVector |
|
140 { |
|
141 public: |
|
142 CObjectVector(){}; |
|
143 ~CObjectVector() { Clear(); } |
|
144 CObjectVector(const CObjectVector &objectVector) |
|
145 { *this = objectVector; } |
|
146 CObjectVector& operator=(const CObjectVector &objectVector) |
|
147 { |
|
148 Clear(); |
|
149 return (*this += objectVector); |
|
150 } |
|
151 CObjectVector& operator+=(const CObjectVector &objectVector) |
|
152 { |
|
153 int size = objectVector.Size(); |
|
154 Reserve(Size() + size); |
|
155 for(int i = 0; i < size; i++) |
|
156 Add(objectVector[i]); |
|
157 return *this; |
|
158 } |
|
159 const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); } |
|
160 T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); } |
|
161 T& Front() { return operator[](0); } |
|
162 const T& Front() const { return operator[](0); } |
|
163 T& Back() { return operator[](_size - 1); } |
|
164 const T& Back() const { return operator[](_size - 1); } |
|
165 int Add(const T& item) |
|
166 { return CPointerVector::Add(new T(item)); } |
|
167 void Insert(int index, const T& item) |
|
168 { CPointerVector::Insert(index, new T(item)); } |
|
169 virtual void Delete(int index, int num = 1) |
|
170 { |
|
171 TestIndexAndCorrectNum(index, num); |
|
172 for(int i = 0; i < num; i++) |
|
173 delete (T *)(((void **)_items)[index + i]); |
|
174 CPointerVector::Delete(index, num); |
|
175 } |
|
176 int Find(const T& item) const |
|
177 { |
|
178 for(int i = 0; i < Size(); i++) |
|
179 if (item == (*this)[i]) |
|
180 return i; |
|
181 return -1; |
|
182 } |
|
183 int FindInSorted(const T& item) const |
|
184 { |
|
185 int left = 0, right = Size(); |
|
186 while (left != right) |
|
187 { |
|
188 int mid = (left + right) / 2; |
|
189 const T& midValue = (*this)[mid]; |
|
190 if (item == midValue) |
|
191 return mid; |
|
192 if (item < midValue) |
|
193 right = mid; |
|
194 else |
|
195 left = mid + 1; |
|
196 } |
|
197 return -1; |
|
198 } |
|
199 int AddToSorted(const T& item) |
|
200 { |
|
201 int left = 0, right = Size(); |
|
202 while (left != right) |
|
203 { |
|
204 int mid = (left + right) / 2; |
|
205 const T& midValue = (*this)[mid]; |
|
206 if (item == midValue) |
|
207 { |
|
208 right = mid + 1; |
|
209 break; |
|
210 } |
|
211 if (item < midValue) |
|
212 right = mid; |
|
213 else |
|
214 left = mid + 1; |
|
215 } |
|
216 Insert(right, item); |
|
217 return right; |
|
218 } |
|
219 |
|
220 void Sort(int (*compare)(void *const *, void *const *, void *), void *param) |
|
221 { CPointerVector::Sort(compare, param); } |
|
222 |
|
223 static int CompareObjectItems(void *const *a1, void *const *a2, void *param) |
|
224 { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); } |
|
225 void Sort() { CPointerVector::Sort(CompareObjectItems, 0); } |
|
226 }; |
|
227 |
|
228 #endif |