Index: include/core/SkTDArray.h |
=================================================================== |
--- include/core/SkTDArray.h (revision 8871) |
+++ include/core/SkTDArray.h (working copy) |
@@ -11,44 +11,24 @@ |
#define SkTDArray_DEFINED |
#include "SkTypes.h" |
+#include "SkTemplates.h" |
template <typename T> class SK_API SkTDArray { |
public: |
SkTDArray() { |
- fReserve = fCount = 0; |
- fArray = NULL; |
-#ifdef SK_DEBUG |
- fData = NULL; |
-#endif |
+ this->init(NULL, 0, NULL, 0); |
} |
SkTDArray(const T src[], size_t count) { |
- SkASSERT(src || count == 0); |
- |
- fReserve = fCount = 0; |
- fArray = NULL; |
-#ifdef SK_DEBUG |
- fData = NULL; |
-#endif |
- if (count) { |
- fArray = (T*)sk_malloc_throw(count * sizeof(T)); |
-#ifdef SK_DEBUG |
- fData = (ArrayT*)fArray; |
-#endif |
- memcpy(fArray, src, sizeof(T) * count); |
- fReserve = fCount = count; |
- } |
+ this->init(src, count, NULL, 0); |
} |
SkTDArray(const SkTDArray<T>& src) { |
- fReserve = fCount = 0; |
- fArray = NULL; |
-#ifdef SK_DEBUG |
- fData = NULL; |
-#endif |
- SkTDArray<T> tmp(src.fArray, src.fCount); |
- this->swap(tmp); |
+ this->init(src.fArray, src.fCount, NULL, 0); |
} |
+ |
~SkTDArray() { |
- sk_free(fArray); |
+ if (fArray != fPreAllocMemArray) { |
+ sk_free(fArray); |
+ } |
} |
SkTDArray<T>& operator=(const SkTDArray<T>& src) { |
@@ -72,11 +52,10 @@ |
void swap(SkTDArray<T>& other) { |
SkTSwap(fArray, other.fArray); |
-#ifdef SK_DEBUG |
- SkTSwap(fData, other.fData); |
-#endif |
+ SkTSwap(fPreAllocMemArray, other.fPreAllocMemArray); |
SkTSwap(fReserve, other.fReserve); |
SkTSwap(fCount, other.fCount); |
+ SkTSwap(fPreAllocMemArraySize, other.fPreAllocMemArraySize); |
} |
/** Return a ptr to the array of data, to be freed with sk_free. This also |
@@ -84,9 +63,11 @@ |
*/ |
T* detach() { |
T* array = fArray; |
- fArray = NULL; |
- fReserve = fCount = 0; |
- SkDEBUGCODE(fData = NULL;) |
+ if (fArray == fPreAllocMemArray) { |
bungeman-skia
2013/04/26 15:58:36
If these are both NULL (count==0 and this is SkTDA
|
+ array = (T*)sk_malloc_throw(fCount * sizeof(T)); |
+ memcpy(array, fPreAllocMemArray, fCount * sizeof(T)); |
+ } |
+ this->init(NULL, 0, fPreAllocMemArray, fPreAllocMemArraySize); |
return array; |
} |
@@ -124,16 +105,10 @@ |
} |
void reset() { |
- if (fArray) { |
+ if (fArray != fPreAllocMemArray) { |
sk_free(fArray); |
- fArray = NULL; |
-#ifdef SK_DEBUG |
- fData = NULL; |
-#endif |
- fReserve = fCount = 0; |
- } else { |
- SkASSERT(fReserve == 0 && fCount == 0); |
} |
+ this->init(NULL, 0, fPreAllocMemArray, fPreAllocMemArraySize); |
} |
void rewind() { |
@@ -330,36 +305,105 @@ |
SkASSERT((fReserve == 0 && fArray == NULL) || |
(fReserve > 0 && fArray != NULL)); |
SkASSERT(fCount <= fReserve); |
- SkASSERT(fData == (ArrayT*)fArray); |
} |
#endif |
+protected: |
+ template <size_t N> SkTDArray(SkAlignedSTStorage<N, T>* storage) { |
+ this->init(NULL, 0, (T*)storage->get(), N); |
+ } |
+ template <size_t N> SkTDArray(const T src[], size_t count, SkAlignedSTStorage<N, T>* storage) { |
+ this->init(src, count, (T*)storage->get(), N); |
+ } |
+ template <size_t N> SkTDArray(const SkTDArray<T>& src, SkAlignedSTStorage<N, T>* storage) { |
+ this->init(src.fData, src.fCount, (T*)storage->get(), N); |
+ } |
+ |
+ void init(const T* src, size_t count, T* preAllocStorage, size_t preAllocCount) { |
+ SkASSERT(src || count == 0); |
+ |
+ fArray = NULL; |
+ fPreAllocMemArray = preAllocStorage; |
+ fReserve = 0; |
+ fCount = 0; |
+ fPreAllocMemArraySize = preAllocCount; |
+ |
+ if (count) { |
+ fArray = fPreAllocMemArray; |
+ fReserve = fPreAllocMemArraySize; |
+ fCount = count; |
+ if (NULL == fArray || fCount > fReserve) { |
+ fArray = (T*)sk_malloc_throw(fCount * sizeof(T)); |
+ fReserve = fCount = count; |
+ } |
+ memcpy(fArray, src, sizeof(T) * count); |
+ } |
+ } |
+ |
private: |
-#ifdef SK_DEBUG |
- enum { |
- kDebugArraySize = 16 |
- }; |
- typedef T ArrayT[kDebugArraySize]; |
- ArrayT* fData; |
-#endif |
- T* fArray; |
- size_t fReserve, fCount; |
+ T* fArray; |
+ T* fPreAllocMemArray; |
+ size_t fReserve, fCount, fPreAllocMemArraySize; |
void growBy(size_t extra) { |
SkASSERT(extra); |
if (fCount + extra > fReserve) { |
+ if (NULL == fArray && fCount + extra <= fPreAllocMemArraySize) { |
+ fArray = fPreAllocMemArray; |
+ fReserve = fPreAllocMemArraySize; |
+ fCount += extra; |
+ return; |
+ } |
+ |
size_t size = fCount + extra + 4; |
size += size >> 2; |
- fArray = (T*)sk_realloc_throw(fArray, size * sizeof(T)); |
-#ifdef SK_DEBUG |
- fData = (ArrayT*)fArray; |
-#endif |
+ if (fArray == fPreAllocMemArray) { |
+ fArray = (T*)sk_malloc_throw(size * sizeof(T)); |
+ memcpy(fArray, fPreAllocMemArray, fCount * sizeof(T)); |
+ } else { |
+ fArray = (T*)sk_realloc_throw(fArray, size * sizeof(T)); |
+ } |
fReserve = size; |
} |
fCount += extra; |
} |
}; |
+ |
+/** |
+ * Subclass of SkTDArray that contains a preallocated memory block for the array. |
+ */ |
+template <size_t N, typename T> |
+class SkSTDArray : public SkTDArray<T> { |
+private: |
+ typedef SkTDArray<T> INHERITED; |
+ |
+public: |
+ SkSTDArray() : INHERITED(&fStorage) { |
+ } |
+ |
+ SkSTDArray(const T* src, int count) : INHERITED(src, count, &fStorage) { |
+ } |
+ |
+ SkSTDArray(const SkSTDArray& src) : INHERITED(src, &fStorage) { |
+ } |
+ |
+ explicit SkSTDArray(const INHERITED& src) : INHERITED(src, &fStorage) { |
+ } |
+ |
+ SkSTDArray& operator= (const SkSTDArray& that) { |
+ return *this = *(const INHERITED*)&that; |
+ } |
+ |
+ SkSTDArray& operator= (const INHERITED& that) { |
+ INHERITED::operator=(that); |
+ return *this; |
+ } |
+ |
+private: |
+ SkAlignedSTStorage<N, T> fStorage; |
+}; |
+ |
#endif |