aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/bfc/tlist.h
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/bfc/tlist.h')
-rw-r--r--Src/Wasabi/bfc/tlist.h156
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