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