00001 /*
00002 File: NArray.h
00003
00004 Function: Defines an array type that manages its own storage space,
00005 and can be used as a stack or a list.
00006 This is the sister of the array class -- it, so
00007 it doesn't have to be instantiated for every new
00008 data type, at the cost of an extra word of storage.
00009
00010 Array<> should be used just for standard data types
00011 (char, int, float, double) and NArray for everything else.
00012
00013
00014 Author(s): Andrew Willmott
00015
00016 Copyright: (c) 1995-2000, Andrew Willmott
00017 */
00018
00019 #ifndef __NArray__
00020 #define __NArray__
00021
00022 #include <iostream.h>
00023 #include "cl/Basics.h"
00024 #include <stdio.h>
00025
00026 const Int kFirstNAllocation = 16;
00027
00028
00029
00030 class NBaseArray
00031 {
00032 public:
00033 inline NBaseArray(UInt32 eltSize);
00034 NBaseArray(UInt32 eltSize, Int size, Int alloc = kFirstNAllocation);
00035 NBaseArray(const NBaseArray &array);
00036 ~NBaseArray();
00037
00038 // NBaseArray operators
00039
00040 inline Int NumItems() const;
00041
00042 NBaseArray &operator = (const NBaseArray &array);
00043
00044 // Useful for stack implementations
00045
00046 inline Void Pop();
00047
00048 // List Operations
00049
00050 Void Clear();
00051
00052 Void PreAllocate(UInt32 numItems);
00053 Void SetSize(Int newSize);
00054 Void Add(Int n = 1);
00055 Void Shrink(Int n = 1);
00056 Void Insert(Int i, Int n = 1);
00057 Void Delete(Int i, Int n = 1);
00058 Void ShrinkWrap();
00061 Void Append(const NBaseArray &a);
00062 Void SwapWith(NBaseArray &a);
00063 Void Replace(NBaseArray &a);
00066 Void MemMap(const Char* filename);
00067 Void WriteFile(const Char *filename);
00068 Void ReadFile(const Char *filename);
00069
00070 Int FWrite(FILE *file);
00071 Int FRead(FILE *file);
00072
00073 Void Attach(Void *ptr, Int numItems, Bool shared = false);
00074
00075 UInt32 EltSize()
00076 { return(eltSize); };
00077
00078 protected:
00079 Byte *item;
00080 UInt32 items;
00081 UInt32 allocated;
00082 UInt32 eltSize;
00083
00084 Void Grow();
00085 };
00086
00087
00088
00089 #define TMPLArray template<class T>
00090 #define TNArray NArray<T>
00091
00092 TMPLArray class NArray : public NBaseArray
00099 {
00100 public:
00101 NArray() : NBaseArray(sizeof(T)) {};
00102 NArray(Int size, Int alloc = kFirstNAllocation) :
00103 NBaseArray(sizeof(T), size, alloc) {};
00104
00105 inline T &operator [] (Int i);
00106 inline const T &operator [] (Int i) const;
00107
00108 inline Void Append(const T &t);
00109 inline T &Last();
00110
00111 inline T &Top();
00112 inline Void Push(const T &t);
00113
00114 const T &Item(Int i) const
00115 { return(SELF[i]); };
00116 T &Item(Int i)
00117 { return(SELF[i]); };
00118
00119 Void ClearTo(const T &t);
00120 Void Append(const TNArray &a)
00121 { ((NBaseArray*) this)->Append(a); };
00122 // C++: can't live with it, pass the beer nuts.
00123
00124 // Low level access
00125
00126 inline T *Ref() const;
00127 inline T *Detach();
00129 };
00130
00131 TMPLArray ostream &operator << (ostream &s, TNArray &array);
00132 TMPLArray istream &operator >> (istream &s, TNArray &array);
00133
00134
00135 // --- Inlines ----------------------------------------------------------------
00136
00137
00138 inline NBaseArray::NBaseArray(UInt32 es)
00139 : items(0), item(0), allocated(0), eltSize(es)
00140 {
00141 }
00142
00143 inline Int NBaseArray::NumItems() const
00144 {
00145 return(items);
00146 }
00147
00148 inline Void NBaseArray::Pop()
00149 {
00150 items--;
00151 }
00152
00153 inline Void NBaseArray::Clear()
00154 {
00155 items = 0;
00156 allocated = 0;
00157 delete[] item;
00158 item = 0;
00159 }
00160
00161 TMPLArray inline T &TNArray::operator [] (Int i)
00162 {
00163 CheckRange(i, 0, items, "(NArray::[]) index out of range");
00164
00165 return(*((T*) (item + i * eltSize)));
00166 }
00167
00168 TMPLArray inline const T &TNArray::operator [] (Int i) const
00169 {
00170 CheckRange(i, 0, items, "(NArray::[]) index out of range");
00171
00172 return(*((T*) (item + i * eltSize)));
00173 }
00174
00175 TMPLArray inline T &TNArray::Top()
00176 {
00177 return(*(((T*) item) + (items - 1)));
00178 }
00179
00180 TMPLArray inline T &TNArray::Last()
00181 {
00182 return(*(((T*) item) + (items - 1)));
00183 }
00184
00185 TMPLArray inline Void TNArray::Push(const T &t)
00186 {
00187 if (items >= allocated)
00188 Grow();
00189
00190 *(((T*) item) + items++) = t;
00191 }
00192
00193 TMPLArray inline Void TNArray::ClearTo(const T &t)
00194 {
00195 for (Int i = 0; i < items; i++)
00196 *(((T*) item) + i) = t;
00197 }
00198
00199 TMPLArray inline Void TNArray::Append(const T &t)
00200 {
00201 if (items >= allocated)
00202 Grow();
00203
00204 *(((T*) item) + items++) = t;
00205 }
00206
00207 TMPLArray inline T *TNArray::Ref() const
00208 {
00209 return((T*) item);
00210 }
00211
00212 TMPLArray inline T *TNArray::Detach()
00213 {
00214 T* result = (T*) item;
00215
00216 items = 0;
00217 allocated = 0;
00218 item = 0;
00219
00220 return(result);
00221 }
00222
00223 // --- I/O --------------------------------------------------------------------
00224
00225 // XXX convert these to generic NBaseArray routine with the stream
00226 // function handed in
00227
00228 TMPLArray ostream &operator << (ostream &s, TNArray &array)
00229 {
00230 Int i;
00231 Char sepChar;
00232
00233 s << '[';
00234 if (array.NumItems() >= 16)
00235 sepChar = '\n';
00236 else
00237 sepChar = ' ';
00238
00239 if (array.NumItems() > 0)
00240 {
00241 s << array[0];
00242
00243 for (i = 1; i < array.NumItems(); i++)
00244 s << sepChar << array[i];
00245 }
00246
00247 s << ']';
00248
00249 return(s);
00250 }
00251
00252 TMPLArray istream &operator >> (istream &s, TNArray &array)
00253 {
00254 Char c;
00255
00256 // Expected format: [a b c d ...]
00257
00258 while (isspace(s.peek())) // chomp white space
00259 s.get(c);
00260
00261 if (s.peek() == '[')
00262 {
00263 s.get(c);
00264 array.Clear();
00265
00266 while (isspace(s.peek())) // chomp white space
00267 s.get(c);
00268
00269 while (s.peek() != ']')
00270 {
00271 array.Add(1);
00272 s >> array.Top(); // read an item
00273
00274 if (!s)
00275 {
00276 _Warning("Couldn't read array component");
00277 return(s);
00278 }
00279
00280 while (isspace(s.peek())) // chomp white space
00281 s.get(c);
00282 }
00283 s.get(c);
00284 }
00285 else
00286 {
00287 s.clear(ios::failbit);
00288 _Warning("Error: Expected '[' while reading array");
00289 return(s);
00290 }
00291
00292 return(s);
00293 }
00294
00295
00296 #endif