Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

mpararr.h

Go to the documentation of this file.
00001 
00002 /***************************************************************************
00003     copyright            : (C) 1999 by Marko Grönroos, All Rights Reserved
00004     email                : magi@iki.fi
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 // External:
00018 
00019 //FormatOStream& operator<< (FormatOStream& dc, int i) {;}
00020 
00021 /*
00022 #ifdef new
00023 #undef new
00024 #define new_UNDEFD
00025 #define renew realloc
00026 #endif
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     // Lisää objektin johonkin paikkaan vektoria, muutoin loppuun
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     // Poista objekti ja täytä aukko
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         /* Muuttaa taulukon kokoa, old[lower] = new[lower] */
00316         if (newsize < mSize) { /* Pienennetään */
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 { /* Suurennetaan */
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     /* Currently not in use before I get new stream classes done.
00348     CArchive&   operator>>  (CArchive& arc) const {
00349         arc.name("lower") << lower;
00350         arc.name("size") << size;
00351         for (int i=0; i<size; i++)
00352             arc << ((Object&) (*this)[i]);
00353         return arc;
00354     }
00355     */
00356 
00359     /* Currently not in use before I get new stream classes done.
00360     IStream&    operator<<  (IStream& arc) {
00361         int nlower, nsize;
00362         arc >> nlower;
00363         arc >> nsize;
00364         resize (nlower, nlower+nsize-1);
00365         for (int i=0; i<size; i++) {
00366             arc >> ((Object&) (*this)[i]);
00367         }
00368         return arc;
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 #ifdef new_UNDEFD
00452 #define new DEBUG_NEW
00453 #undef renew
00454 #undef new_UNDEFD
00455 #endif
00456 */
00457 
00458 END_NAMESPACE;
00459 
00460 #endif
00461 

Generated on Thu Feb 10 20:06:42 2005 for LibMagiC by doxygen1.2.18