other-licenses/7zstub/src/Common/Vector.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial