Chromium Code Reviews| 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,9 +52,6 @@ |
| void swap(SkTDArray<T>& other) { |
| SkTSwap(fArray, other.fArray); |
| -#ifdef SK_DEBUG |
| - SkTSwap(fData, other.fData); |
| -#endif |
| SkTSwap(fReserve, other.fReserve); |
| SkTSwap(fCount, other.fCount); |
| } |
| @@ -84,9 +61,11 @@ |
| */ |
| T* detach() { |
| T* array = fArray; |
| - fArray = NULL; |
| - fReserve = fCount = 0; |
| - SkDEBUGCODE(fData = NULL;) |
| + if (fArray == fPreAllocMemArray) { |
|
reed1
2013/04/26 16:06:52
&& fCount > 0 ?
bungeman-skia
2013/04/26 16:26:16
I did this equivalently in PS5 with '&& fArray !=
|
| + array = (T*)sk_malloc_throw(fCount * sizeof(T)); |
| + memcpy(array, fPreAllocMemArray, fCount * sizeof(T)); |
| + } |
| + this->init(NULL, 0, fPreAllocMemArray, fPreAllocMemArraySize); |
| return array; |
| } |
| @@ -124,16 +103,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,20 +303,41 @@ |
| 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); |
| + |
| + fCount = count; |
| + fReserve = preAllocCount; |
| + fPreAllocMemArray = preAllocStorage; |
| + fPreAllocMemArraySize = preAllocCount; |
| + fArray = preAllocStorage; |
| + if (count) { |
| + if (NULL == preAllocStorage || 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; |
|
bungeman-skia
2013/04/25 22:41:30
I removed fData here as it was somewhat of a pain
|
| -#endif |
| - T* fArray; |
| - size_t fReserve, fCount; |
| + T* fArray; |
| + T* fPreAllocMemArray; |
| + size_t fReserve, fCount, fPreAllocMemArraySize; |
| void growBy(size_t extra) { |
| SkASSERT(extra); |
| @@ -352,14 +346,51 @@ |
| 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> |
|
reed1
2013/04/26 16:06:52
dox: N is the number of elements or the number of
bungeman-skia
2013/04/26 16:26:16
The number of elements. Will doc.
|
| +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) { |
|
reed1
2013/04/26 16:06:52
Do we need to support copying from another S versi
bungeman-skia
2013/04/26 16:26:16
I modeled this after SkTArray/SkSTArray, which is
|
| + } |
| + |
| + 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 |