123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- //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
|