00001 /* 00002 * PROPRIETARY INFORMATION. This software is proprietary to 00003 * Side Effects Software Inc., and is not to be reproduced, 00004 * transmitted, or disclosed in any way without written permission. 00005 * 00006 * Produced by: 00007 * Cristin Barghiel 00008 * Side Effects Software Inc. 00009 * 20 Maud St. 00010 * Toronto, Ontario, M5V 2M5 00011 * Canada 00012 * 416-366-4607 00013 * 00014 * NAME: Utility Library (C++) 00015 * 00016 * COMMENTS: 00017 * This is a class template that implements a resizable matrix of 00018 * arbitrary objects. The template parameter represents the type 00019 * of object, and is called Thing. You can instantiate this class 00020 * with any object or pointer, such as: 00021 * UT_PtrMatrixRaw<int> iObj; 00022 * UT_PtrMatrixRaw<GeoPrimMesh> mObj; 00023 * UT_PtrMatrixRaw<GeoPoint*> pObj; ... etc 00024 * The "Val" in the class name stands for "passed by value", which 00025 * is the argument passing strategy used by this class. Use this class 00026 * if you want to construct matrices of pointers or primitive types, 00027 * for which it is more efficient to pass in the value directly rather 00028 * than via refererences. To build matrices of arbitrary objects, use 00029 * UT_RefMatrix instead. 00030 * 00031 * Revision 1.6 1996/03/04 02:49:59 cb 00032 * Changed to NCC. 00033 * 00034 * Revision 1.5 1995/12/28 00:05:46 cb 00035 * Made some "unsigned" fixes and slightly changed the "friend" declarations in *Raw.h 00036 * 00037 * Revision 1.4 1995/12/20 21:27:21 cb 00038 * After compiling with NCC/KCC. 00039 * 00040 * Revision 1.3 1995/09/29 12:30:43 phb 00041 * Changed local includes of UT files from <UT/UT*.h> to "UT*.h" 00042 * 00043 * Revision 1.2 1995/09/28 21:17:44 adubey 00044 * Fixed #include directive calls. 00045 * 00046 * Revision 1.1.1.1 1995/09/17 18:10:25 mark 00047 * initial source release 00048 * 00049 * Revision 1.2 1995/05/11 23:11:59 mark 00050 * Fixed some bugs with allocation 00051 * 00052 * Revision 1.1 1995/03/17 03:33:53 mark 00053 * Initial revision 00054 * 00055 */ 00056 00057 #ifndef __UT_PtrMatrixRaw_h__ 00058 #define __UT_PtrMatrixRaw_h__ 00059 00060 #include "UT_API.h" 00061 #include "UT_PtrArrayRaw.h" 00062 00063 class UT_API UT_PtrMatrixRaw { 00064 public: 00065 // Trivial constructor and destructor. WARNING: this is really meant to 00066 // be a private class. You should normally instantiate it through its 00067 // friend(s). We made these 2 methods public to avoid compiler warnings. 00068 UT_PtrMatrixRaw(unsigned int mSz = 0, unsigned int nSz = 0) : rowArr(mSz) 00069 { 00070 nbrCols = nSz; 00071 } 00072 ~UT_PtrMatrixRaw(void); 00073 00074 // Copy constructor that copies each Thing from the source matrix to 00075 // this matrix using the '=' operator. 00076 UT_PtrMatrixRaw(const UT_PtrMatrixRaw &m); 00077 00078 // Append a row or insert it at a given index. The matrix is grown to 00079 // accommodate it. If dupliCheck is 1, we first search for duplicates; the 00080 // search method uses the (*compare) function on pairs of Things when 00081 // specified, and the '==' operator on UT_PtrArray pairs otherwise. The 00082 // fast insertion methods assign the address of the UT_PtrArray to the 00083 // pointer in the row matrix rather than copying each element piece by 00084 // piece. All methods return the index of the found or inserted row. 00085 // t1 and t2 must be pointers to Thing. 00086 unsigned int insertRow(unsigned int index); 00087 unsigned int insertRow(const UT_PtrArrayRaw &r, unsigned int index); 00088 unsigned int appendRow(const UT_PtrArrayRaw &r); 00089 00090 // Fast insertion: as mentioned above, we just assign the address of r to 00091 // the a row array pointer. The UT_PtrMatrix destructor will delete &r 00092 // when called. Use these methods with care. 00093 unsigned int insertRowFast(const UT_PtrArrayRaw &r, unsigned index); 00094 unsigned int appendRowFast(const UT_PtrArrayRaw &r); 00095 00096 // Append a column or insert it at a given index. The matrix is grown to 00097 // accommodate it. If dupliCheck is 1, we first search for duplicates; the 00098 // search method uses the (*compare) function on pairs of Things when 00099 // specified, and the '==' operator otherwise. t1 and t2 must be pointers 00100 // to Thing. All methods return the index of the found or inserted column, 00101 // or -1 if the matrix has no rows. It is OK to insert a column into a 00102 // matrix with zero row entries but with space already allocated for at 00103 // least one row. 00104 int insertCol(unsigned int index); 00105 int insertCol(const UT_PtrArrayRaw &c, unsigned int index); 00106 int appendCol(const UT_PtrArrayRaw &c); 00107 00108 // Remove a row and possibly all its duplicates given a row object or its 00109 // index in the row array. The methods that take a (*compare)() function 00110 // use it to compare two Things; the other methods use the '==' operator. 00111 // to compare two UT_PtrArrays. 00112 // If dupliCheck is 1, all duplicates found will be removed too. All 00113 // methods return the row index (index of first row removed). Do not 00114 // try to access the row after removal, because its contets are undefined. 00115 // t1 and t2 must be pointers to Thing. 00116 // For increased efficiency, try to use the 'index' methods whenever 00117 // possible. 00118 int removeRow(const UT_PtrArrayRaw &r); 00119 int removeRow(unsigned int index); 00120 00121 // Remove a column and possibly all its duplicates given a column object or 00122 // its index. The methods that take a (*compare)() function 00123 // use it to compare two Things; the other methods use the '==' operator. 00124 // If dupliCheck is 1, all duplicates found will be removed too. All 00125 // methods return the column index (index of last column removed). 00126 // t1 and t2 must be pointers to Thing. 00127 // For increased efficiency, try to use the 'index' methods whenever 00128 // possible. 00129 int removeCol(const UT_PtrArrayRaw &c); 00130 int removeCol(unsigned int index); 00131 00132 // Compare the two matrices: to return 1, they should have the same 00133 // number or entries, and their Things should all match when compared 00134 // with '==' or compare() respectively. 00135 // t1 and t2 must be pointers to Thing. 00136 int operator==(const UT_PtrMatrixRaw &m) const; 00137 int isEqual(const UT_PtrMatrixRaw &m, 00138 int (*compare)(const void *t1,const void *t2) 00139 ) const; 00140 00141 // Assignment operator that copies the array piece by piece using the 00142 // '=' operator defined in UT_PtrArrayRaw. The row and column size of this 00143 // matrix must be greater or equal to the "used" row and column count of 00144 // matrix m. 00145 UT_PtrMatrixRaw &operator=(const UT_PtrMatrixRaw &m); 00146 00147 // Subscript operators to return rows. operator() does not check if the 00148 // matrix needs to be resized. operator[] grows the array of rows to 00149 // accommodate the index if necessary; . 00150 const UT_PtrArrayRaw &operator()(unsigned int i) const 00151 { 00152 return *(const UT_PtrArrayRaw *)rowArr(i); 00153 } 00154 const UT_PtrArrayRaw &operator[](unsigned int i) const 00155 { 00156 return *(const UT_PtrArrayRaw *)rowArr[i]; 00157 } 00158 UT_PtrArrayRaw &operator()(unsigned int i) 00159 { 00160 return *(UT_PtrArrayRaw *)rowArr(i); 00161 } 00162 UT_PtrArrayRaw &operator[](unsigned int i); 00163 00164 // Return an element of the matrix, WITHOUT any BOUND CHECKING. Use 00165 // safeGet() if you don't know whether you are within range or not. 00166 void *operator()(unsigned i, unsigned j) const 00167 { 00168 return (*(UT_PtrArrayRaw*)rowArr(i)).arr[j]; 00169 } 00170 void *&operator()(unsigned int i, unsigned int j) 00171 { 00172 return (*(UT_PtrArrayRaw*)rowArr(i)).arr[j]; 00173 } 00174 00175 // Return an element of the matrix, growing the matrix if necessary in 00176 // the non-const case. 00177 void *safeGet(unsigned i, unsigned j) const 00178 { 00179 UT_PtrArrayRaw *r; 00180 r = (UT_PtrArrayRaw *)rowArr[i]; 00181 return (r) ? (*r)[j] : (void *)0; 00182 } 00183 void *&safeGet(unsigned int i, unsigned int j) 00184 { 00185 if (!rowArr.nbrEntries) insertRow(i); 00186 if (j >= ((UT_PtrArrayRaw *)rowArr(0))->nbrEntries) 00187 insertCol(j); 00188 return ((*this)[i])(j); // yes, operator[] 00189 } 00190 00191 // Return a specified row or column. row() returns an actual reference to 00192 // the row entry in the matrix WITHOUT growing the array of rows if 00193 // needed. 00194 // col() builds a UT_PtrArray from scratch by allocating heap space for it 00195 // and copying each element into it with the '=' operator. The col() 00196 // array must be freed by YOU. 00197 const UT_PtrArrayRaw &row(unsigned int i) const {return *(UT_PtrArrayRaw *)rowArr(i);} 00198 UT_PtrArrayRaw &row(unsigned int i) {return *(UT_PtrArrayRaw *)rowArr(i);} 00199 UT_PtrArrayRaw &col(unsigned int j) const; 00200 00201 // Search for t in each row in one of two ways: linearly using the '==' 00202 // operator, or binary using the function specified in the parameter list 00203 // respectively. find() returns 0 and the indices of the matching element, 00204 // or -1 if not found. t1 and t2 must be pointers to Thing. 00205 int find(const void *t, unsigned int *m, unsigned int *n) const; 00206 00207 // Search for a row or a column in one of two ways: binary, using a user 00208 // defined function (*compare) to compare two Things, or linearly using 00209 // the '==' operator between UT_PtrArrays in findRow() and between Things 00210 // in findCol(). Note that the arrays to be compared must have an equal 00211 // number of entries, and not necessarily the same size. 00212 // Parameter s indicates what index to start searching at. 00213 // All methods return the row/col index if found, and -1 otherwise. 00214 // t1 and t2 must be pointers to Thing. 00215 int findRow(const UT_PtrArrayRaw &r, unsigned int s = 0) const; 00216 int findCol(const UT_PtrArrayRaw &c, unsigned int s = 0) const; 00217 00218 // Return the number of rows and column space has been allocated for, and 00219 // the number of entries used in the rows and columns. 00220 unsigned int rowSize(void) const { return rowArr.capacity(); } 00221 unsigned int colSize(void) const { return nbrCols; } 00222 unsigned int rows(void) const { return rowArr.nbrEntries;} 00223 unsigned int cols(void) const 00224 { 00225 return (rowArr.nbrEntries) ? 00226 ((UT_PtrArrayRaw *)rowArr(0))->nbrEntries : 0; 00227 } 00228 unsigned short isEmpty(void) const 00229 { 00230 return rowArr.nbrEntries == 0 || 00231 (rowArr.nbrEntries == 1 && 00232 ((UT_PtrArrayRaw *)rowArr(0))->nbrEntries == 0); 00233 } 00234 00235 // Resize the array, ie. grow it or shrink it. If copyFlag is 1, the 00236 // function copies the data after reallocating space for the array. 00237 void resize(unsigned int mSz, unsigned int nSz, 00238 unsigned short copyFlag=1); 00239 00240 // Apply a user-defined function to each element of the matrix 00241 // as int as the function returns zero. If applyFct returns 00242 // 1, apply() stops traversing the list and returns 1; otherwise, apply() 00243 // returns 0; 00244 int apply(int (*applyFct)(void *t, void *d), void *d); 00245 00246 // Array of rows, where each row is a reference array of type Thing: 00247 UT_PtrArrayRaw rowArr; 00248 00249 // Number of allocated columns in each row. 00250 unsigned int nbrCols; 00251 00252 // Guts if the insert(...) methods. 00253 unsigned int assignRow(const UT_PtrArrayRaw &r, unsigned int index) 00254 { 00255 rowArr(index) = new UT_PtrArrayRaw(nbrCols); 00256 ((UT_PtrArrayRaw *)rowArr(index))->assignSubset(r); 00257 return index; 00258 } 00259 unsigned int insertFastFill(const UT_PtrArrayRaw &r, unsigned idx); 00260 unsigned int insertSlowFill(unsigned idx, 00261 unsigned uRows, unsigned uCols); 00262 00263 // Guts of removeCol(). 00264 void removeOneCol(unsigned int index); 00265 00266 // Guts of removeRow(). 00267 void removeOneRow(unsigned int index) 00268 { 00269 UT_PtrArrayRaw *rdel=(UT_PtrArrayRaw*)rowArr(index); 00270 rowArr.remove(index); 00271 delete rdel; 00272 } 00273 }; 00274 00275 #endif
1.5.9