157 lines
3.1 KiB
C++
157 lines
3.1 KiB
C++
//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
|