Main Page   Class Hierarchy   Compound List   File List   Compound Members  

mpararr.h

00001 /***************************************************************************
00002     copyright            : (C) 1999 by Marko Grönroos, All Rights Reserved
00003     email                : magi@iki.fi
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 // External:
00017 
00018 //DumpContext& operator<< (DumpContext& dc, int i) {;}
00019 
00020 /*
00021 #ifdef new
00022 #undef new
00023 #define new_UNDEFD
00024 #define renew realloc
00025 #endif
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     // Lisää objektin johonkin paikkaan vektoria, muutoin loppuun
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     // Poista objekti ja täytä aukko
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         /* Muuttaa taulukon kokoa, old[lower] = new[lower] */
00309         if (newsize < size) { /* Pienennetään */
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 { /* Suurennetaan */
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     /* Currently not in use before I get new stream classes done.
00341     CArchive&   operator>>  (CArchive& arc) const {
00342         arc.name("lower") << lower;
00343         arc.name("size") << size;
00344         for (int i=0; i<size; i++)
00345             arc << ((Object&) (*this)[i]);
00346         return arc;
00347     }
00348     */
00349 
00352     /* Currently not in use before I get new stream classes done.
00353     IStream&    operator<<  (IStream& arc) {
00354         int nlower, nsize;
00355         arc >> nlower;
00356         arc >> nsize;
00357         resize (nlower, nlower+nsize-1);
00358         for (int i=0; i<size; i++) {
00359             arc >> ((Object&) (*this)[i]);
00360         }
00361         return arc;
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 #ifdef new_UNDEFD
00441 #define new DEBUG_NEW
00442 #undef renew
00443 #undef new_UNDEFD
00444 #endif
00445 */
00446 
00447 #endif

Generated at Tue Dec 4 19:53:27 2001 for MagiC++ by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001