diff options
author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2022-06-20 00:00:00 +0000 |
---|---|---|
committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2023-12-17 13:35:20 +0500 |
commit | a3e1d227377188734b82f023f96f8e25dc40f3e6 (patch) | |
tree | 23cad8d47eb23d26ea727b4f7f4a65124f724065 /CPP/Common/MyVector.h | |
parent | f19f813537c7aea1c20749c914e756b54a9c3cf5 (diff) | |
download | 7zip-22.00.tar.gz 7zip-22.00.tar.bz2 7zip-22.00.zip |
22.0022.00
Diffstat (limited to 'CPP/Common/MyVector.h')
-rw-r--r-- | CPP/Common/MyVector.h | 215 |
1 files changed, 142 insertions, 73 deletions
diff --git a/CPP/Common/MyVector.h b/CPP/Common/MyVector.h index c851234..3417a17 100644 --- a/CPP/Common/MyVector.h +++ b/CPP/Common/MyVector.h | |||
@@ -5,6 +5,8 @@ | |||
5 | 5 | ||
6 | #include <string.h> | 6 | #include <string.h> |
7 | 7 | ||
8 | const unsigned k_VectorSizeMax = ((unsigned)1 << 31) - 1; | ||
9 | |||
8 | template <class T> | 10 | template <class T> |
9 | class CRecordVector | 11 | class CRecordVector |
10 | { | 12 | { |
@@ -17,31 +19,41 @@ class CRecordVector | |||
17 | memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * sizeof(T)); | 19 | memmove(_items + destIndex, _items + srcIndex, (size_t)(_size - srcIndex) * sizeof(T)); |
18 | } | 20 | } |
19 | 21 | ||
20 | void ReserveOnePosition() | 22 | void ReAllocForNewCapacity(const unsigned newCapacity) |
21 | { | 23 | { |
22 | if (_size == _capacity) | 24 | T *p; |
23 | { | 25 | MY_ARRAY_NEW(p, T, newCapacity); |
24 | unsigned newCapacity = _capacity + (_capacity >> 2) + 1; | 26 | // p = new T[newCapacity]; |
25 | T *p; | 27 | if (_size != 0) |
26 | MY_ARRAY_NEW(p, T, newCapacity); | 28 | memcpy(p, _items, (size_t)_size * sizeof(T)); |
27 | // p = new T[newCapacity]; | 29 | delete []_items; |
28 | if (_size != 0) | 30 | _items = p; |
29 | memcpy(p, _items, (size_t)_size * sizeof(T)); | 31 | _capacity = newCapacity; |
30 | delete []_items; | ||
31 | _items = p; | ||
32 | _capacity = newCapacity; | ||
33 | } | ||
34 | } | 32 | } |
35 | 33 | ||
36 | public: | 34 | public: |
37 | 35 | ||
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 | |||
38 | CRecordVector(): _items(NULL), _size(0), _capacity(0) {} | 49 | CRecordVector(): _items(NULL), _size(0), _capacity(0) {} |
39 | 50 | ||
40 | CRecordVector(const CRecordVector &v): _items(0), _size(0), _capacity(0) | 51 | CRecordVector(const CRecordVector &v): _items(NULL), _size(0), _capacity(0) |
41 | { | 52 | { |
42 | unsigned size = v.Size(); | 53 | const unsigned size = v.Size(); |
43 | if (size != 0) | 54 | if (size != 0) |
44 | { | 55 | { |
56 | // MY_ARRAY_NEW(_items, T, size) | ||
45 | _items = new T[size]; | 57 | _items = new T[size]; |
46 | _size = size; | 58 | _size = size; |
47 | _capacity = size; | 59 | _capacity = size; |
@@ -66,22 +78,25 @@ public: | |||
66 | { | 78 | { |
67 | if (newCapacity > _capacity) | 79 | if (newCapacity > _capacity) |
68 | { | 80 | { |
69 | T *p; | 81 | if (newCapacity > k_VectorSizeMax) |
70 | MY_ARRAY_NEW(p, T, newCapacity); | 82 | throw 2021; |
71 | // p = new T[newCapacity]; | 83 | ReAllocForNewCapacity(newCapacity); |
72 | if (_size != 0) | ||
73 | memcpy(p, _items, (size_t)_size * sizeof(T)); | ||
74 | delete []_items; | ||
75 | _items = p; | ||
76 | _capacity = newCapacity; | ||
77 | } | 84 | } |
78 | } | 85 | } |
79 | 86 | ||
87 | void ChangeSize_KeepData(unsigned newSize) | ||
88 | { | ||
89 | Reserve(newSize); | ||
90 | _size = newSize; | ||
91 | } | ||
92 | |||
80 | void ClearAndReserve(unsigned newCapacity) | 93 | void ClearAndReserve(unsigned newCapacity) |
81 | { | 94 | { |
82 | Clear(); | 95 | Clear(); |
83 | if (newCapacity > _capacity) | 96 | if (newCapacity > _capacity) |
84 | { | 97 | { |
98 | if (newCapacity > k_VectorSizeMax) | ||
99 | throw 2021; | ||
85 | delete []_items; | 100 | delete []_items; |
86 | _items = NULL; | 101 | _items = NULL; |
87 | _capacity = 0; | 102 | _capacity = 0; |
@@ -97,22 +112,6 @@ public: | |||
97 | _size = newSize; | 112 | _size = newSize; |
98 | } | 113 | } |
99 | 114 | ||
100 | void ChangeSize_KeepData(unsigned newSize) | ||
101 | { | ||
102 | if (newSize > _capacity) | ||
103 | { | ||
104 | T *p; | ||
105 | MY_ARRAY_NEW(p, T, newSize) | ||
106 | // p = new T[newSize]; | ||
107 | if (_size != 0) | ||
108 | memcpy(p, _items, (size_t)_size * sizeof(T)); | ||
109 | delete []_items; | ||
110 | _items = p; | ||
111 | _capacity = newSize; | ||
112 | } | ||
113 | _size = newSize; | ||
114 | } | ||
115 | |||
116 | void ReserveDown() | 115 | void ReserveDown() |
117 | { | 116 | { |
118 | if (_size == _capacity) | 117 | if (_size == _capacity) |
@@ -120,6 +119,7 @@ public: | |||
120 | T *p = NULL; | 119 | T *p = NULL; |
121 | if (_size != 0) | 120 | if (_size != 0) |
122 | { | 121 | { |
122 | // MY_ARRAY_NEW(p, T, _size) | ||
123 | p = new T[_size]; | 123 | p = new T[_size]; |
124 | memcpy(p, _items, (size_t)_size * sizeof(T)); | 124 | memcpy(p, _items, (size_t)_size * sizeof(T)); |
125 | } | 125 | } |
@@ -178,7 +178,7 @@ public: | |||
178 | { | 178 | { |
179 | if (&v == this) | 179 | if (&v == this) |
180 | return *this; | 180 | return *this; |
181 | unsigned size = v.Size(); | 181 | const unsigned size = v.Size(); |
182 | if (size > _capacity) | 182 | if (size > _capacity) |
183 | { | 183 | { |
184 | delete []_items; | 184 | delete []_items; |
@@ -196,24 +196,45 @@ public: | |||
196 | 196 | ||
197 | CRecordVector& operator+=(const CRecordVector &v) | 197 | CRecordVector& operator+=(const CRecordVector &v) |
198 | { | 198 | { |
199 | unsigned size = v.Size(); | 199 | const unsigned size = v.Size(); |
200 | Reserve(_size + size); | ||
201 | if (size != 0) | 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); | ||
202 | memcpy(_items + _size, v._items, (size_t)size * sizeof(T)); | 206 | memcpy(_items + _size, v._items, (size_t)size * sizeof(T)); |
203 | _size += size; | 207 | _size = newSize; |
208 | } | ||
204 | return *this; | 209 | return *this; |
205 | } | 210 | } |
206 | 211 | ||
207 | unsigned Add(const T item) | 212 | unsigned Add(const T item) |
208 | { | 213 | { |
209 | ReserveOnePosition(); | 214 | ReserveOnePosition(); |
210 | _items[_size] = item; | 215 | const unsigned size = _size; |
211 | return _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; | ||
212 | } | 229 | } |
230 | */ | ||
213 | 231 | ||
214 | void AddInReserved(const T item) | 232 | unsigned AddInReserved(const T item) |
215 | { | 233 | { |
216 | _items[_size++] = item; | 234 | const unsigned size = _size; |
235 | _size = size + 1; | ||
236 | _items[size] = item; | ||
237 | return size; | ||
217 | } | 238 | } |
218 | 239 | ||
219 | void Insert(unsigned index, const T item) | 240 | void Insert(unsigned index, const T item) |
@@ -224,6 +245,13 @@ public: | |||
224 | _size++; | 245 | _size++; |
225 | } | 246 | } |
226 | 247 | ||
248 | void InsertInReserved(unsigned index, const T item) | ||
249 | { | ||
250 | MoveItems(index + 1, index); | ||
251 | _items[index] = item; | ||
252 | _size++; | ||
253 | } | ||
254 | |||
227 | void MoveToFront(unsigned index) | 255 | void MoveToFront(unsigned index) |
228 | { | 256 | { |
229 | if (index != 0) | 257 | if (index != 0) |
@@ -254,7 +282,8 @@ public: | |||
254 | { | 282 | { |
255 | while (left != right) | 283 | while (left != right) |
256 | { | 284 | { |
257 | unsigned mid = (left + right) / 2; | 285 | // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); |
286 | const unsigned mid = (left + right) / 2; | ||
258 | const T midVal = (*this)[mid]; | 287 | const T midVal = (*this)[mid]; |
259 | if (item == midVal) | 288 | if (item == midVal) |
260 | return (int)mid; | 289 | return (int)mid; |
@@ -270,9 +299,10 @@ public: | |||
270 | { | 299 | { |
271 | while (left != right) | 300 | while (left != right) |
272 | { | 301 | { |
273 | unsigned mid = (left + right) / 2; | 302 | // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); |
303 | const unsigned mid = (left + right) / 2; | ||
274 | const T& midVal = (*this)[mid]; | 304 | const T& midVal = (*this)[mid]; |
275 | int comp = item.Compare(midVal); | 305 | const int comp = item.Compare(midVal); |
276 | if (comp == 0) | 306 | if (comp == 0) |
277 | return (int)mid; | 307 | return (int)mid; |
278 | if (comp < 0) | 308 | if (comp < 0) |
@@ -298,7 +328,8 @@ public: | |||
298 | unsigned left = 0, right = _size; | 328 | unsigned left = 0, right = _size; |
299 | while (left != right) | 329 | while (left != right) |
300 | { | 330 | { |
301 | unsigned mid = (left + right) / 2; | 331 | // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); |
332 | const unsigned mid = (left + right) / 2; | ||
302 | const T midVal = (*this)[mid]; | 333 | const T midVal = (*this)[mid]; |
303 | if (item == midVal) | 334 | if (item == midVal) |
304 | return mid; | 335 | return mid; |
@@ -316,9 +347,10 @@ public: | |||
316 | unsigned left = 0, right = _size; | 347 | unsigned left = 0, right = _size; |
317 | while (left != right) | 348 | while (left != right) |
318 | { | 349 | { |
319 | unsigned mid = (left + right) / 2; | 350 | // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); |
351 | const unsigned mid = (left + right) / 2; | ||
320 | const T& midVal = (*this)[mid]; | 352 | const T& midVal = (*this)[mid]; |
321 | int comp = item.Compare(midVal); | 353 | const int comp = item.Compare(midVal); |
322 | if (comp == 0) | 354 | if (comp == 0) |
323 | return mid; | 355 | return mid; |
324 | if (comp < 0) | 356 | if (comp < 0) |
@@ -431,29 +463,35 @@ public: | |||
431 | CObjectVector() {} | 463 | CObjectVector() {} |
432 | CObjectVector(const CObjectVector &v) | 464 | CObjectVector(const CObjectVector &v) |
433 | { | 465 | { |
434 | unsigned size = v.Size(); | 466 | const unsigned size = v.Size(); |
435 | _v.ConstructReserve(size); | 467 | _v.ConstructReserve(size); |
436 | for (unsigned i = 0; i < size; i++) | 468 | for (unsigned i = 0; i < size; i++) |
437 | _v.AddInReserved(new T(v[i])); | 469 | AddInReserved(v[i]); |
438 | } | 470 | } |
439 | CObjectVector& operator=(const CObjectVector &v) | 471 | CObjectVector& operator=(const CObjectVector &v) |
440 | { | 472 | { |
441 | if (&v == this) | 473 | if (&v == this) |
442 | return *this; | 474 | return *this; |
443 | Clear(); | 475 | Clear(); |
444 | unsigned size = v.Size(); | 476 | const unsigned size = v.Size(); |
445 | _v.Reserve(size); | 477 | _v.Reserve(size); |
446 | for (unsigned i = 0; i < size; i++) | 478 | for (unsigned i = 0; i < size; i++) |
447 | _v.AddInReserved(new T(v[i])); | 479 | AddInReserved(v[i]); |
448 | return *this; | 480 | return *this; |
449 | } | 481 | } |
450 | 482 | ||
451 | CObjectVector& operator+=(const CObjectVector &v) | 483 | CObjectVector& operator+=(const CObjectVector &v) |
452 | { | 484 | { |
453 | unsigned size = v.Size(); | 485 | const unsigned addSize = v.Size(); |
454 | _v.Reserve(Size() + size); | 486 | if (addSize != 0) |
455 | for (unsigned i = 0; i < size; i++) | 487 | { |
456 | _v.AddInReserved(new T(v[i])); | 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 | } | ||
457 | return *this; | 495 | return *this; |
458 | } | 496 | } |
459 | 497 | ||
@@ -466,14 +504,37 @@ public: | |||
466 | 504 | ||
467 | void MoveToFront(unsigned index) { _v.MoveToFront(index); } | 505 | void MoveToFront(unsigned index) { _v.MoveToFront(index); } |
468 | 506 | ||
469 | unsigned Add(const T& item) { return _v.Add(new T(item)); } | 507 | unsigned Add(const T& item) |
508 | { | ||
509 | _v.ReserveOnePosition(); | ||
510 | return AddInReserved(item); | ||
511 | } | ||
512 | |||
513 | unsigned AddInReserved(const T& item) | ||
514 | { | ||
515 | return _v.AddInReserved(new T(item)); | ||
516 | } | ||
517 | |||
518 | void ReserveOnePosition() | ||
519 | { | ||
520 | _v.ReserveOnePosition(); | ||
521 | } | ||
522 | |||
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); | ||
470 | 531 | ||
471 | void AddInReserved(const T& item) { _v.AddInReserved(new T(item)); } | ||
472 | 532 | ||
473 | T& AddNew() | 533 | T& AddNew() |
474 | { | 534 | { |
535 | _v.ReserveOnePosition(); | ||
475 | T *p = new T; | 536 | T *p = new T; |
476 | _v.Add(p); | 537 | _v.AddInReserved(p); |
477 | return *p; | 538 | return *p; |
478 | } | 539 | } |
479 | 540 | ||
@@ -484,12 +545,17 @@ public: | |||
484 | return *p; | 545 | return *p; |
485 | } | 546 | } |
486 | 547 | ||
487 | void Insert(unsigned index, const T& item) { _v.Insert(index, new T(item)); } | 548 | void Insert(unsigned index, const T& item) |
549 | { | ||
550 | _v.ReserveOnePosition(); | ||
551 | _v.InsertInReserved(index, new T(item)); | ||
552 | } | ||
488 | 553 | ||
489 | T& InsertNew(unsigned index) | 554 | T& InsertNew(unsigned index) |
490 | { | 555 | { |
556 | _v.ReserveOnePosition(); | ||
491 | T *p = new T; | 557 | T *p = new T; |
492 | _v.Insert(index, p); | 558 | _v.InsertInReserved(index, p); |
493 | return *p; | 559 | return *p; |
494 | } | 560 | } |
495 | 561 | ||
@@ -514,7 +580,7 @@ public: | |||
514 | 580 | ||
515 | void DeleteFrom(unsigned index) | 581 | void DeleteFrom(unsigned index) |
516 | { | 582 | { |
517 | unsigned size = _v.Size(); | 583 | const unsigned size = _v.Size(); |
518 | for (unsigned i = index; i < size; i++) | 584 | for (unsigned i = index; i < size; i++) |
519 | delete (T *)_v[i]; | 585 | delete (T *)_v[i]; |
520 | _v.DeleteFrom(index); | 586 | _v.DeleteFrom(index); |
@@ -564,9 +630,10 @@ public: | |||
564 | unsigned left = 0, right = Size(); | 630 | unsigned left = 0, right = Size(); |
565 | while (left != right) | 631 | while (left != right) |
566 | { | 632 | { |
567 | unsigned mid = (left + right) / 2; | 633 | // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); |
634 | const unsigned mid = (left + right) / 2; | ||
568 | const T& midVal = (*this)[mid]; | 635 | const T& midVal = (*this)[mid]; |
569 | int comp = item.Compare(midVal); | 636 | const int comp = item.Compare(midVal); |
570 | if (comp == 0) | 637 | if (comp == 0) |
571 | return (int)mid; | 638 | return (int)mid; |
572 | if (comp < 0) | 639 | if (comp < 0) |
@@ -582,9 +649,10 @@ public: | |||
582 | unsigned left = 0, right = Size(); | 649 | unsigned left = 0, right = Size(); |
583 | while (left != right) | 650 | while (left != right) |
584 | { | 651 | { |
585 | unsigned mid = (left + right) / 2; | 652 | // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); |
653 | const unsigned mid = (left + right) / 2; | ||
586 | const T& midVal = (*this)[mid]; | 654 | const T& midVal = (*this)[mid]; |
587 | int comp = item.Compare(midVal); | 655 | const int comp = item.Compare(midVal); |
588 | if (comp == 0) | 656 | if (comp == 0) |
589 | return mid; | 657 | return mid; |
590 | if (comp < 0) | 658 | if (comp < 0) |
@@ -602,9 +670,10 @@ public: | |||
602 | unsigned left = 0, right = Size(); | 670 | unsigned left = 0, right = Size(); |
603 | while (left != right) | 671 | while (left != right) |
604 | { | 672 | { |
605 | unsigned mid = (left + right) / 2; | 673 | // const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2); |
674 | const unsigned mid = (left + right) / 2; | ||
606 | const T& midVal = (*this)[mid]; | 675 | const T& midVal = (*this)[mid]; |
607 | int comp = item.Compare(midVal); | 676 | const int comp = item.Compare(midVal); |
608 | if (comp == 0) | 677 | if (comp == 0) |
609 | { | 678 | { |
610 | right = mid + 1; | 679 | right = mid + 1; |