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

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

Issue 14502003: Add SkSTDArray. Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Remove unwanted change. 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
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
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
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
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