00001
00002
00003
00004
00005
00006
00007 #ifndef __PARARR_H__
00008 #define __PARARR_H__
00009
00010 #include <stdlib.h>
00011
00012 #include <magic/mobject.h>
00013 #include <magic/mstring.h>
00014 #include <magic/marchive.h>
00015 #include <magic/mmagisupp.h>
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 BEGIN_NAMESPACE (MagiC);
00030
00032
00033
00034
00035
00036
00037
00038
00040
00052 template <class TYPE>
00053 class Array : public Object {
00054 bool mIsRef;
00055 int mSize;
00056 TYPE** rep;
00057 public:
00058
00059
00066 Array (int siz=0) {
00067 mSize = 0;
00068 rep = NULL;
00069 mIsRef = false;
00070 make (siz);
00071 }
00072
00073 Array (const Array<TYPE>& orig) {
00074 mSize = 0;
00075 rep = NULL;
00076 mIsRef = false;
00077 operator= (orig);
00078 }
00079
00086 void make (int siz) {
00087 if (mSize) {
00088 empty ();
00089 delete rep;
00090 rep=NULL;
00091 mSize=0;
00092 }
00093 if (siz>0) {
00094 mSize = siz;
00095 ASSERTWITH (rep=new TYPE*[mSize], "Out of memory in array memory allocation");
00096 for (int i=0; i<mSize; i++)
00097 rep[i] = NULL;
00098 }
00099 }
00100
00109 void isRef (bool isref) {mIsRef=isref;}
00110
00113 virtual ~Array () {
00114 empty ();
00115 delete rep;
00116 memset (this, 0xcd, sizeof(Array<TYPE>));
00117 }
00118
00122 void empty () {
00123 if (rep)
00124 for (int i=0;i<mSize;i++) {
00125 if (!mIsRef)
00126 delete rep[i];
00127 rep[i] = NULL;
00128 }
00129 }
00130
00136 void add (TYPE* i) {
00137 resize (mSize + 1);
00138 delete rep [mSize - 1];
00139 rep[mSize - 1] = i;
00140 }
00141
00148 void add (const TYPE& i) {
00149 resize (mSize + 1);
00150 delete rep [mSize-1];
00151 if (mIsRef)
00152 rep[mSize-1] = const_cast<TYPE*>(&i);
00153 else
00154 rep[mSize-1] = new TYPE (i);
00155 }
00156
00165 void put (TYPE* i, int loc) {
00166 ASSERTWITH (i!=NULL, "NULL-objekti put");
00167 if (loc<0 || loc>=mSize)
00168 throw out_of_range ((CONSTR)
00169 format("Index put %d out of Array bounds (size %d)", loc, mSize));
00170 if (!mIsRef)
00171 delete rep [loc];
00172 rep [loc] = i;
00173 }
00174
00184 void put (const TYPE& i, int loc) {
00185 if (loc >= mSize)
00186 resize (loc+1);
00187 if (!mIsRef) {
00188 delete rep [loc];
00189 rep[loc] = new TYPE (i);
00190 } else
00191 rep[loc] = const_cast<TYPE*>(&i);
00192 }
00193
00194
00202 void put (TYPE* p) {
00203 for (int i=0; i < mSize; i++)
00204 if (!rep[i]) {
00205 rep [i] = p;
00206 return;
00207 }
00208 add (p);
00209 }
00210
00218 const TYPE& operator[] (int loc) const {
00219 ASSERTWITH (loc < mSize, format("Index %d out of Array bounds (size %d)", loc, mSize));
00220 if (const TYPE* tmp = rep [loc])
00221 return *tmp;
00222 else if (mIsRef)
00223 return *((TYPE*)NULL);
00224 else
00225 return *(rep [loc] = new TYPE ());
00226 }
00227
00235 TYPE& operator[] (int loc) {
00236 ASSERTWITH (loc < mSize, format("Index %d out of Array bounds (size %d)", loc, mSize));
00237 if (TYPE* tmp = rep [loc])
00238 return *tmp;
00239 else if (mIsRef)
00240 return *((TYPE*)NULL);
00241 else
00242 return *(rep [loc] = new TYPE ());
00243 }
00244
00252 const TYPE* getp (int loc) const {
00253 ASSERTWITH (loc < mSize, format("Index %d out of Array bounds (size %d)", loc, mSize));
00254 return rep [loc];
00255 }
00256
00264 TYPE* getp (int loc) {
00265 ASSERTWITH (loc < mSize, format("Index %d out of Array bounds (size %d)", loc, mSize));
00266 return rep [loc];
00267 }
00268
00272 int find (const TYPE& item) const {
00273 for (int i=0; i<mSize; i++)
00274 if (rep[i] == &item)
00275 return i;
00276 return -1;
00277 }
00278
00282 void remove (int loc) {
00283 ASSERTWITH (loc < mSize, format("Index %d out of Array bounds (size %d)", loc, mSize));
00284 delete rep[loc];
00285 rep[loc] = NULL;
00286 }
00287
00288
00293 void removeFill (int loc) {
00294 ASSERTWITH (loc < mSize, format("Index %d out of Array bounds (size %d)", loc, mSize));
00295 delete rep[loc];
00296 for (int i=loc+1; i<mSize; i++)
00297 rep[i-1]=rep[i];
00298 rep[mSize-1] = NULL;
00299 resize (mSize-1);
00300 }
00301
00306 void cut (int loc) {
00307 ASSERTWITH (loc < mSize, format("Index %d out of Array bounds (size %d)", loc, mSize));
00308 rep[loc] = NULL;
00309 }
00310
00314 void resize (int newsize) {
00315
00316 if (newsize < mSize) {
00317 for (int i=newsize; i<mSize; i++)
00318 delete rep [i];
00319 if (newsize==0) {
00320 delete rep;
00321 rep = NULL;
00322 } else
00323 rep = (TYPE**) renew (rep, sizeof (TYPE*)*(newsize));
00324 } else {
00325 if (rep)
00326 rep = (TYPE**) renew (rep, sizeof (TYPE*)*(newsize));
00327 else
00328 rep = (TYPE**) new TYPE* [newsize];
00329 for (int i=mSize; i<newsize; i++)
00330 rep [i] = NULL;
00331 }
00332 mSize = newsize;
00333 }
00334
00337 void operator= (const Array<TYPE>& other) {
00338 empty ();
00339 make (other.mSize);
00340 for (int i=0; i<other.mSize; i++)
00341 if (other.rep[i])
00342 put (*other.rep[i], i);
00343 }
00344
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00374 virtual void check () const {
00375 ASSERT (mSize>=0);
00376 }
00377
00383 void quicksort () {
00384 qsort (rep, mSize, sizeof (TYPE*), compareComparable);
00385 }
00386
00388 int size () const {
00389 return mSize;
00390 }
00391
00395 class iterator {
00396 const Array<TYPE>& arr;
00397 int i;
00398
00399 public:
00400 iterator (const iterator& o) : arr (o.arr) {i=o.i;}
00401 iterator (const Array<TYPE>& ar) : arr (ar) {i=0;}
00402
00403 void first () {i=0;}
00404 void next () {i++;}
00405 int exhausted () const {return i>=arr.size();}
00406 TYPE& getvaluev () {return const_cast<TYPE&>(arr[i]);}
00407 const TYPE& getvalue () const {return const_cast<const TYPE&> (arr[i]);}
00408 operator const TYPE& () const {return const_cast<const TYPE&> (arr[i]);}
00409 };
00410
00411 iterator start () const {
00412 return iterator (*this);
00413 }
00414 };
00415
00422 template <class TYPE>
00423 Array<TYPE>* clone (const Array<TYPE>& orig) {
00424 Array<TYPE>* res = new Array<TYPE> (orig.size);
00425 for (int i=0; i<orig.size; i++)
00426 put ((TYPE*)orig[i].clone(), i);
00427 }
00428
00435 template <class TYPE>
00436 void copyClone (Array<TYPE>& trg, const Array<TYPE>& orig) {
00437 trg.empty ();
00438 trg.make (orig.size());
00439 for (int i=0; i<orig.size(); i++)
00440 if (orig.getp(i))
00441 trg.put ((TYPE*)orig.getp(i)->clone(), i);
00442 }
00443
00444
00445 #define foreach_Array(valuetype,arrayname,varname) \
00446 for (ArrayIter<keytype,valuetype> varname (arrayname); \
00447 !varname.exhausted(); varname.next())
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 END_NAMESPACE;
00459
00460 #endif
00461