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 utPtr. You can instantiate this class 00020 * with any object or pointer, such as: 00021 * UT_PtrMatrix<int> iObj; 00022 * UT_PtrMatrix<GeoPrimMesh> mObj; 00023 * UT_PtrMatrix<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.3 1995/09/29 12:30:43 phb 00032 * Changed local includes of UT files from <UT/UT*.h> to "UT*.h" 00033 * 00034 * Revision 1.2 1995/09/28 21:17:40 adubey 00035 * Fixed #include directive calls. 00036 * 00037 * Revision 1.1.1.1 1995/09/17 18:10:24 mark 00038 * initial source release 00039 * 00040 * Revision 1.2 1995/05/11 23:22:40 mark 00041 * Changed some method names 00042 * ., 00043 * 00044 * Revision 1.1 1995/03/17 03:33:11 mark 00045 * Initial revision 00046 * 00047 * Revision 1.6 94/02/07 11:18:28 cb 00048 * renamed some of the insert() methods to append() 00049 * 00050 * Revision 1.5 94/01/28 00:47:33 cb 00051 * *** empty log message *** 00052 * 00053 * Revision 1.4 94/01/04 15:35:56 cb 00054 * long has become int 00055 * 00056 * Revision 1.3 1993/11/29 21:11:38 dale 00057 * Cleaning up the code 00058 * 00059 * Revision 1.2 93/11/29 19:41:32 cb 00060 * Bug fix re: usage of cols() vs usedCols() 00061 * 00062 * Revision 1.1 1993/10/19 18:49:59 cb 00063 * Initial revision 00064 * 00065 * 00066 */ 00067 00068 #ifndef __UT_PtrMatrix_h__ 00069 #define __UT_PtrMatrix_h__ 00070 00071 #include "UT_PtrMatrixRaw.h" 00072 #include "UT_PtrArray.h" 00073 00074 00075 template <class utPtr> 00076 class UT_PtrMatrix { 00077 public: 00078 // Trivial constructor and destructor: 00079 UT_PtrMatrix(unsigned mSz = 0, unsigned nSz = 0) : matrix(mSz, nSz) {} 00080 ~UT_PtrMatrix(void) {} 00081 00082 // Copy constructor that copies each utPtr from the source matrix to 00083 // this matrix using the '=' operator. 00084 UT_PtrMatrix(const UT_PtrMatrix<utPtr> &m) 00085 { 00086 matrix = m.matrix; 00087 } 00088 00089 // Append a row or insert it at a given index. The matrix is grown to 00090 // accommodate it. If dupliCheck is 1, we first search for duplicates; the 00091 // search method uses the (*compare) function on pairs of Things when 00092 // specified, and the '==' operator on UT_PtrArray pairs otherwise. The 00093 // fast insertion methods assign the address of the UT_PtrArray to the 00094 // pointer in the row matrix rather than copying each element piece by 00095 // piece. All methods return the index of the found or inserted row. 00096 // t1 and t2 must be pointers to utPtr. 00097 unsigned int insertRow(unsigned int index) 00098 { 00099 return matrix.insertRow(index); 00100 } 00101 unsigned int insertRow(const UT_PtrArray<utPtr> &r, unsigned index) 00102 { 00103 return matrix.insertRow(r.getRawArray(), index); 00104 } 00105 unsigned int appendRow(const UT_PtrArray<utPtr> &r) 00106 { return matrix.appendRow(r.getRawArray()); } 00107 00108 // Fast insertion: as mentioned above, we just assign the address of r to 00109 // the a row array pointer. The UT_PtrMatrix destructor will delete &r 00110 // when called. Use these methods with care. 00111 unsigned int insertRowFast(const UT_PtrArray<utPtr> &r, unsigned idx) 00112 { 00113 return matrix.insertRowFast(r.getRawArray(), idx); 00114 } 00115 unsigned int appendRowFast(const UT_PtrArray<utPtr> &r) 00116 { 00117 return matrix.appendRowFast(r.getRawArray()); 00118 } 00119 00120 // Append a column or insert it at a given index. The matrix is grown to 00121 // accommodate it. If dupliCheck is 1, we first search for duplicates; the 00122 // search method uses the (*compare) function on pairs of Things when 00123 // specified, and the '==' operator otherwise. t1 and t2 must be pointers 00124 // to utPtr. All methods return the index of the found or inserted column, 00125 // or -1 if the matrix has no rows. It is OK to insert a column into a 00126 // matrix with zero row entries but with space already allocated for at 00127 // least one row. 00128 int insertCol(unsigned index) { return matrix.insertCol(index); } 00129 int insertCol(const UT_PtrArray<utPtr> &c, unsigned int index) 00130 { 00131 return matrix.insertCol(c.getRawArray(), index); 00132 } 00133 int appendCol(const UT_PtrArray<utPtr> &c) 00134 { 00135 return matrix.appendCol(c.getRawArray()); 00136 } 00137 00138 // Remove a row and possibly all its duplicates given a row object or its 00139 // index in the row array. The methods that take a (*compare)() function 00140 // use it to compare two Things; the other methods use the '==' operator. 00141 // to compare two UT_PtrArray. 00142 // If dupliCheck is 1, all duplicates found will be removed too. All 00143 // methods return the row index (index of first row removed). Do not 00144 // try to access the row after removal, because its contets are undefined. 00145 // t1 and t2 must be pointers to utPtr. 00146 // For increased efficiency, try to use the 'index' methods whenever 00147 // possible. 00148 int removeRow(const UT_PtrArray<utPtr> &r) 00149 { 00150 return matrix.removeRow(r.getRawArray()); 00151 } 00152 int removeRow(unsigned index) 00153 { 00154 return matrix.removeRow(index); 00155 } 00156 00157 // Remove a column and possibly all its duplicates given a column object or 00158 // its index. The methods that take a (*compare)() function 00159 // use it to compare two Things; the other methods use the '==' operator. 00160 // If dupliCheck is 1, all duplicates found will be removed too. All 00161 // methods return the column index (index of last column removed). 00162 // t1 and t2 must be pointers to utPtr. 00163 // For increased efficiency, try to use the 'index' methods whenever 00164 // possible. 00165 int removeCol(const UT_PtrArray<utPtr> &c) 00166 { 00167 return matrix.removeCol(c.getRawArray()); 00168 } 00169 int removeCol(unsigned int index) 00170 { 00171 return matrix.removeCol(index); 00172 } 00173 00174 // Compare the two matrices: to return 1, they should have the same 00175 // number or entries, and their Things should all match when compared 00176 // with '==' or compare() respectively. 00177 // t1 and t2 must be pointers to utPtr. 00178 int operator==(const UT_PtrMatrix<utPtr> &m) const 00179 { 00180 return matrix == m.matrix; 00181 } 00182 int isEqual(const UT_PtrMatrix<utPtr> &m, 00183 int (*compare)(const void *t1,const void *t2) 00184 ) const 00185 { 00186 return matrix.isEqual(m.matrix, compare); 00187 } 00188 00189 // Assignment operator that copies the array piece by piece using the 00190 // '=' operator defined in UT_PtrArray. The row and column size of this 00191 // matrix must be greater or equal to the "used" row and column count of 00192 // matrix m. 00193 UT_PtrMatrix<utPtr> &operator=(const UT_PtrMatrix<utPtr> &m) 00194 { 00195 matrix = m.matrix; 00196 return *this; 00197 } 00198 00199 #if 0 00200 // There are no operators since we can't really upclass to the template array 00201 // Subscript operators to return rows. operator() does not check if the 00202 // matrix needs to be resized. operator[] grows the array of rows to 00203 // accommodate the index if necessary; . 00204 const UT_PtrArray<utPtr> &operator()(unsigned int i) const 00205 { 00206 return (const UT_PtrArray<utPtr>&)matrix(i); 00207 } 00208 const UT_PtrArray<utPtr> &operator[](unsigned int i) const 00209 { 00210 return *rowArr[i]; 00211 } 00212 UT_PtrArray<utPtr> &operator()(unsigned int i) 00213 { 00214 return *rowArr(i); 00215 } 00216 UT_PtrArray<utPtr> &operator[](unsigned int i); 00217 #endif 00218 00219 // Return an element of the matrix, WITHOUT any BOUND CHECKING. Use 00220 // safeGet() if you don't know whether you are within range or not. 00221 utPtr operator()(unsigned i, unsigned j) const 00222 { 00223 return (utPtr)matrix(i, j); 00224 } 00225 utPtr &operator()(unsigned int i, unsigned int j) 00226 { 00227 return (utPtr &)matrix(i, j); 00228 } 00229 00230 // Return an element of the matrix, growing the matrix if necessary in 00231 // the non-const case. 00232 utPtr safeGet(unsigned i, unsigned j) const 00233 { 00234 return (utPtr)matrix.safeGet(i, j); 00235 } 00236 utPtr &safeGet(unsigned int i, unsigned int j) 00237 { 00238 return (utPtr &)matrix.safeGet(i, j); 00239 } 00240 00241 #if 0 00242 Forget these for now - if someone really needs them, we can figure something out 00243 // Return a specified row or column. row() returns an actual reference to 00244 // the row entry in the matrix WITHOUT growing the array of rows if 00245 // needed. 00246 // col() builds a UT_PtrArray from scratch by allocating heap space for it 00247 // and copying each element into it with the '=' operator. The col() 00248 // array must be freed by YOU. 00249 const UT_PtrArray<utPtr> &row(unsigned int i) const {return *rowArr(i);} 00250 UT_PtrArray<utPtr> &row(unsigned int i) {return *rowArr(i);} 00251 UT_PtrArray<utPtr> &col(unsigned int j) const; 00252 #endif 00253 00254 // Search for t in each row in one of two ways: linearly using the '==' 00255 // operator, or binary using the function specified in the parameter list 00256 // respectively. find() returns 0 and the indices of the matching element, 00257 // or -1 if not found. t1 and t2 must be pointers to utPtr. 00258 int find(utPtr t, unsigned int *m, unsigned int *n) const 00259 { 00260 return matrix.find((const void *)t, m, n); 00261 } 00262 00263 // Search for a row or a column in one of two ways: binary, using a user 00264 // defined function (*compare) to compare two Things, or linearly using 00265 // the '==' operator between UT_PtrArray in findRow() and between Things 00266 // in findCol(). Note that the arrays to be compared must have an equal 00267 // number of entries, and not necessarily the same size. 00268 // Parameter s indicates what index to start searching at. 00269 // All methods return the row/col index if found, and -1 otherwise. 00270 // t1 and t2 must be pointers to utPtr. 00271 int findRow(const UT_PtrArray<utPtr> &r, unsigned int s = 0) const 00272 { 00273 return matrix.findRow(r.getRawArray(), s); 00274 } 00275 int findCol(const UT_PtrArray<utPtr> &c, unsigned int s = 0) const 00276 { 00277 return matrix.findCol(c.getRawArray(), s); 00278 } 00279 00280 // Return the number of rows and column space has been allocated for, and 00281 // the number of entries used in the rows and columns. 00282 unsigned int rowSize(void) const { return matrix.rowSize(); } 00283 unsigned int colSize(void) const { return matrix.colSize(); } 00284 unsigned int rows(void) const { return matrix.rows(); } 00285 unsigned int cols(void) const { return matrix.cols(); } 00286 unsigned short isEmpty(void) const { return matrix.isEmpty(); } 00287 00288 // Resize the array, ie. grow it or shrink it. If copyFlag is 1, the 00289 // function copies the data after reallocating space for the array. 00290 void resize(unsigned int mSz, unsigned int nSz, 00291 unsigned short copyFlag=1) 00292 { 00293 matrix.resize(mSz, nSz, copyFlag); 00294 } 00295 00296 // Apply a user-defined function to each element of the matrix 00297 // as int as the function returns zero. If applyFct returns 00298 // 1, apply() stops traversing the list and returns 1; otherwise, apply() 00299 // returns 0; 00300 int apply(int (*fcn)(utPtr t, void *d), void *d) 00301 { 00302 return matrix.apply((int (*)(void *, void*))fcn, d); 00303 } 00304 00305 private: 00306 UT_PtrMatrixRaw matrix; 00307 }; 00308 00309 00310 #endif
1.5.9