//PORTABLE #ifndef _TLIST_H #define _TLIST_H #include #include #include /* A generic std::vector wannabe... NOTE: you must only use this with basic types! constructors and destructors will not be called. */ #include #include #define TLIST_INCREMENT 32 template class TList { public: TList() { nitems = 0; nslots = 0; items = NULL; } virtual ~TList() { FREE(items); } int getNumItems() const { return nitems; }; // CAN'T PROVIDE BOUNDS CHECKING!!! (except by ASSERT() :( ) T enumItem(int n) const { ASSERT(items != NULL); ASSERT(n >= 0 && n < nitems); return items[n]; } T operator[](int n) const { return enumItem(n); } T getFirst() const { return enumItem(0); } T getLast() const { return enumItem(getNumItems()-1); } T *enumRef(int n) const { ASSERT(items != NULL); ASSERT(n >= 0 && n < nitems); return items+n; } T *addItem(const T &item) { ASSERT(nitems <= nslots); if (items == NULL) { nslots = TLIST_INCREMENT; items = (T *)MALLOC(sizeof(T) * nslots); nitems = 0; } else if (nslots == nitems) { // time to expand T *newitems; nslots += TLIST_INCREMENT; newitems = (T *)MALLOC(sizeof(T) * nslots); MEMCPY(newitems, items, nitems * sizeof(T)); FREE(items); items = newitems; } items[nitems++] = item; return &items[nitems-1]; } T *insertItem(const T &item, int pos) { // position to insert ASSERT(pos >= 0 && pos <= nitems); T *tmp=addItem(item); int n=nitems-1; while (n > pos) { items[n]=items[n-1]; n--; } tmp=items+pos; *tmp=item; return tmp; } T *replaceItemByPos(const T &item, int pos) { ASSERT(items != NULL); ASSERT(nitems != 0); ASSERT(pos >= 0 && pos < nitems); items[pos]=item; return &items[pos]; } void setItem(int pos, const T &newval) { if (pos < 0) return; if (pos >= nitems) return; items[pos] = newval; } int delItem(const T &item) { int c = 0; ASSERT(items != NULL); ASSERT(nitems != 0); T *src = items; T *dst = items; for (int i = 0; i < nitems; i++) { if (*src != item) { *dst++ = *src; c++; } src++; } nitems -= c; return c; } int delByPos(int pos) { if (pos < 0 || pos >= nitems) return 0; --nitems; if (pos == nitems) return 1; // last one? nothing to copy over MEMCPY(items+pos, items+(pos+1), sizeof(T)*(nitems-pos)); // CT:not (nitems-(pos+1)) as nitems has been decremented earlier return 1; } void removeAll() { FREE(items); items = NULL; nitems = 0; nslots = 0; } void freeAll() { for (int i = 0; i < nitems; i++) FREE(items[i]); removeAll(); } int getItemPos(const T &it) const { int n = getNumItems(); for (int i=0;i