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 * 123 Front Street West, Suite 1401 00010 * Toronto, Ontario 00011 * Canada M5J 2M2 00012 * 416-504-9876 00013 * 00014 * NAME: Utility Library (C++) 00015 * 00016 * COMMENTS: 00017 * This is a class template that implements a resizable array of 00018 * arbitrary objects. The template parameter represents the type 00019 * of object, and is called utRef. You can instantiate this class 00020 * with any object or pointer, such as: 00021 * UT_RefArray<int> iObj; 00022 * UT_RefArray<GeoPrimMesh> mObj; 00023 * UT_RefArray<GeoPoint*> pObj; ... etc 00024 * The "Ref" in the class name stands for "passed by reference", which 00025 * is the argument passing strategy used by this class. Use this class 00026 * if you want to construct arrays of arbitrary objects. Pointers and 00027 * primitive types are stored and passed more efficiently in another 00028 * class, UT_PtrArray, which passes arguments by value to avoid the 00029 * referencing overhead. 00030 */ 00031 00032 #ifndef __UT_RefArray_h__ 00033 #define __UT_RefArray_h__ 00034 00035 #ifdef WIN32 00036 #pragma warning(disable:4251) 00037 #pragma warning(disable:4275) 00038 #endif 00039 #include <string.h> 00040 #include <malloc.h> 00041 #include "UT_Assert.h" 00042 #include "UT_Algorithm.h" 00043 #include "UT_ArrayHelp.h" 00044 00045 00046 template <class utRef> 00047 class UT_RefArray { 00048 public: 00049 typedef int (*Comparator)(const utRef *, const utRef *); 00050 00051 // Trivial constructor and destructor: 00052 explicit UT_RefArray(unsigned int sz = 0) 00053 : arrSize(sz), nbrEntries(0) 00054 { 00055 arr = (sz) ? (utRef*)calloc(sizeof(utRef),sz) : 0; 00056 } 00057 UT_RefArray(unsigned int sz, unsigned int count); 00058 00059 virtual ~UT_RefArray(void); 00060 00061 void swap( UT_RefArray &other ); 00062 00063 // Copy constructor that uses operator '=' to assign each of a's utRefs 00064 // to this array. 00065 UT_RefArray(const UT_RefArray<utRef> &a); 00066 00067 // Append an element to the current entries and return its index in the 00068 // array, or insert the element at a specified position; if necessary, 00069 // insert() grows the array to accommodate the element. The insert 00070 // methods use the assignment operator '=' to place the utRef into the 00071 // right spot; be aware that '=' works differently on objects and pointers. 00072 // If utRef is an object that uses the default '=' operator, the result of 00073 // insert() will be a shallow copy of t, and not t itself. 00074 // So, if what you really want to do is create a new object inside the 00075 // array, first grow the array to a good size, then create your object as 00076 // follows: 00077 // UT_RefArray<GeoPoint> arr(3); 00078 // GeoPoint *p = new (&arr[0]) GeoPoint(....); 00079 // The test for duplicates uses the logical equal operator '=='; as with 00080 // '=', the behaviour of the equality operator on pointers versus objects 00081 // is not the same. If utRef is an object, we recommend you either avoid 00082 // using insert(), or define both '=' and '==' operators in its class. 00083 // Use the subscript operators instead of insert() if you are appending 00084 // to the array, or if you don't mind overwriting the element already 00085 // inserted at the given index. 00086 unsigned int append(void) { return insert(nbrEntries); } 00087 unsigned int append(const utRef& t); 00088 unsigned int append(const utRef& t, unsigned short dupliCheck); 00089 unsigned int insert(unsigned int index); 00090 unsigned int insert(const utRef& t, unsigned int index); 00091 unsigned int insert(const utRef& t, unsigned int index, 00092 unsigned short dupliCheck); 00093 00094 // Takes another pointer array and concatenate it onto my end 00095 unsigned int concat(const UT_RefArray<utRef> &a); 00096 00097 // Insert an element "count" times at the given index. Return the index. 00098 unsigned int multipleInsert(unsigned int index, unsigned int count); 00099 00100 // Two more insert() methods that check for duplicates in the array, 00101 // assuming that the array is sorted. t1 and t2 must be pointers to utRef. 00102 unsigned int append(const utRef& t, Comparator compare); 00103 unsigned int insert(const utRef& t, 00104 unsigned int index, 00105 Comparator compare 00106 ); 00107 unsigned int sortedInsert(const utRef& t, Comparator compare); 00108 void sortedUnion( 00109 const UT_RefArray<utRef> &other, 00110 UT_RefArray<utRef> &result, 00111 Comparator compare 00112 ) const; 00113 00114 // Assuming the array is already a heap, it inserts item t maintaining 00115 // the heap. It returns the index of the inserted item. 00116 unsigned int heapPush(const utRef &t, Comparator compare ); 00117 // Assuming the array is already a heap, extracts the top (maximum) 00118 // element from the heap and returns it. 00119 void heapPop(Comparator compare); 00120 // Assuming the array is already a heap, return the top (maximum) 00121 // element. 00122 utRef &heapMax() const 00123 { 00124 UT_ASSERT_P(nbrEntries > 0); 00125 return arr[0]; 00126 } 00127 00128 // An alias for unique element insertion at a certain index. Also used by 00129 // the other insertion methods. 00130 unsigned int insertAt(const utRef &t, unsigned int index); 00131 00132 // Remove one element from the array given the element itself or its 00133 // position in the list, and fill the gap by shifting the elements down 00134 // by one position. Both methods return the index if successful, 00135 // and (int)-1 if the element is not found. The method that takes 00136 // an index argument does not return a reference to the object for safety 00137 // purposes: if utRef is an object, then when the array is shrunk the 00138 // memory previously used by utRef will be overwritten by the next 00139 // element. If dupliCheck is 1, both methods search for all objects that 00140 // match t or arr[index] respectively. 00141 int remove(const utRef& t ); 00142 int remove(unsigned int at_index ) 00143 { 00144 return (at_index < nbrEntries) 00145 ? removeAt(at_index) : -1; 00146 } 00147 int remove(const utRef& t, unsigned short dupliCheck); 00148 int remove(unsigned int at_index, unsigned short dupliCheck) 00149 { 00150 return (at_index < nbrEntries) 00151 ? removeAt(at_index, dupliCheck) : -1; 00152 } 00153 00154 // Two more remove() methods that search for the object to be removed and 00155 // all its duplicates (if dupliCheck is 1) with a user-defined comparison 00156 // function. These methods assume the array is sorted. t1 and t2 must be 00157 // pointers to utRef. The methods return the last (removed) object index. 00158 int remove(const utRef& t, 00159 Comparator compare, 00160 unsigned short dupliCheck = 0); 00161 int remove(unsigned int at_index, 00162 Comparator compare, 00163 unsigned short dupliCheck = 0) 00164 { 00165 return (at_index < nbrEntries) 00166 ? removeAt(at_index, compare, dupliCheck) : -1; 00167 } 00168 00169 // A convenience method to remove the last element. The method returns 00170 // the index if sucessful, and -1 if the array was empty. 00171 int removeLast() 00172 { 00173 return nbrEntries ? removeAt(nbrEntries-1) : -1; 00174 } 00175 00176 // Move howMany objects starting at index srcIndex to destIndex; 00177 // Method returns 0 if OK, -1 if overflow. 00178 int shift(unsigned int srcIdx, 00179 unsigned int destIdx, 00180 unsigned int howMany); 00181 // Move howMany objects starting at index srcIndex to destIndex; 00182 // Unlike shift, this method moves entries instead of overwriting them. 00183 void move(int srcIdx, int destIdx, int howMany); 00184 // Performs a cyclical shift of the entries by howMany 00185 void cycle(int howMany); 00186 00187 // Search for t in one of two ways: linearly using the '==' operator, or 00188 // binary using the function specified in the parameter list respectively. 00189 // find() returns the index of the matching element or (int)-1. 00190 // Parameter s indicates the index to start the search at. 00191 int find(const utRef &t, unsigned int s = 0) const; 00192 int find(const utRef &t, Comparator compare, 00193 unsigned int s = 0) const; 00194 00195 // Search for 'any' until compare() returns 0 and return the index; 00196 // otherwise return -1. The array is assumed to be sorted. 00197 int find(void *any, Comparator compare, unsigned int s = 0) const; 00198 00199 // The fastest search possible, which does pointer arithmetic to find the 00200 // index of the element. WARNING: index() does no out-of-bounds checking. 00201 int index(const utRef &t) const { return &t - arr; } 00202 int safeIndex(const utRef &t) const 00203 { 00204 return (&t >= arr && (&t - arr < (int)nbrEntries)) ? &t - arr : -1; 00205 } 00206 00207 // Sort the array using a comparison function that you must provide. t1 and 00208 // t2 are pointers to utRef. 00209 void sort(Comparator compare); 00210 00211 // Resize the array, ie. grow it or shrink it. If copyFlag is 1, the 00212 // function copies the data after reallocating space for the array. 00213 void resize(unsigned int sz, unsigned short copyFlag=1); 00214 void resizeIfNeeded(uint sz, bool copyFlag=true) 00215 { 00216 if (sz > capacity()) 00217 resize(sz, copyFlag); 00218 } 00219 00220 // Query the allocated length of the array or the number of elements 00221 // in the array: capacity() >= entries(). 00222 uint capacity(void) const { return arrSize; } 00223 int64 getMemoryUsage() const { return capacity()*sizeof(utRef); } 00224 uint entries(void) const { return nbrEntries; } 00225 bool isEmpty(void) const { return nbrEntries==0; } 00226 00227 // Set the number of entries. Normally, you should not have to use it. 00228 void entries(unsigned int ne); 00229 // Resets list to an empty list. 00230 void clear() { entries(0); } 00231 00232 // Assign array a to this array by copying each of a's utRefs with the 00233 // '=' operator. 00234 UT_RefArray<utRef> &operator=(const UT_RefArray<utRef> &a); 00235 00236 // Compare two array and return 1 if they are equal and 0 otherwise. 00237 // Two utRefs are checked against each other using operator '==' or 00238 // compare() respectively. Arrays of different size but equal number of 00239 // entries are checked for member-wise equality. 00240 // t1 and t2 must point to utRefs. 00241 int operator==(const UT_RefArray<utRef> &a) const; 00242 int operator!=(const UT_RefArray<utRef> &a) const; 00243 int isEqual(const UT_RefArray<utRef> &a, 00244 Comparator compare) const; 00245 00246 // Subscript operators. operator() does NOT do any bound checking, while 00247 // the non-const operator[] grows the array to accommodate the given index. 00248 utRef &operator()(unsigned int i) 00249 { 00250 UT_ASSERT_P(i < nbrEntries); 00251 return arr[i]; 00252 } 00253 const utRef &operator()(unsigned int i) const 00254 { 00255 UT_ASSERT_P(i < nbrEntries); 00256 return arr[i]; 00257 } 00258 utRef &operator[](unsigned int i); 00259 const utRef &operator[](unsigned int i) const 00260 { 00261 UT_ASSERT_P(i < nbrEntries); 00262 return arr[i]; 00263 } 00264 00265 utRef &last() 00266 { 00267 UT_ASSERT_P(nbrEntries); 00268 return arr[nbrEntries-1]; 00269 } 00270 00271 const utRef &last() const 00272 { 00273 UT_ASSERT_P(nbrEntries); 00274 return arr[nbrEntries-1]; 00275 } 00276 00277 // Apply a user-defined function to each element of the array 00278 // as int as the function returns zero. If applyFct returns 00279 // 1, apply() stops traversing the list and returns the current 00280 // index; otherwise, apply() returns the number of entries. 00281 unsigned int apply(int (*applyFct)(utRef &t, void *d), void *d); 00282 00283 const utRef *getRawArray(void) const { return arr; } 00284 00285 private: 00286 // Pointer to a list of elements of type utRef: 00287 utRef *arr; 00288 00289 // The number of elements we have allocated space for versus the actual 00290 // number of entries in the array: 00291 unsigned int arrSize; 00292 unsigned int nbrEntries; 00293 00294 // The guts of the remove() methods. 00295 int removeAt(unsigned int index); 00296 int removeAt(unsigned int index, unsigned short dupliCheck); 00297 int removeAt(unsigned int index, Comparator compare, 00298 unsigned short dupliCheck); 00299 00300 // The guts of the popHeap() method. 00301 void heapify(unsigned int index, Comparator compare); 00302 }; 00303 00304 #if defined( WIN32 ) || defined( LINUX ) || defined(MBSD) || defined(GAMEOS) 00305 #include "UT_RefArray.C" 00306 #endif 00307 00308 00309 UT_SWAPPER_TEMPLATE( UT_RefArray ); 00310 00311 #endif
1.5.9