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