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 }