• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Common/MyVector.h
2 
3 #ifndef __COMMON_MY_VECTOR_H
4 #define __COMMON_MY_VECTOR_H
5 
6 #include <string.h>
7 
8 const unsigned k_VectorSizeMax = ((unsigned)1 << 31) - 1;
9 
10 template <class T>
11 class CRecordVector
12 {
13   T *_items;
14   unsigned _size;
15   unsigned _capacity;
16 
MoveItems(unsigned destIndex,unsigned srcIndex)17   void MoveItems(unsigned destIndex, unsigned srcIndex)
18   {
19     memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * sizeof(T));
20   }
21 
ReAllocForNewCapacity(const unsigned newCapacity)22   void ReAllocForNewCapacity(const unsigned newCapacity)
23   {
24     T *p;
25     MY_ARRAY_NEW(p, T, newCapacity);
26     // p = new T[newCapacity];
27     if (_size != 0)
28       memcpy(p, _items, (size_t)_size * sizeof(T));
29     delete []_items;
30     _items = p;
31     _capacity = newCapacity;
32   }
33 
34 public:
35 
ReserveOnePosition()36   void ReserveOnePosition()
37   {
38     if (_size != _capacity)
39       return;
40     if (_capacity >= k_VectorSizeMax)
41       throw 2021;
42     const unsigned rem = k_VectorSizeMax - _capacity;
43     unsigned add = (_capacity >> 2) + 1;
44     if (add > rem)
45       add = rem;
46     ReAllocForNewCapacity(_capacity + add);
47   }
48 
CRecordVector()49   CRecordVector(): _items(NULL), _size(0), _capacity(0) {}
50 
CRecordVector(const CRecordVector & v)51   CRecordVector(const CRecordVector &v): _items(NULL), _size(0), _capacity(0)
52   {
53     const unsigned size = v.Size();
54     if (size != 0)
55     {
56       // MY_ARRAY_NEW(_items, T, size)
57       _items = new T[size];
58       _size = size;
59       _capacity = size;
60       memcpy(_items, v._items, (size_t)size * sizeof(T));
61     }
62   }
63 
Size()64   unsigned Size() const { return _size; }
IsEmpty()65   bool IsEmpty() const { return _size == 0; }
66 
ConstructReserve(unsigned size)67   void ConstructReserve(unsigned size)
68   {
69     if (size != 0)
70     {
71       MY_ARRAY_NEW(_items, T, size)
72       // _items = new T[size];
73       _capacity = size;
74     }
75   }
76 
Reserve(unsigned newCapacity)77   void Reserve(unsigned newCapacity)
78   {
79     if (newCapacity > _capacity)
80     {
81       if (newCapacity > k_VectorSizeMax)
82         throw 2021;
83       ReAllocForNewCapacity(newCapacity);
84     }
85   }
86 
ChangeSize_KeepData(unsigned newSize)87   void ChangeSize_KeepData(unsigned newSize)
88   {
89     Reserve(newSize);
90     _size = newSize;
91   }
92 
ClearAndReserve(unsigned newCapacity)93   void ClearAndReserve(unsigned newCapacity)
94   {
95     Clear();
96     if (newCapacity > _capacity)
97     {
98       if (newCapacity > k_VectorSizeMax)
99         throw 2021;
100       delete []_items;
101       _items = NULL;
102       _capacity = 0;
103       MY_ARRAY_NEW(_items, T, newCapacity)
104       // _items = new T[newCapacity];
105       _capacity = newCapacity;
106     }
107   }
108 
ClearAndSetSize(unsigned newSize)109   void ClearAndSetSize(unsigned newSize)
110   {
111     ClearAndReserve(newSize);
112     _size = newSize;
113   }
114 
ReserveDown()115   void ReserveDown()
116   {
117     if (_size == _capacity)
118       return;
119     T *p = NULL;
120     if (_size != 0)
121     {
122       // MY_ARRAY_NEW(p, T, _size)
123       p = new T[_size];
124       memcpy(p, _items, (size_t)_size * sizeof(T));
125     }
126     delete []_items;
127     _items = p;
128     _capacity = _size;
129   }
130 
~CRecordVector()131   ~CRecordVector() { delete []_items; }
132 
ClearAndFree()133   void ClearAndFree()
134   {
135     delete []_items;
136     _items = NULL;
137     _size = 0;
138     _capacity = 0;
139   }
140 
Clear()141   void Clear() { _size = 0; }
142 
DeleteBack()143   void DeleteBack() { _size--; }
144 
DeleteFrom(unsigned index)145   void DeleteFrom(unsigned index)
146   {
147     // if (index <= _size)
148       _size = index;
149   }
150 
DeleteFrontal(unsigned num)151   void DeleteFrontal(unsigned num)
152   {
153     if (num != 0)
154     {
155       MoveItems(0, num);
156       _size -= num;
157     }
158   }
159 
Delete(unsigned index)160   void Delete(unsigned index)
161   {
162     MoveItems(index, index + 1);
163     _size -= 1;
164   }
165 
166   /*
167   void Delete(unsigned index, unsigned num)
168   {
169     if (num > 0)
170     {
171       MoveItems(index, index + num);
172       _size -= num;
173     }
174   }
175   */
176 
177   CRecordVector& operator=(const CRecordVector &v)
178   {
179     if (&v == this)
180       return *this;
181     const unsigned size = v.Size();
182     if (size > _capacity)
183     {
184       delete []_items;
185       _capacity = 0;
186       _size = 0;
187       _items = NULL;
188       _items = new T[size];
189       _capacity = size;
190     }
191     _size = size;
192     if (size != 0)
193       memcpy(_items, v._items, (size_t)size * sizeof(T));
194     return *this;
195   }
196 
197   CRecordVector& operator+=(const CRecordVector &v)
198   {
199     const unsigned size = v.Size();
200     if (size != 0)
201     {
202       if (_size >= k_VectorSizeMax || size > k_VectorSizeMax - _size)
203         throw 2021;
204       const unsigned newSize = _size + size;
205       Reserve(newSize);
206       memcpy(_items + _size, v._items, (size_t)size * sizeof(T));
207       _size = newSize;
208     }
209     return *this;
210   }
211 
Add(const T item)212   unsigned Add(const T item)
213   {
214     ReserveOnePosition();
215     const unsigned size = _size;
216     _size = size + 1;
217     _items[size] = item;
218     return size;
219   }
220 
221   /*
222   unsigned Add2(const T &item)
223   {
224     ReserveOnePosition();
225     const unsigned size = _size;
226     _size = size + 1;
227     _items[size] = item;
228     return size;
229   }
230   */
231 
AddInReserved(const T item)232   unsigned AddInReserved(const T item)
233   {
234     const unsigned size = _size;
235     _size = size + 1;
236     _items[size] = item;
237     return size;
238   }
239 
Insert(unsigned index,const T item)240   void Insert(unsigned index, const T item)
241   {
242     ReserveOnePosition();
243     MoveItems(index + 1, index);
244     _items[index] = item;
245     _size++;
246   }
247 
InsertInReserved(unsigned index,const T item)248   void InsertInReserved(unsigned index, const T item)
249   {
250     MoveItems(index + 1, index);
251     _items[index] = item;
252     _size++;
253   }
254 
MoveToFront(unsigned index)255   void MoveToFront(unsigned index)
256   {
257     if (index != 0)
258     {
259       T temp = _items[index];
260       memmove(_items + 1, _items, (size_t)index * sizeof(T));
261       _items[0] = temp;
262     }
263   }
264 
265   const T& operator[](unsigned index) const { return _items[index]; }
266         T& operator[](unsigned index)       { return _items[index]; }
Front()267   const T& Front() const { return _items[0]; }
Front()268         T& Front()       { return _items[0]; }
Back()269   const T& Back() const  { return _items[(size_t)_size - 1]; }
Back()270         T& Back()        { return _items[(size_t)_size - 1]; }
271 
272   /*
273   void Swap(unsigned i, unsigned j)
274   {
275     T temp = _items[i];
276     _items[i] = _items[j];
277     _items[j] = temp;
278   }
279   */
280 
FindInSorted(const T item,unsigned left,unsigned right)281   int FindInSorted(const T item, unsigned left, unsigned right) const
282   {
283     while (left != right)
284     {
285       // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
286       const unsigned mid = (left + right) / 2;
287       const T midVal = (*this)[mid];
288       if (item == midVal)
289         return (int)mid;
290       if (item < midVal)
291         right = mid;
292       else
293         left = mid + 1;
294     }
295     return -1;
296   }
297 
FindInSorted2(const T & item,unsigned left,unsigned right)298   int FindInSorted2(const T &item, unsigned left, unsigned right) const
299   {
300     while (left != right)
301     {
302       // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
303       const unsigned mid = (left + right) / 2;
304       const T& midVal = (*this)[mid];
305       const int comp = item.Compare(midVal);
306       if (comp == 0)
307         return (int)mid;
308       if (comp < 0)
309         right = mid;
310       else
311         left = mid + 1;
312     }
313     return -1;
314   }
315 
FindInSorted(const T item)316   int FindInSorted(const T item) const
317   {
318     return FindInSorted(item, 0, _size);
319   }
320 
FindInSorted2(const T & item)321   int FindInSorted2(const T &item) const
322   {
323     return FindInSorted2(item, 0, _size);
324   }
325 
AddToUniqueSorted(const T item)326   unsigned AddToUniqueSorted(const T item)
327   {
328     unsigned left = 0, right = _size;
329     while (left != right)
330     {
331       // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
332       const unsigned mid = (left + right) / 2;
333       const T midVal = (*this)[mid];
334       if (item == midVal)
335         return mid;
336       if (item < midVal)
337         right = mid;
338       else
339         left = mid + 1;
340     }
341     Insert(right, item);
342     return right;
343   }
344 
AddToUniqueSorted2(const T & item)345   unsigned AddToUniqueSorted2(const T &item)
346   {
347     unsigned left = 0, right = _size;
348     while (left != right)
349     {
350       // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
351       const unsigned mid = (left + right) / 2;
352       const T& midVal = (*this)[mid];
353       const int comp = item.Compare(midVal);
354       if (comp == 0)
355         return mid;
356       if (comp < 0)
357         right = mid;
358       else
359         left = mid + 1;
360     }
361     Insert(right, item);
362     return right;
363   }
364 
SortRefDown(T * p,unsigned k,unsigned size,int (* compare)(const T *,const T *,void *),void * param)365   static void SortRefDown(T* p, unsigned k, unsigned size, int (*compare)(const T*, const T*, void *), void *param)
366   {
367     T temp = p[k];
368     for (;;)
369     {
370       unsigned s = (k << 1);
371       if (s > size)
372         break;
373       if (s < size && compare(p + s + 1, p + s, param) > 0)
374         s++;
375       if (compare(&temp, p + s, param) >= 0)
376         break;
377       p[k] = p[s];
378       k = s;
379     }
380     p[k] = temp;
381   }
382 
Sort(int (* compare)(const T *,const T *,void *),void * param)383   void Sort(int (*compare)(const T*, const T*, void *), void *param)
384   {
385     unsigned size = _size;
386     if (size <= 1)
387       return;
388     T* p = (&Front()) - 1;
389     {
390       unsigned i = size >> 1;
391       do
392         SortRefDown(p, i, size, compare, param);
393       while (--i != 0);
394     }
395     do
396     {
397       T temp = p[size];
398       p[size--] = p[1];
399       p[1] = temp;
400       SortRefDown(p, 1, size, compare, param);
401     }
402     while (size > 1);
403   }
404 
SortRefDown2(T * p,unsigned k,unsigned size)405   static void SortRefDown2(T* p, unsigned k, unsigned size)
406   {
407     T temp = p[k];
408     for (;;)
409     {
410       unsigned s = (k << 1);
411       if (s > size)
412         break;
413       if (s < size && p[(size_t)s + 1].Compare(p[s]) > 0)
414         s++;
415       if (temp.Compare(p[s]) >= 0)
416         break;
417       p[k] = p[s];
418       k = s;
419     }
420     p[k] = temp;
421   }
422 
Sort2()423   void Sort2()
424   {
425     unsigned size = _size;
426     if (size <= 1)
427       return;
428     T* p = (&Front()) - 1;
429     {
430       unsigned i = size >> 1;
431       do
432         SortRefDown2(p, i, size);
433       while (--i != 0);
434     }
435     do
436     {
437       T temp = p[size];
438       p[size--] = p[1];
439       p[1] = temp;
440       SortRefDown2(p, 1, size);
441     }
442     while (size > 1);
443   }
444 };
445 
446 typedef CRecordVector<int> CIntVector;
447 typedef CRecordVector<unsigned int> CUIntVector;
448 typedef CRecordVector<bool> CBoolVector;
449 typedef CRecordVector<unsigned char> CByteVector;
450 typedef CRecordVector<void *> CPointerVector;
451 
452 template <class T>
453 class CObjectVector
454 {
455   CPointerVector _v;
456 public:
Size()457   unsigned Size() const { return _v.Size(); }
IsEmpty()458   bool IsEmpty() const { return _v.IsEmpty(); }
ReserveDown()459   void ReserveDown() { _v.ReserveDown(); }
460   // void Reserve(unsigned newCapacity) { _v.Reserve(newCapacity); }
ClearAndReserve(unsigned newCapacity)461   void ClearAndReserve(unsigned newCapacity) { Clear(); _v.ClearAndReserve(newCapacity); }
462 
CObjectVector()463   CObjectVector() {}
CObjectVector(const CObjectVector & v)464   CObjectVector(const CObjectVector &v)
465   {
466     const unsigned size = v.Size();
467     _v.ConstructReserve(size);
468     for (unsigned i = 0; i < size; i++)
469       AddInReserved(v[i]);
470   }
471   CObjectVector& operator=(const CObjectVector &v)
472   {
473     if (&v == this)
474       return *this;
475     Clear();
476     const unsigned size = v.Size();
477     _v.Reserve(size);
478     for (unsigned i = 0; i < size; i++)
479       AddInReserved(v[i]);
480     return *this;
481   }
482 
483   CObjectVector& operator+=(const CObjectVector &v)
484   {
485     const unsigned addSize = v.Size();
486     if (addSize != 0)
487     {
488       const unsigned size = Size();
489       if (size >= k_VectorSizeMax || addSize > k_VectorSizeMax - size)
490         throw 2021;
491       _v.Reserve(size + addSize);
492       for (unsigned i = 0; i < addSize; i++)
493         AddInReserved(v[i]);
494     }
495     return *this;
496   }
497 
498   const T& operator[](unsigned index) const { return *((T *)_v[index]); }
499         T& operator[](unsigned index)       { return *((T *)_v[index]); }
Front()500   const T& Front() const { return operator[](0); }
Front()501         T& Front()       { return operator[](0); }
Back()502   const T& Back() const  { return *(T *)_v.Back(); }
Back()503         T& Back()        { return *(T *)_v.Back(); }
504 
MoveToFront(unsigned index)505   void MoveToFront(unsigned index) { _v.MoveToFront(index); }
506 
Add(const T & item)507   unsigned Add(const T& item)
508   {
509     _v.ReserveOnePosition();
510     return AddInReserved(item);
511   }
512 
AddInReserved(const T & item)513   unsigned AddInReserved(const T& item)
514   {
515     return _v.AddInReserved(new T(item));
516   }
517 
ReserveOnePosition()518   void ReserveOnePosition()
519   {
520     _v.ReserveOnePosition();
521   }
522 
AddInReserved_Ptr_of_new(T * ptr)523   unsigned AddInReserved_Ptr_of_new(T *ptr)
524   {
525     return _v.AddInReserved(ptr);
526   }
527 
528   #define VECTOR_ADD_NEW_OBJECT(v, a) \
529     (v).ReserveOnePosition(); \
530     (v).AddInReserved_Ptr_of_new(new a);
531 
532 
AddNew()533   T& AddNew()
534   {
535     _v.ReserveOnePosition();
536     T *p = new T;
537     _v.AddInReserved(p);
538     return *p;
539   }
540 
AddNewInReserved()541   T& AddNewInReserved()
542   {
543     T *p = new T;
544     _v.AddInReserved(p);
545     return *p;
546   }
547 
Insert(unsigned index,const T & item)548   void Insert(unsigned index, const T& item)
549   {
550     _v.ReserveOnePosition();
551     _v.InsertInReserved(index, new T(item));
552   }
553 
InsertNew(unsigned index)554   T& InsertNew(unsigned index)
555   {
556     _v.ReserveOnePosition();
557     T *p = new T;
558     _v.InsertInReserved(index, p);
559     return *p;
560   }
561 
~CObjectVector()562   ~CObjectVector()
563   {
564     for (unsigned i = _v.Size(); i != 0;)
565       delete (T *)_v[--i];
566   }
567 
ClearAndFree()568   void ClearAndFree()
569   {
570     Clear();
571     _v.ClearAndFree();
572   }
573 
Clear()574   void Clear()
575   {
576     for (unsigned i = _v.Size(); i != 0;)
577       delete (T *)_v[--i];
578     _v.Clear();
579   }
580 
DeleteFrom(unsigned index)581   void DeleteFrom(unsigned index)
582   {
583     const unsigned size = _v.Size();
584     for (unsigned i = index; i < size; i++)
585       delete (T *)_v[i];
586     _v.DeleteFrom(index);
587   }
588 
DeleteFrontal(unsigned num)589   void DeleteFrontal(unsigned num)
590   {
591     for (unsigned i = 0; i < num; i++)
592       delete (T *)_v[i];
593     _v.DeleteFrontal(num);
594   }
595 
DeleteBack()596   void DeleteBack()
597   {
598     delete (T *)_v.Back();
599     _v.DeleteBack();
600   }
601 
Delete(unsigned index)602   void Delete(unsigned index)
603   {
604     delete (T *)_v[index];
605     _v.Delete(index);
606   }
607 
608   /*
609   void Delete(unsigned index, unsigned num)
610   {
611     for (unsigned i = 0; i < num; i++)
612       delete (T *)_v[index + i];
613     _v.Delete(index, num);
614   }
615   */
616 
617   /*
618   int Find(const T& item) const
619   {
620     unsigned size = Size();
621     for (unsigned i = 0; i < size; i++)
622       if (item == (*this)[i])
623         return i;
624     return -1;
625   }
626   */
627 
FindInSorted(const T & item)628   int FindInSorted(const T& item) const
629   {
630     unsigned left = 0, right = Size();
631     while (left != right)
632     {
633       // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
634       const unsigned mid = (left + right) / 2;
635       const T& midVal = (*this)[mid];
636       const int comp = item.Compare(midVal);
637       if (comp == 0)
638         return (int)mid;
639       if (comp < 0)
640         right = mid;
641       else
642         left = mid + 1;
643     }
644     return -1;
645   }
646 
AddToUniqueSorted(const T & item)647   unsigned AddToUniqueSorted(const T& item)
648   {
649     unsigned left = 0, right = Size();
650     while (left != right)
651     {
652       // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
653       const unsigned mid = (left + right) / 2;
654       const T& midVal = (*this)[mid];
655       const int comp = item.Compare(midVal);
656       if (comp == 0)
657         return mid;
658       if (comp < 0)
659         right = mid;
660       else
661         left = mid + 1;
662     }
663     Insert(right, item);
664     return right;
665   }
666 
667   /*
668   unsigned AddToSorted(const T& item)
669   {
670     unsigned left = 0, right = Size();
671     while (left != right)
672     {
673       // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
674       const unsigned mid = (left + right) / 2;
675       const T& midVal = (*this)[mid];
676       const int comp = item.Compare(midVal);
677       if (comp == 0)
678       {
679         right = mid + 1;
680         break;
681       }
682       if (comp < 0)
683         right = mid;
684       else
685         left = mid + 1;
686     }
687     Insert(right, item);
688     return right;
689   }
690   */
691 
Sort(int (* compare)(void * const *,void * const *,void *),void * param)692   void Sort(int (*compare)(void *const *, void *const *, void *), void *param)
693     { _v.Sort(compare, param); }
694 
CompareObjectItems(void * const * a1,void * const * a2,void *)695   static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */)
696     { return (*(*((const T *const *)a1))).Compare(*(*((const T *const *)a2))); }
697 
Sort()698   void Sort() { _v.Sort(CompareObjectItems, NULL); }
699 };
700 
701 #define FOR_VECTOR(_i_, _v_) for (unsigned _i_ = 0; _i_ < (_v_).Size(); _i_++)
702 
703 #endif
704