00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 #ifndef INC_MI32_SIMPLEAR_H
00172 #define INC_MI32_SIMPLEAR_H
00173
00174 #ifndef INC_MI32_MEMALLOC_H
00175 #include <mi32/memalloc.h>
00176 #endif
00177
00178 #ifndef INC_MI32_SORT_H
00179 #include <mi32/sort.h>
00180 #endif
00181
00182 #ifndef INC_MI32_MEMBUF_H
00183 #include <mi32/membuf.h>
00184 #endif
00185
00186 #ifndef INC_MEMORY_H
00187 #include <memory.h>
00188 #define INC_MEMORY_H
00189 #endif
00190
00191 #ifndef INC_STRING_H
00192 #include <string.h>
00193 #define INC_STRING_H
00194 #endif
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 template <class _CT> class SIMPLE_ARRAY {
00213 public:
00214
00215
00216 SIMPLE_ARRAY (
00217 ):
00218 m_items(0),
00219 m_numitems(0),
00220 m_numalloc(0),
00221 m_RefCount(1)
00222 { }
00223
00224
00225 SIMPLE_ARRAY (
00226 const SIMPLE_ARRAY<_CT>& rhs
00227 ):
00228 m_items(0),
00229 m_RefCount(1)
00230 {
00231 MmAllocExc((void**)&m_items,rhs.m_numalloc*sizeof(_CT));
00232 m_numalloc = rhs.m_numalloc;
00233 memcpy(m_items,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00234 m_numitems = rhs.m_numitems;
00235 }
00236
00237
00238 ~SIMPLE_ARRAY (
00239 ) {
00240 if (m_items != 0) {
00241 free(m_items);
00242 m_numitems = 0;
00243 }
00244 }
00245
00246
00247 SIMPLE_ARRAY<_CT>& operator= (
00248 const SIMPLE_ARRAY<_CT>& rhs
00249 ) {
00250 if (this != &rhs) {
00251 if (m_numalloc < rhs.m_numalloc) {
00252
00253 MmFree(m_items);
00254 MmAllocExc((void**)&m_items,rhs.m_numalloc*sizeof(_CT));
00255 m_numalloc = rhs.m_numalloc;
00256 }
00257 memcpy(m_items,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00258 m_numitems = rhs.m_numitems;
00259 }
00260 return (*this);
00261 }
00262
00263
00264 bool operator== (
00265 const SIMPLE_ARRAY<_CT>& rhs
00266 ) const {
00267 if (m_numitems != rhs.m_numitems) return (false);
00268 if (m_numitems == 0) return (true);
00269 return (memcmp(m_items,rhs.m_items,m_numitems*sizeof(_CT)) == 0);
00270 }
00271
00272
00273 bool operator!= (
00274 const SIMPLE_ARRAY<_CT>& rhs
00275 ) const {
00276 return (!operator==(rhs));
00277 }
00278
00279
00280 operator const _CT*(
00281 ) const {
00282 return (m_items);
00283 }
00284
00285
00286 operator _CT*(
00287 ) {
00288 return (m_items);
00289 }
00290
00291
00292
00293
00294 template <typename _IDXTYPE> const _CT& operator[] (
00295 _IDXTYPE index
00296 ) const {
00297 return (m_items[index]);
00298 }
00299
00300
00301
00302
00303 template <typename _IDXTYPE> _CT& operator[] (
00304 _IDXTYPE index
00305 ) {
00306 return (m_items[index]);
00307 }
00308
00309
00310 void AddRef (
00311 ) { ++m_RefCount; }
00312
00313
00314 ERRVALUE Append (
00315 const _CT& item
00316 ) {
00317 if (m_numitems >= m_numalloc) {
00318 int err;
00319 if ((err = Reserve(MAX(16,2*m_numitems))) < 0) return (err);
00320 }
00321 m_items[m_numitems++] = item;
00322 return (0);
00323 }
00324
00325
00326 ERRVALUE Append (
00327 const _CT *items,
00328 int numitems
00329 ) {
00330 int err;
00331 if ((err = Reserve(m_numitems+numitems)) < 0) return (err);
00332 memcpy(m_items+m_numitems,items,numitems*sizeof(_CT));
00333 m_numitems += numitems;
00334 return (0);
00335 }
00336
00337
00338 ERRVALUE Append (
00339 const SIMPLE_ARRAY<_CT>& rhs
00340 ) {
00341 int err;
00342 if ((err = Reserve(m_numitems+rhs.m_numitems)) < 0) return (err);
00343 memcpy(m_items+m_numitems,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00344 m_numitems += rhs.m_numitems;
00345 return (0);
00346 }
00347
00348
00349
00350 void AppendExc (
00351 const _CT& item
00352 ) {
00353 if (m_numitems >= m_numalloc) {
00354 ReserveExc(MAX(16,2*m_numitems));
00355 }
00356 m_items[m_numitems++] = item;
00357 return;
00358 }
00359
00360
00361
00362 void AppendExc (
00363 const _CT *items,
00364 int numitems
00365 ) {
00366 ReserveExc(m_numitems+numitems);
00367 memcpy(m_items+m_numitems,items,numitems*sizeof(_CT));
00368 m_numitems += numitems;
00369 return;
00370 }
00371
00372
00373
00374 void AppendExc (
00375 const SIMPLE_ARRAY<_CT>& rhs
00376 ) {
00377 ReserveExc(m_numitems+rhs.m_numitems);
00378 memcpy(m_items+m_numitems,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00379 m_numitems += rhs.m_numitems;
00380 return;
00381 }
00382
00383
00384 ERRVALUE AppendUnique (
00385 const _CT& item
00386 ) {
00387 INT32 j;
00388 for (j = 0;(j < m_numitems);++j) {
00389 if (m_items[j] == item) break;
00390 }
00391 return ((j == m_numitems) ? Append(item) : 0);
00392 }
00393
00394
00395
00396 void AppendUniqueExc (
00397 const _CT& item
00398 ) {
00399 INT32 j;
00400 for (j = 0;(j < m_numitems);++j) {
00401 if (m_items[j] == item) break;
00402 }
00403 if (j == m_numitems) AppendExc(item);
00404 return;
00405 }
00406
00407
00408
00409 ERRVALUE Assign (
00410 const _CT *items,
00411 int numitems
00412 ) {
00413 int err;
00414 if ((err = Reserve(numitems)) < 0) return (err);
00415 memcpy(m_items,items,numitems*sizeof(_CT));
00416 m_numitems = numitems;
00417 return (0);
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 void Attach (
00429 _CT *& items,
00430 int numitems
00431 ) {
00432 Free();
00433 m_items = items;
00434 m_numitems = m_numalloc = numitems;
00435 items = 0;
00436 return;
00437 }
00438
00439
00440
00441 void Clear (
00442 ) {
00443 m_numitems = 0;
00444 return;
00445 }
00446
00447
00448 void ClearItems (
00449 int start = 0,
00450 int end = -1
00451 ) {
00452 if (end < start) end = m_numitems - 1;
00453 if (end >= start) {
00454 memset(m_items + start, 0, (end - start + 1) * sizeof(_CT));
00455 }
00456 return;
00457 }
00458
00459
00460
00461
00462 ERRVALUE Copy (
00463 const SIMPLE_ARRAY<_CT>& rhs
00464 ) {
00465 if (this != &rhs) {
00466 if (m_numalloc < rhs.m_numalloc) {
00467
00468 MmFree(m_items);
00469 ERRVALUE err = MmAlloc((void**)&m_items,rhs.m_numalloc*sizeof(_CT));
00470 if (err < 0) return (err);
00471 m_numalloc = rhs.m_numalloc;
00472 }
00473 memcpy(m_items,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00474 m_numitems = rhs.m_numitems;
00475 }
00476 return (0);
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 _CT* Detach (
00489 ) {
00490 _CT* ret = m_items;
00491 m_numalloc = m_numitems = 0;
00492 m_items = 0;
00493 return (ret);
00494 }
00495
00496
00497 void Free (
00498 ) {
00499 m_numalloc = m_numitems = 0;
00500 MmFree(m_items);
00501 return;
00502 }
00503
00504
00505 const _CT& GetItem (
00506 int index
00507 ) const { return (m_items[index]); }
00508
00509
00510
00511 const _CT& GetLast (
00512 ) const { return (m_items[m_numitems-1]); }
00513
00514
00515 int GetMaxItems (
00516 ) const { return (m_numalloc); }
00517
00518
00519 int GetNumItems (
00520 ) const { return (m_numitems); }
00521
00522
00523 UINT32 GetRefCount (
00524 ) const { return (m_RefCount); }
00525
00526
00527 int GetSizeInBytes (
00528 ) const { return (m_numitems*sizeof(_CT)); }
00529
00530
00531
00532
00533 bool HasItem (
00534 const _CT& item
00535 ) const {
00536 for (INT32 i = 0;(i < m_numitems);++i) {
00537 if (m_items[i] == item) return (true);
00538 }
00539 return (false);
00540 }
00541
00542
00543 void InsertItems (
00544 int start,
00545 int num = 1
00546 ) {
00547 ReserveExc(m_numitems+num);
00548 memmove(&m_items[start + num], &m_items[start], (m_numitems - start) * sizeof(_CT));
00549 m_numitems += num;
00550 return;
00551 }
00552
00553
00554 bool IsEmpty (
00555 ) const { return (GetNumItems() == 0); }
00556
00557
00558
00559
00560
00561 template<class _Pr1>
00562 INT32 Locate (
00563 const _CT& item,
00564 _Pr1 _Pr,
00565 bool bReturnNegativeOneIfNotFound = false
00566 ) const {
00567 if (m_numitems == 0) return (bReturnNegativeOneIfNotFound ? -1 : 0);
00568 INT32 l = 0, r = m_numitems-1, q;
00569 do {
00570 q = (l+r)/2;
00571 int test = _Pr(item, m_items[q]);
00572 if (test == 0) return (q);
00573 if (test < 0) {
00574 r = q - 1;
00575 q = r;
00576 }
00577 else {
00578 l = q + 1;
00579 q = l;
00580 }
00581 } while (l <= r);
00582 return (bReturnNegativeOneIfNotFound ? -1 : q);
00583 }
00584
00585
00586 void Release (
00587 ) { if (--m_RefCount == 0) delete this; }
00588
00589
00590 void RemoveDuplicates (
00591 ) {
00592 for (INT32 i = 0;(i < m_numitems);++i) {
00593 for (INT32 k = i+1;(k < m_numitems);++k) {
00594 if (m_items[i] == m_items[k]) {
00595 m_items[k] = m_items[m_numitems-1];
00596 m_numitems --;
00597 k --;
00598 }
00599 }
00600 }
00601 return;
00602 }
00603
00604
00605 void RemoveFast (
00606 INT32 item
00607 ) {
00608 if (item >= 0 && item < m_numitems) {
00609 m_numitems --;
00610 m_items[item] = m_items[m_numitems];
00611 }
00612 return;
00613 }
00614
00615
00616
00617 void RemoveItem (
00618 INT32 item
00619 ) {
00620 if (item < m_numitems && item >= 0) {
00621 --m_numitems;
00622 if (item < m_numitems) { memmove(&m_items[item], &m_items[item+1], (m_numitems - item) * sizeof(_CT)); }
00623 }
00624 return;
00625 }
00626
00627
00628 void RemoveLast (
00629 INT32 count = 1
00630 ) {
00631 if (count > m_numitems)
00632 m_numitems = 0;
00633 else
00634 m_numitems -= count;
00635 return;
00636 }
00637
00638
00639
00640
00641 bool RemoveMatchingItems (
00642 const _CT& item
00643 ) {
00644 INT32 i, num;
00645 for (num = i = 0;(i < m_numitems); ++i) {
00646 if (m_items[i] != item) {
00647 if (num < i) m_items[num] = m_items[i];
00648 num ++;
00649 }
00650 }
00651 bool retval = (m_numitems != num);
00652 m_numitems = num;
00653 return (retval);
00654 }
00655
00656
00657 ERRVALUE Reserve (
00658 int newmaxitems,
00659 bool clear = false
00660 ) {
00661 if (clear) m_numitems = 0;
00662 if (newmaxitems > m_numalloc) {
00663 int err;
00664 if (m_numitems == 0) {
00665
00666 MmFree(m_items);
00667 }
00668 if ((err = MmRealloc((void**)&m_items,newmaxitems*sizeof(_CT))) < 0) return (err);
00669 m_numalloc = newmaxitems;
00670 }
00671 return (0);
00672 }
00673
00674
00675
00676 void ReserveExc (
00677 int newmaxitems,
00678 bool clear = false
00679 ) {
00680 if (clear) m_numitems = 0;
00681 if (newmaxitems > m_numalloc) {
00682 if (m_numitems == 0) {
00683
00684 MmFree(m_items);
00685 }
00686 MmReallocExc((void**)&m_items,newmaxitems*sizeof(_CT));
00687 m_numalloc = newmaxitems;
00688 }
00689 return;
00690 }
00691
00692
00693
00694
00695 ERRVALUE Resize (
00696 int numitems,
00697 bool keepold = true,
00698 bool clear = false
00699 ) {
00700 int err;
00701 if ((err = Reserve(numitems,!keepold)) < 0) return (err);
00702 if (clear && numitems > m_numitems) memset(static_cast<void*>(m_items+m_numitems),0,(numitems-m_numitems)*sizeof(_CT));
00703 m_numitems = numitems;
00704 return (0);
00705 }
00706
00707
00708 void Reverse (
00709 ) {
00710 for (int i = 0; (i < m_numitems/2); ++i) {
00711 _CT temp(m_items[i]);
00712 m_items[i] = m_items[m_numitems-i-1];
00713 m_items[m_numitems-i-1] = temp;
00714 }
00715 return;
00716 }
00717
00718
00719 void SetItem (
00720 int index,
00721 const _CT& item
00722 ) {
00723 m_items[index] = item;
00724 }
00725
00726
00727
00728 ERRVALUE SetItems (
00729 int firstitem,
00730 const _CT *items,
00731 int numitems
00732 ) {
00733 int err;
00734 if ((err = Reserve(firstitem+numitems)) < 0) return (err);
00735 memcpy(m_items+firstitem,items,numitems*sizeof(_CT));
00736 if (m_numitems < firstitem + numitems) m_numitems = firstitem + numitems;
00737 return (0);
00738 }
00739
00740
00741
00742
00743 void Sort (
00744 int (*CompFunc)(_CT*, _CT*, void*),
00745 void *data = 0
00746 ) {
00747
00748 heapsort(m_items, m_numitems, sizeof(_CT), reinterpret_cast<int (*)(void*, void*, void*)>(CompFunc), data);
00749 }
00750
00751
00752
00753
00754 void SortRange (
00755 int (*CompFunc)(_CT*, _CT*, void*),
00756 int firstidx,
00757 int numitems,
00758 void *data = 0
00759 ) {
00760 if (numitems <= 0 || firstidx < 0 || firstidx + numitems > m_numitems) return;
00761 heapsort(m_items + firstidx, numitems, sizeof(_CT), reinterpret_cast<int (*)(void*, void*, void*)>(CompFunc), data);
00762 }
00763
00764
00765
00766 void Swap (
00767 SIMPLE_ARRAY<_CT>& rhs
00768 ) {
00769 _CT *t_items = m_items;
00770 m_items = rhs.m_items;
00771 rhs.m_items = t_items;
00772 int t_numitems = m_numitems;
00773 m_numitems = rhs.m_numitems;
00774 rhs.m_numitems = t_numitems;
00775 int t_numalloc = m_numalloc;
00776 m_numalloc = rhs.m_numalloc;
00777 rhs.m_numalloc = t_numalloc;
00778 }
00779
00780
00781 void SwapBytes (
00782 ) {
00783 for (int i = 0;(i < m_numitems);++i) ::SwapBytes(m_items[i]);
00784 }
00785
00786 private:
00787 #ifndef GENERATING_DOXYGEN_OUTPUT
00788 _CT *m_items;
00789 int m_numitems;
00790 int m_numalloc;
00791 UINT32 m_RefCount;
00792 #endif // GENERATING_DOXYGEN_OUTPUT
00793
00794 };
00795
00796 #endif