aboutsummaryrefslogtreecommitdiffstats
path: root/src/gpu/GrTDArray.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/GrTDArray.h')
-rw-r--r--src/gpu/GrTDArray.h216
1 files changed, 216 insertions, 0 deletions
diff --git a/src/gpu/GrTDArray.h b/src/gpu/GrTDArray.h
new file mode 100644
index 0000000..731001a
--- /dev/null
+++ b/src/gpu/GrTDArray.h
@@ -0,0 +1,216 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef GrTDArray_DEFINED
+#define GrTDArray_DEFINED
+
+#include "GrTypes.h"
+#include "GrRefCnt.h"
+
+static int GrInitialArrayAllocationCount() {
+ return 4;
+}
+
+static int GrNextArrayAllocationCount(int count) {
+ return count + ((count + 1) >> 1);
+}
+
+template <typename T> class GrTDArray {
+public:
+ GrTDArray() : fArray(NULL), fAllocated(0), fCount(0) {}
+ GrTDArray(const GrTDArray& src) {
+ fCount = fAllocated = src.fCount;
+ fArray = (T*)GrMalloc(fAllocated * sizeof(T));
+ memcpy(fArray, src.fArray, fCount * sizeof(T));
+ }
+ ~GrTDArray() {
+ if (fArray) {
+ GrFree(fArray);
+ }
+ }
+
+ bool isEmpty() const { return 0 == fCount; }
+ int count() const { return fCount; }
+
+ const T& at(int index) const {
+ GrAssert((unsigned)index < (unsigned)fCount);
+ return fArray[index];
+ }
+ T& at(int index) {
+ GrAssert((unsigned)index < (unsigned)fCount);
+ return fArray[index];
+ }
+
+ const T& operator[](int index) const { return this->at(index); }
+ T& operator[](int index) { return this->at(index); }
+
+ GrTDArray& operator=(const GrTDArray& src) {
+ if (fAllocated < src.fCount) {
+ fAllocated = src.fCount;
+ GrFree(fArray);
+ fArray = (T*)GrMalloc(fAllocated * sizeof(T));
+ }
+ fCount = src.fCount;
+ memcpy(fArray, src.fArray, fCount * sizeof(T));
+ return *this;
+ }
+
+ void reset() {
+ if (fArray) {
+ GrFree(fArray);
+ fArray = NULL;
+ }
+ fAllocated = fCount = 0;
+ }
+
+ T* begin() const { return fArray; }
+ T* end() const { return fArray + fCount; }
+ T* back() const { GrAssert(fCount); return fArray + (fCount - 1); }
+
+ T* prepend() {
+ this->growAt(0);
+ return fArray;
+ }
+
+ T* append() {
+ this->growAt(fCount);
+ return fArray + fCount - 1;
+ }
+
+ /**
+ * index may be [0..count], so that you can insert at the end (like append)
+ */
+ T* insert(int index) {
+ GrAssert((unsigned)index <= (unsigned)fCount);
+ this->growAt(index);
+ return fArray + index;
+ }
+
+ void remove(int index) {
+ GrAssert((unsigned)index < (unsigned)fCount);
+ fCount -= 1;
+ if (index < fCount) {
+ int remaining = fCount - index;
+ memmove(fArray + index, fArray + index + 1, remaining * sizeof(T));
+ }
+ }
+
+ void removeShuffle(int index) {
+ GrAssert((unsigned)index < (unsigned)fCount);
+ fCount -= 1;
+ if (index < fCount) {
+ memmove(fArray + index, fArray + fCount, sizeof(T));
+ }
+ }
+
+ // Utility iterators
+
+ /**
+ * Calls GrFree() on each element. Assumes each is NULL or was allocated
+ * with GrMalloc().
+ */
+ void freeAll() {
+ T* stop = this->end();
+ for (T* curr = this->begin(); curr < stop; curr++) {
+ GrFree(*curr);
+ }
+ this->reset();
+ }
+
+ /**
+ * Calls delete on each element. Assumes each is NULL or was allocated
+ * with new.
+ */
+ void deleteAll() {
+ T* stop = this->end();
+ for (T* curr = this->begin(); curr < stop; curr++) {
+ delete *curr;
+ }
+ this->reset();
+ }
+
+ /**
+ * Calls GrSafeUnref() on each element. Assumes each is NULL or is a
+ * subclass of GrRefCnt.
+ */
+ void unrefAll() {
+ T* stop = this->end();
+ for (T* curr = this->begin(); curr < stop; curr++) {
+ GrSafeUnref(*curr);
+ }
+ this->reset();
+ }
+
+ void visit(void visitor(T&)) const {
+ T* stop = this->end();
+ for (T* curr = this->begin(); curr < stop; curr++) {
+ if (*curr) {
+ visitor(*curr);
+ }
+ }
+ }
+
+ int find(const T& elem) const {
+ int count = this->count();
+ T* curr = this->begin();
+ for (int i = 0; i < count; i++) {
+ if (elem == curr[i]) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ friend bool operator==(const GrTDArray<T>& a, const GrTDArray<T>& b) {
+ return a.count() == b.count() &&
+ (0 == a.count() ||
+ 0 == memcmp(a.begin(), b.begin(), a.count() * sizeof(T)));
+ }
+ friend bool operator!=(const GrTDArray<T>& a, const GrTDArray<T>& b) {
+ return !(a == b);
+ }
+
+private:
+ T* fArray;
+ int fAllocated, fCount;
+
+ // growAt will increment fCount, reallocate fArray (as needed), and slide
+ // the contents of fArray to make a hole for new data at index.
+ void growAt(int index) {
+ GrAssert(fCount <= fAllocated);
+ if (0 == fAllocated) {
+ fAllocated = GrInitialArrayAllocationCount();
+ fArray = (T*)GrMalloc(fAllocated * sizeof(T));
+ } else if (fCount == fAllocated) {
+ fAllocated = GrNextArrayAllocationCount(fAllocated);
+ T* newArray = (T*)GrMalloc(fAllocated * sizeof(T));
+ memcpy(newArray, fArray, index * sizeof(T));
+ memcpy(newArray + index + 1, fArray + index,
+ (fCount - index) * sizeof(T));
+ GrFree(fArray);
+ fArray = newArray;
+ } else {
+ // check that we're not just appending
+ if (index < fCount) {
+ memmove(fArray + index + 1, fArray + index,
+ (fCount - index) * sizeof(T));
+ }
+ }
+ GrAssert(fCount < fAllocated);
+ fCount += 1;
+ }
+};
+
+extern void* GrTDArray_growAt(void*, int* allocated, int& count, int index,
+ size_t);
+
+
+#endif
+