00001
00002
00003
00004
00005
00006 #ifndef __PARARR_H__
00007 #define __PARARR_H__
00008
00009 #include <stdlib.h>
00010
00011 #include <magic/mobject.h>
00012 #include <magic/mstring.h>
00013 #include <magic/marchive.h>
00014 #include <magic/mmagisupp.h>
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032
00033
00034
00035
00036
00037
00039
00051 template <class TYPE>
00052 class Array : public Object {
00053 bool mIsRef;
00054 TYPE** rep;
00055 public:
00056
00058 int size;
00059
00066 Array (int siz=0) {
00067 size = 0;
00068 rep = NULL;
00069 make (siz);
00070 mIsRef = false;
00071 }
00072
00079 void make (int siz) {
00080 if (size) {
00081 empty ();
00082 delete rep;
00083 rep=NULL;
00084 size=0;
00085 }
00086 if (siz>0) {
00087 size = siz;
00088 ASSERTWITH (rep=new TYPE*[size], "Out of memory in array memory allocation");
00089 for (int i=0; i<size; i++)
00090 rep[i] = NULL;
00091 }
00092 }
00093
00102 void isRef (bool isref) {mIsRef=isref;}
00103
00106 virtual ~Array () {
00107 empty ();
00108 delete rep;
00109 memset (this, 0xcd, sizeof(Array<TYPE>));
00110 }
00111
00115 void empty () {
00116 if (rep)
00117 for (int i=0;i<size;i++) {
00118 if (!mIsRef)
00119 delete rep[i];
00120 rep[i] = NULL;
00121 }
00122 }
00123
00129 void add (TYPE* i) {
00130 resize (size+1);
00131 delete rep [size-1];
00132 rep[size-1] = i;
00133 }
00134
00141 void add (const TYPE& i) {
00142 resize (size+1);
00143 delete rep [size-1];
00144 if (mIsRef)
00145 rep[size-1] = const_cast<TYPE*>(&i);
00146 else
00147 rep[size-1] = new TYPE (i);
00148 }
00149
00158 void put (TYPE* i, int loc) {
00159 ASSERTWITH (i!=NULL, "NULL-objekti put");
00160 if (loc<0 || loc>=size)
00161 throw out_of_range ((CONSTR)
00162 format("Index put %d out of Array bounds (size %d)", loc, size));
00163 if (!mIsRef)
00164 delete rep [loc];
00165 rep [loc] = i;
00166 }
00167
00177 void put (const TYPE& i, int loc) {
00178 if (loc>=size)
00179 resize (loc+1);
00180 if (!mIsRef) {
00181 delete rep [loc];
00182 rep[loc] = new TYPE (i);
00183 } else
00184 rep[loc] = const_cast<TYPE*>(&i);
00185 }
00186
00187
00195 void put (TYPE* p) {
00196 for (int i=0; i<size; i++)
00197 if (!rep[i]) {
00198 rep [i] = p;
00199 return;
00200 }
00201 add (p);
00202 }
00203
00211 const TYPE& operator[] (int loc) const {
00212 ASSERTWITH (loc<size, format("Index %d out of Array bounds (size %d)", loc, size));
00213 if (const TYPE* tmp = rep [loc])
00214 return *tmp;
00215 else if (mIsRef)
00216 return *((TYPE*)NULL);
00217 else
00218 return *(rep [loc] = new TYPE ());
00219 }
00220
00228 TYPE& operator[] (int loc) {
00229 ASSERTWITH (loc<size, format("Index %d out of Array bounds (size %d)", loc, size));
00230 if (TYPE* tmp = rep [loc])
00231 return *tmp;
00232 else if (mIsRef)
00233 return *((TYPE*)NULL);
00234 else
00235 return *(rep [loc] = new TYPE ());
00236 }
00237
00245 const TYPE* getp (int loc) const {
00246 ASSERTWITH (loc<size, format("Index %d out of Array bounds (size %d)", loc, size));
00247 return rep [loc];
00248 }
00249
00257 TYPE* getp (int loc) {
00258 ASSERTWITH (loc<size, format("Index %d out of Array bounds (size %d)", loc, size));
00259 return rep [loc];
00260 }
00261
00265 int find (const TYPE& item) const {
00266 for (int i=0; i<size; i++)
00267 if (rep[i] == &item)
00268 return i;
00269 return -1;
00270 }
00271
00275 void remove (int loc) {
00276 ASSERTWITH (loc<size, format("Index %d out of Array bounds (size %d)", loc, size));
00277 delete rep[loc];
00278 rep[loc] = NULL;
00279 }
00280
00281
00286 void removeFill (int loc) {
00287 ASSERTWITH (loc<size, format("Index %d out of Array bounds (size %d)", loc, size));
00288 delete rep[loc];
00289 for (int i=loc+1; i<size; i++)
00290 rep[i-1]=rep[i];
00291 rep[size-1] = NULL;
00292 resize (size-1);
00293 }
00294
00299 void cut (int loc) {
00300 ASSERTWITH (loc<size, format("Index %d out of Array bounds (size %d)", loc, size));
00301 rep[loc] = NULL;
00302 }
00303
00307 void resize (int newsize) {
00308
00309 if (newsize < size) {
00310 for (int i=newsize; i<size; i++)
00311 delete rep [i];
00312 if (newsize==0) {
00313 delete rep;
00314 rep = NULL;
00315 } else
00316 rep = (TYPE**) renew (rep, sizeof (TYPE*)*(newsize));
00317 } else {
00318 if (rep)
00319 rep = (TYPE**) renew (rep, sizeof (TYPE*)*(newsize));
00320 else
00321 rep = (TYPE**) new TYPE* [newsize];
00322 for (int i=size; i<newsize; i++)
00323 rep [i] = NULL;
00324 }
00325 size = newsize;
00326 }
00327
00330 void operator= (const Array<TYPE>& other) {
00331 empty ();
00332 make (other.size);
00333 for (int i=0; i<other.size; i++)
00334 if (other.rep[i])
00335 put (*other.rep[i], i);
00336 }
00337
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00367 virtual void check () const {
00368 ASSERT (size>=0);
00369 }
00370
00376 void quicksort () {
00377 qsort (rep, size, sizeof (TYPE*), compareComparable);
00378 }
00379
00380
00384 class iterator {
00385 const Array<TYPE>& arr;
00386 int i;
00387
00388 public:
00389 iterator (const iterator& o) : arr (o.arr) {i=o.i;}
00390 iterator (const Array<TYPE>& ar) : arr (ar) {i=0;}
00391
00392 void first () {i=0;}
00393 void next () {i++;}
00394 int exhausted () const {return i>=arr.size;}
00395 TYPE& getvaluev () {return const_cast<TYPE&>(arr[i]);}
00396 const TYPE& getvalue () const {return const_cast<const TYPE&> (arr[i]);}
00397 operator const TYPE& () const {return const_cast<const TYPE&> (arr[i]);}
00398 };
00399
00400 iterator start () const {
00401 return iterator (*this);
00402 }
00403 };
00404
00411 template <class TYPE>
00412 Array<TYPE>* clone (const Array<TYPE>& orig) {
00413 Array<TYPE>* res = new Array<TYPE> (orig.size);
00414 for (int i=0; i<orig.size; i++)
00415 put ((TYPE*)orig[i].clone(), i);
00416 }
00417
00424 template <class TYPE>
00425 void copyClone (Array<TYPE>& trg, const Array<TYPE>& orig) {
00426 trg.empty ();
00427 trg.make (orig.size);
00428 for (int i=0; i<orig.size; i++)
00429 if (orig.getp(i))
00430 trg.put ((TYPE*)orig.getp(i)->clone(), i);
00431 }
00432
00433
00434 #define foreach_Array(valuetype,arrayname,varname) \
00435 for (ArrayIter<keytype,valuetype> varname (arrayname); \
00436 !varname.exhausted(); varname.next())
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 #endif