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         innercomparator = comparator;
00088 	::qsort(xseq, xcount, sizeof(WvLink*), &WvVectorBase::wrapcomparator);
00089     }
00090 
00091 public:
00092     class IterBase;
00093     friend class IterBase;
00094 
00096     int count() const
00097     {
00098         return xcount;
00099     }
00100 
00102     bool isempty() const
00103     {
00104         return xcount == 0;
00105     }
00106 
00108     int get_capacity() const
00109     {
00110         return xslots;
00111     }
00112 
00119     void set_capacity(int newslots);
00120 
00122     void compact()
00123     {
00124         set_capacity(xcount);
00125     }
00126 
00127     class IterBase
00128     {
00129     protected:
00130         const WvVectorBase &vec;
00131         int i;
00132         WvLink *link;
00133 
00134         friend class WvVectorBase;
00135 
00136     public:
00140         IterBase(const WvVectorBase &v)
00141             : vec(v), i(-1), link(NULL)
00142         {
00143         }
00144 
00149         void rewind()
00150         {
00151             i = -1;
00152             link = (vec.xcount >= 0) ? vec.xseq[0] : NULL;
00153         }
00154 
00159         void unwind()
00160         {
00161             i = vec.xcount - 1;
00162             link = (i >= 0) ? vec.xseq[i] : NULL;
00163         }
00164 
00174         WvLink *next()
00175         {
00176             if (++i > vec.xcount - 1)
00177                 return NULL;
00178             else
00179             {
00180                 link = vec.xseq[i];
00181                 return link;
00182             }
00183         }
00184 
00191         WvLink *prev()
00192         {
00193             if (--i < 0)
00194                 return NULL;
00195             else
00196                 return vec.xseq[i];
00197         }
00198 
00206         WvLink *cur() const
00207         {
00208             return link;
00209         }
00210 
00224         WvLink *find(const void *data);
00225 
00236         WvLink *find_next(const void *data);
00237     };
00238 };
00239 
00245 template<class T>
00246 class WvVector : public WvVectorBase
00247 {
00248 public:
00250     WvVector()
00251         : WvVectorBase()
00252     {
00253     }
00254 
00259     WvVector(int slots)
00260         : WvVectorBase(slots)
00261     {
00262     }
00263 
00265     ~WvVector()
00266     {
00267         zap();
00268     }
00269 
00271     T *operator[] (int slot)
00272     {
00273         if (slot >= 0 && slot < xcount)
00274             return static_cast<T *>(xseq[slot]->data);
00275         return NULL;
00276     }
00277 
00279     void zap(bool destroy = true)
00280     {
00281         if (xcount > 0)
00282             for (int i = xcount - 1; i >= 0; --i)
00283                 remove(i, destroy);
00284     }
00285 
00287     T *first()
00288     {
00289         return (*this)[0];
00290     }
00291 
00293     T *last()
00294     {
00295         return (*this)[xcount - 1];
00296     }
00297 
00299     void remove(int slot, bool destroy = true)
00300     {
00301         WvLink *l = xseq[slot];
00302         T *obj = ((destroy && l->get_autofree())
00303                   ? static_cast<T*>(l->data)
00304                   : NULL);
00305         if (obj)
00306             WvTraits<T>::release(obj);
00307         delete l;
00308         WvVectorBase::remove(slot);
00309     }
00310 
00312     void remove_last(bool destroy = true)
00313     {
00314         if (xcount)
00315             remove(xcount - 1, destroy);
00316     }
00317 
00319     void insert(int slot, T *elem, bool autofree)
00320     {
00321         WvVectorBase::insert(slot, new WvLink(elem, autofree));
00322     }
00323 
00325     void prepend(T *elem, bool autofree)
00326     {
00327         WvVectorBase::prepend(new WvLink(elem, autofree));
00328     }
00329 
00331     void append(T *elem, bool autofree)
00332     {
00333         WvVectorBase::append(new WvLink(elem, autofree));
00334     }
00335 
00341     typedef int (*comparison_type_fn_t)(const T *, const T *);
00342     void qsort(comparison_type_fn_t comparator)
00343     {
00344         if (xcount < 2)
00345             return;
00346         WvVectorBase::qsort(reinterpret_cast<comparison_type_t>(comparator));
00347     }
00348 
00350     class Iter : public WvVector::IterBase
00351     {
00352     public:
00354         Iter(const WvVector &v) : IterBase(v)
00355         {
00356         }
00357 
00359         T *ptr() const
00360         {
00361             return static_cast<T *>(cur()->data);
00362         }
00363 
00364         WvIterStuff(T);
00365 
00369         bool get_autofree() const
00370         {
00371             return link->get_autofree();
00372         }
00373 
00377         void set_autofree(bool autofree)
00378         {
00379             link->set_autofree(autofree);
00380         }
00381 
00387         void remove(bool destroy = true)
00388         {
00389             WvVector::vec.remove(i, destroy);
00390         }
00391 
00405         void xremove(bool destroy = true)
00406         {
00407             WvVector::vec.remove(i, destroy);
00408             prev();
00409         }
00410     };
00411 };
00412 
00413 #define DeclareWvVector2(_classname_, _type_)  \
00414     typedef class WvVector<_type_> _classname_
00415 
00416 #define DeclareWvVector(_type_) DeclareWvVector2(_type_##Vector, _type_)
00417 
00418 #endif // __WVVECTOR_H

Generated on Wed Jul 12 17:53:22 2006 for WvStreams by  doxygen 1.4.7