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 10 const unsigned k_VectorSizeMax = ((unsigned)1 << 31) - 1; 11 12 template <class T> 13 class CRecordVector 14 { 15 T *_items; 16 unsigned _size; 17 unsigned _capacity; 18 MoveItems(unsigned destIndex,unsigned srcIndex)19 void MoveItems(unsigned destIndex, unsigned srcIndex) 20 { 21 memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * sizeof(T)); 22 } 23 ReAllocForNewCapacity(const unsigned newCapacity)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 36 public: 37 ReserveOnePosition()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 CRecordVector()51 CRecordVector(): _items(NULL), _size(0), _capacity(0) {} 52 CRecordVector(const CRecordVector & v)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 Size()66 unsigned Size() const { return _size; } IsEmpty()67 bool IsEmpty() const { return _size == 0; } 68 ConstructReserve(unsigned size)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 Reserve(unsigned newCapacity)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 ChangeSize_KeepData(unsigned newSize)89 void ChangeSize_KeepData(unsigned newSize) 90 { 91 Reserve(newSize); 92 _size = newSize; 93 } 94 ClearAndReserve(unsigned newCapacity)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 ClearAndSetSize(unsigned newSize)111 void ClearAndSetSize(unsigned newSize) 112 { 113 ClearAndReserve(newSize); 114 _size = newSize; 115 } 116 ReserveDown()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 ~CRecordVector()133 ~CRecordVector() { delete []_items; } 134 ClearAndFree()135 void ClearAndFree() 136 { 137 delete []_items; 138 _items = NULL; 139 _size = 0; 140 _capacity = 0; 141 } 142 Clear()143 void Clear() { _size = 0; } 144 DeleteBack()145 void DeleteBack() { _size--; } 146 DeleteFrom(unsigned index)147 void DeleteFrom(unsigned index) 148 { 149 // if (index <= _size) 150 _size = index; 151 } 152 DeleteFrontal(unsigned num)153 void DeleteFrontal(unsigned num) 154 { 155 if (num != 0) 156 { 157 MoveItems(0, num); 158 _size -= num; 159 } 160 } 161 Delete(unsigned index)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 Add(const T item)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 AddInReserved(const T item)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 Insert(unsigned index,const T item)242 void Insert(unsigned index, const T item) 243 { 244 ReserveOnePosition(); 245 MoveItems(index + 1, index); 246 _items[index] = item; 247 _size++; 248 } 249 InsertInReserved(unsigned index,const T item)250 void InsertInReserved(unsigned index, const T item) 251 { 252 MoveItems(index + 1, index); 253 _items[index] = item; 254 _size++; 255 } 256 MoveToFront(unsigned index)257 void MoveToFront(unsigned index) 258 { 259 if (index != 0) 260 { 261 const 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 ConstData()272 const T* ConstData() const { return _items; } NonConstData()273 T* NonConstData() const { return _items; } NonConstData()274 T* NonConstData() { return _items; } 275 Data()276 const T* Data() const { return _items; } Data()277 T* Data() { return _items; } 278 FrontItem()279 const T& FrontItem() const { return _items[0]; } FrontItem()280 T& FrontItem() { return _items[0]; } 281 /* 282 const T Front() const { return _items[0]; } 283 T Front() { return _items[0]; } 284 const T& Front() const { return _items[0]; } 285 T& Front() { return _items[0]; } 286 */ Back()287 const T& Back() const { return _items[(size_t)_size - 1]; } Back()288 T& Back() { return _items[(size_t)_size - 1]; } 289 290 /* 291 void Swap(unsigned i, unsigned j) 292 { 293 const T temp = _items[i]; 294 _items[i] = _items[j]; 295 _items[j] = temp; 296 } 297 */ 298 FindInSorted(const T item,unsigned left,unsigned right)299 int FindInSorted(const T item, unsigned left, unsigned right) const 300 { 301 while (left != right) 302 { 303 // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); 304 const unsigned mid = (left + right) / 2; 305 const T midVal = (*this)[mid]; 306 if (item == midVal) 307 return (int)mid; 308 if (item < midVal) 309 right = mid; 310 else 311 left = mid + 1; 312 } 313 return -1; 314 } 315 FindInSorted2(const T & item,unsigned left,unsigned right)316 int FindInSorted2(const T &item, unsigned left, unsigned right) const 317 { 318 while (left != right) 319 { 320 // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); 321 const unsigned mid = (left + right) / 2; 322 const T& midVal = (*this)[mid]; 323 const int comp = item.Compare(midVal); 324 if (comp == 0) 325 return (int)mid; 326 if (comp < 0) 327 right = mid; 328 else 329 left = mid + 1; 330 } 331 return -1; 332 } 333 FindInSorted(const T item)334 int FindInSorted(const T item) const 335 { 336 return FindInSorted(item, 0, _size); 337 } 338 FindInSorted2(const T & item)339 int FindInSorted2(const T &item) const 340 { 341 return FindInSorted2(item, 0, _size); 342 } 343 AddToUniqueSorted(const T item)344 unsigned AddToUniqueSorted(const T item) 345 { 346 unsigned left = 0, right = _size; 347 while (left != right) 348 { 349 // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); 350 const unsigned mid = (left + right) / 2; 351 const T midVal = (*this)[mid]; 352 if (item == midVal) 353 return mid; 354 if (item < midVal) 355 right = mid; 356 else 357 left = mid + 1; 358 } 359 Insert(right, item); 360 return right; 361 } 362 AddToUniqueSorted2(const T & item)363 unsigned AddToUniqueSorted2(const T &item) 364 { 365 unsigned left = 0, right = _size; 366 while (left != right) 367 { 368 // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); 369 const unsigned mid = (left + right) / 2; 370 const T& midVal = (*this)[mid]; 371 const int comp = item.Compare(midVal); 372 if (comp == 0) 373 return mid; 374 if (comp < 0) 375 right = mid; 376 else 377 left = mid + 1; 378 } 379 Insert(right, item); 380 return right; 381 } 382 SortRefDown(T * p,unsigned k,unsigned size,int (* compare)(const T *,const T *,void *),void * param)383 static void SortRefDown(T* p, unsigned k, unsigned size, int (*compare)(const T*, const T*, void *), void *param) 384 { 385 const T temp = p[k]; 386 for (;;) 387 { 388 unsigned s = (k << 1); 389 if (s > size) 390 break; 391 if (s < size && compare(p + s + 1, p + s, param) > 0) 392 s++; 393 if (compare(&temp, p + s, param) >= 0) 394 break; 395 p[k] = p[s]; 396 k = s; 397 } 398 p[k] = temp; 399 } 400 Sort(int (* compare)(const T *,const T *,void *),void * param)401 void Sort(int (*compare)(const T*, const T*, void *), void *param) 402 { 403 unsigned size = _size; 404 if (size <= 1) 405 return; 406 T* p = _items - 1; 407 { 408 unsigned i = size >> 1; 409 do 410 SortRefDown(p, i, size, compare, param); 411 while (--i); 412 } 413 do 414 { 415 const T temp = p[size]; 416 p[size--] = p[1]; 417 p[1] = temp; 418 SortRefDown(p, 1, size, compare, param); 419 } 420 while (size > 1); 421 } 422 SortRefDown2(T * p,unsigned k,unsigned size)423 static void SortRefDown2(T* p, unsigned k, unsigned size) 424 { 425 const T temp = p[k]; 426 for (;;) 427 { 428 unsigned s = (k << 1); 429 if (s > size) 430 break; 431 if (s < size && p[(size_t)s + 1].Compare(p[s]) > 0) 432 s++; 433 if (temp.Compare(p[s]) >= 0) 434 break; 435 p[k] = p[s]; 436 k = s; 437 } 438 p[k] = temp; 439 } 440 Sort2()441 void Sort2() 442 { 443 unsigned size = _size; 444 if (size <= 1) 445 return; 446 T* p = _items - 1; 447 { 448 unsigned i = size >> 1; 449 do 450 SortRefDown2(p, i, size); 451 while (--i); 452 } 453 do 454 { 455 const T temp = p[size]; 456 p[size--] = p[1]; 457 p[1] = temp; 458 SortRefDown2(p, 1, size); 459 } 460 while (size > 1); 461 } 462 }; 463 464 typedef CRecordVector<int> CIntVector; 465 typedef CRecordVector<unsigned int> CUIntVector; 466 typedef CRecordVector<bool> CBoolVector; 467 typedef CRecordVector<unsigned char> CByteVector; 468 typedef CRecordVector<void *> CPointerVector; 469 470 template <class T> 471 class CObjectVector 472 { 473 CPointerVector _v; 474 public: Size()475 unsigned Size() const { return _v.Size(); } IsEmpty()476 bool IsEmpty() const { return _v.IsEmpty(); } ReserveDown()477 void ReserveDown() { _v.ReserveDown(); } 478 // void Reserve(unsigned newCapacity) { _v.Reserve(newCapacity); } ClearAndReserve(unsigned newCapacity)479 void ClearAndReserve(unsigned newCapacity) { Clear(); _v.ClearAndReserve(newCapacity); } 480 CObjectVector()481 CObjectVector() {} CObjectVector(const CObjectVector & v)482 CObjectVector(const CObjectVector &v) 483 { 484 const unsigned size = v.Size(); 485 _v.ConstructReserve(size); 486 for (unsigned i = 0; i < size; i++) 487 AddInReserved(v[i]); 488 } 489 CObjectVector& operator=(const CObjectVector &v) 490 { 491 if (&v == this) 492 return *this; 493 Clear(); 494 const unsigned size = v.Size(); 495 _v.Reserve(size); 496 for (unsigned i = 0; i < size; i++) 497 AddInReserved(v[i]); 498 return *this; 499 } 500 501 CObjectVector& operator+=(const CObjectVector &v) 502 { 503 const unsigned addSize = v.Size(); 504 if (addSize != 0) 505 { 506 const unsigned size = Size(); 507 if (size >= k_VectorSizeMax || addSize > k_VectorSizeMax - size) 508 throw 2021; 509 _v.Reserve(size + addSize); 510 for (unsigned i = 0; i < addSize; i++) 511 AddInReserved(v[i]); 512 } 513 return *this; 514 } 515 516 const T& operator[](unsigned index) const { return *((T *)_v[index]); } 517 T& operator[](unsigned index) { return *((T *)_v[index]); } 518 const T& operator[](int index) const { return *((T *)_v[(unsigned)index]); } 519 T& operator[](int index) { return *((T *)_v[(unsigned)index]); } Front()520 const T& Front() const { return operator[](0); } Front()521 T& Front() { return operator[](0); } Back()522 const T& Back() const { return *(T *)_v.Back(); } Back()523 T& Back() { return *(T *)_v.Back(); } 524 MoveToFront(unsigned index)525 void MoveToFront(unsigned index) { _v.MoveToFront(index); } 526 Add(const T & item)527 unsigned Add(const T& item) 528 { 529 _v.ReserveOnePosition(); 530 return AddInReserved(item); 531 } 532 AddInReserved(const T & item)533 unsigned AddInReserved(const T& item) 534 { 535 return _v.AddInReserved(new T(item)); 536 } 537 ReserveOnePosition()538 void ReserveOnePosition() 539 { 540 _v.ReserveOnePosition(); 541 } 542 AddInReserved_Ptr_of_new(T * ptr)543 unsigned AddInReserved_Ptr_of_new(T *ptr) 544 { 545 return _v.AddInReserved(ptr); 546 } 547 548 #define VECTOR_ADD_NEW_OBJECT(v, a) \ 549 (v).ReserveOnePosition(); \ 550 (v).AddInReserved_Ptr_of_new(new a); 551 552 AddNew()553 T& AddNew() 554 { 555 _v.ReserveOnePosition(); 556 T *p = new T; 557 _v.AddInReserved(p); 558 return *p; 559 } 560 AddNewInReserved()561 T& AddNewInReserved() 562 { 563 T *p = new T; 564 _v.AddInReserved(p); 565 return *p; 566 } 567 Insert(unsigned index,const T & item)568 void Insert(unsigned index, const T& item) 569 { 570 _v.ReserveOnePosition(); 571 _v.InsertInReserved(index, new T(item)); 572 } 573 InsertNew(unsigned index)574 T& InsertNew(unsigned index) 575 { 576 _v.ReserveOnePosition(); 577 T *p = new T; 578 _v.InsertInReserved(index, p); 579 return *p; 580 } 581 ~CObjectVector()582 ~CObjectVector() 583 { 584 for (unsigned i = _v.Size(); i != 0;) 585 delete (T *)_v[--i]; 586 } 587 ClearAndFree()588 void ClearAndFree() 589 { 590 Clear(); 591 _v.ClearAndFree(); 592 } 593 Clear()594 void Clear() 595 { 596 for (unsigned i = _v.Size(); i != 0;) 597 delete (T *)_v[--i]; 598 _v.Clear(); 599 } 600 DeleteFrom(unsigned index)601 void DeleteFrom(unsigned index) 602 { 603 const unsigned size = _v.Size(); 604 for (unsigned i = index; i < size; i++) 605 delete (T *)_v[i]; 606 _v.DeleteFrom(index); 607 } 608 DeleteFrontal(unsigned num)609 void DeleteFrontal(unsigned num) 610 { 611 for (unsigned i = 0; i < num; i++) 612 delete (T *)_v[i]; 613 _v.DeleteFrontal(num); 614 } 615 DeleteBack()616 void DeleteBack() 617 { 618 delete (T *)_v.Back(); 619 _v.DeleteBack(); 620 } 621 Delete(unsigned index)622 void Delete(unsigned index) 623 { 624 delete (T *)_v[index]; 625 _v.Delete(index); 626 } 627 // void Delete(int index) { Delete((unsigned)index); } 628 629 /* 630 void Delete(unsigned index, unsigned num) 631 { 632 for (unsigned i = 0; i < num; i++) 633 delete (T *)_v[index + i]; 634 _v.Delete(index, num); 635 } 636 */ 637 638 /* 639 int Find(const T& item) const 640 { 641 unsigned size = Size(); 642 for (unsigned i = 0; i < size; i++) 643 if (item == (*this)[i]) 644 return i; 645 return -1; 646 } 647 */ 648 FindInSorted(const T & item)649 int FindInSorted(const T& item) const 650 { 651 unsigned left = 0, right = Size(); 652 while (left != right) 653 { 654 // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); 655 const unsigned mid = (left + right) / 2; 656 const T& midVal = (*this)[mid]; 657 const int comp = item.Compare(midVal); 658 if (comp == 0) 659 return (int)mid; 660 if (comp < 0) 661 right = mid; 662 else 663 left = mid + 1; 664 } 665 return -1; 666 } 667 AddToUniqueSorted(const T & item)668 unsigned AddToUniqueSorted(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 return mid; 679 if (comp < 0) 680 right = mid; 681 else 682 left = mid + 1; 683 } 684 Insert(right, item); 685 return right; 686 } 687 688 /* 689 unsigned AddToSorted(const T& item) 690 { 691 unsigned left = 0, right = Size(); 692 while (left != right) 693 { 694 // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); 695 const unsigned mid = (left + right) / 2; 696 const T& midVal = (*this)[mid]; 697 const int comp = item.Compare(midVal); 698 if (comp == 0) 699 { 700 right = mid + 1; 701 break; 702 } 703 if (comp < 0) 704 right = mid; 705 else 706 left = mid + 1; 707 } 708 Insert(right, item); 709 return right; 710 } 711 */ 712 Sort(int (* compare)(void * const *,void * const *,void *),void * param)713 void Sort(int (*compare)(void *const *, void *const *, void *), void *param) 714 { _v.Sort(compare, param); } 715 CompareObjectItems(void * const * a1,void * const * a2,void *)716 static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */) 717 { return (*(*((const T *const *)a1))).Compare(*(*((const T *const *)a2))); } 718 Sort()719 void Sort() { _v.Sort(CompareObjectItems, NULL); } 720 }; 721 722 #define FOR_VECTOR(_i_, _v_) for (unsigned _i_ = 0; _i_ < (_v_).Size(); _i_++) 723 724 #endif 725