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 #ifndef INC_MI32_SIMPLEAR_H
00149 #define INC_MI32_SIMPLEAR_H
00150
00151 #ifndef INC_MI32_MIODEFNS_H
00152 #include <mi32/miodefns.h>
00153 #endif
00154
00155 #ifndef INC_MI32_STDANSIC_H
00156 #include <mi32/stdansic.h>
00157 #endif
00158
00159 #ifndef INC_MI32_MEMBUF_H
00160 #include <mi32/membuf.h>
00161 #endif
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 template <class _CT> class SIMPLE_ARRAY {
00180 public:
00181
00182
00183 SIMPLE_ARRAY (
00184 ):
00185 m_items(0),
00186 m_numitems(0),
00187 m_numalloc(0),
00188 m_spare(0)
00189 { }
00190
00191
00192 SIMPLE_ARRAY (
00193 const SIMPLE_ARRAY<_CT>& rhs
00194 ) {
00195 MmAllocExc((void**)&m_items,rhs.m_numalloc*sizeof(_CT));
00196 m_numalloc = rhs.m_numalloc;
00197 memcpy(m_items,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00198 m_numitems = rhs.m_numitems;
00199 m_spare = rhs.m_spare;
00200 }
00201
00202
00203 ~SIMPLE_ARRAY (
00204 ) {
00205 if (m_items != 0) free(m_items);
00206 }
00207
00208
00209 SIMPLE_ARRAY<_CT>& operator= (
00210 const SIMPLE_ARRAY<_CT>& rhs
00211 ) {
00212 if (this != &rhs) {
00213 if (m_numalloc < rhs.m_numalloc) {
00214
00215 MmFree(m_items);
00216 MmAllocExc((void**)&m_items,rhs.m_numalloc*sizeof(_CT));
00217 m_numalloc = rhs.m_numalloc;
00218 }
00219 memcpy(m_items,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00220 m_numitems = rhs.m_numitems;
00221 }
00222 return (*this);
00223 }
00224
00225
00226 bool operator== (
00227 const SIMPLE_ARRAY<_CT>& rhs
00228 ) const {
00229 if (m_numitems != rhs.m_numitems) return (false);
00230 if (m_numitems == 0) return (true);
00231 return (memcmp(m_items,rhs.m_items,m_numitems*sizeof(_CT)) == 0);
00232 }
00233
00234
00235 bool operator!= (
00236 const SIMPLE_ARRAY<_CT>& rhs
00237 ) const {
00238 return (!operator==(rhs));
00239 }
00240
00241
00242 operator const _CT*(
00243 ) const {
00244 return (m_items);
00245 }
00246
00247
00248 operator _CT*(
00249 ) {
00250 return (m_items);
00251 }
00252
00253
00254
00255
00256 const _CT& operator[] (
00257 int index
00258 ) const {
00259 return (m_items[index]);
00260 }
00261
00262
00263
00264
00265 _CT& operator[] (
00266 int index
00267 ) {
00268 return (m_items[index]);
00269 }
00270
00271 #ifndef GENERATING_DOXYGEN_OUTPUT
00272 #if defined(MAC_NATIVE) || defined(SUN64)
00273
00274
00275
00276
00277
00278 const _CT& operator[] (
00279 long index
00280 ) const {
00281 return (m_items[index]);
00282 }
00283
00284
00285
00286
00287 _CT& operator[] (
00288 long index
00289 ) {
00290 return (m_items[index]);
00291 }
00292 #endif
00293 #endif
00294
00295
00296 ERRVALUE Append (
00297 const _CT& item
00298 ) {
00299 if (m_numitems >= m_numalloc) {
00300 int err;
00301 if ((err = Reserve(MAX(16,2*m_numitems))) < 0) return (err);
00302 }
00303 m_items[m_numitems++] = item;
00304 return (0);
00305 }
00306
00307
00308 ERRVALUE Append (
00309 const _CT *items,
00310 int numitems
00311 ) {
00312 int err;
00313 if ((err = Reserve(m_numitems+numitems)) < 0) return (err);
00314 memcpy(m_items+m_numitems,items,numitems*sizeof(_CT));
00315 m_numitems += numitems;
00316 return (0);
00317 }
00318
00319
00320 ERRVALUE Append (
00321 const SIMPLE_ARRAY<_CT>& rhs
00322 ) {
00323 int err;
00324 if ((err = Reserve(m_numitems+rhs.m_numitems)) < 0) return (err);
00325 memcpy(m_items+m_numitems,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00326 m_numitems += rhs.m_numitems;
00327 return (0);
00328 }
00329
00330
00331
00332 void AppendExc (
00333 const _CT& item
00334 ) {
00335 if (m_numitems >= m_numalloc) {
00336 ReserveExc(MAX(16,2*m_numitems));
00337 }
00338 m_items[m_numitems++] = item;
00339 return;
00340 }
00341
00342
00343
00344 void AppendExc (
00345 const _CT *items,
00346 int numitems
00347 ) {
00348 ReserveExc(m_numitems+numitems);
00349 memcpy(m_items+m_numitems,items,numitems*sizeof(_CT));
00350 m_numitems += numitems;
00351 return;
00352 }
00353
00354
00355
00356 void AppendExc (
00357 const SIMPLE_ARRAY<_CT>& rhs
00358 ) {
00359 ReserveExc(m_numitems+rhs.m_numitems);
00360 memcpy(m_items+m_numitems,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00361 m_numitems += rhs.m_numitems;
00362 return;
00363 }
00364
00365
00366 ERRVALUE AppendUnique (
00367 const _CT& item
00368 ) {
00369 INT32 j;
00370 for (j = 0;(j < m_numitems);++j) {
00371 if (m_items[j] == item) break;
00372 }
00373 return ((j == m_numitems) ? Append(item) : 0);
00374 }
00375
00376
00377
00378 void AppendUniqueExc (
00379 const _CT& item
00380 ) {
00381 INT32 j;
00382 for (j = 0;(j < m_numitems);++j) {
00383 if (m_items[j] == item) break;
00384 }
00385 if (j == m_numitems) AppendExc(item);
00386 return;
00387 }
00388
00389
00390
00391 ERRVALUE Assign (
00392 const _CT *items,
00393 int numitems
00394 ) {
00395 int err;
00396 if ((err = Reserve(numitems)) < 0) return (err);
00397 memcpy(m_items,items,numitems*sizeof(_CT));
00398 m_numitems = numitems;
00399 return (0);
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 void Attach (
00411 _CT *& items,
00412 int numitems
00413 ) {
00414 Free();
00415 m_items = items;
00416 m_numitems = m_numalloc = numitems;
00417 items = 0;
00418 return;
00419 }
00420
00421
00422
00423 void Clear (
00424 ) {
00425 m_numitems = 0;
00426 return;
00427 }
00428
00429
00430 void ClearItems (
00431 int start = 0,
00432 int end = -1
00433 ) {
00434 if (end < start) end = m_numitems - 1;
00435 if (end >= start) {
00436 memset(m_items + start, 0, (end - start + 1) * sizeof(_CT));
00437 }
00438 return;
00439 }
00440
00441
00442
00443
00444 ERRVALUE Copy (
00445 const SIMPLE_ARRAY<_CT>& rhs
00446 ) {
00447 if (this != &rhs) {
00448 if (m_numalloc < rhs.m_numalloc) {
00449
00450 MmFree(m_items);
00451 ERRVALUE err = MmAlloc((void**)&m_items,rhs.m_numalloc*sizeof(_CT));
00452 if (err < 0) return (err);
00453 m_numalloc = rhs.m_numalloc;
00454 }
00455 memcpy(m_items,rhs.m_items,rhs.m_numitems*sizeof(_CT));
00456 m_numitems = rhs.m_numitems;
00457 }
00458 return (0);
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 _CT* Detach (
00471 ) {
00472 _CT* ret = m_items;
00473 m_numalloc = m_numitems = 0;
00474 m_items = 0;
00475 return (ret);
00476 }
00477
00478
00479 void Free (
00480 ) {
00481 m_numalloc = m_numitems = 0;
00482 MmFree(m_items);
00483 return;
00484 }
00485
00486
00487 const _CT& GetItem (
00488 int index
00489 ) const { return (m_items[index]); }
00490
00491
00492
00493 const _CT& GetLast (
00494 ) const { return (m_items[m_numitems-1]); }
00495
00496
00497 int GetMaxItems (
00498 ) const { return (m_numalloc); }
00499
00500
00501 int GetNumItems (
00502 ) const { return (m_numitems); }
00503
00504
00505 int GetSizeInBytes (
00506 ) const { return (m_numitems*sizeof(_CT)); }
00507
00508
00509
00510
00511 bool HasItem (
00512 const _CT& item
00513 ) const {
00514 for (INT32 i = 0;(i < m_numitems);++i) {
00515 if (m_items[i] == item) return (true);
00516 }
00517 return (false);
00518 }
00519
00520
00521 void InsertItems (
00522 int start,
00523 int num = 1
00524 ) {
00525 ReserveExc(m_numitems+num);
00526 memmove(&m_items[start + num], &m_items[start], (m_numitems - start) * sizeof(_CT));
00527 m_numitems += num;
00528 return;
00529 }
00530
00531
00532 bool IsEmpty (
00533 ) const { return (GetNumItems() == 0); }
00534
00535
00536
00537
00538
00539 template<class _Pr1>
00540 INT32 Locate (
00541 const _CT& item,
00542 _Pr1 _Pr
00543 ) const {
00544 if (m_numitems == 0) return (0);
00545 INT32 l = 0, r = m_numitems-1, q;
00546 do {
00547 q = (l+r)/2;
00548 int test = _Pr(item, m_items[q]);
00549 if (test == 0) return (q);
00550 if (test < 0) {
00551 r = q - 1;
00552 q = r;
00553 }
00554 else {
00555 l = q + 1;
00556 q = l;
00557 }
00558 } while (l <= r);
00559 return (q);
00560 }
00561
00562
00563 void RemoveDuplicates (
00564 ) {
00565 for (INT32 i = 0;(i < m_numitems);++i) {
00566 for (INT32 k = i+1;(k < m_numitems);++k) {
00567 if (m_items[i] == m_items[k]) {
00568 m_items[k] = m_items[m_numitems-1];
00569 m_numitems --;
00570 k --;
00571 }
00572 }
00573 }
00574 return;
00575 }
00576
00577
00578 void RemoveFast (
00579 INT32 item
00580 ) {
00581 if (item >= 0 && item < m_numitems) {
00582 m_numitems --;
00583 m_items[item] = m_items[m_numitems];
00584 }
00585 return;
00586 }
00587
00588
00589
00590 void RemoveItem (
00591 INT32 item
00592 ) {
00593 if (item < m_numitems && item >= 0) {
00594 --m_numitems;
00595 if (item < m_numitems) { memmove(&m_items[item], &m_items[item+1], (m_numitems - item) * sizeof(_CT)); }
00596 }
00597 return;
00598 }
00599
00600
00601 void RemoveLast (
00602 INT32 count = 1
00603 ) {
00604 if (count > m_numitems)
00605 m_numitems = 0;
00606 else
00607 m_numitems -= count;
00608 return;
00609 }
00610
00611
00612
00613
00614 bool RemoveMatchingItems (
00615 const _CT& item
00616 ) {
00617 INT32 i, num;
00618 for (num = i = 0;(i < m_numitems); ++i) {
00619 if (m_items[i] != item) {
00620 if (num < i) m_items[num] = m_items[i];
00621 num ++;
00622 }
00623 }
00624 bool retval = (m_numitems != num);
00625 m_numitems = num;
00626 return (retval);
00627 }
00628
00629
00630 ERRVALUE Reserve (
00631 int newmaxitems,
00632 bool clear = false
00633 ) {
00634 if (clear) m_numitems = 0;
00635 if (newmaxitems > m_numalloc) {
00636 int err;
00637 if (m_numitems == 0) {
00638
00639 MmFree(m_items);
00640 }
00641 if ((err = MmRealloc((void**)&m_items,newmaxitems*sizeof(_CT))) < 0) return (err);
00642 m_numalloc = newmaxitems;
00643 }
00644 return (0);
00645 }
00646
00647
00648
00649 void ReserveExc (
00650 int newmaxitems,
00651 bool clear = false
00652 ) {
00653 if (clear) m_numitems = 0;
00654 if (newmaxitems > m_numalloc) {
00655 if (m_numitems == 0) {
00656
00657 MmFree(m_items);
00658 }
00659 MmReallocExc((void**)&m_items,newmaxitems*sizeof(_CT));
00660 m_numalloc = newmaxitems;
00661 }
00662 return;
00663 }
00664
00665
00666
00667
00668 ERRVALUE Resize (
00669 int numitems,
00670 bool keepold = true,
00671 bool clear = false
00672 ) {
00673 int err;
00674 if ((err = Reserve(numitems,!keepold)) < 0) return (err);
00675 if (clear && numitems > m_numitems) memset(static_cast<void*>(m_items+m_numitems),0,(numitems-m_numitems)*sizeof(_CT));
00676 m_numitems = numitems;
00677 return (0);
00678 }
00679
00680
00681 void Reverse (
00682 ) {
00683 for (int i = 0; (i < m_numitems/2); ++i) {
00684 _CT temp(m_items[i]);
00685 m_items[i] = m_items[m_numitems-i-1];
00686 m_items[m_numitems-i-1] = temp;
00687 }
00688 return;
00689 }
00690
00691
00692 void SetItem (
00693 int index,
00694 const _CT& item
00695 ) {
00696 m_items[index] = item;
00697 }
00698
00699
00700
00701 ERRVALUE SetItems (
00702 int firstitem,
00703 const _CT *items,
00704 int numitems
00705 ) {
00706 int err;
00707 if ((err = Reserve(firstitem+numitems)) < 0) return (err);
00708 memcpy(m_items+firstitem,items,numitems*sizeof(_CT));
00709 if (m_numitems < firstitem + numitems) m_numitems = firstitem + numitems;
00710 return (0);
00711 }
00712
00713
00714
00715
00716 void Sort (
00717 int (*CompFunc)(_CT*, _CT*, void*),
00718 void *data = 0
00719 ) {
00720
00721 heapsort(m_items, m_numitems, sizeof(_CT), reinterpret_cast<int (*)(void*, void*, void*)>(CompFunc), data);
00722 }
00723
00724
00725
00726 void Swap (
00727 SIMPLE_ARRAY<_CT>& rhs
00728 ) {
00729 _CT *t_items = m_items;
00730 m_items = rhs.m_items;
00731 rhs.m_items = t_items;
00732 int t_numitems = m_numitems;
00733 m_numitems = rhs.m_numitems;
00734 rhs.m_numitems = t_numitems;
00735 int t_numalloc = m_numalloc;
00736 m_numalloc = rhs.m_numalloc;
00737 rhs.m_numalloc = t_numalloc;
00738 }
00739
00740
00741 void SwapBytes (
00742 ) {
00743 for (int i = 0;(i < m_numitems);++i) ::SwapBytes(m_items[i]);
00744 }
00745
00746 private:
00747 #ifndef GENERATING_DOXYGEN_OUTPUT
00748 _CT *m_items;
00749 int m_numitems;
00750 int m_numalloc;
00751 int m_spare;
00752 #endif // GENERATING_DOXYGEN_OUTPUT
00753
00754 };
00755
00756 #endif