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 #ifndef __UT_RefMatrix_C__
00074 #define __UT_RefMatrix_C__
00075
00076 #include "UT_Assert.h"
00077 #include "UT_RefMatrix.h"
00078
00079 template <class utRef>
00080 UT_RefMatrix<utRef>::UT_RefMatrix(const UT_RefMatrix<utRef> &m)
00081 : rowArr(m.usedRows()), nbrCols(m.usedCols())
00082 {
00083 rowArr.entries(m.usedRows());
00084 for (unsigned int i = 0; i < m.usedRows(); i++)
00085 rowArr(i) = new UT_RefArray<utRef>(m.row(i));
00086 }
00087
00088 template <class utRef>
00089 UT_RefMatrix<utRef>::~UT_RefMatrix(void)
00090 {
00091 for (unsigned int i = 0; i < rowArr.entries(); i++)
00092 delete rowArr(i);
00093 }
00094
00095 template <class utRef>
00096 unsigned int
00097 UT_RefMatrix<utRef>::insertRow(unsigned int index)
00098 {
00099 unsigned int uRows = usedRows();
00100 unsigned int uCols = usedCols();
00101 rowArr.insert(index);
00102 return insertSlowFill(index, uRows, uCols);
00103 }
00104
00105 template <class utRef>
00106 unsigned int
00107 UT_RefMatrix<utRef>::appendRow(const UT_RefArray<utRef> &r,
00108 unsigned short dupliCheck)
00109 {
00110 int ridx;
00111 if (dupliCheck && (ridx = findRow(r)) != -1) return (unsigned int)ridx;
00112 ridx = rowArr.insertAt((UT_RefArray<utRef>*)&r, usedRows());
00113 return assignRow(r, (unsigned int)ridx);
00114 }
00115
00116 template <class utRef>
00117 unsigned int
00118 UT_RefMatrix<utRef>::insertRow(const UT_RefArray<utRef> &r,
00119 unsigned int index,
00120 unsigned short dupliCheck)
00121 {
00122 int ridx;
00123 if (dupliCheck && (ridx = findRow(r)) != -1) return (unsigned int)ridx;
00124 unsigned int uRows = usedRows();
00125 unsigned int uCols = usedCols();
00126 rowArr.insertAt((UT_RefArray<utRef>*)&r, index);
00127 insertSlowFill(index, uRows, uCols);
00128 *rowArr(index) = r;
00129 return index;
00130 }
00131
00132 template <class utRef>
00133 unsigned int
00134 UT_RefMatrix<utRef>::appendRow(const UT_RefArray<utRef> &r,
00135 int (*compare)(const void *t1,const void *t2))
00136 {
00137 int ridx;
00138 if ((ridx = findRow(r,compare)) != -1) return (unsigned int)ridx;
00139 ridx = rowArr.insertAt((UT_RefArray<utRef>*)&r, usedRows());
00140 return assignRow(r, (unsigned int)ridx);
00141 }
00142
00143 template <class utRef>
00144 unsigned int
00145 UT_RefMatrix<utRef>::insertRow(const UT_RefArray<utRef> &r,
00146 unsigned int index,
00147 int (*compare)(const void *t1,const void *t2))
00148 {
00149 int ridx;
00150 if ((ridx = findRow(r,compare)) != -1) return (unsigned int)ridx;
00151 unsigned int uRows = usedRows();
00152 unsigned int uCols = usedCols();
00153 rowArr.insertAt((UT_RefArray<utRef>*)&r, index);
00154 insertSlowFill(index, uRows, uCols);
00155 *rowArr(index) = r;
00156 return index;
00157 }
00158
00159 template <class utRef>
00160 unsigned int
00161 UT_RefMatrix<utRef>::appendRowFast(const UT_RefArray<utRef> &r,
00162 unsigned short dupliCheck)
00163 {
00164 int ridx;
00165 if (dupliCheck && (ridx = findRow(r)) != -1) return (unsigned int)ridx;
00166 return rowArr.append((UT_RefArray<utRef>*)&r, (unsigned short)0);
00167 }
00168
00169 template <class utRef>
00170 unsigned int
00171 UT_RefMatrix<utRef>::insertRowFast(const UT_RefArray<utRef> &r,
00172 unsigned int index,
00173 unsigned short dupliCheck)
00174 {
00175 int ridx;
00176 if (dupliCheck && (ridx = findRow(r)) != -1) return (unsigned int)ridx;
00177 return insertFastFill(r, index);
00178 }
00179
00180 template <class utRef>
00181 unsigned int
00182 UT_RefMatrix<utRef>::appendRowFast(const UT_RefArray<utRef> &r,int (*compare)
00183 (const void *t1,const void *t2))
00184 {
00185 int ridx;
00186 if ((ridx = findRow(r,compare)) != -1) return (unsigned int)ridx;
00187 return rowArr.append((UT_RefArray<utRef>*)&r, (unsigned short)0);
00188 }
00189
00190 template <class utRef>
00191 unsigned int
00192 UT_RefMatrix<utRef>::insertRowFast(const UT_RefArray<utRef> &r,
00193 unsigned int index, int (*compare)
00194 (const void *t1,const void *t2))
00195 {
00196 int ridx;
00197 if ((ridx = findRow(r,compare)) != -1) return (unsigned int)ridx;
00198 return insertFastFill(r, index);
00199 }
00200
00201 template <class utRef>
00202 int
00203 UT_RefMatrix<utRef>::insertCol(unsigned int index)
00204 {
00205 unsigned int cnt = rowArr.entries(); if (!cnt) return -1;
00206 for (unsigned int i = 0; i < cnt; i++)
00207 rowArr(i)->insert(index);
00208 nbrCols = rowArr(0)->capacity();
00209 return (int)index;
00210 }
00211
00212 template <class utRef>
00213 int
00214 UT_RefMatrix<utRef>::appendCol(const UT_RefArray<utRef> &r,
00215 unsigned short dupliCheck)
00216 {
00217 unsigned int cnt = rowArr.entries();
00218 if ((!cnt) || (cnt != r.capacity())) return -1;
00219
00220 int cidx;
00221 if (dupliCheck && (cidx = findCol(r)) != -1) return cidx;
00222 for (unsigned int i = 0; i < cnt; i++)
00223 rowArr(i)->append(r(i), (unsigned short)0);
00224
00225 nbrCols = rowArr(0)->capacity();
00226 return rowArr(0)->entries()-1;
00227 }
00228
00229 template <class utRef>
00230 int
00231 UT_RefMatrix<utRef>::insertCol(const UT_RefArray<utRef> &r,
00232 unsigned int index,
00233 unsigned short dupliCheck)
00234 {
00235 unsigned int cnt = rowArr.entries();
00236 if ((!cnt) || (cnt != r.capacity())) return -1;
00237
00238 int cidx;
00239 if (dupliCheck && (cidx = findCol(r)) != -1) return cidx;
00240 for (unsigned int i = 0; i < cnt; i++)
00241 rowArr(i)->insert(r(i),index, (unsigned short)0);
00242
00243 nbrCols = rowArr(0)->capacity();
00244 return index;
00245 }
00246
00247 template <class utRef>
00248 int
00249 UT_RefMatrix<utRef>::appendCol(const UT_RefArray<utRef> &r,
00250 int (*compare)(const void *t1,const void *t2))
00251 {
00252 unsigned int cnt = rowArr.entries();
00253 if ((!cnt) || (cnt != r.capacity())) return -1;
00254
00255 int cidx;
00256 if ((cidx = findCol(r,compare)) != -1) return cidx;
00257 for (unsigned int i = 0; i < cnt; i++)
00258 rowArr(i)->append(r(i), (unsigned short)0);
00259
00260 nbrCols = rowArr(0)->capacity();
00261 return rowArr(0)->entries()-1;
00262 }
00263
00264 template <class utRef>
00265 int
00266 UT_RefMatrix<utRef>::insertCol(const UT_RefArray<utRef> &r,
00267 unsigned int index,
00268 int (*compare)(const void *t1,const void *t2))
00269 {
00270 unsigned int cnt = rowArr.entries();
00271 if ((!cnt) || (cnt != r.capacity())) return -1;
00272
00273 int cidx;
00274 if ((cidx = findCol(r,compare)) != -1) return cidx;
00275 for (unsigned int i = 0; i < cnt; i++)
00276 rowArr(i)->insert(r(i),index, (unsigned short)0);
00277
00278 nbrCols = rowArr(0)->capacity();
00279 return index;
00280 }
00281
00282 template <class utRef>
00283 int
00284 UT_RefMatrix<utRef>::removeRow(const UT_RefArray<utRef> &r,
00285 unsigned short dupliCheck)
00286 {
00287 int ridx = findRow(r); if (ridx < 0) return -1;
00288 if (dupliCheck)
00289 {
00290 UT_RefArray<utRef> dup = *rowArr(ridx);
00291 int nextIdx = ridx;
00292 do
00293 removeOneRow(nextIdx);
00294 while ((nextIdx = findRow(dup, nextIdx)) != -1);
00295 }
00296 else
00297 removeOneRow(ridx);
00298
00299 return ridx;
00300 }
00301
00302 template <class utRef>
00303 int
00304 UT_RefMatrix<utRef>::removeRow(unsigned int index,
00305 unsigned short dupliCheck)
00306 {
00307 if (index >= rowArr.entries()) return -1;
00308 if (dupliCheck)
00309 {
00310 UT_RefArray<utRef> dup = *rowArr(index);
00311 int nextIdx = index;
00312 do
00313 removeOneRow(nextIdx);
00314 while ((nextIdx = findRow(dup, nextIdx)) != -1);
00315 }
00316 else
00317 removeOneRow(index);
00318
00319 return index;
00320 }
00321
00322 template <class utRef>
00323 int
00324 UT_RefMatrix<utRef>::removeRow(const UT_RefArray<utRef> &r,
00325 int (*compare)(const void *t1,const void *t2),
00326 unsigned short dupliCheck)
00327 {
00328 int ridx = findRow(r, compare); if (ridx < 0) return -1;
00329 if (dupliCheck)
00330 {
00331 UT_RefArray<utRef> dup = *rowArr(ridx);
00332 int nextIdx = ridx;
00333 do
00334 removeOneRow(nextIdx);
00335 while ((nextIdx = findRow(dup, compare, nextIdx)) != -1);
00336 }
00337 else
00338 removeOneRow(ridx);
00339
00340 return ridx;
00341 }
00342
00343 template <class utRef>
00344 int
00345 UT_RefMatrix<utRef>::removeRow(unsigned int index,
00346 int (*compare)(const void *t1,const void *t2),
00347 unsigned short dupliCheck)
00348 {
00349 if (index >= rowArr.entries()) return -1;
00350 if (dupliCheck)
00351 {
00352 UT_RefArray<utRef> dup = *rowArr(index);
00353 int nextIdx = index;
00354 do
00355 removeOneRow(nextIdx);
00356 while ((nextIdx = findRow(dup, compare, nextIdx)) != -1);
00357 }
00358 else
00359 removeOneRow(index);
00360
00361 return index;
00362 }
00363
00364 template <class utRef>
00365 int
00366 UT_RefMatrix<utRef>::removeCol(const UT_RefArray<utRef> &c,
00367 unsigned short dupliCheck)
00368 {
00369 int cidx = findCol(c); if (cidx < 0) return -1;
00370 removeOneCol(cidx);
00371 if (dupliCheck)
00372 {
00373 int nextIdx = cidx;
00374 while ((nextIdx = findCol(c, nextIdx)) != -1)
00375 removeOneCol(nextIdx);
00376 }
00377 return cidx;
00378 }
00379
00380 template <class utRef>
00381 void
00382 UT_RefMatrix<utRef>::cycle(int rowshift, int colshift)
00383 {
00384 int ctr;
00385
00386 rowArr.cycle(rowshift);
00387
00388 for ( ctr=0; ctr<usedRows(); ++ctr )
00389 rowArr(ctr)->cycle(colshift);
00390
00391 return;
00392 }
00393
00394 template <class utRef>
00395 int
00396 UT_RefMatrix<utRef>::removeCol(unsigned int index,
00397 unsigned short )
00398 {
00399 if (!rowArr.entries() || index >= rowArr(0)->entries()) return -1;
00400
00401 #if 0
00402
00403 if (dupliCheck)
00404 {
00405 UT_RefArray<utRef> &c = col(index);
00406 removeOneCol(index);
00407 int nextIdx = 0;
00408 while ((nextIdx = findCol(c, nextIdx)) != -1)
00409 removeOneCol(nextIdx);
00410 delete &c;
00411 }
00412 else
00413 #endif
00414 removeOneCol(index);
00415 return index;
00416 }
00417
00418 template <class utRef>
00419 int
00420 UT_RefMatrix<utRef>::removeCol(const UT_RefArray<utRef> &c,
00421 int (*compare)(const void *t1,const void *t2),
00422 unsigned short dupliCheck)
00423 {
00424 int cidx = findCol(c, compare); if (cidx < 0) return -1;
00425 removeOneCol(cidx);
00426 if (dupliCheck)
00427 {
00428 int nextIdx = cidx;
00429 while ((nextIdx = findCol(c, compare, nextIdx)) != -1)
00430 removeOneCol(nextIdx);
00431 }
00432 return cidx;
00433 }
00434
00435 template <class utRef>
00436 int
00437 UT_RefMatrix<utRef>::removeCol(unsigned int index,
00438 int (*compare)(const void *t1,const void *t2),
00439 unsigned short )
00440 {
00441 if (!rowArr.entries() || index >= rowArr(0)->entries()) return -1;
00442 #if 0
00443 col() is unsafe
00444 if (dupliCheck)
00445 {
00446 UT_RefArray<utRef> &c = col(index);
00447 removeOneCol(index);
00448 int nextIdx = 0;
00449 while ((nextIdx = findCol(c, compare, nextIdx)) != -1)
00450 removeOneCol(nextIdx);
00451 delete &c;
00452 }
00453 else
00454 #endif
00455 removeOneCol(index);
00456 return index;
00457 }
00458
00459 template <class utRef>
00460 int
00461 UT_RefMatrix<utRef>::find(const utRef &t, unsigned int *m,
00462 unsigned int *n) const
00463 {
00464 for (*m = 0; *m < rowArr.entries(); (*m)++)
00465 for (*n = 0; *n < rowArr(0)->entries(); (*n)++)
00466 if ((*this)(*m,*n) == t) return 0;
00467 return -1;
00468 }
00469
00470 template <class utRef>
00471 int
00472 UT_RefMatrix<utRef>::find(const utRef &t, unsigned int *m, unsigned int *n,
00473 int (*compare)(const void *t1, const void *t2)) const
00474 {
00475 for (*m = 0; *m < rowArr.entries(); (*m)++)
00476 if ((*n = rowArr(*m)->find(t,compare)) != -1)
00477 return 0;
00478 return -1;
00479 }
00480
00481 template <class utRef>
00482 int
00483 UT_RefMatrix<utRef>::findRow(const UT_RefArray<utRef> &r, unsigned int s) const
00484 {
00485 unsigned int cnt = rowArr.entries();
00486 if (!cnt) return -1;
00487 for (unsigned int i = s; i < cnt; i++)
00488 if (*rowArr(i) == r) return (int) i;
00489 return -1;
00490 }
00491
00492 template <class utRef>
00493 int
00494 UT_RefMatrix<utRef>::findRow(const UT_RefArray<utRef> &r,
00495 int (*compare)(const void *t1, const void *t2),
00496 unsigned int s) const
00497 {
00498 unsigned int cnt = rowArr.entries();
00499 if (!cnt) return -1;
00500 for (unsigned int i = s; i < cnt; i++)
00501 if (rowArr(i)->isEqual(r,compare)) return (int) i;
00502 return -1;
00503 }
00504
00505 template <class utRef>
00506 int
00507 UT_RefMatrix<utRef>::findCol(const UT_RefArray<utRef> &c, unsigned int s) const
00508 {
00509 unsigned int rcnt = rowArr.entries();
00510 if ((!rcnt) || (c.entries() != rcnt)) return -1;
00511 unsigned int ccnt = rowArr(0)->entries();
00512 for (unsigned int j = s; j < ccnt; j++)
00513 {
00514 unsigned int i;
00515 for (i = 0; i < rcnt; i++)
00516 if (!((*this)(i,j) == c(i))) break;
00517 if (i == rcnt) return (int)j;
00518 }
00519 return -1;
00520 }
00521
00522 template <class utRef>
00523 int
00524 UT_RefMatrix<utRef>::findCol(const UT_RefArray<utRef> &c,
00525 int (*compare)(const void *t1, const void *t2),
00526 unsigned int s) const
00527 {
00528 unsigned int rcnt = rowArr.entries();
00529 if ((!rcnt) || (c.entries() != rcnt)) return -1;
00530 unsigned int ccnt = rowArr(0)->entries();
00531 for (unsigned int j = s; j < ccnt; j++)
00532 {
00533 unsigned int i;
00534 for (i = 0; i < rcnt; i++)
00535 if (compare(&((*this)(i,j)), &c(i))) break;
00536 if (i == rcnt) return (int)j;
00537 }
00538 return -1;
00539 }
00540
00541 template <class utRef>
00542 void
00543 UT_RefMatrix<utRef>::resize(unsigned int mSz, unsigned int nSz,
00544 unsigned short copyFlag)
00545 {
00546 unsigned int i, nbrRows;
00547 if (mSz == (nbrRows = rowArr.capacity()) && nSz == nbrCols) return;
00548 if (mSz == 0)
00549 {
00550 for (i = 0; i < rowArr.entries(); i++)
00551 delete rowArr(i);
00552 rowArr.resize(mSz);
00553 nbrCols = 0;
00554 return;
00555 }
00556 if (mSz != nbrRows)
00557 {
00558 if (mSz < nbrRows)
00559 {
00560 for (i = mSz; i < rowArr.entries(); i++)
00561 delete rowArr(i);
00562 }
00563 rowArr.resize(mSz,1);
00564 }
00565 if (nSz != nbrCols)
00566 {
00567 for (i = 0; i < rowArr.entries(); i++) rowArr(i)->resize(nSz, copyFlag);
00568 nbrCols = nSz;
00569 }
00570 }
00571
00572 template <class utRef>
00573 UT_RefMatrix<utRef> &
00574 UT_RefMatrix<utRef>::operator=(const UT_RefMatrix<utRef> &m)
00575 {
00576 if (this == &m) return *this;
00577 UT_ASSERT(rows() >= m.usedRows() && cols() >= m.usedCols());
00578 unsigned int i;
00579 for (i = 0; i < rowArr.entries(); i++) delete rowArr(i);
00580 for (i = 0; i < m.usedRows(); i++) *rowArr[i] = m(i);
00581 return *this;
00582 }
00583
00584 template <class utRef>
00585 int
00586 UT_RefMatrix<utRef>::operator==(const UT_RefMatrix<utRef> &m) const
00587 {
00588 if (this == &m) return 1;
00589 if (!(usedRows() == m.usedRows() && usedCols() == m.usedCols()))
00590 return 0;
00591 for (unsigned int i = 0; i < m.usedRows(); i++)
00592 if (!(*rowArr(i) == m(i))) return 0;
00593 return 1;
00594 }
00595
00596 template <class utRef>
00597 int
00598 UT_RefMatrix<utRef>::isEqual(const UT_RefMatrix<utRef> &m,
00599 int (*compare)(const void *t1,const void *t2)
00600 ) const
00601 {
00602 if (this == &m) return 1;
00603 if (!(usedRows() == m.usedRows() && usedCols() == m.usedCols()))
00604 return 0;
00605 for (unsigned int i = 0; i < m.usedRows(); i++)
00606 if (!rowArr(i)->isEqual(m(i),compare)) return 0;
00607 return 1;
00608 }
00609
00610 template <class utRef>
00611 int
00612 UT_RefMatrix<utRef>::apply(int (*applyFct)(utRef &t, void *d), void *d)
00613 {
00614 unsigned int cnt = rowArr.entries();
00615 for (unsigned int i = 0; i < cnt; i++)
00616 if (rowArr(i)->apply(applyFct,d) != rowArr(i)->entries()) return 1;
00617 return 0;
00618 }
00619
00620 template <class utRef>
00621 UT_RefArray<utRef> &
00622 UT_RefMatrix<utRef>::operator[](unsigned int i)
00623 {
00624 unsigned int cnt = rowArr.entries();
00625 unsigned int uCols = usedCols();
00626
00627
00628 if( i >= cnt )
00629 rowArr[i] = NULL;
00630
00631 unsigned int newcnt = rowArr.entries();
00632 if (newcnt != cnt)
00633 {
00634 if (!nbrCols) nbrCols = 1;
00635 for (unsigned int k=cnt; k<newcnt; k++)
00636 rowArr(k) = new UT_RefArray<utRef>(nbrCols, uCols);
00637 }
00638 return *rowArr(i);
00639 }
00640
00641 #if 0
00642
00643
00644 template <class utRef>
00645 UT_RefArray<utRef> &
00646 UT_RefMatrix<utRef>::col(unsigned int j) const
00647 {
00648 unsigned int cnt = rowArr.entries();
00649 UT_RefArray<utRef>* c = new UT_RefArray<utRef>(cnt, cnt);
00650 for (unsigned int i = 0; i < cnt; i++)
00651 (*c)(i) = (*this)(i,j);
00652 return *c;
00653 }
00654 #endif
00655
00656 template <class utRef>
00657 unsigned int
00658 UT_RefMatrix<utRef>::insertFastFill(const UT_RefArray<utRef> &r,
00659 unsigned int index)
00660 {
00661 unsigned int oldUsed = usedRows();
00662 unsigned int uCols = usedCols();
00663 rowArr.insert((UT_RefArray<utRef>*)&r, index,
00664 (unsigned short)0);
00665 if (index > oldUsed)
00666 {
00667 UT_RefArray<utRef> *newRow;
00668 unsigned int crtUsed = usedRows()-1;
00669 for (unsigned int i= oldUsed; i < crtUsed; i++)
00670 {
00671 newRow = new UT_RefArray<utRef>(nbrCols, uCols);
00672 rowArr(i) = newRow;
00673 }
00674 }
00675 return index;
00676 }
00677
00678 template <class utRef>
00679 unsigned int
00680 UT_RefMatrix<utRef>::insertSlowFill(unsigned int index,
00681 unsigned int uRows, unsigned int uCols)
00682 {
00683 UT_RefArray<utRef> *newRow;
00684 if (index <= uRows)
00685 {
00686 newRow = new UT_RefArray<utRef>(nbrCols, uCols);
00687 rowArr(index) = newRow;
00688 }
00689 else
00690 {
00691 unsigned int crtUsed = usedRows();
00692 for (unsigned int i= uRows; i < crtUsed; i++)
00693 {
00694 newRow = new UT_RefArray<utRef>(nbrCols, uCols);
00695 rowArr(i) = newRow;
00696 }
00697 }
00698 return index;
00699 }
00700
00701 template <class utRef>
00702 void
00703 UT_RefMatrix<utRef>::removeOneCol(unsigned int index)
00704 {
00705 unsigned int sz = rowArr.entries();
00706 for (unsigned int i = 0; i < sz; i++)
00707 rowArr(i)->remove(index, (unsigned short)0);
00708 }
00709
00710 #endif // __UT_RefMatrix_C__