00001
00002
00003
00004
00005
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 &);
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
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