Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #ifndef SkTDArray_DEFINED | 10 #ifndef SkTDArray_DEFINED |
| 11 #define SkTDArray_DEFINED | 11 #define SkTDArray_DEFINED |
| 12 | 12 |
| 13 #include "SkTypes.h" | 13 #include "SkTypes.h" |
| 14 #include "SkTemplates.h" | |
| 14 | 15 |
| 15 template <typename T> class SK_API SkTDArray { | 16 template <typename T> class SK_API SkTDArray { |
| 16 public: | 17 public: |
| 17 SkTDArray() { | 18 SkTDArray() { |
| 18 fReserve = fCount = 0; | 19 this->init(NULL, 0, NULL, 0); |
| 19 fArray = NULL; | |
| 20 #ifdef SK_DEBUG | |
| 21 fData = NULL; | |
| 22 #endif | |
| 23 } | 20 } |
| 24 SkTDArray(const T src[], size_t count) { | 21 SkTDArray(const T src[], size_t count) { |
| 25 SkASSERT(src || count == 0); | 22 this->init(src, count, NULL, 0); |
| 26 | |
| 27 fReserve = fCount = 0; | |
| 28 fArray = NULL; | |
| 29 #ifdef SK_DEBUG | |
| 30 fData = NULL; | |
| 31 #endif | |
| 32 if (count) { | |
| 33 fArray = (T*)sk_malloc_throw(count * sizeof(T)); | |
| 34 #ifdef SK_DEBUG | |
| 35 fData = (ArrayT*)fArray; | |
| 36 #endif | |
| 37 memcpy(fArray, src, sizeof(T) * count); | |
| 38 fReserve = fCount = count; | |
| 39 } | |
| 40 } | 23 } |
| 41 SkTDArray(const SkTDArray<T>& src) { | 24 SkTDArray(const SkTDArray<T>& src) { |
| 42 fReserve = fCount = 0; | 25 this->init(src.fArray, src.fCount, NULL, 0); |
| 43 fArray = NULL; | |
| 44 #ifdef SK_DEBUG | |
| 45 fData = NULL; | |
| 46 #endif | |
| 47 SkTDArray<T> tmp(src.fArray, src.fCount); | |
| 48 this->swap(tmp); | |
| 49 } | 26 } |
| 27 | |
| 50 ~SkTDArray() { | 28 ~SkTDArray() { |
| 51 sk_free(fArray); | 29 if (fArray != fPreAllocMemArray) { |
| 30 sk_free(fArray); | |
| 31 } | |
| 52 } | 32 } |
| 53 | 33 |
| 54 SkTDArray<T>& operator=(const SkTDArray<T>& src) { | 34 SkTDArray<T>& operator=(const SkTDArray<T>& src) { |
| 55 if (this != &src) { | 35 if (this != &src) { |
| 56 if (src.fCount > fReserve) { | 36 if (src.fCount > fReserve) { |
| 57 SkTDArray<T> tmp(src.fArray, src.fCount); | 37 SkTDArray<T> tmp(src.fArray, src.fCount); |
| 58 this->swap(tmp); | 38 this->swap(tmp); |
| 59 } else { | 39 } else { |
| 60 memcpy(fArray, src.fArray, sizeof(T) * src.fCount); | 40 memcpy(fArray, src.fArray, sizeof(T) * src.fCount); |
| 61 fCount = src.fCount; | 41 fCount = src.fCount; |
| 62 } | 42 } |
| 63 } | 43 } |
| 64 return *this; | 44 return *this; |
| 65 } | 45 } |
| 66 | 46 |
| 67 friend bool operator==(const SkTDArray<T>& a, const SkTDArray<T>& b) { | 47 friend bool operator==(const SkTDArray<T>& a, const SkTDArray<T>& b) { |
| 68 return a.fCount == b.fCount && | 48 return a.fCount == b.fCount && |
| 69 (a.fCount == 0 || | 49 (a.fCount == 0 || |
| 70 !memcmp(a.fArray, b.fArray, a.fCount * sizeof(T))); | 50 !memcmp(a.fArray, b.fArray, a.fCount * sizeof(T))); |
| 71 } | 51 } |
| 72 | 52 |
| 73 void swap(SkTDArray<T>& other) { | 53 void swap(SkTDArray<T>& other) { |
| 74 SkTSwap(fArray, other.fArray); | 54 SkTSwap(fArray, other.fArray); |
| 75 #ifdef SK_DEBUG | |
| 76 SkTSwap(fData, other.fData); | |
| 77 #endif | |
| 78 SkTSwap(fReserve, other.fReserve); | 55 SkTSwap(fReserve, other.fReserve); |
| 79 SkTSwap(fCount, other.fCount); | 56 SkTSwap(fCount, other.fCount); |
| 80 } | 57 } |
| 81 | 58 |
| 82 /** Return a ptr to the array of data, to be freed with sk_free. This also | 59 /** Return a ptr to the array of data, to be freed with sk_free. This also |
| 83 resets the SkTDArray to be empty. | 60 resets the SkTDArray to be empty. |
| 84 */ | 61 */ |
| 85 T* detach() { | 62 T* detach() { |
| 86 T* array = fArray; | 63 T* array = fArray; |
| 87 fArray = NULL; | 64 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 !=
| |
| 88 fReserve = fCount = 0; | 65 array = (T*)sk_malloc_throw(fCount * sizeof(T)); |
| 89 SkDEBUGCODE(fData = NULL;) | 66 memcpy(array, fPreAllocMemArray, fCount * sizeof(T)); |
| 67 } | |
| 68 this->init(NULL, 0, fPreAllocMemArray, fPreAllocMemArraySize); | |
| 90 return array; | 69 return array; |
| 91 } | 70 } |
| 92 | 71 |
| 93 bool isEmpty() const { return fCount == 0; } | 72 bool isEmpty() const { return fCount == 0; } |
| 94 | 73 |
| 95 /** | 74 /** |
| 96 * Return the number of elements in the array | 75 * Return the number of elements in the array |
| 97 */ | 76 */ |
| 98 int count() const { return (int)fCount; } | 77 int count() const { return (int)fCount; } |
| 99 | 78 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 117 } | 96 } |
| 118 | 97 |
| 119 T& getAt(int index) { | 98 T& getAt(int index) { |
| 120 return (*this)[index]; | 99 return (*this)[index]; |
| 121 } | 100 } |
| 122 const T& getAt(int index) const { | 101 const T& getAt(int index) const { |
| 123 return (*this)[index]; | 102 return (*this)[index]; |
| 124 } | 103 } |
| 125 | 104 |
| 126 void reset() { | 105 void reset() { |
| 127 if (fArray) { | 106 if (fArray != fPreAllocMemArray) { |
| 128 sk_free(fArray); | 107 sk_free(fArray); |
| 129 fArray = NULL; | |
| 130 #ifdef SK_DEBUG | |
| 131 fData = NULL; | |
| 132 #endif | |
| 133 fReserve = fCount = 0; | |
| 134 } else { | |
| 135 SkASSERT(fReserve == 0 && fCount == 0); | |
| 136 } | 108 } |
| 109 this->init(NULL, 0, fPreAllocMemArray, fPreAllocMemArraySize); | |
| 137 } | 110 } |
| 138 | 111 |
| 139 void rewind() { | 112 void rewind() { |
| 140 // same as setCount(0) | 113 // same as setCount(0) |
| 141 fCount = 0; | 114 fCount = 0; |
| 142 } | 115 } |
| 143 | 116 |
| 144 void setCount(size_t count) { | 117 void setCount(size_t count) { |
| 145 if (count > fReserve) { | 118 if (count > fReserve) { |
| 146 this->growBy(count - fCount); | 119 this->growBy(count - fCount); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 323 visitor(*curr); | 296 visitor(*curr); |
| 324 } | 297 } |
| 325 } | 298 } |
| 326 } | 299 } |
| 327 | 300 |
| 328 #ifdef SK_DEBUG | 301 #ifdef SK_DEBUG |
| 329 void validate() const { | 302 void validate() const { |
| 330 SkASSERT((fReserve == 0 && fArray == NULL) || | 303 SkASSERT((fReserve == 0 && fArray == NULL) || |
| 331 (fReserve > 0 && fArray != NULL)); | 304 (fReserve > 0 && fArray != NULL)); |
| 332 SkASSERT(fCount <= fReserve); | 305 SkASSERT(fCount <= fReserve); |
| 333 SkASSERT(fData == (ArrayT*)fArray); | |
| 334 } | 306 } |
| 335 #endif | 307 #endif |
| 336 | 308 |
| 309 protected: | |
| 310 template <size_t N> SkTDArray(SkAlignedSTStorage<N, T>* storage) { | |
| 311 this->init(NULL, 0, (T*)storage->get(), N); | |
| 312 } | |
| 313 template <size_t N> SkTDArray(const T src[], size_t count, SkAlignedSTStorag e<N, T>* storage) { | |
| 314 this->init(src, count, (T*)storage->get(), N); | |
| 315 } | |
| 316 template <size_t N> SkTDArray(const SkTDArray<T>& src, SkAlignedSTStorage<N, T>* storage) { | |
| 317 this->init(src.fData, src.fCount, (T*)storage->get(), N); | |
| 318 } | |
| 319 | |
| 320 void init(const T* src, size_t count, T* preAllocStorage, size_t preAllocCou nt) { | |
| 321 SkASSERT(src || count == 0); | |
| 322 | |
| 323 fCount = count; | |
| 324 fReserve = preAllocCount; | |
| 325 fPreAllocMemArray = preAllocStorage; | |
| 326 fPreAllocMemArraySize = preAllocCount; | |
| 327 fArray = preAllocStorage; | |
| 328 if (count) { | |
| 329 if (NULL == preAllocStorage || fCount > fReserve) { | |
| 330 fArray = (T*)sk_malloc_throw(fCount * sizeof(T)); | |
| 331 fReserve = fCount = count; | |
| 332 } | |
| 333 memcpy(fArray, src, sizeof(T) * count); | |
| 334 } | |
| 335 } | |
| 336 | |
| 337 private: | 337 private: |
| 338 #ifdef SK_DEBUG | 338 T* fArray; |
| 339 enum { | 339 T* fPreAllocMemArray; |
| 340 kDebugArraySize = 16 | 340 size_t fReserve, fCount, fPreAllocMemArraySize; |
| 341 }; | |
| 342 typedef T ArrayT[kDebugArraySize]; | |
| 343 ArrayT* fData; | |
|
bungeman-skia
2013/04/25 22:41:30
I removed fData here as it was somewhat of a pain
| |
| 344 #endif | |
| 345 T* fArray; | |
| 346 size_t fReserve, fCount; | |
| 347 | 341 |
| 348 void growBy(size_t extra) { | 342 void growBy(size_t extra) { |
| 349 SkASSERT(extra); | 343 SkASSERT(extra); |
| 350 | 344 |
| 351 if (fCount + extra > fReserve) { | 345 if (fCount + extra > fReserve) { |
| 352 size_t size = fCount + extra + 4; | 346 size_t size = fCount + extra + 4; |
| 353 size += size >> 2; | 347 size += size >> 2; |
| 354 | 348 |
| 355 fArray = (T*)sk_realloc_throw(fArray, size * sizeof(T)); | 349 if (fArray == fPreAllocMemArray) { |
| 356 #ifdef SK_DEBUG | 350 fArray = (T*)sk_malloc_throw(size * sizeof(T)); |
| 357 fData = (ArrayT*)fArray; | 351 memcpy(fArray, fPreAllocMemArray, fCount * sizeof(T)); |
| 358 #endif | 352 } else { |
| 353 fArray = (T*)sk_realloc_throw(fArray, size * sizeof(T)); | |
| 354 } | |
| 359 fReserve = size; | 355 fReserve = size; |
| 360 } | 356 } |
| 361 fCount += extra; | 357 fCount += extra; |
| 362 } | 358 } |
| 363 }; | 359 }; |
| 364 | 360 |
| 361 | |
| 362 /** | |
| 363 * Subclass of SkTDArray that contains a preallocated memory block for the array . | |
| 364 */ | |
| 365 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.
| |
| 366 class SkSTDArray : public SkTDArray<T> { | |
| 367 private: | |
| 368 typedef SkTDArray<T> INHERITED; | |
| 369 | |
| 370 public: | |
| 371 SkSTDArray() : INHERITED(&fStorage) { | |
| 372 } | |
| 373 | |
| 374 SkSTDArray(const T* src, int count) : INHERITED(src, count, &fStorage) { | |
| 375 } | |
| 376 | |
| 377 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
| |
| 378 } | |
| 379 | |
| 380 explicit SkSTDArray(const INHERITED& src) : INHERITED(src, &fStorage) { | |
| 381 } | |
| 382 | |
| 383 SkSTDArray& operator= (const SkSTDArray& that) { | |
| 384 return *this = *(const INHERITED*)&that; | |
| 385 } | |
| 386 | |
| 387 SkSTDArray& operator= (const INHERITED& that) { | |
| 388 INHERITED::operator=(that); | |
| 389 return *this; | |
| 390 } | |
| 391 | |
| 392 private: | |
| 393 SkAlignedSTStorage<N, T> fStorage; | |
| 394 }; | |
| 395 | |
| 365 #endif | 396 #endif |
| OLD | NEW |