Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(207)

Side by Side Diff: include/core/SkTDArray.h

Issue 14502003: Add SkSTDArray. Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Preserve count==0, detatch()==NULL. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 55 SkTSwap(fPreAllocMemArray, other.fPreAllocMemArray);
76 SkTSwap(fData, other.fData);
77 #endif
78 SkTSwap(fReserve, other.fReserve); 56 SkTSwap(fReserve, other.fReserve);
79 SkTSwap(fCount, other.fCount); 57 SkTSwap(fCount, other.fCount);
58 SkTSwap(fPreAllocMemArraySize, other.fPreAllocMemArraySize);
80 } 59 }
81 60
82 /** Return a ptr to the array of data, to be freed with sk_free. This also 61 /** Return a ptr to the array of data, to be freed with sk_free. This also
83 resets the SkTDArray to be empty. 62 resets the SkTDArray to be empty.
84 */ 63 */
85 T* detach() { 64 T* detach() {
86 T* array = fArray; 65 T* array = fArray;
87 fArray = NULL; 66 if (NULL != fArray && fArray == fPreAllocMemArray) {
88 fReserve = fCount = 0; 67 array = (T*)sk_malloc_throw(fCount * sizeof(T));
89 SkDEBUGCODE(fData = NULL;) 68 memcpy(array, fPreAllocMemArray, fCount * sizeof(T));
69 }
70 this->init(NULL, 0, fPreAllocMemArray, fPreAllocMemArraySize);
90 return array; 71 return array;
91 } 72 }
92 73
93 bool isEmpty() const { return fCount == 0; } 74 bool isEmpty() const { return fCount == 0; }
94 75
95 /** 76 /**
96 * Return the number of elements in the array 77 * Return the number of elements in the array
97 */ 78 */
98 int count() const { return (int)fCount; } 79 int count() const { return (int)fCount; }
99 80
(...skipping 17 matching lines...) Expand all
117 } 98 }
118 99
119 T& getAt(int index) { 100 T& getAt(int index) {
120 return (*this)[index]; 101 return (*this)[index];
121 } 102 }
122 const T& getAt(int index) const { 103 const T& getAt(int index) const {
123 return (*this)[index]; 104 return (*this)[index];
124 } 105 }
125 106
126 void reset() { 107 void reset() {
127 if (fArray) { 108 if (fArray != fPreAllocMemArray) {
128 sk_free(fArray); 109 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 } 110 }
111 this->init(NULL, 0, fPreAllocMemArray, fPreAllocMemArraySize);
137 } 112 }
138 113
139 void rewind() { 114 void rewind() {
140 // same as setCount(0) 115 // same as setCount(0)
141 fCount = 0; 116 fCount = 0;
142 } 117 }
143 118
144 void setCount(size_t count) { 119 void setCount(size_t count) {
145 if (count > fReserve) { 120 if (count > fReserve) {
146 this->growBy(count - fCount); 121 this->growBy(count - fCount);
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 visitor(*curr); 298 visitor(*curr);
324 } 299 }
325 } 300 }
326 } 301 }
327 302
328 #ifdef SK_DEBUG 303 #ifdef SK_DEBUG
329 void validate() const { 304 void validate() const {
330 SkASSERT((fReserve == 0 && fArray == NULL) || 305 SkASSERT((fReserve == 0 && fArray == NULL) ||
331 (fReserve > 0 && fArray != NULL)); 306 (fReserve > 0 && fArray != NULL));
332 SkASSERT(fCount <= fReserve); 307 SkASSERT(fCount <= fReserve);
333 SkASSERT(fData == (ArrayT*)fArray);
334 } 308 }
335 #endif 309 #endif
336 310
311 protected:
312 template <size_t N> SkTDArray(SkAlignedSTStorage<N, T>* storage) {
313 this->init(NULL, 0, (T*)storage->get(), N);
314 }
315 template <size_t N> SkTDArray(const T src[], size_t count, SkAlignedSTStorag e<N, T>* storage) {
316 this->init(src, count, (T*)storage->get(), N);
317 }
318 template <size_t N> SkTDArray(const SkTDArray<T>& src, SkAlignedSTStorage<N, T>* storage) {
319 this->init(src.fData, src.fCount, (T*)storage->get(), N);
320 }
321
322 void init(const T* src, size_t count, T* preAllocStorage, size_t preAllocCou nt) {
323 SkASSERT(src || count == 0);
324
325 fArray = NULL;
326 fPreAllocMemArray = preAllocStorage;
327 fReserve = 0;
328 fCount = 0;
329 fPreAllocMemArraySize = preAllocCount;
330
331 if (count) {
332 fArray = fPreAllocMemArray;
333 fReserve = fPreAllocMemArraySize;
334 fCount = count;
335 if (NULL == fArray || fCount > fReserve) {
336 fArray = (T*)sk_malloc_throw(fCount * sizeof(T));
337 fReserve = fCount = count;
338 }
339 memcpy(fArray, src, sizeof(T) * count);
340 }
341 }
342
337 private: 343 private:
338 #ifdef SK_DEBUG 344 T* fArray;
339 enum { 345 T* fPreAllocMemArray;
340 kDebugArraySize = 16 346 size_t fReserve, fCount, fPreAllocMemArraySize;
341 };
342 typedef T ArrayT[kDebugArraySize];
343 ArrayT* fData;
344 #endif
345 T* fArray;
346 size_t fReserve, fCount;
347 347
348 void growBy(size_t extra) { 348 void growBy(size_t extra) {
349 SkASSERT(extra); 349 SkASSERT(extra);
350 350
351 if (fCount + extra > fReserve) { 351 if (fCount + extra > fReserve) {
352 if (NULL == fArray && fCount + extra <= fPreAllocMemArraySize) {
bungeman-skia 2013/04/26 16:26:17 Note that the same effect can be had by placing i
353 fArray = fPreAllocMemArray;
354 fReserve = fPreAllocMemArraySize;
355 fCount += extra;
356 return;
357 }
358
352 size_t size = fCount + extra + 4; 359 size_t size = fCount + extra + 4;
353 size += size >> 2; 360 size += size >> 2;
354 361
355 fArray = (T*)sk_realloc_throw(fArray, size * sizeof(T)); 362 if (fArray == fPreAllocMemArray) {
356 #ifdef SK_DEBUG 363 fArray = (T*)sk_malloc_throw(size * sizeof(T));
357 fData = (ArrayT*)fArray; 364 memcpy(fArray, fPreAllocMemArray, fCount * sizeof(T));
358 #endif 365 } else {
366 fArray = (T*)sk_realloc_throw(fArray, size * sizeof(T));
367 }
359 fReserve = size; 368 fReserve = size;
360 } 369 }
361 fCount += extra; 370 fCount += extra;
362 } 371 }
363 }; 372 };
364 373
374
375 /**
376 * Subclass of SkTDArray that contains a preallocated memory block for the array .
377 */
378 template <size_t N, typename T>
379 class SkSTDArray : public SkTDArray<T> {
380 private:
381 typedef SkTDArray<T> INHERITED;
382
383 public:
384 SkSTDArray() : INHERITED(&fStorage) {
385 }
386
387 SkSTDArray(const T* src, int count) : INHERITED(src, count, &fStorage) {
388 }
389
390 SkSTDArray(const SkSTDArray& src) : INHERITED(src, &fStorage) {
391 }
392
393 explicit SkSTDArray(const INHERITED& src) : INHERITED(src, &fStorage) {
394 }
395
396 SkSTDArray& operator= (const SkSTDArray& that) {
397 return *this = *(const INHERITED*)&that;
398 }
399
400 SkSTDArray& operator= (const INHERITED& that) {
401 INHERITED::operator=(that);
402 return *this;
403 }
404
405 private:
406 SkAlignedSTStorage<N, T> fStorage;
407 };
408
365 #endif 409 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698