aboutsummaryrefslogtreecommitdiff
path: root/Src/nu/Vectors.h
diff options
context:
space:
mode:
Diffstat (limited to 'Src/nu/Vectors.h')
-rw-r--r--Src/nu/Vectors.h221
1 files changed, 221 insertions, 0 deletions
diff --git a/Src/nu/Vectors.h b/Src/nu/Vectors.h
new file mode 100644
index 00000000..16a19e0e
--- /dev/null
+++ b/Src/nu/Vectors.h
@@ -0,0 +1,221 @@
+#ifndef NULLSOFT_VECTOR_H
+#define NULLSOFT_VECTOR_H
+#include <assert.h>
+#include <bfc/platform/types.h>
+
+template <class Type, int INCREMENT = 32, int MULTIPLIER=1>
+class Vector
+{
+public:
+ typedef Type *iterator;
+ typedef const Type *const_iterator;
+public:
+ Vector() {}
+ virtual ~Vector()
+ {
+ delete [] values;
+ }
+
+ Vector(const Vector<Type, INCREMENT, MULTIPLIER> &copy)
+ {
+ if (copy.numPtrs)
+ {
+ values = new Type[copy.numPtrs];
+ allocSize = copy.numPtrs;
+ numPtrs = copy.numPtrs;
+ for (size_t i = 0;i != numPtrs;i++)
+ {
+ values[i] = copy.values[i];
+ }
+ }
+ }
+
+ void operator=(const Vector<Type, INCREMENT, MULTIPLIER> &copy)
+ {
+ Reset();
+ if (copy.numPtrs)
+ {
+ values = new Type[copy.numPtrs];
+ allocSize = copy.numPtrs;
+ numPtrs = copy.numPtrs;
+ for (size_t i = 0;i != numPtrs;i++)
+ {
+ values[i] = copy.values[i];
+ }
+ }
+ }
+
+ Type &operator[](size_t index)
+ {
+ return values[index];
+ }
+ Type *data()
+ {
+ return values;
+ }
+ Type *begin() const
+ {
+ return values;
+ }
+ Type *end() const
+ {
+ if (values) return values + numPtrs; else return 0;
+ }
+ void Reset()
+ {
+ delete [] values; values = 0; numPtrs = 0; allocSize=0;
+ }
+ void clear()
+ {
+ numPtrs = 0;
+ }
+ size_t size() const
+ {
+ return numPtrs;
+ }
+ size_t capacity()
+ {
+ return allocSize;
+ }
+ Type &back()
+ {
+ return values[numPtrs-1];
+ }
+
+ Type &at(size_t index) const
+ {
+ return values[index];
+ }
+
+ void reserve(size_t size)
+ {
+ if (size <= numPtrs)
+ return;
+
+ Type *newTable = new Type[size];
+ for (size_t i = 0;i != numPtrs;i++)
+ {
+ newTable[i] = values[i];
+ }
+ allocSize = size;
+ delete[] values;
+ values = newTable;
+ }
+
+ void push_back(Type t)
+ {
+ if (numPtrs == allocSize)
+ reserve(allocSize*MULTIPLIER + INCREMENT);
+ values[numPtrs++] = t;
+ }
+
+ void insert(size_t index, const Type &value)
+ {
+ if (numPtrs == allocSize)
+ reserve(allocSize*MULTIPLIER + INCREMENT);
+
+ for (size_t i = numPtrs;i != index;i--)
+ {
+ values[i] = values[i-1];
+ }
+ values[index] = value;
+ numPtrs++;
+ }
+
+ void append(size_t size, Type *t)
+ {
+ reserve(numPtrs + size + INCREMENT);
+ for (size_t i = 0;i != size;i++)
+ {
+ push_back(t[i]);
+ }
+ }
+
+ void pop_back()
+ {
+ if (numPtrs)
+ {
+ numPtrs--;
+ // next line removed to allow structs and classes
+ // values[numPtrs] = 0; // TODO: an inplace delete might be better?
+ }
+ }
+
+ void erase(iterator itr)
+ {
+ size_t index = itr - values;
+ eraseAt(index);
+ }
+
+ void eraseAt(size_t index)
+ {
+ if (numPtrs > index)
+ {
+ for (size_t k = index + 1; k < numPtrs; k++)
+ values[k-1] = values[k];
+
+ --numPtrs;
+ }
+ }
+
+ /* Removes an item by swapping it with the last item in the list. faster but can ruin order */
+ void eraseAtFast(size_t index)
+ {
+ if (index < numPtrs)
+ {
+ values[index] = values[--numPtrs];
+// if (numPtrs != index)
+// values[numPtrs]=0;
+ }
+ }
+
+ bool empty() const
+ {
+ return numPtrs == 0;
+ }
+
+ void resize(size_t newSize, Type val)
+ {
+ if (newSize < numPtrs)
+ {
+ numPtrs = newSize;
+ }
+ else if (newSize > numPtrs)
+ {
+ reserve(allocSize + (newSize - numPtrs) + INCREMENT);
+
+ while(numPtrs < newSize)
+ {
+ values[numPtrs] = val;
+ numPtrs++;
+ }
+ }
+ }
+
+ void resize(size_t newSize)
+ {
+ if (newSize < numPtrs)
+ {
+ numPtrs = newSize;
+ }
+ else if (newSize > numPtrs)
+ {
+ reserve(allocSize + (newSize - numPtrs) + INCREMENT);
+ numPtrs = newSize;
+ }
+ }
+
+ void set(Type *ptr, size_t num)
+ {
+ delete [] values;
+ values=ptr;
+ numPtrs=num;
+ }
+
+private:
+ size_t numPtrs = 0;
+ size_t allocSize = 0;
+ Type *values = 0;
+};
+
+#endif