wvvector.h

00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  * Provides an auto-resizing array data structure.
00006  */
00007 #ifndef __WVVECTOR_H
00008 #define __WVVECTOR_H
00009 
00010 #include "wvxplc.h"
00011 #include "wvlink.h"
00012 #include "wvtypetraits.h"
00013 #include <string.h>
00014 #include <cstdio>
00015 
00020 class WvVectorBase
00021 {
00022 private:
00023     WvVectorBase(const WvVectorBase &); // hide the copy constructor
00024 
00025 protected:
00026     static const int DEFAULTSIZE = 4;
00029     WvLink **xseq; 
00030     int xcount; 
00031     int xslots; 
00034     WvVectorBase(int slots = DEFAULTSIZE);
00035 
00037     ~WvVectorBase()
00038     {
00039         if (xseq)
00040             free(xseq);
00041     }
00042 
00044     void remove(int slot);
00045 
00047     void insert(int slot, WvLink *elem);
00048 
00050     void prepend(WvLink *elem)
00051     {
00052         insert(0, elem);
00053     }
00054 
00056     void append(WvLink *elem);
00057 
00059     bool get_autofree(int slot)
00060     {
00061         if (slot >= 0 && slot < xcount)
00062             return xseq[slot]->get_autofree();
00063         return false;
00064     }
00065 
00067     void set_autofree(int slot, bool autofree)
00068     {
00069         if (slot >= 0 && slot < xcount)
00070             xseq[slot]->set_autofree(autofree);
00071     }
00072 
00073     // Comparison functions for use later in qsort()
00074     typedef int (*comparison_type_t)(const void *, const void *);
00075 private:
00076     static comparison_type_t innercomparator;
00077 protected:
00078     static int wrapcomparator(const void *_a, const void *_b)
00079     {
00080         WvLink *a = *static_cast<WvLink**>(const_cast<void*>(_a));
00081         WvLink *b = *static_cast<WvLink**>(const_cast<void*>(_b));
00082         return innercomparator(a->data, b->data);
00083     }
00084 
00085     void qsort(comparison_type_t comparator)
00086     {
00087         comparison_type_t old_innercomparator = innercomparator;
00088         innercomparator = comparator;
00089         ::qsort(xseq, xcount, sizeof(WvLink*), &WvVectorBase::wrapcomparator);
00090         innercomparator = old_innercomparator;
00091     }
00092 
00093 public:
00094     class IterBase;
00095     friend class IterBase;
00096 
00098     int count() const
00099     {
00100         return xcount;
00101     }
00102 
00104     bool isempty() const
00105     {
00106         return xcount == 0;
00107     }
00108 
00110     int get_capacity() const
00111     {
00112         return xslots;
00113     }
00114 
00121     void set_capacity(int newslots);
00122 
00124     void compact()
00125     {
00126         set_capacity(xcount);
00127     }
00128 
00129     class IterBase
00130     {
00131     protected:
00132         const WvVectorBase &vec;
00133         int i;
00134         WvLink *link;
00135 
00136         friend class WvVectorBase;
00137 
00138     public:
00142         IterBase(const WvVectorBase &v)
00143             : vec(v), i(-1), link(NULL)
00144         {
00145         }
00146 
00151         void rewind()
00152         {
00153             i = -1;
00154             link = NULL;
00155         }
00156 
00161         void unwind()
00162         {
00163             i = vec.xcount;
00164             link = NULL;
00165         }
00166 
00176         WvLink *next()
00177         {
00178             ++i;
00179             if (i < 0 || i >= vec.xcount)
00180                 return NULL;
00181             else
00182             {
00183                 link = vec.xseq[i];
00184                 return link;
00185             }
00186         }
00187 
00194         WvLink *prev()
00195         {
00196             --i;
00197             if (i < 0 || i >= vec.xcount)
00198                 return NULL;
00199             else
00200             {
00201                 link = vec.xseq[i];
00202                 return link;
00203             }
00204         }
00205 
00213         WvLink *cur() const
00214         {
00215             return link;
00216         }
00217 
00231         WvLink *find(const void *data);
00232 
00243         WvLink *find_next(const void *data);
00244     };
00245 };
00246 
00252 template<class T>
00253 class WvVector : public WvVectorBase
00254 {
00255 public:
00257     WvVector()
00258         : WvVectorBase()
00259     {
00260     }
00261 
00266     WvVector(int slots)
00267         : WvVectorBase(slots)
00268     {
00269     }
00270 
00272     ~WvVector()
00273     {
00274         zap();
00275     }
00276 
00278     T *operator[] (int slot)
00279     {
00280         if (slot >= 0 && slot < xcount)
00281             return static_cast<T *>(xseq[slot]->data);
00282         else
00283             return NULL;
00284     }
00285     const T *operator[] (int slot) const
00286     {
00287         if (slot >= 0 && slot < xcount)
00288             return static_cast<T *>(xseq[slot]->data);
00289         else
00290             return NULL;
00291     }
00292 
00294     T *first()
00295     {
00296         if (xcount > 0)
00297             return (*this)[0];
00298         else
00299             return NULL;
00300     }
00301 
00303     T *last()
00304     {
00305         if (xcount > 0)
00306             return (*this)[xcount - 1];
00307         else
00308             return NULL;
00309     }
00310 
00312     void remove(int slot, bool destroy = true)
00313     {
00314         if (slot < 0 || slot >= xcount)
00315             return;
00316         WvLink *l = xseq[slot];
00317         T *obj = ((destroy && l->get_autofree())
00318                   ? static_cast<T*>(l->data)
00319                   : NULL);
00320         if (obj)
00321             WvTraits<T>::release(obj);
00322         delete l;
00323         WvVectorBase::remove(slot);
00324     }
00325 
00327     void remove_last(bool destroy = true)
00328     {
00329         if (xcount > 0)
00330             remove(xcount - 1, destroy);
00331     }
00332 
00334     void zap(bool destroy = true)
00335     {
00336         while (xcount > 0)
00337             remove_last(destroy);
00338     }
00339 
00341     void insert(int slot, T *elem, bool autofree)
00342     {
00343         WvVectorBase::insert(slot, new WvLink(elem, autofree));
00344     }
00345 
00347     void prepend(T *elem, bool autofree)
00348     {
00349         WvVectorBase::prepend(new WvLink(elem, autofree));
00350     }
00351 
00353     void append(T *elem, bool autofree)
00354     {
00355         WvVectorBase::append(new WvLink(elem, autofree));
00356     }
00357 
00363     typedef int (*comparison_type_fn_t)(const T *, const T *);
00364     void qsort(comparison_type_fn_t comparator)
00365     {
00366         if (xcount < 2)
00367             return;
00368         WvVectorBase::qsort(reinterpret_cast<comparison_type_t>(comparator));
00369     }
00370 
00372     class Iter : public WvVectorBase::IterBase
00373     {
00374     public:
00376         Iter(const WvVector &v) : IterBase(v)
00377         {
00378         }
00379 
00381         T *ptr() const
00382         {
00383             return static_cast<T *>(this->cur()->data);
00384         }
00385 
00386         WvIterStuff(T);
00387 
00391         bool get_autofree() const
00392         {
00393             return this->link->get_autofree();
00394         }
00395 
00399         void set_autofree(bool autofree)
00400         {
00401             this->link->set_autofree(autofree);
00402         }
00403 
00409         void remove(bool destroy = true)
00410         {
00411             WvVector::vec.remove(this->i, destroy);
00412         }
00413 
00427         void xremove(bool destroy = true)
00428         {
00429             WvVector::vec.remove(this->i, destroy);
00430             this->prev();
00431         }
00432     };
00433 };
00434 
00435 #define DeclareWvVector2(_classname_, _type_)  \
00436     typedef class WvVector<_type_> _classname_
00437 
00438 #define DeclareWvVector(_type_) DeclareWvVector2(_type_##Vector, _type_)
00439 
00440 #endif // __WVVECTOR_H

Generated on Thu Jan 24 16:50:57 2008 for WvStreams by  doxygen 1.5.4