diff options
Diffstat (limited to 'Src/nu/Vectors.h')
-rw-r--r-- | Src/nu/Vectors.h | 221 |
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> ©) + { + 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> ©) + { + 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 |