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 that is used by UT_PtrArray to do all the work... 00018 * 00019 */ 00020 00021 #ifndef __UT_PtrArrayRaw_h__ 00022 #define __UT_PtrArrayRaw_h__ 00023 00024 #include "UT_API.h" 00025 #include <string.h> 00026 #include <malloc.h> 00027 #include <SYS/SYS_Types.h> 00028 #include "UT_ArrayHelp.h" 00029 #include "UT_Assert.h" 00030 00031 UT_API extern int UTcomparePointers(void *const* a, void *const* b); 00032 00033 class UT_API UT_PtrArrayRaw { 00034 public: 00035 typedef int (*Comparator)(const void *, const void *); 00036 typedef bool (*ComparatorBool)(const void *, const void *); 00037 00038 // Trivial constructor and destructor. WARNING: this is really meant to 00039 // be a private class. You should normally instantiate it through its 00040 // friend(s). We made these 2 methods public to avoid compiler warnings. 00041 explicit UT_PtrArrayRaw(unsigned int sz = 0) : arrSize(sz), nbrEntries(0) 00042 { 00043 arr = (sz) ? (void **)calloc(sizeof(void *), sz) : 0; 00044 } 00045 ~UT_PtrArrayRaw(void); 00046 00047 // Copy constructor that uses operator '=' to assign each of a's Things 00048 // to this array. 00049 UT_PtrArrayRaw(const UT_PtrArrayRaw &a); 00050 00051 void swap( UT_PtrArrayRaw &other ); 00052 00053 // Append an element to the current entries and return its index in the 00054 // array, or insert the element at a specified position; if necessary, 00055 // insert() grows the array to accommodate the element. The insert 00056 // methods use the assignment operator '=' to place the Thing into the 00057 // right spot; be aware that '=' works differently on objects and pointers. 00058 // The test for duplicates uses the logical equal operator '=='; as with 00059 // '=', the behaviour of the equality operator on pointers versus objects 00060 // is not the same. 00061 // Use the subscript operators instead of insert() if you are appending 00062 // to the array, or if you don't mind overwriting the element already 00063 // inserted at the given index. 00064 unsigned int append(void) { return insert(nbrEntries); } 00065 unsigned int append(const void *t); 00066 unsigned int append(const void *t, int checkForDup); 00067 unsigned int insert(unsigned index); 00068 unsigned int insert(const void *t, unsigned index); 00069 00070 // Assuming the array is sorted, it inserts item t maintaining the sorted 00071 // state of the array. It returns the index of the inserted item. 00072 unsigned int sortedInsert(const void *t, Comparator compare); 00073 unsigned int uniqueSortedInsert(const void *t, Comparator compare); 00074 00075 bool hasSortedSubset( UT_PtrArrayRaw const& other, 00076 Comparator compare) const; 00077 00078 void sortedIntersection( UT_PtrArrayRaw const& other, 00079 Comparator compare); 00080 void sortedIntersection( UT_PtrArrayRaw const& other, 00081 UT_PtrArrayRaw &result, 00082 Comparator compare) const; 00083 void sortedUnion( UT_PtrArrayRaw const& other, 00084 Comparator compare ); 00085 void sortedUnion( UT_PtrArrayRaw const& other, 00086 UT_PtrArrayRaw &result, 00087 Comparator compare ) const; 00088 00089 // Assuming that the array is sorted without duplicates, it inserts item t 00090 // provided that it does not already exist in the array. 00091 // Returns the index of the inserted item, or the index of the existing 00092 // item if found. 00093 unsigned int uniqueSortedInsert(const void *t); 00094 00095 // Assuming the array is already a heap, it inserts item t maintaining 00096 // the heap. It returns the index of the inserted item. 00097 unsigned int heapPush(const void *t, Comparator compare ); 00098 // Assuming the array is already a heap, extracts the top (maximum) 00099 // element from the heap and returns it. 00100 void *heapPop(Comparator compare); 00101 // Assuming the array is already a heap, return the top (maximum) 00102 // element. 00103 void *heapMax() const 00104 { 00105 UT_ASSERT_P(nbrEntries > 0); 00106 return arr[0]; 00107 } 00108 00109 // Takes another pointer array and concatenate it onto my end 00110 unsigned int concat(const UT_PtrArrayRaw &a); 00111 00112 // Insert an element "count" times at the given index. Return the index. 00113 unsigned int multipleInsert(unsigned int index, unsigned int count); 00114 00115 // An alias for unique element insertion at a certain index. Also used by 00116 // the other insertion methods. 00117 unsigned int insertAt(const void *t, unsigned int index); 00118 00119 // Remove one element from the array given the element itself or its 00120 // position in the list, and fill the gap by shifting the elements down 00121 // by one position. Both methods return the index if successful, 00122 // If dupliCheck is 1, both methods search for all objects that match t or 00123 // arr[index] respectively. 00124 int remove(const void *t); 00125 int remove(unsigned int index) 00126 { 00127 return (index < nbrEntries) ? removeAt(index) : -1; 00128 } 00129 00130 int removeZeros(); 00131 00132 // A little quicker version of remove which avoids the 00133 // unneccessary shift 00134 void *removeLast() 00135 { return nbrEntries ? arr[--nbrEntries] : 0; } 00136 00137 // Sort and remove all duplicate entries 00138 void sortAndRemoveDuplicates(); 00139 00140 // Move howMany objects starting at index srcIndex to destIndex; 00141 // Method returns 0 if OK, -1 if overflow. 00142 int shift(unsigned int srcIdx, 00143 unsigned int destIdx, 00144 unsigned int howMany); 00145 // Move howMany objects starting at index srcIndex to destIndex; 00146 // Unlike shift, this method moves entries instead of overwriting them. 00147 void move(int srcIdx, int destIdx, int howMany); 00148 // Collapse the array to remove all the null pointer entries. 00149 // Note: Indices to elements may change due to shifting 00150 void collapse(); 00151 00152 // Cyclically shifts the entire array by howMany 00153 void cycle(int howMany); 00154 00155 // Reverse the entries in the array 00156 void reverse(); 00157 00158 // Search for t in one of two ways: linearly using the '==' operator, or 00159 // binary using the function specified in the parameter list respectively. 00160 // find() returns the index of the matching element or (int)-1. 00161 // Parameter s indicates the index the search should start at. 00162 int find(const void *t, unsigned int s = 0) const; 00163 int find(const void *t, int (*compare)(const void *, const void *)) const; 00164 00165 // Searches for the given string assuming that our array points to 00166 // strings. 00167 // The advantage is that we avoid all callbacks, can inline code, 00168 // so should be super fast. 00169 int findString(const char *str) const; 00170 00171 // Sort the array using a comparison function that you must provide. t1 and 00172 // t2 are pointers to Thing. 00173 void sort(Comparator compare); 00174 00175 // Resize the array, ie. grow it or shrink it. If copyFlag is 1, the 00176 // function copies the data after reallocating space for the array. 00177 void resize(unsigned int sz, unsigned short copyFlag=1); 00178 00179 // Query the allocated length of the array or the number of elements 00180 // in the array: capacity() >= entries(). 00181 uint capacity(void) const { return arrSize; } 00182 int64 getMemoryUsage() const { return capacity()*sizeof(void *); } 00183 uint entries(void) const { return nbrEntries; } 00184 bool isEmpty(void) const { return nbrEntries==0; } 00185 00186 // Set the number of entries. Normally, you should not have to use it. 00187 void entries(unsigned int ne) { nbrEntries = ne; } 00188 00189 // Assign array a to this array by copying each of a's Things with the 00190 // '=' operator. The size of this array must be greater or equal to the 00191 // entry count of array a. 00192 // WARNING: Will *NOT* reduce nbrEntries, will only increase if necessary 00193 UT_PtrArrayRaw &assignSubset(const UT_PtrArrayRaw &a); 00194 00195 // Assign array a to this array by copying each of a's Things with the 00196 // '=' operator. 00197 UT_PtrArrayRaw &operator=(const UT_PtrArrayRaw &a); 00198 00199 // Compare two array and return 1 if they are equal and 0 otherwise. 00200 // Two Things are checked against each other using operator '==' or 00201 // compare() respectively. Arrays of different size but equal number of 00202 // entries are checked for member-wise equality. 00203 // t1 and t2 must point to Things. 00204 int operator==(const UT_PtrArrayRaw &a) const; 00205 int isEqual(const UT_PtrArrayRaw &a, 00206 int (*compare)(const void *t1, const void *t2) 00207 ) const; 00208 00209 // Subscript operators. operator() does NOT do any bound checking, while 00210 // the non-const operator[] grows the array to accommodate the given index. 00211 void *&operator()(unsigned int i) 00212 { 00213 UT_ASSERT_P( i < nbrEntries ); 00214 return arr[i]; 00215 } 00216 void *operator()(unsigned int i) const 00217 { 00218 UT_ASSERT_P( i < nbrEntries ); 00219 return arr[i]; 00220 } 00221 void *&operator[](unsigned int i) 00222 { 00223 if (i >= arrSize ) resize(bumpAlloc(i+1)); 00224 if (i >= nbrEntries) nbrEntries = i+1; 00225 return arr[i]; 00226 } 00227 void *operator[](unsigned int i) const 00228 { 00229 UT_ASSERT_P( i < nbrEntries ); 00230 return (i < nbrEntries) ? arr[i] : (void *)0; 00231 } 00232 00233 // Apply a user-defined function to each element of the array 00234 // as int as the function returns zero. If applyFct returns 00235 // 1, apply() stops traversing the list and returns the current 00236 // index; otherwise, apply() returns the number of entries. 00237 unsigned int apply(int (*applyFct)(void *t, void *d), void *d); 00238 00239 00240 // Derived class should use these three methods to get a handle to the 00241 // internal data, and set the array size. 00242 void *array(void) const { return arr; } 00243 void setCapacity(unsigned int sz) { arrSize = sz; } 00244 00245 // Pointer to a list of elements of type Thing: 00246 void **arr; 00247 00248 // The number of elements we have allocated space for versus the actual 00249 // number of entries in the array: 00250 unsigned int arrSize; 00251 unsigned int nbrEntries; 00252 00253 // The guts of the remove() methods. 00254 int removeAt(unsigned int index); 00255 // The guts of the popHeap() method. 00256 void heapify(unsigned int index, Comparator compare); 00257 }; 00258 00259 #endif
1.5.9