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 fixed-size 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, while also giving a size to the array: 00021 * UT_RefFixArray<int, 10> iObj; 00022 * UT_RefFixArray<GeoPrimMesh, 20> mObj; 00023 * UT_RefFixArray<GeoPoint*, 50> 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_RefFixArray_h__ 00033 #define __UT_RefFixArray_h__ 00034 00035 #include <string.h> 00036 #include <SYS/SYS_Types.h> 00037 #include "UT_Assert.h" 00038 00039 00040 template <class utRef, unsigned long FixedSize> 00041 class UT_RefFixArray { 00042 public: 00043 // Trivial constructor and destructor: 00044 UT_RefFixArray(void) : nbrEntries(0) {} 00045 virtual ~UT_RefFixArray(void); 00046 00047 // Append an element to the current entries and return its index in the 00048 // array, or insert the element at a specified position; if the index is 00049 // greater than or equal to FixedSize-1, insert() returns -1. The insertion 00050 // methods use the assignment operator '=' to place the utRef into the 00051 // right spot; be aware that '=' works differently on objects and pointers. 00052 // If utRef is an object that uses the default '=' operator, the result of 00053 // insert() will be a shallow copy of t, and not t itself. 00054 // The test for duplicates uses the logical equal operator '=='; as with 00055 // '=', the behaviour of the equality operator on pointers versus objects 00056 // is not the same. If utRef is an object, we recommend you either avoid 00057 // using insert(), or define both '=' and '==' operators in its class. 00058 // Use the subscript operators instead of insert() if you are appending 00059 // to the array, or if you don't mind overwriting the element already 00060 // inserted at the given index. 00061 long insert(const utRef& t, unsigned short duplicates = 1); 00062 long insert(const utRef& t, unsigned long index, 00063 unsigned short duplicates = 1); 00064 00065 // Two more insert() methods that check for duplicates in the array, 00066 // assuming that the array is sorted. t1 and t2 must be pointers to utRef. 00067 long insert(const utRef& t, 00068 int (*compare)(const void *t1, const void *t2) 00069 ); 00070 long insert(const utRef& t, 00071 unsigned long index, 00072 int (*compare)(const void *t1, const void *t2) 00073 ); 00074 00075 // Remove one element from the array given the element itself or its 00076 // position in the list, and fill the gap by shifting the elements down 00077 // by one position. Both methods return the index if successful, 00078 // and (long)-1 if the element is not found. The method that takes 00079 // an index argument does not return a reference to the object for safety 00080 // purposes: if utRef is an object, then when the array is shrunk, the 00081 // memory previously used by utRef will be overwritten by the next 00082 // element. If duplicates is 1, both methods search for all objects that 00083 // match t or arr[index] respectively. 00084 long remove(const utRef& t, unsigned short duplicates=1); 00085 long remove(unsigned long index, unsigned short duplicates=1) 00086 { 00087 if (index < nbrEntries) removeAt(index, duplicates); 00088 return (index < nbrEntries) ? index : -1; 00089 } 00090 00091 // Two more remove() methods that search for the object to be removed and 00092 // all its duplicates (if duplicates is 1) with a user-defined comparison 00093 // function. These methods assume the array is sorted. t1 and t2 must be 00094 // pointers to utRef. The methods return the last (removed) object index. 00095 long remove(const utRef& t, 00096 int (*compare)(const void *t1, const void *t2), 00097 unsigned short duplicates = 1); 00098 long remove(unsigned long index, 00099 int (*compare)(const void *t1, const void *t2), 00100 unsigned short duplicates = 1) 00101 { 00102 if (index < nbrEntries) 00103 removeAt(index, compare, duplicates); 00104 return (index < nbrEntries) ? index : -1; 00105 } 00106 00107 // Move howMany objects starting at index srcIndex to destIndex; 00108 // Method returns 0 if OK, -1 if overflow. 00109 int shift(unsigned long srcIdx, 00110 unsigned long destIdx, 00111 unsigned long howMany); 00112 00113 // Search for t in one of two ways: linearly using the '==' operator, or 00114 // binary using the function specified in the parameter list respectively. 00115 // find() returns the index of the matching element or (long)-1. 00116 long find(const utRef &t) const; 00117 long find(const utRef &t, 00118 int (*compare)(const void *t1, const void *t2) 00119 ) const; 00120 00121 // Sort the array using a comparison function that you must provide. t1 and 00122 // t2 are pointers to utRef. 00123 void sort(int (*compare)(const void *t1, const void *t2)); 00124 00125 // Query the allocated length of the array or the number of elements 00126 // in the array: capacity() >= entries(). 00127 uint capacity(void) const { return FixedSize; } 00128 int64 getMemoryUsage() const { return capacity()*sizeof(utRef); } 00129 uint entries(void) const { return nbrEntries; } 00130 bool isEmpty(void) const { return nbrEntries==0; } 00131 00132 // Subscript operators. operator() does NOT do any bound checking. 00133 utRef &operator()(unsigned long i) 00134 { 00135 if (i >= nbrEntries) nbrEntries = i+1; 00136 UT_ASSERT_P(nbrEntries < FixedSize); 00137 return arr[i]; 00138 } 00139 const utRef &operator()(unsigned long i) const 00140 { 00141 UT_ASSERT_P(i < nbrEntries); 00142 return arr[i]; 00143 } 00144 utRef &operator[](unsigned long i) 00145 { 00146 if (i >= FixedSize ) i = FixedSize-1; 00147 if (i >= nbrEntries) nbrEntries = i+1; 00148 return arr[i]; 00149 } 00150 const utRef &operator[](unsigned long i) const 00151 { 00152 UT_ASSERT_P(i < nbrEntries); 00153 return arr[i]; 00154 } 00155 00156 // Apply a user-defined function to each element of the array 00157 // as long as the function returns zero. If applyFct returns 00158 // 1, apply() stops traversing the list and returns the current 00159 // index; otherwise, apply() returns the number of entries. 00160 unsigned long apply(int (*applyFct)(utRef &t, void *d), void *d); 00161 00162 00163 protected: 00164 // Set the number of entries. 00165 void entries(unsigned long ne) { nbrEntries = ne; } 00166 00167 private: 00168 // List of elements of type utRef: 00169 utRef arr[FixedSize]; 00170 00171 // Number of entries in the array: 00172 unsigned long nbrEntries; 00173 00174 // The guts of the public insert(...index...) methods. 00175 long insertAt(const utRef &t, unsigned long index) 00176 { 00177 long idx; 00178 if (nbrEntries < FixedSize) 00179 { 00180 if (&arr[0] <= &t && &t <= &arr[FixedSize-1]) 00181 { 00182 utRef tCopy = t; 00183 memmove(&arr[index+1], &arr[index], 00184 (int)((nbrEntries-index)*sizeof(utRef))); 00185 arr[index] = tCopy; 00186 } 00187 else 00188 { 00189 memmove(&arr[index+1], &arr[index], 00190 (int)((nbrEntries-index)*sizeof(utRef))); 00191 arr[index] = t; 00192 } 00193 nbrEntries++; 00194 idx = (long) index; 00195 } 00196 else idx = -1; 00197 return idx; 00198 } 00199 00200 // The guts of the remove() methods. 00201 void removeAt(unsigned long index,unsigned short duplicates); 00202 void removeAt(unsigned long index, 00203 int (*compare)(const void *t1, const void *t2), 00204 unsigned short duplicates); 00205 }; 00206 00207 00208 #endif
1.5.9