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 * 00008 * Cristin Barghiel 00009 * Side Effects Software Inc 00010 * 123 Front Street West, Suite 1401 00011 * Toronto, Ontario 00012 * Canada M5J 2M2 00013 * 416-504-9876 00014 * 00015 * NAME: Utility Library (C++) 00016 * 00017 * COMMENTS: 00018 */ 00019 00020 #ifndef __UT_Vector4Array_h__ 00021 #define __UT_Vector4Array_h__ 00022 00023 #include "UT_API.h" 00024 #include <string.h> 00025 #include <malloc.h> 00026 #include <SYS/SYS_Types.h> 00027 #include "UT_Assert.h" 00028 #include "UT_Vector4.h" 00029 00030 class UT_API UT_Vector4Array { 00031 public: 00032 // Trivial constructor and destructor: 00033 explicit UT_Vector4Array(unsigned int sz = 0) 00034 : arrSize(sz), nbrEntries(0) 00035 { 00036 arr = (sz) ? (UT_Vector4*)calloc(sizeof(UT_Vector4),sz) : 0; 00037 } 00038 UT_Vector4Array(unsigned int sz, unsigned int count); 00039 00040 virtual ~UT_Vector4Array(void); 00041 00042 // Copy constructor that uses operator '=' to assign each of a's UT_Vector4 00043 // to this array. 00044 UT_Vector4Array(const UT_Vector4Array &a); 00045 00046 // Append an element to the current entries and return its index in the 00047 // array, or insert the element at a specified position; if necessary, 00048 // insert() grows the array to accommodate the element. The insert 00049 // methods use the assignment operator '=' to place the UT_Vector4 into the 00050 // right spot; be aware that '=' works differently on objects and pointers. 00051 // If UT_Vector4 is an object that uses the default '=' operator, the result of 00052 // insert() will be a shallow copy of t, and not t itself. 00053 // So, if what you really want to do is create a new object inside the 00054 // array, first grow the array to a good size, then create your object as 00055 // follows: 00056 // UT_Vector4Array<GeoPoint> arr(3); 00057 // GeoPoint *p = new (&arr[0]) GeoPoint(....); 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 unsigned int append(void) { return insert(nbrEntries); } 00062 unsigned int append(const UT_Vector4& t); 00063 unsigned int insert(unsigned int index); 00064 unsigned int insert(const UT_Vector4& t, unsigned int index); 00065 00066 // Takes another pointer array and concatenate it onto my end 00067 unsigned int concat(const UT_Vector4Array &a); 00068 00069 // Insert an element "count" times at the given index. Return the index. 00070 unsigned int multipleInsert(unsigned int index, unsigned int count); 00071 00072 // Two more insert() methods that check for duplicates in the array, 00073 // assuming that the array is sorted. t1 and t2 must be pointers to UT_Vector4. 00074 unsigned int append(const UT_Vector4& t, 00075 int (*compare)(const UT_Vector4 *t1, const UT_Vector4 *t2) 00076 ); 00077 unsigned int insert(const UT_Vector4& t, 00078 unsigned int index, 00079 int (*compare)(const UT_Vector4 *t1, const UT_Vector4 *t2) 00080 ); 00081 00082 // An alias for unique element insertion at a certain index. Also used by 00083 // the other insertion methods. 00084 unsigned int insertAt(const UT_Vector4 &t, unsigned int index); 00085 00086 /// Remove one element from the array given the element itself or its 00087 /// position in the list, and fill the gap by shifting the elements down 00088 /// by one position. Both methods return the index if successful, 00089 /// and (int)-1 if the element is not found. The method that takes 00090 /// an index argument does not return a reference to the object for safety 00091 /// purposes: if UT_Vector4 is an object, then when the array is shrunk the 00092 /// memory previously used by UT_Vector4 will be overwritten by the next 00093 /// element. 00094 // @{ 00095 int remove(const UT_Vector4& t); 00096 int remove(unsigned int aindex) 00097 { 00098 return (aindex < nbrEntries) 00099 ? removeAt(aindex) : -1; 00100 } 00101 // @} 00102 00103 /// More remove() methods that search for the object to be removed 00104 /// with a user-defined comparison 00105 /// function. These methods assume the array is sorted. t1 and t2 must be 00106 /// pointers to UT_Vector4. The methods return the last (removed) object 00107 /// index. 00108 int remove(const UT_Vector4& t, 00109 int (*compare)(const UT_Vector4 *t1, 00110 const UT_Vector4 *t2)); 00111 00112 // Move howMany objects starting at index srcIndex to destIndex; 00113 // Method returns 0 if OK, -1 if overflow. 00114 int shift(unsigned int srcIdx, 00115 unsigned int destIdx, 00116 unsigned int howMany); 00117 // Performs a cyclical shift of the entries by howMany 00118 void cycle(int howMany); 00119 00120 // Search for t in one of two ways: linearly using the '==' operator, or 00121 // binary using the function specified in the parameter list respectively. 00122 // find() returns the index of the matching element or (int)-1. 00123 // Parameter s indicates the index to start the search at. 00124 int find(const UT_Vector4 &t, unsigned int s = 0) const; 00125 int find(const UT_Vector4 &t, 00126 int (*compare)(const UT_Vector4 *t1, const UT_Vector4 *t2), 00127 unsigned int s = 0) const; 00128 00129 // Search for 'any' until compare() returns 0 and return the index; 00130 // otherwise return -1. The array is assumed to be sorted. 00131 int find(const void *any, 00132 int (*compare)(const UT_Vector4 *t1, const UT_Vector4 *t2), 00133 unsigned int s = 0) const; 00134 00135 // The fastest search possible, which does pointer arithmetic to find the 00136 // index of the element. WARNING: index() does no out-of-bounds checking. 00137 int index(const UT_Vector4 &t) const { return &t - arr; } 00138 int safeIndex(const UT_Vector4 &t) const 00139 { 00140 return (&t >= arr && (&t - arr < (int)nbrEntries)) ? &t - arr : -1; 00141 } 00142 00143 // Sort the array using a comparison function that you must provide. t1 and 00144 // t2 are pointers to UT_Vector4. 00145 void sort(int (*compare)(const UT_Vector4 *t1, const UT_Vector4 *t2)); 00146 00147 // Resize the array, ie. grow it or shrink it. If copyFlag is 1, the 00148 // function copies the data after reallocating space for the array. 00149 void resize(unsigned int sz, unsigned short copyFlag=1); 00150 void resizeIfNeeded(uint sz, bool copyFlag=true) 00151 { 00152 if (sz > capacity()) 00153 resize(sz, copyFlag); 00154 } 00155 00156 // Query the allocated length of the array or the number of elements 00157 // in the array: capacity() >= entries(). 00158 uint capacity(void) const { return arrSize; } 00159 int64 getMemoryUsage() const { return capacity()*sizeof(UT_Vector4);} 00160 uint entries(void) const { return nbrEntries; } 00161 bool isEmpty(void) const { return nbrEntries==0; } 00162 00163 // Set the number of entries. Normally, you should not have to use it. 00164 void entries(unsigned int ne) { nbrEntries = ne; } 00165 00166 // Assign array a to this array by copying each of a's UT_Vector4 with the 00167 // '=' operator. 00168 UT_Vector4Array &operator=(const UT_Vector4Array &a); 00169 00170 // Compare two array and return 1 if they are equal and 0 otherwise. 00171 // Two UT_Vector4 are checked against each other using operator '==' or 00172 // compare() respectively. Arrays of different size but equal number of 00173 // entries are checked for member-wise equality. 00174 // t1 and t2 must point to UT_Vector4. 00175 int operator==(const UT_Vector4Array &a) const; 00176 int isEqual(const UT_Vector4Array &a, 00177 int (*compare)(const UT_Vector4 *t1, const UT_Vector4 *t2) 00178 ) const; 00179 00180 // Subscript operators. operator() does NOT do any bound checking, while 00181 // the non-const operator[] grows the array to accommodate the given index. 00182 UT_Vector4 &operator()(unsigned int i) 00183 { 00184 UT_ASSERT_P(i < nbrEntries); 00185 return arr[i]; 00186 } 00187 const UT_Vector4 &operator()(unsigned int i) const 00188 { 00189 UT_ASSERT_P(i < nbrEntries); 00190 return arr[i]; 00191 } 00192 UT_Vector4 &operator[](unsigned int i); 00193 const UT_Vector4 &operator[](unsigned int i) const 00194 { 00195 UT_ASSERT_P(i < nbrEntries); 00196 return arr[i]; 00197 } 00198 UT_Vector4 &last() 00199 { 00200 UT_ASSERT_P(nbrEntries); 00201 return arr[nbrEntries-1]; 00202 } 00203 UT_Vector4 last() const 00204 { 00205 return nbrEntries ? arr[nbrEntries-1] 00206 : UT_Vector4(); 00207 } 00208 00209 // Apply a user-defined function to each element of the array 00210 // as int as the function returns zero. If applyFct returns 00211 // 1, apply() stops traversing the list and returns the current 00212 // index; otherwise, apply() returns the number of entries. 00213 unsigned int apply(int (*applyFct)(UT_Vector4 &t, void *d), void *d); 00214 00215 const UT_Vector4 *getRawArray(void) const { return arr; } 00216 UT_Vector4 *array(void) { return arr; } 00217 00218 private: 00219 // Pointer to a list of elements of type UT_Vector4: 00220 UT_Vector4 *arr; 00221 00222 // The number of elements we have allocated space for versus the actual 00223 // number of entries in the array: 00224 unsigned int arrSize; 00225 unsigned int nbrEntries; 00226 00227 // The guts of the remove() methods. 00228 int removeAt(unsigned int index); 00229 }; 00230 00231 #endif
1.5.9