00001 /* 00002 File: Array.cc 00003 00004 Function: Template definitions for Array.h 00005 00006 Author(s): Andrew Willmott 00007 00008 Copyright: (c) 1995-2000, Andrew Willmott 00009 00010 Notes: 00011 00012 */ 00013 00014 #define __ArrayTmpl__ 00015 #include "cl/Array.h" 00016 #include <ctype.h> 00017 00032 TMPLArray TArray::Array(UInt32 size, Int alloc) : items(size), 00033 allocated(alloc) 00034 { 00035 Assert(size > 0, "(Array) Initial array size must be positive!"); 00036 if (allocated < size) 00037 allocated = size; 00038 00039 item = new T[allocated]; 00040 } 00041 00042 TMPLArray TArray::Array(const TArray &array) : items(array.items), 00043 allocated(array.allocated) 00044 { 00045 UInt32 i; 00046 00047 if (!allocated) 00048 allocated = items; 00049 item = new T[allocated]; 00050 00051 for (i = 0; i < array.items; i++) 00052 item[i] = array.item[i]; 00053 } 00054 00055 TMPLArray TArray::~Array() 00056 { 00057 if (allocated) delete[] item; 00058 } 00059 00060 TMPLArray TArray &TArray::operator = (const TArray &array) 00061 { 00062 Int i; 00063 00064 if (allocated < array.items) 00065 { 00066 if (allocated) delete[] item; 00067 allocated = array.items; 00068 item = new T[allocated]; 00069 } 00070 00071 for (i = 0; i < array.items; i++) 00072 item[i] = array.item[i]; 00073 00074 items = array.items; 00075 00076 return(SELF); 00077 } 00078 00079 TMPLArray ostream &operator << (ostream &s, TArray &array) 00080 { 00081 Int i; 00082 Char sepChar; 00083 00084 s << '['; 00085 if (array.NumItems() >= 16) 00086 sepChar = '\n'; 00087 else 00088 sepChar = ' '; 00089 00090 if (array.NumItems() > 0) 00091 { 00092 s << array[0]; 00093 00094 for (i = 1; i < array.NumItems(); i++) 00095 s << sepChar << array[i]; 00096 } 00097 00098 s << ']'; 00099 00100 return(s); 00101 } 00102 00103 TMPLArray istream &operator >> (istream &s, TArray &array) 00104 { 00105 Char c; 00106 00107 // Expected format: [a b c d ...] 00108 00109 while (isspace(s.peek())) // chomp white space 00110 s.get(c); 00111 00112 if (s.peek() == '[') 00113 { 00114 s.get(c); 00115 array.Clear(); 00116 00117 while (isspace(s.peek())) // chomp white space 00118 s.get(c); 00119 00120 while (s.peek() != ']') 00121 { 00122 array.Add(1); 00123 s >> array.Top(); // read an item 00124 00125 if (!s) 00126 { 00127 _Warning("Couldn't read array component"); 00128 return(s); 00129 } 00130 00131 while (isspace(s.peek())) // chomp white space 00132 s.get(c); 00133 } 00134 s.get(c); 00135 } 00136 else 00137 { 00138 s.clear(ios::failbit); 00139 _Warning("Error: Expected '[' while reading array"); 00140 return(s); 00141 } 00142 00143 return(s); 00144 } 00145 00146 TMPLArray Void TArray::PreAllocate(UInt32 newSize) 00147 { 00148 UInt32 i, oldAllocated = allocated; 00149 T *newArray; 00150 00151 if (newSize > allocated) 00152 { 00153 if (allocated == 0) 00154 allocated = kFirstAllocation; 00155 else 00156 allocated *= 2; 00157 00158 while (newSize > allocated) 00159 allocated *= 2; 00160 00161 newArray = new T[allocated]; 00162 00163 for (i = 0; i < items; i++) 00164 newArray[i] = item[i]; 00165 00166 if (oldAllocated) delete[] item; 00167 item = newArray; 00168 } 00169 } 00170 00171 TMPLArray Void TArray::SetSize(Int newSize) 00172 { 00173 PreAllocate(newSize); 00174 items = newSize; 00175 } 00176 00177 TMPLArray Void TArray::Add(Int n) 00178 { 00179 SetSize(items + n); 00180 } 00181 00182 TMPLArray Void TArray::Shrink(Int n) 00183 // take away n items. 00184 { 00185 items -= n; 00186 } 00187 00188 TMPLArray Void TArray::Insert(Int i, Int n) 00189 // Make space at position i for n items. 00190 { 00191 Assert(i >= 0 && i <= items, "(Array:Insert) Illegal index"); 00192 Assert(n > 0, "(Array:Insert) Illegal insert amount"); 00193 00194 Int j; 00195 00196 Add(n); 00197 00198 for (j = items - 1; j >= i + n; j--) 00199 item[j] = (item - n)[j]; 00200 } 00201 00202 TMPLArray Void TArray::Delete(Int i, Int n) 00203 // Delete n items at position i. 00204 { 00205 Assert(i >= 0 && i <= items, "(Array:Insert) Illegal index"); 00206 Assert(n > 0, "(Array:Delete) Illegal insert amount"); 00207 00208 Int j; 00209 00210 items -= n; 00211 00212 for (j = i; j < items; j++) 00213 item[j] = (item + n)[j]; 00214 } 00215 00216 TMPLArray Void TArray::ShrinkWrap() 00217 // Shrink allocated space to be only the current size of array 00218 // There is no realloc version of new in C++, so this involves another copy. 00219 { 00220 Int i, oldAllocated = allocated; 00221 T *newArray; 00222 00223 allocated = items; 00224 00225 newArray = new T[allocated]; 00226 00227 for (i = 0; i < items; i++) 00228 newArray[i] = item[i]; 00229 00230 if (oldAllocated) delete[] item; 00231 item = newArray; 00232 } 00233 00234 TMPLArray Void TArray::Grow() 00235 // Allocate more space for the array. Used internally prior to an items++. 00236 { 00237 UInt32 i, oldAllocated = allocated; 00238 T *newArray; 00239 00240 if (allocated == 0) 00241 allocated = kFirstAllocation; 00242 else 00243 allocated *= 2; 00244 00245 newArray = new T[allocated]; 00246 00247 for (i = 0; i < items; i++) 00248 newArray[i] = item[i]; 00249 00250 if (oldAllocated) delete[] item; 00251 item = newArray; 00252 } 00253 00254 TMPLArray Void TArray::Append(const TArray &a) 00255 { 00256 Int i, j, start, newSize; 00257 00258 newSize = items + a.items; 00259 PreAllocate(newSize); 00260 00261 for (i = items, j = 0; j < a.items; i++, j++) 00262 item[i] = a.item[j]; 00263 00264 items = newSize; 00265 } 00266 00267 TMPLArray Void TArray::SwapWith(TArray &a) 00268 { 00269 Int a1, b1; 00270 00271 Swap(a1, b1); 00272 00273 Swap(items, a.items); 00274 Swap(allocated, a.allocated); 00275 Swap(item, a.item); 00276 } 00277 00278 TMPLArray Void TArray::Replace(TArray &a) 00279 { 00280 if (allocated) delete[] item; 00281 item = a.item; 00282 items = a.items; 00283 allocated = a.allocated; 00284 00285 a.item = 0; 00286 a.items = 0; 00287 a.allocated = 0; 00288 } 00289 00290 TMPLArray Void TArray::WriteFile(const Char *filename) 00291 { 00292 FILE *file; 00293 00294 file = fopen(filename, "wb"); 00295 if (file) 00296 { 00297 fwrite(item, sizeof(T), items, file); 00298 fclose(file); 00299 } 00300 } 00301 00302 TMPLArray Void TArray::ReadFile(const Char *filename) 00303 { 00304 FILE *file = fopen(filename, "rb"); 00305 00306 if (file) 00307 { 00308 Int fsize; 00309 00310 fseek(file, 0, SEEK_END); 00311 fsize = ftell(file); 00312 rewind(file); 00313 items = fsize / sizeof(T); 00314 Assert(items * sizeof(T) == fsize, "(Array::ReadFile) bad file size"); 00315 item = new T[items]; 00316 allocated = items; 00317 fread(item, sizeof(T), items, file); 00318 00319 fclose(file); 00320 } 00321 } 00322 00323 TMPLArray Int TArray::FWrite(FILE *file) 00324 { 00325 fwrite(&items, sizeof(Int), 1, file); 00326 fwrite(item, sizeof(T), items, file); 00327 return(ferror(file)); 00328 } 00329 00330 TMPLArray Int TArray::FRead(FILE *file) 00331 { 00332 if (fread(&items, sizeof(Int), 1, file) != 1) 00333 return(-1); 00334 item = new T[items]; 00335 allocated = items; 00336 return(fread(item, sizeof(T), items, file) != items); 00337 } 00338 00339 TMPLArray Void TArray::Attach(T *itemsPtr, Int numItems, Bool shared) 00340 { 00341 Clear(); 00342 00343 item = itemsPtr; 00344 items = numItems; 00345 00346 if (!shared) 00347 allocated = numItems; 00348 }