diff options
Diffstat (limited to 'Src/Wasabi/bfc/tlist.h')
-rw-r--r-- | Src/Wasabi/bfc/tlist.h | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/Src/Wasabi/bfc/tlist.h b/Src/Wasabi/bfc/tlist.h new file mode 100644 index 00000000..14e591bf --- /dev/null +++ b/Src/Wasabi/bfc/tlist.h @@ -0,0 +1,156 @@ +//PORTABLE +#ifndef _TLIST_H +#define _TLIST_H + +#include <bfc/common.h> +#include <bfc/wasabi_std.h> +#include <bfc/named.h> + +/* + +A generic std::vector wannabe... + +NOTE: you must only use this with basic types! constructors and destructors +will not be called. + +*/ + +#include <bfc/bfc_assert.h> +#include <bfc/std_mem.h> + +#define TLIST_INCREMENT 32 + +template<class T> +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<n;i++) + if(!MEMCMP(&items[i],&it,sizeof(T))) return i; // CT if (items[i] == it) return i; + return -1; + } + int haveItem(const T &it) const { + return (getItemPos(it) != -1); + } + +private: + int nitems, nslots; + T *items; +}; + + +#endif |