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 #ifndef __UT_RefArray_C__
00033 #define __UT_RefArray_C__
00034
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <new.h>
00038 #include "UT_Assert.h"
00039 #include "UT_RefArray.h"
00040
00041 template <class utRef>
00042 UT_RefArray<utRef>::UT_RefArray(unsigned int sz, unsigned int count)
00043 : arrSize(sz)
00044 {
00045 arr = (sz) ? (utRef*)calloc(sizeof(utRef), sz) : 0;
00046
00047 if (sz < count) count = sz;
00048 if (nbrEntries = count)
00049 for (int i = 0; i < nbrEntries; i++)
00050 new (&arr[i]) utRef();
00051 }
00052
00053 template <class utRef>
00054 UT_RefArray<utRef>::UT_RefArray(const UT_RefArray<utRef> &a)
00055 : arrSize(a.entries()), nbrEntries(a.entries())
00056 {
00057 unsigned int en = a.entries();
00058 arr = (en) ? (utRef*)calloc(sizeof(utRef), en) : 0;
00059 for (unsigned int i = 0; i < en; i++)
00060 {
00061 new (&arr[i]) utRef();
00062 arr[i] = a(i);
00063 }
00064 }
00065
00066 template <class utRef>
00067 UT_RefArray<utRef>::~UT_RefArray(void)
00068 {
00069 resize(0);
00070 }
00071
00072 template <class utRef>
00073 void
00074 UT_RefArray<utRef>::swap( UT_RefArray<utRef> &other )
00075 {
00076 UTswap( arr, other.arr );
00077 UTswap( arrSize, other.arrSize );
00078 UTswap( nbrEntries, other.nbrEntries );
00079 }
00080
00081
00082 template <class utRef>
00083 unsigned int
00084 UT_RefArray<utRef>::insert(unsigned int iindex)
00085 {
00086 if (iindex >= nbrEntries)
00087 {
00088 if (iindex >= arrSize) resize(bumpAlloc(iindex));
00089
00090 for (unsigned t = nbrEntries; t <= iindex; t++)
00091 new (&arr[t]) utRef();
00092
00093 nbrEntries = iindex+1;
00094 return iindex;
00095 }
00096 if (nbrEntries == arrSize)
00097 {
00098 arrSize = bumpAlloc(arrSize);
00099 arr = (utRef*)realloc(arr, arrSize*sizeof(utRef));
00100 UT_ASSERT(arr);
00101 }
00102 memmove(&arr[iindex+1], &arr[iindex],((nbrEntries-iindex)*sizeof(utRef)));
00103 new (&arr[iindex]) utRef();
00104
00105 nbrEntries++;
00106 return iindex;
00107 }
00108
00109 template <class utRef>
00110 unsigned int
00111 UT_RefArray<utRef>::append(const utRef& t)
00112 {
00113 if (nbrEntries == arrSize)
00114 {
00115 if (arr <= &t && &t <= arr+nbrEntries)
00116 {
00117 utRef save; save = t;
00118 resize(bumpAlloc(arrSize));
00119 new (&arr[nbrEntries]) utRef();
00120 arr[nbrEntries] = save;
00121 }
00122 else
00123 {
00124 resize(bumpAlloc(arrSize));
00125 new (&arr[nbrEntries]) utRef();
00126 arr[nbrEntries] = t;
00127 }
00128 }
00129 else
00130 {
00131 new (&arr[nbrEntries]) utRef();
00132 arr[nbrEntries] = t;
00133 }
00134
00135 return nbrEntries++;
00136 }
00137
00138 template <class utRef>
00139 unsigned int
00140 UT_RefArray<utRef>::append(const utRef& t, unsigned short dupliCheck)
00141 {
00142 int idx = -1;
00143 if (dupliCheck && ((idx = find(t)) != -1)) return (unsigned int)idx;
00144 return append( t );
00145 }
00146
00147 template <class utRef>
00148 unsigned int
00149 UT_RefArray<utRef>::insert(const utRef& t, unsigned int iindex)
00150 {
00151
00152 return insertAt(t, iindex);
00153 }
00154
00155 template <class utRef>
00156 unsigned int
00157 UT_RefArray<utRef>::insert(const utRef& t, unsigned int iindex,
00158 unsigned short dupliCheck)
00159 {
00160
00161 int idx = -1;
00162 return (dupliCheck && ((idx=find(t)) != -1)) ? (unsigned int)idx
00163 : insertAt(t, iindex);
00164 }
00165
00166 template <class utRef>
00167 unsigned int
00168 UT_RefArray<utRef>::append(const utRef& t, Comparator compare)
00169 {
00170 int idx = -1;
00171 if ((idx=find(t, compare)) != -1) return (unsigned int)idx;
00172 if (nbrEntries == arrSize)
00173 {
00174 if (arr <= &t && &t <= arr+nbrEntries)
00175 {
00176 utRef save; save = t;
00177 resize(bumpAlloc(arrSize));
00178 new (&arr[nbrEntries]) utRef();
00179 arr[nbrEntries] = save;
00180 }
00181 else
00182 {
00183 resize(bumpAlloc(arrSize));
00184 new (&arr[nbrEntries]) utRef();
00185 arr[nbrEntries] = t;
00186 }
00187 }
00188 else
00189 {
00190 new (&arr[nbrEntries]) utRef();
00191 arr[nbrEntries] = t;
00192 }
00193
00194 return nbrEntries++;
00195 }
00196
00197 template <class utRef>
00198 unsigned int
00199 UT_RefArray<utRef>::insert(const utRef& t, unsigned int iindex,
00200 Comparator compare)
00201 {
00202
00203 int idx = -1;
00204 return ((idx=find(t, compare)) != -1) ? (unsigned int)idx
00205 : insertAt(t, iindex);
00206 }
00207
00208 template <class utRef>
00209 unsigned int
00210 UT_RefArray<utRef>::sortedInsert(const utRef& t, Comparator compare)
00211 {
00212 int lo, mid, hi, half, num;
00213
00214 lo = 0;
00215 hi = entries();
00216 num = entries();
00217
00218 while( lo < hi )
00219 {
00220 half = (hi - lo) / 2;
00221 mid = lo + half;
00222 if( compare(&t, &arr[mid]) > 0 )
00223 lo = mid + 1;
00224 else
00225 hi = mid;
00226 }
00227
00228 return insertAt(t, hi);
00229 }
00230
00231
00232 template <class utRef>
00233 void
00234 UT_RefArray<utRef>::sortedUnion( const UT_RefArray<utRef> &other,
00235 UT_RefArray<utRef> &result,
00236 Comparator compare
00237 ) const
00238 {
00239 utRef *first1 = arr;
00240 utRef *last1 = arr + nbrEntries;
00241 utRef *first2 = other.arr;
00242 utRef *last2 = other.arr + other.nbrEntries;
00243
00244
00245 UT_ASSERT(&result != this && &result != &other);
00246 UT_ASSERT(result.entries() == 0);
00247
00248 while( first1 != last1 && first2 != last2 )
00249 {
00250 if( compare(first1, first2) < 0 )
00251 {
00252 result.append( *first1 );
00253 ++first1;
00254 }
00255 else if( compare(first2, first1) < 0 )
00256 {
00257 result.append( *first2 );
00258 ++first2;
00259 }
00260 else
00261 {
00262 result.append( *first1 );
00263 ++first1;
00264 ++first2;
00265 }
00266 }
00267 while( first1 != last1 )
00268 {
00269 result.append( *first1 );
00270 ++first1;
00271 }
00272 while( first2 != last2 )
00273 {
00274 result.append( *first2 );
00275 ++first2;
00276 }
00277 }
00278
00279 template <class utRef>
00280 unsigned int
00281 UT_RefArray<utRef>::heapPush(const utRef &t, Comparator compare)
00282 {
00283 int i = append(t);
00284
00285 while( i > 0 && compare(&arr[i / 2], &t) < 0 )
00286 {
00287 arr[i] = arr[i / 2];
00288 i = i / 2;
00289 }
00290 arr[i] = t;
00291 return i;
00292 }
00293
00294 template <class utRef>
00295 void
00296 UT_RefArray<utRef>::heapPop(Comparator compare)
00297 {
00298 UT_ASSERT_P(nbrEntries > 0);
00299 if( nbrEntries > 0 )
00300 {
00301 arr[0] = arr[nbrEntries - 1];
00302 removeAt(nbrEntries - 1);
00303 heapify(0, compare);
00304 }
00305 return;
00306 }
00307
00308 template <class utRef>
00309 unsigned int
00310 UT_RefArray<utRef>::concat(const UT_RefArray<utRef> &a)
00311 {
00312 unsigned int old_entries;
00313 unsigned int i;
00314
00315 old_entries = nbrEntries;
00316 multipleInsert(nbrEntries, a.nbrEntries);
00317
00318 for ( i = 0; i < a.nbrEntries ; i++ )
00319 arr[old_entries + i] = a.arr[i];
00320
00321 return nbrEntries;
00322 }
00323
00324 template <class utRef>
00325 unsigned int
00326 UT_RefArray<utRef>::multipleInsert(unsigned int iindex, unsigned int count)
00327 {
00328 unsigned bigindex = iindex+count;
00329 unsigned t;
00330
00331 if (iindex >= nbrEntries)
00332 {
00333 if (bigindex >= arrSize) resize(bumpAlloc(bigindex));
00334
00335 for (t = nbrEntries; t <= bigindex; t++)
00336 new (&arr[t]) utRef();
00337
00338 nbrEntries = bigindex;
00339 return iindex;
00340 }
00341 if ((nbrEntries + count) > arrSize)
00342 {
00343 resize(bumpAlloc(nbrEntries+count));
00344 UT_ASSERT(arr);
00345 }
00346 memmove(&arr[bigindex], &arr[iindex],((nbrEntries-iindex)*sizeof(utRef)));
00347
00348 nbrEntries += count;
00349
00350 for (t = count; t-- > 0;)
00351 new (&arr[iindex+t]) utRef();
00352
00353 return iindex;
00354 }
00355
00356 template <class utRef>
00357 unsigned int
00358 UT_RefArray<utRef>::insertAt(const utRef &t, unsigned int iindex)
00359 {
00360 const utRef *save;
00361 if (&arr[iindex] <= &t && &t <= &arr[arrSize-1])
00362 {
00363 utRef tCopy; tCopy = t;
00364 save = &tCopy;
00365 }
00366 else
00367 save = &t;
00368
00369 if (iindex >= nbrEntries)
00370 {
00371 int i;
00372
00373 if (iindex >= arrSize) resize(bumpAlloc(iindex));
00374 for (i = nbrEntries; i <= iindex; i++)
00375 new (&arr[i]) utRef();
00376 nbrEntries = iindex+1;
00377 arr[iindex] = *save;
00378 return iindex;
00379 }
00380 if (nbrEntries == arrSize)
00381 {
00382
00383 arrSize = bumpAlloc(arrSize);
00384 arr = (utRef*)realloc(arr, arrSize*sizeof(utRef));
00385 UT_ASSERT(arr);
00386 }
00387 memmove(&arr[iindex+1], &arr[iindex],((nbrEntries-iindex)*sizeof(utRef)));
00388
00389 new (&arr[iindex]) utRef();
00390 arr[iindex] = *save;
00391
00392 nbrEntries++;
00393 return iindex;
00394 }
00395
00396 template <class utRef>
00397 int
00398 UT_RefArray<utRef>::remove(const utRef& t)
00399 {
00400 int idx = find(t);
00401 return (idx < 0) ? -1 : removeAt((unsigned int)idx);
00402 }
00403
00404 template <class utRef>
00405 int
00406 UT_RefArray<utRef>::remove(const utRef& t, unsigned short dupliCheck)
00407 {
00408 int idx = find(t);
00409 return (idx < 0) ? -1 : removeAt((unsigned int)idx, dupliCheck);
00410 }
00411
00412 template <class utRef>
00413 int
00414 UT_RefArray<utRef>::removeAt(unsigned int idx)
00415 {
00416 arr[idx].~utRef();
00417 if (idx != --nbrEntries)
00418 memmove(&arr[idx], &arr[idx+1], ((nbrEntries-idx)*sizeof(utRef)));
00419
00420 return (int)idx;
00421 }
00422
00423
00424 template <class utRef>
00425 int
00426 UT_RefArray<utRef>::removeAt(unsigned int idx, unsigned short dupliCheck)
00427 {
00428 if (dupliCheck)
00429 {
00430 const utRef &rem = arr[idx];
00431 unsigned int *gapArr = new unsigned int[nbrEntries];
00432 UT_ASSERT(gapArr);
00433 int gapCnt = 0;
00434 for (unsigned int i = 0; i < nbrEntries; i++)
00435 if (arr[i] == rem) gapArr[gapCnt++] = i;
00436 for (int g = gapCnt-1; g >= 0; g--, nbrEntries--)
00437 {
00438 unsigned int rmIdx = gapArr[g];
00439 arr[rmIdx].~utRef();
00440 if (rmIdx != nbrEntries)
00441 memmove(&arr[rmIdx], &arr[rmIdx+1],
00442 ((nbrEntries-rmIdx-1)*sizeof(utRef)));
00443 }
00444 delete [] gapArr;
00445 }
00446 else
00447 {
00448 idx = removeAt( idx );
00449 }
00450
00451 return (int)idx;
00452 }
00453
00454 template <class utRef>
00455 int
00456 UT_RefArray<utRef>::remove(const utRef& t, Comparator compare,
00457 unsigned short dupliCheck)
00458 {
00459 int idx = find(t, compare);
00460 return (idx < 0) ? -1 : removeAt((unsigned int)idx, compare, dupliCheck);
00461 }
00462
00463 template <class utRef>
00464 int
00465 UT_RefArray<utRef>::removeAt(unsigned int idx, Comparator compare,
00466 unsigned short dupliCheck)
00467 {
00468 if (dupliCheck)
00469 {
00470 const utRef &rem = arr[idx];
00471 int *gapArr = new int[nbrEntries];
00472 UT_ASSERT(gapArr);
00473 int gapCnt = 0;
00474 for (unsigned int i = 0; i < nbrEntries; i++)
00475 if (!compare(&arr[i],&rem)) gapArr[gapCnt++] = i;
00476 for (int g = gapCnt-1; g >= 0; g--, nbrEntries--)
00477 {
00478 unsigned int rmIdx = gapArr[g];
00479 arr[rmIdx].~utRef();
00480 if (rmIdx != nbrEntries)
00481 memmove(&arr[rmIdx], &arr[rmIdx+1],
00482 ((nbrEntries-rmIdx)*sizeof(utRef)));
00483 }
00484 delete [] gapArr;
00485 }
00486 else
00487 {
00488 arr[idx].~utRef();
00489 if (idx != --nbrEntries)
00490 memmove(&arr[idx], &arr[idx+1], ((nbrEntries-idx)*sizeof(utRef)));
00491 }
00492
00493 return idx;
00494 }
00495
00496 template <class utRef>
00497 int
00498 UT_RefArray<utRef>::shift(unsigned int srcIdx, unsigned int destIdx,
00499 unsigned int howMany)
00500 {
00501 if (srcIdx == destIdx) return 0;
00502 unsigned int sIdx = srcIdx + howMany - 1;
00503 unsigned int dIdx = destIdx + howMany - 1;
00504 if (sIdx>=arrSize || dIdx>=arrSize) return -1;
00505 if (dIdx>=nbrEntries|| (sIdx==nbrEntries-1 && sIdx > dIdx))
00506 nbrEntries = dIdx+1;
00507
00508 memmove(&arr[destIdx], &arr[srcIdx], (howMany*sizeof(utRef)));
00509 return 0;
00510 }
00511
00512 template <class utRef>
00513 void
00514 UT_RefArray<utRef>::move(int srcIdx, int destIdx, int howMany)
00515 {
00516
00517 if( srcIdx < 0 )
00518 srcIdx = 0;
00519 if( destIdx < 0 )
00520 destIdx = 0;
00521
00522
00523 if( srcIdx + howMany > entries() )
00524 howMany = entries() - srcIdx;
00525
00526
00527 if( destIdx + howMany > entries() )
00528 destIdx = entries() - howMany;
00529 if( srcIdx != destIdx && howMany > 0 )
00530 {
00531 utRef *tmp = 0;
00532 unsigned int savelen;
00533
00534 savelen = abs(srcIdx - destIdx);
00535 tmp = (utRef *)calloc(savelen, sizeof(utRef));
00536 if( srcIdx > destIdx && howMany > 0 )
00537 {
00538
00539
00540
00541
00542 memcpy(tmp, &arr[destIdx], (savelen*sizeof(utRef)));
00543 memmove(&arr[destIdx], &arr[srcIdx], (howMany*sizeof(utRef)));
00544 memcpy(&arr[destIdx+howMany], tmp, (savelen*sizeof(utRef)));
00545 }
00546 if( srcIdx < destIdx && howMany > 0 )
00547 {
00548
00549
00550
00551
00552
00553 memcpy(tmp, &arr[srcIdx+howMany], (savelen*sizeof(utRef)));
00554 memmove(&arr[destIdx], &arr[srcIdx], (howMany*sizeof(utRef)));
00555 memcpy(&arr[srcIdx], tmp, (savelen*sizeof(utRef)));
00556 }
00557 free(tmp);
00558 }
00559 }
00560
00561 template <class utRef>
00562 void
00563 UT_RefArray<utRef>::cycle(int howMany)
00564 {
00565 char *tempPtr;
00566 int numShift;
00567 int theRest;
00568
00569 if (howMany == 0 || nbrEntries < 1) return;
00570
00571 numShift = howMany % (int)nbrEntries;
00572 if (numShift < 0) numShift += (int)nbrEntries;
00573 theRest = (int)nbrEntries - numShift;
00574 tempPtr = new char [numShift * sizeof(utRef)];
00575
00576 memmove(tempPtr, &arr[theRest], (numShift * sizeof(utRef)));
00577 memmove(&arr[numShift], &arr[0], (theRest * sizeof(utRef)));
00578 memmove(&arr[0], tempPtr, (numShift * sizeof(utRef)));
00579
00580 delete [] tempPtr;
00581 }
00582
00583 template <class utRef>
00584 int
00585 UT_RefArray<utRef>::find(const utRef &t, unsigned int s) const
00586 {
00587 int idx;
00588 for (idx = (int)s; ((unsigned)idx) < nbrEntries; idx++)
00589 if (arr[idx] == t) return idx;
00590
00591 return (int)-1;
00592 }
00593
00594 template <class utRef>
00595 int
00596 UT_RefArray<utRef>::find(const utRef &t, Comparator compare,
00597 unsigned int s) const
00598 {
00599 if (!nbrEntries) return -1;
00600 utRef *match = (utRef*) bsearch((const void*)&t, arr+s, nbrEntries,
00601 sizeof(utRef), (ut_ptr_compare_func_t)compare);
00602 return (match) ? match-arr : (int)-1;
00603 }
00604
00605 template <class utRef>
00606 int
00607 UT_RefArray<utRef>::find(void *any, Comparator compare,
00608 unsigned int s) const
00609 {
00610 if (!nbrEntries) return -1;
00611 utRef *match = (utRef*) bsearch(any, arr+s, nbrEntries,
00612 sizeof(utRef), (ut_ptr_compare_func_t)compare);
00613 return (match) ? match-arr : (int)-1;
00614 }
00615
00616 template <class utRef>
00617 void
00618 UT_RefArray<utRef>::sort(Comparator compare)
00619 {
00620 qsort(arr, nbrEntries, sizeof(utRef), (ut_ptr_compare_func_t)compare);
00621 }
00622
00623 template <class utRef>
00624 void
00625 UT_RefArray<utRef>::resize(unsigned int sz, unsigned short )
00626 {
00627 if (sz == arrSize)
00628 return;
00629
00630 if (sz == 0)
00631 {
00632 if (arr)
00633 {
00634 for( unsigned i = 0; i < nbrEntries; i++ )
00635 arr[i].~utRef();
00636 free(arr);
00637 }
00638 arr = 0;
00639 arrSize = nbrEntries = 0;
00640 return;
00641 }
00642
00643 if (sz < nbrEntries)
00644 {
00645 for( unsigned i = sz; i < nbrEntries; i++ )
00646 arr[i].~utRef();
00647 nbrEntries = sz;
00648 }
00649
00650 if( arr )
00651 {
00652 arr = (utRef*)realloc(arr, sz*sizeof(utRef));
00653
00654
00655
00656 }
00657 else
00658 arr = (utRef*)calloc(sizeof(utRef), sz);
00659
00660 arrSize = sz;
00661 UT_ASSERT(arr);
00662 }
00663
00664 template <class utRef>
00665 void
00666 UT_RefArray<utRef>::entries(unsigned int ne)
00667 {
00668 UT_ASSERT(ne <= arrSize);
00669 if( nbrEntries > ne )
00670 {
00671 for( int i = ne; i < nbrEntries; i++ )
00672 arr[i].~utRef();
00673 }
00674 else if( nbrEntries < ne )
00675 {
00676 for( int i = nbrEntries; i < ne; i++ )
00677 new (&arr[i]) utRef();
00678 }
00679 nbrEntries = ne;
00680 }
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697 template <class utRef>
00698 utRef &
00699 UT_RefArray<utRef>::operator[](unsigned int i)
00700 {
00701 if (i >= arrSize ) resize(i+1);
00702 if (i >= nbrEntries)
00703 {
00704 for (unsigned t = nbrEntries; t <= i; t++)
00705 new (&arr[t]) utRef();
00706 nbrEntries = i+1;
00707 }
00708 return arr[i];
00709 }
00710
00711 template <class utRef>
00712 UT_RefArray<utRef> &
00713 UT_RefArray<utRef>::operator=(const UT_RefArray<utRef> &a)
00714 {
00715 if (this == &a) return *this;
00716
00717
00718 resizeIfNeeded( a.entries() );
00719
00720
00721
00722 entries(a.entries());
00723
00724
00725 for (unsigned int i = 0; i < a.entries(); i++)
00726 arr[i] = a(i);
00727
00728 return *this;
00729 }
00730
00731 template <class utRef>
00732 int
00733 UT_RefArray<utRef>::operator==(const UT_RefArray<utRef> &a) const
00734 {
00735 if (this == &a) return 1;
00736 if (entries() != a.entries()) return 0;
00737 for (unsigned int i = 0; i < a.entries(); i++)
00738 if (!(arr[i] == a(i))) return 0;
00739 return 1;
00740 }
00741
00742 template <class utRef>
00743 int
00744 UT_RefArray<utRef>::operator!=(const UT_RefArray<utRef> &a) const
00745 {
00746 return !(*this == a);
00747 }
00748
00749 template <class utRef>
00750 int
00751 UT_RefArray<utRef>::isEqual(const UT_RefArray<utRef> &a,
00752 Comparator compare
00753 ) const
00754 {
00755 if (this == &a) return 1;
00756 if (entries() != a.entries()) return 0;
00757 for (unsigned int i = 0; i < a.entries(); i++)
00758 if (compare(&arr[i], &a(i))) return 0;
00759 return 1;
00760 }
00761
00762 template <class utRef>
00763 unsigned int
00764 UT_RefArray<utRef>::apply(int (*applyFct)(utRef &t, void *d), void *d)
00765 {
00766 unsigned int i;
00767 for (i = 0; i < nbrEntries; i++)
00768 if (applyFct(arr[i],d)) break;
00769 return i;
00770 }
00771
00772 template <class utRef>
00773 void
00774 UT_RefArray<utRef>::heapify(unsigned int idx, Comparator compare)
00775 {
00776 int lidx = 2*idx, ridx = lidx + 1;
00777 int largest = idx;
00778
00779 if( lidx < nbrEntries && compare(&arr[lidx], &arr[largest]) > 0 )
00780 {
00781 largest = lidx;
00782 }
00783 if( ridx < nbrEntries && compare(&arr[ridx], &arr[largest]) > 0 )
00784 {
00785 largest = ridx;
00786 }
00787 if( largest != idx )
00788 {
00789 utRef temp; temp = arr[largest];
00790 arr[largest] = arr[idx];
00791 arr[idx] = temp;
00792 heapify(largest, compare);
00793 }
00794 }
00795
00796 #endif // __UT_RefArray_C__