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